標籤:

HTTP漏洞分析及基於JS的加密實現

一、 文章簡介

本文通過了解學慣用Node.js構建HTTP伺服器,學會使用Kali進行ARP欺騙,學會用Wireshark抓數據包,利用JavaScript實現HTTP的加密傳輸。

二、 知識儲備

1. 關於Node.js的一些基礎知識

Node.js是一個基於Chrome JavaScript運行時建立的平台, 用於方便地搭建響應速度快、易於擴展的網路應用。Node.js 使用事件驅動, 非阻塞I/O 模型而得以輕量和高效,非常適合在分散式設備上運行的數據密集型的實時應用。Node.js提供一些特殊的API庫,因此在編寫Node.js的時候可以理解為,使用JavaScript語言利用Node.js的API庫進行伺服器端的開發。

2. 關於Kali的一些基礎知識

Kali Linux 前身是 BackTrack(基於ubuntu),是一個基於 Debian 的 Linux 發行版,包含很多安全和取證方面的相關工具。支持 ARM架構。Kali Linux是基於Debian的Linux發行版, 設計用於數字取證和滲透測試 和 黑客攻防。由Offensive Security Ltd維護和資助。最先由Offensive Security的Mati Aharoni和Devon Kearns通過重寫BackTrack來完成,BackTrack是他們之前寫的用於取證的Linux發行版 。Kali Linux預裝了許多滲透測試軟體,包括nmap (埠掃描器)、Wireshark (數據包分析器)、John the Ripper (密碼破解器),以及Aircrack-ng (一套用於對無線區域網進行滲透測試的軟體). 用戶可通過硬碟、live CD或live USB運行Kali Linux。Metasploit的Metasploit Framework支持Kali Linux,Metasploit一套針對遠程主機進行開發和執行Exploit代碼的工具。.Kali Linux既有32位和64位的鏡像。可用於x86 指令集。同時還有基於ARM架構的鏡像,可用於樹莓派和三星的ARMChromebook。這裡使用Kali做中間人攻擊。

3. 關於Wireshark的一些基礎知識

Wireshark是一個網路封包分析軟體。網路封包分析軟體的功能是擷取網路封包,並儘可能顯示出最為詳細的網路封包資料。Wireshark使用WinPCAP作為介面,直接與網卡進行數據報文交換。

網路封包, 分析軟體的功能, 可想像成 "電工技師使用電錶來量測電流、電壓、電阻" 的工作 - 只是將場景移植到網路上,並將電線替換成網路線。在過去,網路封包分析軟體是非常昂貴,或是專門屬於營利用的軟體。Wireshark的出現改變了這一切。在GNUGPL通用許可證的保障範圍底下,使用者可以以免費的代價取得軟體與其源代碼,並擁有針對其源代碼修改及客制化的權利。Wireshark是目前全世界最廣泛的網路封包分析軟體之一。

4. 關於JS(JavaScript)的一些基礎知識

JavaScript一種直譯式腳本語言,是一種動態類型、弱類型、基於原型的語言,內置支持類型。它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用於客戶端的腳本語言,最早是在HTML(標準通用標記語言下的一個應用)網頁上使用,用來給HTML網頁增加動態功能。

三、 環境說明

Windows xp虛擬機用作客戶端(IP:111.195.214.137)

Ubuntu(64位)虛擬機用作HTTP伺服器(IP:111.195.214.136)

Kali用來做ARP欺騙及抓包(IP:111.195.214.130)

輔助工具:Node.js,Wireshark,火狐瀏覽器

四、 實戰步驟

HTTP是一個客戶端和伺服器端請求和應答的標準(TCP)。客戶端是終端用戶,伺服器端是網站。通過使用Web瀏覽器、網路爬蟲或者其它的工具,客戶端發起一個到伺服器上指定埠(默認埠為80)的HTTP請求。但是通過中間人攻擊,如ARP欺騙很容易就可以獲取客戶端與伺服器之間傳輸的數據包,竊取其中的敏感信息如密碼等。那麼能不能將想傳輸的敏感信息加密後再傳送給伺服器,提高HTTP的安全性呢?

