0

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)

  1. I am assembling the XOR decoder for windows - nasm -fwin64 (with message box shellcode pasted in)
  2. linking for windows using golink
  3. Failing to execute on windows

This is the Linux XOR encode/decode method that works great.


  1. Uses HelloWorld.nasm
  2. Assemble with - nasm -felf64 HelloWorld.nasm -o HelloWorld.o
  3. Extract shellcode with - for i in $(objdump -d [binary-or-objectfile] |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo
  4. 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();
    
    }
    
  5. 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
  1. 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
    
    1. Assembled with - nasm -felf64 HelloWorldEncoded.nasm -o HelloWorldEncoded.o
    2. 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:

  1. nasm -f win64 messageBox64bit.asm -o messageBox64bit.obj

  2. golink /console messageBox64bit.obj

  3. Execute on Win764 ./messageBox64bit.exe

GREAT! messageBox64bit.exe pops the message box. Now the ISSUE.

  1. I assembled messageBox64bit.nasm with nasm
  2. ran extracted messagebox shellcode through XOR encoder
  3. pasted asm friendly XOR encoded shellcode into decoder
  4. Adjust RCX (cl) counter for new shellcode length
  5. Assembled decoder with nasm with -fwin64 option
  6. Linked with golink /console messageBox64bit.obj
  7. 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
  • where does it crash? what is the instruction at the crash location and what memory it's trying to access? – Igor Skochinsky Sep 5 '17 at 17:41
  • Just added the crash. It is crashing on the XOR function that I have set up in the decoder. – hexhatchet Sep 5 '17 at 17:42
  • 1
    C0000096 is "privileged instruction"; 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. – Igor Skochinsky Sep 6 '17 at 7:29
  • can you post the full nasm code that fails – Paweł Łukasik Sep 6 '17 at 20:08
  • I made an edit above with the full nasm. Source of the XORed shellcode is from a messagebox. here .tophertimzen.com/blog/windowsx64Shellcode – hexhatchet Sep 7 '17 at 1:24
2

There are few issues with your code.

1st is what Igor mentioned - .text section is RO. This was solved in this answer.

The 2nd is that you did not copy correctly the bytes or lost some of them in other way. Your shellcode has 260 bytes, but if I compile the example for the link that you've provided then I get 262. I run them by a short python script to xor them and after that I get this:

db 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, 0x2, 0x8, 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, 0xaa, 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, 0xaa, 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, 0x6, 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

After you do this the result is

enter image description here

Full code:

bits 64
section .text
global start

start:
        jmp find_address

decoder:
        pop rdi
        xor rcx, rcx
        add cx, 262
decode:
        xor byte [rdi],0xAA
        inc rdi
        loop decode

        jmp short encoded_shellcode

find_address:
        call decoder


encoded_shellcode: 
       db 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, 0x2, 0x8, 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, 0xaa, 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, 0xaa, 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, 0x6, 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
2

I think the problem is that the executable code is not writeable by default on Windows, so it fails when xor tries to modify the code. You should look into how to modify .text section permissions, either at assembly/link time or at runtime.

Another solution could be to copy the shellcode to writeable memory before decryption, however this may lead to the opposite problem - it may be non-executable.

  • Thanks for your help. You definitely noticed the RWE issue. I couldn't figure out why after I edited it as writeable, it still didn't work. My count was bad for the decoder! – hexhatchet Sep 17 '17 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.