kunpeng source code analysis

Posted by lipsius at 2020-02-29

*After turning to security, I have read a lot of open source tools roughly, and have been considering writing some source code analysis articles of artifact. Looking back to pocsuite and bugscan, plug-in POC was very popular at that time. Many people dream of having such a powerful POC framework. Yesterday, I saw @ wolf and several big bulls open source a go cross language POC detection framework Kunpeng. Just because it has a small amount of code, it is suitable for the next year. Take it as the beginning of this series.

According to the introduction of the official documents, this project is provided to go and other languages in the form of dynamic link library, so there will be two roles of caller and callee, please distinguish them carefully.

Get objects

The caller calls the plugin package to load the so file and gets the greeter object:

plugin Greeter

Because plugin. Lookup() gets an interface {} type object, it needs to make a type assertion to access the public properties in the greeter object. Fortunately, go has the language feature of non-invasive interface, which enables the caller to locally define an interface belonging to the public method subset of the greeter object to assert success:

Plugin.Lookup() interface{} Greeter Greeter

Execution detection

The caller defines a task structure, which is converted into a JSON string after instantiation and passed to greeter. Check(), waiting for the detection result:

Task Greeter.Check()

After parsing the JSON string and getting the plugin.task object (the structure is the same as the task defined by the caller), the callee's check () will directly give it to plugin.scan () to execute the actual detection logic, and the result will be converted into the JSON string to return:

Check() plugin.Task Task plugin.Scan()

As you can see from the above code, in order to support cross language calls, Kunpeng uses a lower level, more compatible CGO to handle the original data types in several entry functions.

Plugin. Scan() traverses goplugins and jsonplugins respectively (for the specific differences between the two types of plug-ins, please refer to the following plug-in development and plug-in loading chapters), selects POC subsets according to the target field of the task to detect and return the result set:

plugin.Scan() GoPlugins JSONPlugins Task Target

Plug-in development

Go type plug in

Kunpeng defines a public structure plugin to describe plug-in information:


And public interface goplugin:


Because Kunpeng does not define the plug-in's related base classes and default fields and methods, we need to create a new. Go file in the plugin / go / directory, where we need to customize a structure containing the info and result fields to represent the new plug-in:

plugin/go/ info result

Then, implement all methods in goplugin interface for the structure:


Func (p * pluginxxx) check (netloc string, meta taskmeta) bool {/ / customize the logic of the detection process, return true for success and false return false for failure}

func (p *pluginXXX) GetResult() []plugin.Plugin {return p.result}

In the init () method of the file, call plugin.Regist () to register the plug-in.

init() plugin.Regist()

JSON type plug-in

Kunpeng also prepared the public structure jsonplugin for us to describe JSON plug-in information, and implemented the unified detection method jsoncheck():

JSONPlugin jsonCheck()

We can create a new. JSON file in the plugin / JSON / directory and write the information we need (refer to the official document for details):


Plug-in loading

Go type plug in

As mentioned earlier, a go type plug-in needs to be registered at init(). Register() will put the plug-in object into the goplugins collection with target as the key, and initialize the plug-in information:

init() Regist() target GoPlugins

Because the plugin / go package is imported anonymously in the entry file, all the written plug-ins of go type will be init() loaded into goplugins when the program starts.

plugin/go init() GoPlugins

JSON type plug-in

In contrast, the loading process of JSON type plug-ins is a little tedious.

After the entry file imports the plugin / JSON package anonymously, the init() method in the plugin / JSON / init.go file will be called to load:

plugin/json plugin/json/init.go init()

Loadjsonplugin() traverses all the. JSON files in the directory and submits them to readplugin() for processing. Readplugin() parses the JSON string into a jsonplugin object after reading the file, and all non repetitive plug-in objects will be put into the jsonplugins collection with target as the key.

loadJSONPlugin() readPlugin() readPlugin() JSONPlugin target JSONPlugins

The newly opened goroutine calls loadextrajsonplugin() to load the configured extra plugin path directory every 20 seconds.

loadExtraJSONPlugin() extra_plugin_path loadJSONPlugin()

In order to save space, I won't elaborate here.

In the last words

I really admire the open source spirit of several big bulls. Please give more PR to contribute to this new POC framework and vulnerability library.

Reference resources