Lab Overview
公鑰加密是當今安全通訊的基礎,但當通訊的一方向另一方傳送其公鑰時,它會受到中間人的攻擊。根本的問題是,沒有簡單的方法來驗證公鑰的所有權,即,給定公鑰及其宣告的所有者資訊,如何確保該公鑰確實屬於宣告的所有者?公鑰基礎設施(PKI)是解決這一問題的一種切實可行的方法。
通過這個實驗,我們應該能夠更好地瞭解PKI是如何工作的,PKI是如何用來保護網路,以及PKI如何打敗中間人攻擊。此外,我們將能夠了解在公鑰基礎設施中信任的根源,以及如果這種根源信任被破壞會出現什麼問題。本實驗所涵蓋的主題如下:
• Public-key encryption
• Public-Key Infrastructure (PKI)
• Certificate Authority (CA) and root CA
• X.509 certificate and self-signed certificate
• Apache, HTTP, and HTTPS
• Man-in-the-middle attacks
Lab Environment
這個實驗在我kali VM和Ubuntu 16.04 VM上進行了測試.在這個實驗中,我們將使用openssl命令和庫。
Lab Tasks
Task1: Becoming a Certificate Authority(CA)
證書頒發機構(CA)是釋出數字證書的受信任實體。數字證書通過證書的命名主體來驗證公鑰的所有權。一些商業性的CAs被視為根類CAs;在撰寫本文時,VeriSign是最大的CA。想要獲得商業核證機關發出的數字證書的使用者需要向這些核證機關支付費用。
在這個實驗室,我們需要建立數字證書,但是我們不會支付任何商業CA,我們自己會成為一個根CA,然後用這個CA為其他人(比如伺服器)頒發證書。在這個任務中,我們將使自己成為一個根CA,併為這個CA生成一個證書。RootCA的認證通常預裝在大多數作業系統、web瀏覽器和其他依賴於PKI的軟體中。根CA的證書是無條件信任的。
The Configuration File openssl.conf
為了使用OpenSSL建立證書,必須有一個配置檔案。配置檔案通常有一個extension.cnf。它由三個OpenSSL命令使用:ca、req和x509。可以使用谷歌搜尋找到openssl.conf的手冊頁。還可以從/usr/lib/ssl/openssl.cnf獲得配置檔案的副本。將此檔案複製到當前目錄後,需要按照配置檔案中指定的方式建立子目錄(檢視[CA default]部分):
對於index.txt檔案,只需建立一個空檔案。對於serial檔案,在檔案中放入一個字串格式的數字(例如1000)。設定好配置檔案openssl.cnf之後,就可以建立和頒發證書了。
CertificateAuthority(CA).
如前所述,我們需要為我們的CA生成一個自簽名證書,這意味著這個CA是完全可信的,它的證書將作為根證書。執行以下命令為CA生成自簽名證書:
系統將提示您輸入資訊和密碼。不要丟失此密碼,因為每次要使用此CA為其他人簽名證書時,都必須鍵入口令。您還將被要求填寫一些資訊,如國家名稱、常用名稱等。該命令的輸出儲存在兩個檔案中:ca.key和ca.crt。檔案CA .key包含CA的私鑰,而CA .crt包含公鑰證書。
Task2: Creating a Certificate for SEEDPKILab2018.com
現在,我們成為一個根CA,我們準備為我們的客戶簽署數字證書。我們的第一個客戶是一家名為SEEDPKILab2018.com的公司。該公司要從CA獲得數字證書,需要經過三個步驟。
Step 1: Generate public/private key pair 。公司需要首先建立自己的公鑰/私鑰對。可以執行以下命令來生成RSA金鑰對(私有和公共金鑰)。您還需要提供一個密碼來加密私鑰(使用AES-128加密演算法,在命令選項中指定)。金鑰將儲存在檔案伺服器中。
server.key是一個編碼的文字檔案(也是加密的),因此無法看到實際內容,例如模數、私有指數等。要檢視這些,可以執行以下命令:
Step 2: Generate a Certificate Signing Request (CSR). 一旦公司擁有了金鑰檔案,它應該生成一個證書籤名請求(CSR),它基本上包括公司的公鑰。CSR將被髮送到CA, CA將為金鑰生成證書(通常在確保CSR中的身份資訊與伺服器的真實身份匹配之後)。使用SEEDPKILab2018.com作為證書請求的通用名稱。
需要注意的是,上面的命令與我們為CA建立自簽名證書時使用的命令非常相似,唯一的區別是使用了-x509選項。沒有它,命令生成一個請求;使用它,該命令生成一個自簽名證書。
Step 3: Generating Certificates . CSR檔案需要有CA的簽名才能形成證書。在現實世界中,CSR檔案通常被髮送到受信任的CA進行簽名。在這個實驗中,我們將使用我們自己的可信CA來生成證書。以下命令使用CA的CA .crt和CA .key將證書籤名請求(server.csr)轉換為X509證書(server.crt):
如果OpenSSL拒絕生成證書,您請求中的名稱很可能與ca的名稱不匹配。匹配規則在配置檔案中指定(檢視[policy match]部分)。您可以更改請求的名稱以符合策略,也可以更改策略。配置檔案還包括另一個限制較少的策略(稱為任何策略)。您可以通過更改以下行來選擇該策略:
"policy = policy_match" change to "policy = policy_anything".
Task3: Deploying Certificate in an HTTPS Web Server
在這個實驗中,我們將探索網站如何使用公鑰證書來保護web瀏覽。我們將使用openssl的內建web伺服器建立一個HTTPS網站。
Step1: Configuring DNS .我們選擇SEEDPKILab2018.com作為我們的網站名稱。為了讓我們的計算機識別這個名稱,讓我們將下面的條目新增到/etc/hosts;這個條目基本上將主機名SEEDPKILab2018.com對映到本地主機(即127.0.0.1):
Step 2: Configuring the web server. 讓我們使用在上一個任務中生成的證書啟動一個簡單的web伺服器。OpenSSL允許我們使用s_server命令啟動一個簡單的web伺服器:
預設情況下,伺服器將監聽埠4433。您可以使用-accept選項進行更改。現在,您可以使用以下URL訪問伺服器:https://SEEDPKILab2018.com:4433/。最有可能的是,您將從瀏覽器中得到一條錯誤訊息。在Firefox中,您將看到如下訊息:“seedpkilab2018.com:4433使用了無效的安全證書。該證書不受信任,因為釋出者證書未知”.
Step3: Getting the browser to accept our CA certificate. 如果我們的證書是由VeriSign分配的,就不會出現這樣的錯誤訊息,因為VeriSign的證書很可能已經預載入到Firefox的證書儲存庫中了。很遺憾,SEEDPKILab2018.com的證書是由我們自己的CA,並且Firefox無法識別此CA。有兩種方法可以讓Firefox接受CA的自簽名證書。
- 我們可以請求Mozilla將我們的CA證書包含在Firefox軟體中,這樣每個使用Firefox的人都可以識別我們的CA。不幸的是,我們自己的CA沒有足夠大的市場讓Mozilla包含我們的證書,所以我們不會追求這個方向。
- 載入CA .crt到Firefox中:我們可以手動新增我們的CA證書到Firefox瀏覽器通過點選下面的選單序列:
Edit -> Preference -> Privacy & Security -> View Certificates
您將看到一個已經被Firefox接受的證書列表。從這裡,我們可以“匯入”我們自己的證書。請匯入CA .crt,並選擇以下選項:“信任此CA識別網站”。您將看到我們的CA證書現在位於Firefox接受的證書列表中。
Step4. Testing our HTTPS website . 現在,將瀏覽器指向https://SEEDPKILab2018.com: 4433,可以正常訪問
Task4: Deploying Certificate in an Apache-Based HTTPS Website
使用openssl的s_server命令設定HTTPS伺服器主要用於除錯和演示目的。在這個實驗中,我們基於Apache建立了一個真正的HTTPS web伺服器。Apache伺服器(已經安裝在我們的VM中)支援HTTPS協議。要建立一個HTTPS網站,我們只需要配置Apache伺服器,這樣它就知道從哪裡獲得私鑰和證書。
一個Apache伺服器可以同時託管多個網站。它需要知道網站檔案儲存的目錄。這是通過它的VirtualHost檔案完成的,該檔案位於/etc/apache2/sites-available目錄中。要新增一個HTTP網站,我們需要在檔案000-default.conf中新增一個虛擬主機條目。而要新增一個HTTPS網站,我們則需要在同一個資料夾的default-ssl.conf檔案中新增一個VirtualHost條目。
ServerName條目指定網站的名稱,而DocumentRoot條目指定網站檔案儲存的位置。在設定中,我們需要告訴Apache伺服器證書和私鑰儲存在哪裡。
修改了default-ssl.conf檔案之後,我們需要執行一系列命令來啟用SSL。Apache將要求我們輸入用於加密私鑰的密碼。一旦一切都設定好了,我們就可以瀏覽網站了,瀏覽器和伺服器之間的所有流量都被加密了。
Task5: Launching a Man-In-The-Middle Attack
在這個任務中,我們將展示PKI如何擊敗中間人(MITM)攻擊。下圖描述了MITM攻擊的工作原理。假設Alice想通過HTTPS協議訪問example.com。她需要從example.com伺服器獲取公鑰;Alice將生成一個金鑰,並使用伺服器的公鑰對該金鑰進行加密,然後將其傳送到伺服器。如果攻擊者可以攔截Alice和伺服器之間的通訊,則攻擊者可以用自己的公鑰替換伺服器的公鑰。因此,Alice的祕密實際上是用攻擊者的公鑰加密的,因此攻擊者將能夠讀取祕密。攻擊者可以使用伺服器的公鑰將金鑰轉發給伺服器。祕密用於加密Alice和伺服器之間的通訊,因此攻擊者可以解密加密的通訊。
Step 1: Setting up the malicious website. 在Task 4中,我們已經為SEEDPKILab2018.com建立了一個HTTPS網站。我們將使用相同的Apache伺服器模擬example.com 。為此,我們將按照任務4中的指令向Apache的SSL配置檔案新增一個VirtualHost條目:ServerName應該是example.com,但配置的其餘部分可以與任務4中使用的相同。我們的目標如下:當使用者試圖訪問example.com時,我們將讓使用者登陸我們的伺服器,其中為example.com託管一個假網站。如果這是一個社交網站,虛假網站可以顯示一個登入頁面類似於目標網站。如果使用者不能分辨出兩者的區別,他們可能會在假網頁中輸入他們的帳戶憑據,本質上就是向攻擊者披露憑據。
Step2: Becoming the man in the middle 。有幾種方法可以讓使用者的HTTPS請求到達我們的web伺服器。一種方法是攻擊路由,將使用者的HTTPS請求路由到我們的web伺服器。另一種方法是攻擊DNS,當受害者的機器試圖找到目標網路伺服器的IP地址時,它會得到我們的網路伺服器的IP地址。在此任務中,我們使用“攻擊”DNS。我們只需修改受害者機器的/etc/hosts檔案,以模擬DNS快取設定攻擊的結果,而不是啟動實際的DNS快取中毒攻擊。
Step3: Browse the target website 。一切都設定好了,現在訪問目標真實的網站。
可以看到,我們訪問到的是kali攻擊機的預設目錄。
訪問https服務的時候,由於kali攻擊機的證書不被信任,所以會有安全警告
Task6: Launching a Man-In-The-Middle Attack with a Compromised CA
設計一個實驗來證明攻擊者可以在任何HTTPS網站上成功發起MITM攻擊。可以使用在Task 5中建立的相同設定,但是這一次,需要演示MITM攻擊是成功的。即,當受害者試圖訪問一個網站而進入MITM攻擊者的假網站時,瀏覽器不會引起任何懷疑。