题外话
下面的每一个标题都包含着一道ctf题目,推荐一边做题一边看……
0x01 数组绕过md5判断
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] != $_GET['b'])
if (md5($_GET['a']) === md5($_GET['b']))
die('Flag: '.$flag);
else
print 'Wrong.';
}

如果传入md5函数的参数为数组类型,则返回null,null===null
,因此可以通过数组可以绕过 ===
md5判断
0x02 数组绕过strcmp
$pass=@$_POST['pass'];
$pass1=***********;//被隐藏起来的密码
if(isset($pass))
{
if(@!strcmp($pass,$pass1)){
echo "flag:nctf{*}";
}else{
echo "the pass is wrong!";
}
}else{
echo "please input pass!";
}
strcmp函数用于字符串的比较
int strcmp ( string $str1 , string $str2 )
返回值:如果
str1
小于str2
返回 < 0; 如果str1
大于str2
返回 > 0;如果两者相等,返回 0。
- 5.2 中是将两个参数先转换成string类型。
- 5.3.3 以后,当比较数组和字符串的时候,返回是0。
- 5.5 中如果参数不是string类型,直接return了
存在以下情况
strcmp("foo", array()) => NULL + PHP Warning strcmp("foo", new stdClass) => NULL + PHP Warning strcmp(function(){}, "") => NULL + PHP Warning
因此post提交pass[]=aa,通过数组绕过strcmp。
0x03 数组绕过ereg
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
ereg函数的漏洞 :
-
存在%00截断(已被preg_match替代)
-
输入参数为数组时返回值为null

payload:
- ?nctf=111%00%23biubiubiu
- ?nctf[]=aa
0x04 php的弱类型+数组绕过正则
function is_valid($title, $data)
{
$data = $title . $data;
return preg_match('|\A[ _a-zA-Z0-9]+\z|is', $data);
}
function write_cache($title, $content)
{
$dir = changedir(CACHE_DIR . get_username() . '/');
if(!is_dir($dir)) {
mkdir($dir);
}
ini_set('open_basedir', $dir);
if (!is_valid($title, $content)) {
exit("title or content error");
}
$filename = "{$dir}{$title}.php";
file_put_contents($filename, $content);
ini_set('open_basedir', __DIR__ . '/');
}
preg_match()返回
pattern
的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索subject
直到到达结尾。 如果发生错误preg_match()返回 FALSE。
preg_match本身并没有什么问题,但是在正则匹配之前,$title
和$content
进行了字符串连接。得益于PHP的弱类型特性,数组会被强制转换成字符串,也就是Array
,Array肯定是满足正则\A[ _a-zA-Z0-9]+\z
的,所以不会被拦截。
file_put_contents函数可以处理数组,所以构造payload:?title=s&content[]=<?php phpinfo();?>
此文章侧重于数组绕过部分的讲解,本题完整题解详见 国家保卫者
>> 浓缩的都是精华
md5(array()) = null
sha1(array()) = null
ereg(pattern,array()) = null vs preg_match(pattern,array) = false
strcmp(array(), "abc") = null
strpos(array(),"abc") = null
网友评论