我們的任務分為3部分:

1. 在伺服器上(Ubuntu)用Node.js搭建簡單的HTTP伺服器

2. 用ARP欺騙進行中間人攻擊並用Wireshark抓取數據包得到敏感數據

3. 用JS實現HTTP的加密傳輸,並再次利用中間人攻擊抓取數據包查看所抓到的數據

4.1 步驟一

描述:在伺服器(Ubuntu)上下載並安裝Node.js並用Node.js實現簡單HTTP伺服器

1.Node.js下載與安裝與HTTP的創建

(1)在官網(nodejs.org)下載適合自己操作系統的版本(如圖1)。這裡主要講解Linux下的下載與安裝,其餘操作系統的安裝可參考Node.js開發實戰詳解這本書。

(2)在這裡選擇Linux Binaries 64位的壓縮包(可選擇適應自己Linux的位數的安裝包)。這個安裝包是已經編譯好的可執行文件,下載後直接解壓就行。解壓後進入相應文件夾目錄下的node-v4.2.4-linux-x64文件夾下的bin文件夾,找到裡面的node可執行文件。

(3)現在可以開始建立簡單的HTTP伺服器了,在bin文件夾中創建app.js的Node.js文件,用任意編輯器在app.js文件中輸入2中的Node.js代碼,保存並退出。

【代碼說明】

require(『http』):獲取Node.js原生模塊提供的HTTP模塊對象

http.createServer():使用HTTP對象API方法createServer來創建伺服器。

res.writeHead():通過res的HTTP響應對象,編寫HTTP響應的頭信息,並設定Content-Type指定返回數據類型為文本text,當然這裡的數據類型也可以是其他格式,例如html,css和image等。

listen:是HTTP對象的一個方法,其主要是啟動伺服器監聽的埠和IP,第二個參數為可選參數,默認為本地127.0.0.1。

console.log():是Node.js和JavaScript共有的調試介面。

本段代碼是應用require來調用HTTP模塊中的方法和屬性,該require模塊成功返回的是Node.js中HTTP模塊的方法和屬性。如上代碼中的listen介面的兩個參數分別為運行埠號和伺服器地址,其中埠號為一個Number類型,伺服器地址為字元串,運行時如果埠號數據類型不正確會報錯,只要不被其他應用程序佔用,都可以作為Node.js的服務埠。

(4)在命令窗口中用cd命令進入app.js的路徑,運行./node app.js的命令,運行成功後會顯示Server running at 127.0.0.1:1337 如3所示。

(5)打開任意瀏覽器(建議使用火狐瀏覽器),在瀏覽器中輸入伺服器地址127.0.0.1:1337,在web頁面中我們將看到Hello World的字元串,如圖4所示。

這樣就簡單的運用Node.js簡單的創建了HTTP伺服器。但這個伺服器沒有傳輸信息的功能。接下來在這個app.js文件中修改代碼,使得客戶端與伺服器能夠簡單的傳輸信息。

(6)修改app.js的代碼,實現客戶端與伺服器簡單的信息傳輸,要求創建的HTTP伺服器能夠讀取一個index.html頁面,index.html頁面中有一個form表單,該表單提交數據到127.0.0.1:1337/add,伺服器端獲取POST數據後列印顯示當前的請求路徑,POST字元串,POST的json參數對象。修改後的代碼如圖5。

【代碼說明】

require(『http』):獲取Node.js原生模塊提供的HTTP模塊對象。

require(『fs』):獲取Node.js原生模塊fs讀取index.html頁面信息。

require(『url』):獲取Node.js原生模塊url解析請求資源路徑。

require(『querystring』):獲取Node.js原生模塊querystring解析POST數據。

var pathname = url.parse(req.url).pathname:獲取客戶端的HTTP請求路徑,也就是請求模塊。這裡是利用「特定規則請求路徑」的路由處理方法做簡單的路由處理。

switch():判斷請求資源類型分配,在這裡根據不同的請求路徑執行不同的函數資源。這裡有兩個不同的請求路徑,有兩個不同的函數。

resDefault(res):顯示index.html頁面函數邏輯,主要實現返回客戶端一個index.html頁面。

resAdd(res,req):列印POST請求數據函數邏輯。

var readPath = url.parse(index.html).pathname:獲取index.html文件的路徑。

var indexPage = fs.readFileSync(readPath):讀取相應的html頁面。

res.writeHead(200, { Content-type: text/html }):指定數據返回類型為html。

res.end(indexPage):響應相應的html頁面。

var postData = :設置初始POST數據。

req.setEncoding(utf8):設置數據接收編碼格式為UTF-8。

req.addListener(data, function(postDataChunk)):接收數據塊並將其賦值給postData。

req.addListener(end, function()):數據接收完畢執行回調函數。

var param = querystring.parse(postData):利用querystring模塊解析POST數據。

res.end(success):執行成功後,向客戶端返回信息success。

(7)按(4)中的方法再次運行app.js如圖6所示。

(8)打開火狐瀏覽器在瀏覽器中輸入伺服器地址111.195.214.136:1337,在web頁面中我們將看到相應的html頁面,如圖7所示。

其中index.html的代碼如圖8所示。

(9)輸入一串字元串並點擊login如輸入123456,則伺服器端顯示如圖9所示。

同時客戶端的瀏覽器顯示如圖10所示。

這樣就創建了一個簡單的HTTP伺服器,並且能夠與客戶端進行信息傳輸。接下來可以開始用ARP欺騙的方法進行中間人攻擊。通過中間人攻擊獲取客戶端與伺服器之間傳輸的信息。

做這部分時要注意:app.js文件,index.html文件都要放在解壓後node.exe這個可執行文件的路徑下。

4.2 步驟二

描述:在Kali上用ARP欺騙實現中間人攻擊,並利用wireshark抓取數據包

1.ARP欺騙的原理

ARP欺騙,有時也被稱為ARP下毒,是指攻擊者在有線乙太網或無線網路上發送偽造的ARP消息,對特定IP所對應的MAC地址進行假冒的欺騙,從而達到惡意目的的攻擊技術。

ARP欺騙攻擊的根源在於ARP攻擊在設計時認為區域網內部所有用戶都是可信的,但事實並非如此,區域網內可以存在內部攻擊者或滲透到內部的外部攻擊者或惡意代碼。ARP協議在進行IP地址到MAC地址映射是存在安全缺陷,一方面採用廣播請求包的方式在區域網中詢問映射關係,但沒有對相應結果進行真實性驗證的流程和方法,而另一方面,為了提高查詢的效率,設計了ARP緩存機制,以及會將主動的ARP應答視作有效信息進行接受,這使得ARP緩存非常容易被注入偽造的IP到MAC地址間的映射,從而進行ARP欺騙。

2.中間人攻擊的實現

(1)中間人攻擊需要三台虛擬機,一台作為伺服器,一台作為客戶端,還有一台作為中間人進行攻擊,三台虛擬機應在同一個區域網段內。

這裡使用Ubuntu作為伺服器運行Node.js及相應的程序實現4.1步驟中的伺服器,將IP地址設為111.195.214.136。使用win xp作為客戶端(建議使用火狐瀏覽器),IP地址設為111.195.214.137。使用Kali作為中間人,IP地址設為111.195.214.130。。

(2)首先分別在三台虛擬機上ping另兩台虛擬機,看是否連通,連通後通過arp –a的命令查看未進行arp欺騙時IP與MAC地址間的映射。

在Ubuntu上操作後結果如圖11所示:

在win xp上操作後結果如圖12所示:

這裡沒有把ping的結果截圖接下來,只把執行了arp –a命令後的結果截圖。

在Kal上操作後如圖13所示:

通過上面的對比可以看到沒進行ARP欺騙之前,IP與MAC地址中間的映射是正常的,不同的IP地址對應不同的MAC地址。

(3)在沒進行ARP欺騙之前先用Kali抓包看是否能夠抓到數據包。這裡用wireshark來抓包。

首先打開wireshark,在Kali中已經安裝好了這個軟體,路徑如圖14所示:

這裡由於空間關係截圖中沒有顯示出來,但就在Network Sniffers下,下拉就能看到wireshark。

打開wireshark後的界面顯示如圖15所示:

點擊第二行最左邊像攝像機一樣的圖標彈出對話框如圖16所示:

在這裡選擇eth3(因為我在設置IP地址時是通過eth3這個區域網口設置的,所以選擇eth3,大家可以用ifconfig的命令查看自己的區域網網口,選擇相應的區域網網口即可)即抓捕經過這個區域網網口的數據包。然後點擊Options,彈出對話框如圖17所示:

在這裡要注意,彈出這個對話框後,如果Capture on all interfaces和Capture all in promiscuous mode這兩個模塊已經默認選擇上了即前面的小方框已經打上對勾了,那麼要將這兩個對勾去掉(再點擊一次即可),不能選擇這兩個模塊。這是因為整個實驗是在虛擬機上進行的,所有的數據實際都是通過一個網卡傳輸,如果選擇這兩個模塊,那麼不用任何操做,都可以捕捉到所有的數據包。然後雙擊eth3出現對話框如圖18所示:

然後點擊Capture Filter,在裡面設置一些過濾條件,以方便所需的數據包,彈出對話框如圖19所示:

單擊IP address,在裡面填上伺服器的IP地址即只抓目的IP地址是到伺服器的數據包。然後點擊OK,設置完畢,這時wireshark就可以工作了,開始抓包了。

(4)回到Ubuntu虛擬機上,按4.1中所講的方法,運行修改後的app.js這個文件,創建有簡單傳輸功能的HTTP伺服器,然後回到xp系統,在這個系統上運行火狐瀏覽器,訪問伺服器IP地址,傳輸簡單的字元串,如123456,成功後瀏覽器上返回success,伺服器上顯示123456的數據,一次簡單的傳輸就完成了。這是再回到Kali的wireshark,查看是否抓到數據包,結果如圖20所示:

可以看到這是只能抓到廣播詢問ARP映射的數據包,並不能抓到傳輸數據的數據包。

(5)現在開始進行ARP欺騙,Kali上已經提前集成的ARPSPOOF的包,因此直接打開命令行窗口,輸入相應的指令即可開始ARP欺騙。

首先在Kali上打開路由功能,使得其能夠接收和轉發數據包。相應的指令為echo 1 > /proc/sys/net/ipv4/ip_forward。指令輸入完成後回車即開啟了路由功能。

接下來進行ARP欺騙,ARP欺騙的指令格式非常簡單,指令格式如下:

arpspoof –i 區域網網口 –t IP地址1 IP地址2

上面的區域網網口即Kali的區域網網口,這條指令的意思是欺騙IP地址1,Kali的MAC地址即為IP地址2的MAC地址。實際操作結果如圖21所示:

從圖21中可以看出,執行的是欺騙111.15.214.137,這裡是111.195.214.136的MAC地址,即欺騙客戶端Kali是伺服器。可以看到,執行命令後,Kali不斷地想客戶端發送數據包,毒化客戶端的ARP映射,使得伺服器的MAC地址映射成為Kali的MAC地址。下面欺騙伺服器Kali是客戶端,用同樣的指令格式,只是把兩個IP地址的位置換換。再打開一個命令行窗口,輸入圖22中的指令,運行結果如圖22所示:

這樣ARP欺騙就完成了,可以通過下面這個步驟來簡單檢查ARP欺騙後的結果。

(6)回到伺服器重新ping一下客戶端,然後運行指令arp –a查看相應的MAC地址,結果如圖23所示:

從圖23可以看出此時伺服器中ARP的映射里客戶端的MAC地址已經成為了Kali的MAC地址了。在客戶端中執行同樣的操作,結果如圖24所示:

同樣可以看到在客戶端中ARP的映射里伺服器的MAC地址已經成為了Kali的MAC地址了。

(7)現在可以用上面講過的方法再用wireshark抓包看看抓包的結果,結果如圖25所示:

