natas(16)
<?
$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");
}
}
?>
PHP又是上次字符过滤的升级版,在grep的检索中添加了引号,封死了添加其他选项和参数的路
并且过滤了双引号,无法像sql注入那样更改代码
尝试使用CHAR()函数绕过过滤,不知道为什么没有转换成功
关键问题是引号内无法再添加选项和参数,不过PHP里的$
()即使在引号内也可以使用,这个就比较厉害了
在$
()内执行grep str /etc/natas_webpass/natas17,如果str踩中了,就会返回结果,没踩中则返回空值
然而我们还是无法看到$()返回的结果,只能用它影响外层的grep查询
这与上一关的爆破思路相同,想办法将内层的结果反应出来:
我们知道dictionary.txt中存在的字符串,比如说Doctor,用它与$
(grep)的返回值相加,如果内层返回了结果将检索出空值,如果返回空值则外层的grep会返回结果
eg:若password中首字母为a,构成
grep -I "$(grep ^a /etc/natas_webpass/natas17)Doctor" dictionary.txt
由于内部的$
()命令返回了a,则使外层命令变为
grep -I "aDoctor" dictionary.txt
由于dictionary中没有aDoctor,从而返回空值
而如果内层$
()命令返回空值,外层则能正确检索到Doctor,于是返回值,证明首字母不是a
按照这个原理可以构造出爆破脚本,在上一关的基础上稍加变动即可
The password is 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw