Mercury靶机WP

下载地址:

https://download.vulnhub.com/theplanets/Mercury.ova

sql注入手测

横向提权

环境变量PATH劫持

nmap

访问8080端口:

除此之外好像没有什么信息,robots.txt无信息

扫描目录,无信息

这种找不到任何信息的情况下,可能只有尝试触发信息或者报错之类的,再不行扫一下udp

随便构造一下url

报错说我请求的url和上述任意一个都不匹配,这也暴露出了目录mercuryfacts

访问之后,进入这样一个页面

获取线索

先全局的看一下这两个选项,获得初步的判断

选项1

这一看就像是数据库的返回结果

再看url,应该采用的是通过路径参数来访问数据库中的特定记录的做法

选项2

线索1:从刚开始的development到现在的todo,都说明这个网站在开发中,还有很多事没做,可以渗透的概率理应很大

线索2:这里也说了是用的直接调用mysql的方式,也印证了之前的推测

线索3: 这里面有一个表,名叫users,很有可能有我们感兴趣的东西

回到选项1,我们来测试一下是否有办法sql注入,由于是练习,我们采用手测的方式

SQL注入

尝试加了一个 ', 就报错了

tips:

在现代 Web 应用中:

/user/42/URL 路由规则匹配的一部分

不一定对应服务器文件系统的真实路径(不像传统静态网站那样)

Django(或其他 Web 框架)会把这个路径映射给某个视图函数处理,而不会去硬盘上找什么 /user/42/ 目录。

只有静态服务器才会真的查目录

比如 nginx 配置静态目录:

location /static/ {
    root /var/www/html/;
}

这时访问 /static/images/logo.png 就真的会找 /var/www/html/static/images/logo.png 文件。

那这里路径参数是什么就会完全返回给数据库去查询,这就与一般的sql注入一样了

try0:

http://10.10.10.132:8080/mercuryfacts/1'%20or%201=1--%20-/

看报错,路径参数左右两边是没有 '的,这就说明这应该是把你输入的内容作为字符串包裹起来,所以应该在SQL注入中忽略掉这两个 '(总之就是不在一个图层的意思)

第二个图直接给出了路径参数作为sql语句返回的位置,可以看到fact_id左边是没有sql语句中的字符 '的,因此注入的时候加了'是非法语法会报错

try1:

http://10.10.10.132:8080/mercuryfacts/'1'%20or%201=1--%20-/
http://10.10.10.132:8080/mercuryfacts/1%20or%201=1--%20-/

这两种写法都可以也印证了这是mysql而非默认更严格的postgreSQL

sql注入测试成功,开始构造

payload0:

首先要确定有多少个字段

我一般习惯从3开始测

看来只有一个字段

由于这里我们已经知道我们想要的表名,所以可以直接查列名,数据库名这些就先不查了,后面有需要再说

payload1:1 union select column_name from information_schema.columns where table_name='users'

查出users表有三个列名:id,username,password,这也正是我们想要的

由于一次只能查询一个字段,为了效率,我们使用group_concat

group_concat用于在分组查询时将同一组内多个字段的值合并成一个字符串,各值之间用指定的分隔值隔开

group_concat数据库按默认行顺序处理,大概不会自动乱序

1 union select group_concat(id,0x2d,username,0x2d,password) from users

成功得到四位用户

评估这些开发者的严谨程度,直接碰撞ssh成功的概率大概不会小

[22][ssh] host: 10.10.10.132   login: webmaster   password: mercuryisthesizeof0.056Earths

果然有一位爆破成功

ssh连接成功

提权

sudo -l: webmaster不能运行sudo

suid:

这个pkexec又时好像有用,先继续看吧

writable:

userflag

webmaster顾名思义是管理web的,大部分可写文件都是有关网站的

发现了有趣的东西

得到密码:

mercurymeandiameteris4880km

去home看一下用户,确实有一个Linuxmaster

切换成功

枚举

sudo -l:

有一个可以以root身份执行的脚本

有读和执行权限

执行这个脚本可以显示该日志最后十行的内容

也就是说,虽然普通用户可以执行这个脚本,但是普通用户执行的这个脚本没有tail查看该日志的权限,所以给了sudo

既然没有什么隐藏信息,遇到这种在sudo 脚本里有调用命令行工具的情况,直接考虑环境变量劫持

tail 是外部命令,脚本里调用时没有使用绝对路径(比如 /usr/bin/tail),这就给我们利用环境变量 PATH 做命令劫持的机会。

写一个恶意的tail在一个指定目录中,然后设置环境变量PATH,让系统先查找这个目录,然后sudo 执行脚本让恶意tail以root身份执行

因为 **sudo** 以 root 权限运行脚本,脚本中的命令(如 tail)默认也会以 root 权限运行。

写法 含义
PATH 环境变量的 名字,表示我们在设置或引用它
$PATH 环境变量的 ,表示我们在使用它的内容

$PATH是我们当前普通用户的环境变量PATH值,sudo执行命令之前,一般会从当前shell即系这个$PATH

因此,我们需要把新定义的环境变量加到$PATH之前,从而优先查找该目录的命令

:是路径分隔符,用于区分多个路径

PATH=/dir1:/dir2:/dir3 表示依次搜索 /dir1/dir2/dir3

所以PATH=/home/linuxmaster:$PATH

表示将 /home/linuxmaster 添加到原有 PATH 的最前面。

PATH=/home/linuxmaster:$PATH /usr/bin/check_syslog.sh

$PATH /usr/bin/check_syslog.sh:影响的是脚本里调用命令时,去哪里找这个命令

只在这一次执行 /usr/bin/check_syslog.sh 的过程中,使用修改后的 PATH 环境变量。对系统的 PATH 不会造成永久影响。

以 root 身份执行的脚本中调用的命令,也默认以 root 权限执行。如果这个命令是打开 shell,那么打开的就是 root shell。

当我以root身份执行一个脚本时,这个脚本的进程具有root权限

脚本里执行的任何命令都是由这个脚本的进程派生(fork/exec)出来的子进程

这些进程继承了父进程的权限,也就是root权限

/bin/bash 是由 tail 启动的子进程,所以它会继承 tail 的权限 —— 如果 tail 是以 root 运行的,那 bash 也就是 root 权限。

#!/bin/bash\n/bin/bash

这是脚本的内容,由两部分组成:

1、#!/bin/bash

叫做 shebang(解释器声明)

告诉系统:这个脚本用 /bin/bash 来解释执行。

如果没有这一行,有些系统可能无法正确运行脚本。

2.、/bin/bash

是脚本的第二行,表示:

执行一个新的 Bash shell。

echo -e "字符串"

其中 -e 的作用是:

让 echo 理解并处理字符串中的转义序列

单引号 '...' 会完全禁止变量和转义展开,安全可靠。

posted @ 2025-07-16 11:58  Ex1st  阅读(23)  评论(0)    收藏  举报