從圖25可以看出,這時就可以抓到相應的tcp數據包了。選擇其中一個tcp數據包,右鍵如圖26所示:

右鍵後出現一個菜單欄,選擇其中的Follow TCP Stream,就可以查看所捕獲的TCP數據包,如圖27所示為其中的一部分:

從圖中可以看到已經捕獲到了所傳輸的信息123456。並且此時觀察伺服器與客戶端可以發現伺服器仍然正常顯示123456,客戶端正常顯示success。即完成了伺服器與客戶端不知情的情況下,得到所傳輸的數據,即完成了中間人攻擊。

到這裡我們可以看到,HTTP協議是不安全的,是容易泄露敏感信息的。一個簡單的解決辦法是在html文件中引入JavaScript語言,將敏感信息加密後再進行傳輸。

4.3 步驟三

描述:用JS實現HTTP的加密傳輸,然後再次抓包查看抓到的數據

1.加密傳輸的實現

基本的思路是在開始的index.html文件中加入JS語言,使其實現在傳輸之前將相應的信息加密,這樣傳輸的就是密文,提高安全性能。首先要選擇合適的加密解密的演算法,比較安全的有公鑰加密演算法,如RSA演算法,這裡為了簡化實驗,使較簡單的md5演算法,並且在伺服器端不進行解密,直接接收密文。

在index.html文件的路徑下新生成一個md5index.html文件,可以先將index.html文件的內容複製到md5index.html文件中,然後在此基礎上進行修改。修改後的代碼這裡就不詳細講解了,感興趣的同學可以直接查看md5index.html這個文件。

同時在app.js文件的路徑下新生成一個md5test.js文件,可以先將app.js文件的內容複製到md5test.js文件中,然後在此基礎上進行修改。只需要修改resDefault(res)函數中的var readPath = url.parse(md5index.html).pathname;這一句話即可,將app.js中的index.html改為md5index.html即可。

然後按照前面4.1的方法用Node.js執行md5test.js文件創建HTTP伺服器,在到客戶端訪問伺服器網址即可,同樣在客戶端發送123456後伺服器的顯示如圖28所示。

可以看到接收的是密文,正常情況下伺服器端應當還有相應的解密流程,這裡為了簡化實驗就將這步去掉了。另外,在客戶端使用瀏覽器訪問伺服器時,建議使用火狐瀏覽器。因為這裡在調試JS代碼時實在火狐瀏覽器下調試的,並沒有使用兼容的JS格式,用其它瀏覽器訪問可能會有問題。

現在再用4.2中的方法進行ARP欺騙,然後用wireshark抓包並分析結果如圖29所示:

從圖中可以看到即使現在能夠抓到數據包,得到的也只有加密後的結果,並不知道客戶端傳輸的內容是什麼。這樣能夠提高HTTP傳輸的安全性。

五、思考與總結

即使加密後HTTP傳輸仍然防不住中間人攻擊,雖然抓到的包是加密的數據,但對於簡單的加密演算法可以分析數據包以解密,對於公鑰加密的方法,可以在抓到數據包後篡改數據包中的公鑰再用自己的私鑰進行解密。甚至還可以直接對數據包中的JS部分進行篡改重發。所以若對傳輸的安全性的要求高的話,建議使用HTTPS即安全HTTP協議進行信息的傳輸。

本文中Node.js的部分主要參考《Node.js開發實戰詳解》這本書的內容,Node.js的功能不止這些,感興趣的同學可以自己學習。讀者切記不要使用這些技術做違法的事情。如讀者因此做出危害網路安全的行為後果自負,與合天智匯及本人無關,特此聲明。


推薦閱讀:

蘋果強制使用HTTPS傳輸了怎麼辦?——關於HTTPS,APP開發者必須知道的事
https的網站還能被過濾掉嗎?
關於HTTPS的常見6個問題解答
TLS完全指南(三):用Go語言寫HTTPS程序
https 頁面上如何嵌入像優酷這樣的非 https 的外部資源?

TAG:HTTPS |