Should I be able to extract shellcode from a basic (tested and working) Win7-64 message box app and place the extracted shellcode into a tested and working assembly language encoder/decoder and expect it to work? (Assembling & linking for windows instead of linking for linux)
I have tested a simple XOR encoder/decoder on linux with success using the steps listed below. In short, I have a WORKING XOR encoder/decoder system and I tried using win764 message box shellcode with my encode/decode sytem.(I know this seems obvious I can't run shellcode from linux to windows but there is more to it)
I simply replaced the extracted shellcode from the Win7 message box into my encode/decode system. Assembled with nasm -fwin64 then linked with golink on windows to get an exe and it crashes every time. (Tested steps without encoder and assemble/link/execute work perfectly)
- I am assembling the XOR decoder for windows - nasm -fwin64 (with message box shellcode pasted in)
- linking for windows using golink
- Failing to execute on windows
This is the Linux XOR encode/decode method that works great.
- Uses HelloWorld.nasm
- Assemble with - nasm -felf64 HelloWorld.nasm -o HelloWorld.o
- Extract shellcode with - for i in $(objdump -d [binary-or-objectfile] |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo
Place HelloWorld shellcode in C wrapper
#include<stdio.h> #include<string.h> unsigned char code[] = \ "\xeb\x1e\x5e\x48\x31\xc0\xb0\x01\x48\x89\xc7\x48\x89\xfa\x48\x83\xc2\x22\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xdd\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x20\x0a"; int main() { printf("Shellcode Length: %d\n", (int)strlen(code)); int (*ret)() = (int(*)())code; ret(); }
Run ./HelloWorld (validated that shellcode works in C wrapper)
Now, I use a simple XOR encoder with python to XOR the HelloWorld shellcode.
1.python XOREncoder.py
XORed HelloWorld shellcode formated for nasm output:
0x41,0xb4,0xf4,0xe2,0x9b,0x6a,0x1a,0xab,0xe2,0x23,0x6d,0xe2,0x23,0x50,0xe2,0x29,0x68,0x88,0xa5,0xaf,0xe2,0x9b,0x6a,0xe2,0x29,0x6a,0x96,0xe2,0x9b,0x55,0xa5,0xaf,0x42,0x77,0x55,0x55,0x55,0xe2,0xcf,0xc6,0xc6,0xc5,0x8a,0xfd,0xc5,0xd8,0xc6,0xce,0x8a,0xa0
Place XORed shellcode in XORdecoder.nasm like this:
global _start section .text _start: start: jmp find_address decoder: pop rdi xor rcx, rcx add cl, 50 decode: xor byte [rdi], 0xAA inc rdi loop decode jmp short encoded_shellcode find_address: call decoder encoded_shellcode: db 0x41,0xb4,0xf4,0xe2,0x9b,0x6a,0x1a,0xab,0xe2,0x23,0x6d,0xe2,0x23,0x50,0xe2,0x29,0x68,0x88,0xa5,0xaf,0xe2,0x9b,0x6a,0xe2,0x29,0x6a,0x96,0xe2,0x9b,0x55,0xa5,0xaf,0x42,0x77,0x55,0x55,0x55,0xe2,0xcf,0xc6,0xc6,0xc5,0x8a,0xfd,0xc5,0xd8,0xc6,0xce,0x8a,0xa0
- Assembled with - nasm -felf64 HelloWorldEncoded.nasm -o HelloWorldEncoded.o
- Compiled with GCC and tested. WORKS!
NOW, here is the issue on Windows 7 64
I found a great example of a WIN 7 64 bit messagebox.nasm that just pops a message box here. So naturally I wanted to test my XOR decoder. So I tried to assemble and link my decoder for windows like this.
I tested this using these steps described in the link:
nasm -f win64 messageBox64bit.asm -o messageBox64bit.obj
golink /console messageBox64bit.obj
- Execute on Win764 ./messageBox64bit.exe
GREAT! messageBox64bit.exe pops the message box. Now the ISSUE.
- I assembled messageBox64bit.nasm with nasm
- ran extracted messagebox shellcode through XOR encoder
- pasted asm friendly XOR encoded shellcode into decoder
- Adjust RCX (cl) counter for new shellcode length
- Assembled decoder with nasm with -fwin64 option
- Linked with golink /console messageBox64bit.obj
Try to execute on WIN 7 64.
It crashes every damn time What is wrong here?.
EDIT1:
Crashes in windbg on the XOR function:
Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
xordecoder2+0x1009:
00000000`00401009 8037aa xor byte ptr [rdi],0AAh ds:00000000`00401018=e7
0:000> t
ds:00000000`00401018=e7
0:000> t
Edit2. Following the advice from Igor below, I edited the EXE to have the .text section writeable. Apparently the .text section is not writeable for a windows EXE. Error changed to this now:
(1f08.1af0): Unknown exception - code c0000096 (first chance)
(1f08.1af0): Unknown exception - code c0000096 (!!! second chance !!!)
*** ERROR: Module load completed but symbols could not be loaded for C:\data_section_xorencoder7.exe
data_section_xorencoder7+0x1016:
00000000`00401016 e7ff out 0FFh,eax
EDIT Nasm code. XORed shellcode.
bits 64
section .text
global start
start:
jmp find_address
decoder:
pop rdi
xor rcx, rcx
add cx, 260
decode:
xor byte [rdi], 0xAA
inc rdi
loop decode
jmp short encoded_shellcode
find_address:
call decoder
encoded_shellcode: 0xe2,0x29,0x46,0x82,0xe2,0x29,0x4e,0x5a,0xcf,0xe6,0x21,0x8e,0x8f,0xca,0xaa,0xaa,0xaa,0xe7,0x21,0xce,0x8e,0xb2,0xe7,0x21,0xce,0x8e,0x8a,0xe7,0x21,0x8e,0x8e,0xe7,0x21,0xd6,0x8e,0x8a,0xe7,0x21,0x8e,0x8e,0xe7,0x21,0xce,0x8e,0x8a,0x10,0x24,0xe4,0xa4,0x46,0xe6,0x23,0x4b,0x42,0xc2,0xaa,0xaa,0xaa,0x41,0x9e,0xf3,0x55,0x7a,0x10,0x02,0x08,0xe7,0x16,0xe2,0x23,0x6b,0x42,0xfc,0xaa,0xaa,0xaa,0xe2,0x23,0x69,0xe7,0x9b,0x63,0x41,0x94,0xeb,0xf2,0x41,0x82,0xf0,0xe2,0x9b,0x63,0x55,0x79,0x10,0xda,0x67,0x95,0x87,0xe6,0x23,0x53,0x42,0x9d,0xaa,0xaa,0xaa,0xe2,0x9b,0x63,0x55,0x7a,0x42,0x6d,0x55,0x55,0x55,0xdf,0xd9,0xcf,0xd8,0x99,0x98,0x84,0xce,0xc6,0xc6,0x42,0x79,0x55,0x55,0x55,0xfe,0xc2,0xc3,0xd9,0x8a,0xc3,0xd9,0x8a,0xcc,0xdf,0xc4,0x8b,0xaa,0x42,0x17,0x55,0x55,0x55,0x9a,0xd2,0xce,0xcf,0xcb,0xce,0xc8,0xcf,0xcf,0xcc,0xe3,0x23,0x67,0xcd,0xeb,0x21,0xef,0x96,0xcd,0xef,0x21,0x1e,0xaf,0x22,0xaa,0xaa,0xaa,0xef,0xab,0x44,0xcd,0xef,0x21,0xfc,0xb2,0xcd,0xeb,0x21,0xf4,0x8a,0xee,0xab,0x41,0xcd,0x49,0x95,0xeb,0x55,0x60,0xcd,0xe8,0x21,0x9e,0x39,0xee,0xab,0x44,0x9b,0x55,0x9b,0x6a,0x56,0x06,0x2e,0x6a,0xde,0xad,0x6b,0x65,0xa7,0xab,0x6d,0x41,0x5e,0x93,0x7d,0xdf,0x77,0xcd,0xeb,0x21,0xf4,0x8e,0xee,0xab,0x41,0x9b,0x63,0xcc,0xcd,0xe8,0x21,0xa6,0xf9,0xcd,0xeb,0x21,0xf4,0xb6,0xee,0xab,0x41,0xcd,0x21,0xae,0x21,0xee,0xab,0x42,0x69
out
instructions can only be executed in kernel mode. looks like something is wrong with either your shellcode, or the encryption/decryption process. You'll just have to step through it and figure out what's the problem.