report 1: reverse rules of alibaba cloud security knight webshell

Posted by millikan at 2020-03-13

Environment / tools:

Debian 8, GDB, GDB-peda,,IDA-pro

Introduction to Knight an

Alicloud security knight is alicloud shield's client on user VPS, similar to the client of osec. It can continuously run in the client server, check the files under the sensitive directory of the server and related system processes at regular intervals, and judge whether there is a vulnerability, webshell, and mount program. The most interesting part is alicloud horse How to identify webshell. The main process name of aliyundun is aliyundun, and its file directory is under / usr / local / aegis / aegis ﹣ client /. There may be different versions. Here we choose aegis ﹣ 10 ﹣ 25 as our analysis object.

Basic framework understanding and information collection

In the folder of Android, in addition to the main program aliyundun, we can also see some of its own dynamic link libraries. From the name of the dynamic link library, we can roughly understand the functions of these dynamic link libraries. For example, must be related to our interesting webshell detection.

After that, we found the information related to the webshell detection in the conf directory and the rule directory respectively. In the conf directory, there are configuration files for webshell detection:


The data directory stores the log data of Knight Ann. The suffix after data is determined by the week of the day. For example, if today is Friday, the log file name generated in the data directory is data.5. Through these logs, we can judge the status of each module of the knight.

Some data related to matching rules are stored in the rule directory, most of which are encrypted. The main purpose of this report is to introduce how to crack these encrypted data.

Specific reverse process

Determine the file location of webshell rule store:

We can delete the files in the rule directory one by one, restart the aliyundun process, and then check the logs in the data directory to see whether there is an error of webshell module startup failure. Then we can determine which configuration files are related to webshell. Finally, we can test out that is a necessary module for the normal operation of webshell module.

Reverse DLL:

Throw the function library into IDA pro, and then try to search text. The content of text is the encrypted file stored by webshell rules that we just found. After finding the string, we can transfer it to the function using the string through XRef.

This function is the loaddb function in the cwebshellchecker class. After a brief look at this function, we can see that this function calls the decryption function cwebshellchecker:: decoderulefile, and the secret key looks like aaaabbbb.

Continue to trace, we can find that the final function to realize decryption is AQS:: cagorithmutil:: xxaesdecrypt:

Guessing may be that the common AES algorithm encrypts files, but it doesn't rule out that Ali encapsulates an AES function. If the cost is too high to continue tracking, we might as well write a CPP program to call this function. However, we are not sure about the parameters that need to be passed to the function. Therefore, it is better to directly call the loaddb function that does not accept any parameters, and then import the decrypted file from memory through GDB tracking before CPP destroys the cwebshellchecker class.

The complete call process of decryption function is as follows:

    CWebShellChecker::LoadDb => CWebShellChecker::DecodeRuleFile     aqs::CAlgorithmUtil::xxAesDecrypt

The first attempt is to directly debug the main program aliyundun, but the main program has an unknown anti debugging mechanism, so it failed.

3. Write / compile CPP program

First, we write the following CPP program to call the loaddb function in the webshell module.


When compiling, we need to pay attention to that because we call, we need to specify the linked function library in the compilation. In addition, these function libraries have complex interdependencies. We simply link all the function libraries. The options of this compile command can be generated through Python script:

The contents of so.txt can be generated using the awk command.

The final compilation command is:

It should be noted that some additional link libraries need to be added later to meet the compilation dependency: - LDL - lcurl - Levent - lpthread - levent_ptthreads - lhack. is because we can't find which function library get UUID belongs to, so we built a function library ourselves to meet the compilation dependency. The source code of is as follows:

Then compile the source code into a shared link library:

Finally, we can use GDB to debug the generated binary 1.

4. Debugging binaries

Before debugging, we need to determine the names of several key functions to facilitate setting breakpoints during GDB debugging:

Loaddb runtime function name: "zn16cwebshellchecker6loaddbev"

Decoderulefile runtime function name: "zn16cwebshellchecker14decoderulefilesrss1"_

Xxaesdecrypt runtime function name: 〝 zn3aqs14calgorithmutil12xxaesdecrypterkss2 〝 RSS

GetInstance runtime function name: "zn10csingletoni20cwbeshellplusscannere11getinstanceev"

Cmutexlockutil runtime function name: 〝 zn3aqs14cmutexlockutilc1epns 〝 10cmutexutile (a lock related function that needs to be bypassed)

The above function names are all found by attaching to the original aliyundun process and searching mem.

Next, we start debugging program 1. First, we break the program after the getInstance function. When the getInstance runs, we need to set the return value to non-zero to bypass the function check. Because according to the fastcall calling convention, the return value is stored in $rax, so we can set $rax = 1.

When cmutexlockutil is executed, skip the function directly through set $rip = next instruction address.

Then go to the decoderulefile, and we can see the contents of the parameters clearly:

In this case, our call is equivalent to decoderulefile (0x0, "/ usr / local / aegis / aegis [Client / aegis / rule / plusdata. Data", 0x0, "aaaaabbbb")

At the end of this function, the decrypted content has appeared in the file. We can locate the starting address of the file in memory through some keywords, and finally export the file using DumpMem 0x7ffff7f3f028 0x7ffff7f85803.

Check the content of and find that it is the rules of webshell detection that we want to extract.

There are other files in the rule folder. The decryption method is similar.


Through this reverse process, we briefly reviewed the use of GDB and GDB PEDA, and learned how to debug and load the dynamic link library. In addition, attention should be paid to the handling of multi process programs during debugging:

Set detach on fork on

Set follow fork mode child