参考文献:https://github.com/bowu678/php_bugs
1.extract变量覆盖
看extract变量覆盖这个的时候,代码里面出现了trim这个函数,就查了一下用法,说是去掉字符串开头和结尾的换行符或者是空格,还可以去掉不想出现的字符串。要说起来这个函数还是挺好理解的。就比如说最后一个吧,heordw,先从首开始看,到l的时候想去掉的字符串里面没有,所以到l的时候不再去掉任何字符,然后从尾往前看,是和首同样的道理1
2
3
4
5$str="helloeorldhelloworld";
echo trim($str,"herl");//oeorldhelloworld
echo trim($str,"heorld");//w
$str="helloeorlwdhelloworod";
echo trim($str,"heordw");//lloeorlwdhell
file_get_contents($flag)
//若是$flag的内容为字符串直接返回为空,若是txt的话能打开里面的内容。extract($_GET)
这个函数可以判断是get提交还是post提交,当为get提交时可以url中可以这样使用http://localhost/php/extract1.php?flag&shiyan
#flag和shiyan是php中的两个变量。在extract()中,若是在url中有给变量赋值,则原本这个变量的值会被替换。可以预防被覆盖的方法是在php.ini这个文件中有register_globals这个变量的话将它改为off就行了,可能php版本问题,我的文件中没有这个变量。。。可能这个bug还是挺有用的。。
2.绕过过滤的空白字符
首先is_numeric
这个函数要求的是为数字字符串,所以要想跳过这个函数可以加字母或者加一些编码后的符号。
然后$req['number']==strval(intval($req['number']))
这个是要求输入的字符串取整和原本字符串相等,但是取整的时候若是有字母或是特殊字符直接截断了,若是构造这个数字100.000000000000010
可以跳过这个函数,但是最开始的条件就跳不过了,若是在后面加上字母什么的可以跳过第一个,但是传入的字符串是存到数组中的,所以自己不会发生溢出情况。$number[$i] !== $number[$j]
,后面的这个函数就容易实现了%00%0c191,%0c是\f的转义字符,%00的ascii值是0,后面的数字可以任意写,%00为截断,不能省略。
3.多重加密
这是题目给的加密方式
解密
4.SQL注入_WITH ROLLUP绕过(实验吧 因缺思汀的绕过)
1 | $filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";这个是不能使用的单词。 |
当用rollup这个语句的时候,会在数据库的最后一行生成一个密码为NULL的字段
用下面这个payload1
' or 1=1 group by pwd with rollup limit 1 offset 2 #
这样查询语句就会变成1
SELECT * FROM interest WHERE uname = ' ' or 1=1 group by pwd with rollup limit 1 offset 2 #
group by pwd with rollup
这个可以在数据库中添加一行pwd为NULL的数据,limit 1是之查询一行,offset 2这个数字可以换,不同的数字出现的是不同行的内容。
5.ereg正则%00截断
1 | ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE //这个函数要求输入的密码只能是大小写字母和数字 |
6.strcmp比较字符串
1 | strcmp($_GET['a'], $flag) == 0// 参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;只有两者相等,才返回 0。 |
strcmp只会处理字符串参数,如果给个数组的话,就会返回NULL,而判断使用是==,NULL==0是bool(true),所以构造这个函数a[]=1
就行了。
7.sha1()函数比较绕过
1 | $_GET['name'] == $_GET['password'])//若是传入的两个参数不同才能绕过这个函数 |
sha1()函数默认的传入参数类型是字符串型,要是给它传入数组会出现错误,使sha1()函数返回错误,也就是返回false,这样一来===运算符就可以发挥作用了,需要构造username和password既不相等,又同样是数组类型
构造?name[]=1&password[]=12
这样可以绕过
8.SESSION验证绕过
1 | $_GET['password'] == $_SESSION['password']//在这个函数中,需要让提交的密码和session这个相等 |
?password=这样构建并把cookie清空,刚开始我以为isset会把这个空的过滤掉,但虽然是空也没过滤。
9.密码md5比较绕过$pass = md5($_POST[pass])
;
1 | $row = mysql_fetch_array($query, MYSQL_ASSOC); |
10.urldecode二次编码绕过
1 | eregi("hackerDJ",$_GET['id'] |
这段代码是首先先匹配输入的值是否和hackerDJ相等,若是不等才可以继续下面的解码再让相等才可以,所以直接其中的一个字母编码两次就可以了。不知道为什么在php代码或者找的网站中都不能编码只能解码,所以看了原题目的wp。。不知道什么原因就是不能编码有点难受。。1
http://localhost/php_bug/10.php/?id=%2568ackerDJ