Hello I am Arsalan. Offensive Security Engineer, I blog about Cyber security, CTF writeup, Programming, Blockchain and more about tech. born and raised in indonesia, currently living in indonesia
on 6 December 2020, me and my team TNT participated in a national CTF competition event held by CSIRT.ID. I got firstblood on this challenge baby arm.
it’s quite hard for me, especially on the debugging process since this is an arm binary. In this post I will cover how I solved this challenge from
static analysis, debugging process to cat the flag. before solving this challenge I already have some experience solving arm binary challenge
you can also read my writeup from MetaCTF 2020 | executor arm64here writing shellcode to get the flag,
Setup environment
since I only have an intel based machine so I need to install some tools in order to debug the binary
gdb-multiarch
qemu
qemu arm supported packages
python2
Static Analysis
main: ELF 32-bit LSB executable, ARM,
EABI5 version 1 (GNU/Linux), statically linked,
BuildID[sha1]=bbba9cc93bb8366814ab20761eb8447eafe08ee4,
for GNU/Linux 3.2.0, not stripped
we already know this is an arm 32bit elf binary, so we can load this binary on ida pro 32bit.
let’s take a look at the main function
it’s call 2 function sice() and vuln(), now let’s take a look at sice()
looks like a normal ctf binary challenge but there’s a system() function, we can use system() instead of execve()
and this is the vuln() function
this function looks very similar to ezrop revenge challenge from hacktoday final 2019 link now we have to make a ropchain to write our reverse shell payload on the .bss
segment then use system() to get a remote shell.
Collecting All We Need
we can use ropper to acquire all the gadgets we need.
0x0001e944 (0x0001e945): pop {r0, r1, r2, r3, pc};
0x00036bb2 (0x00036bb3): str r1, [r3]; pop {r4, r5, r6, pc};
we need pop {r0, r1, r2, r3, pc}; to store our string on the register %r1 and .bss address on %r3
then write our value to addres of %r3 using gadget str r1, [r3]; pop {r4, r5, r6, pc};. now we can
use readelf to get .bss segment address.
the last one, we can use ida to get system address
Debugging Process
we can use gdb to debug this binary and write our payload to a file so we can easily debug our rop
first we can use pattern create from gdb-gef to determine what is the offset to overwrite the Instruction Pointer.
in order to input our payload, we can just pipe our exploit to the binary like
python exploit.py| qemu-arm -g 12346 ./main
for example, our exploit.py will look like
and on the gdb side first, we can set the architecture
set arch armv5
then set the debugging target for remote debugging
target remote localhost:12345
as you can see here, we have overwritten the %pc
Exploitation
now we can try to write something on the .bss segment. for example I will try to write /bin/firefox to the
.bss segment then spawn firefox
now our exploit will look like this
at this point, we successfully write to the.bss segment
now, in order to get the shell, we can use these string below
since I have ssh access from my university CTF club so I can use it for the reverse shell, after writing these string to .bss
we can directly call system() function it can be easier than using syscall socket,
and this is my final exploit. PS: I am so lazy, so I don’t clean up my exploit lol
run it and we got our shell
I enjoy solving this challenge and learn much. kudos to the problem setter for this high-quality CTF challenge!