我来惹,作为一个web狗,简单总结一下刷ctf遇到的常见php黑魔法:
1.题主说的,Strcmp利用数组绕过
$password=$_GET['password'];
if(strcmp('ceshi',$password)){
echo '错误!';
}else{
echo '正确!';
}
?>
输入password[]=1,则会返回'正确!'
2.md5函数特性
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] != $_GET['b']
&& md5($_GET['a']) == md5($_GET['b'])) {
echo "success";
}
}
?>
这里利用了php处理0e开头的md5值时的hash字符串漏洞:PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
md5('QNKCDZO') =='0e830400451993494058024219903391'
md5('240610708') =='0e462097431906509019562988736854'
所以payload:?a=QNKCDZO&b=240610708
md5特性和sha1特性一样
3.假如2里的函数是全等于:md5($_GET['a']) === md5($_GET['b'])
则md5比较可以利用数组绕过md5和sha1对一个数组进行加密将返回NULL;而NULL===NULL返回true,所以可绕过判断。
4.eregi数组绕过,%00截断
eregi()函数在一个字符串搜索指定的模式的字符串。它处理的是字符串,传入数组之后返回null,d另外eregi() 会被 %00 截断
5.intval()
Intval最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807
另外,intval()可以被%00截断
可以使用php伪协议进行绕过。
7.parse_url()绕过,parse_url()会把//认为是相对路径(5.4.7以前)
$data = parse_url($_SERVER['REQUEST_URI']);
var_dump($data);
$filter=array("aaa","qqqq");
foreach($filter as $f)
{
if(preg_match("/".$f."/i", $data['query']))
{
die("Attack Detected");
}
}
?>
当我们输入http://127.0.0.1/1.php?/home/aaa/ 会被attack detected
但如果输入http://127.0.0.1//1.php?/home/aaa/ 则会被当做相对url,此时的1.php?成了host 而path成了/hone/aaa,导致绕过$data[‘query’]的过滤
8.php会将TO解析成GET方法
9.iconv导致字符截断
$d=iconv("utf-8","gb2312",$c);
该代码是将变量c从utf-8编码转换为gb2312,那么当$c中存在一个不能被gb2312表示的字符时,就会截断该字符后的内容
10.NULL,0,”0″,array()使用==和false比较时,都是会返回true的
11.preg_replace()函数:
函数第一个参数如果存在/e模式修饰符,则允许代码执行。(如果没有可以尝试%00截断)
想到别的再更。