隨著現代 Web 框架和 API 的普及,遠端命令注入攻擊的發生率已大幅下降,但嵌入式裝置仍然是主要的攻擊目標。這些裝置通常直接在系統層級執行命令,且更新頻率較低,容易被攻擊者利用。命令注入攻擊的核心問題在於未經過濾的使用者輸入被當作 Shell 命令執行,攻擊者可藉此插入特殊字元,例如分號、管道符號等,以操控系統。針對嵌入式裝置的攻擊,透明代理模式的 Mitmproxy 可以有效攔截和分析流量,而 Python 指令碼則能實作自動化操作,例如修改 HTML 內容。理解 HTTPS 的運作機制對於防禦中間人攻擊至關重要。TLS 握手過程確保了通訊的機密性和完整性,但 CA 的信任度是關鍵。自建 CA 可以幫助理解其運作原理,但實際應用中需要謹慎考量安全性。使用 OpenSSL 可以生成私鑰、公鑰、CSR 並簽署憑證,以及管理 CRL。Mitmproxy 和 Mitmweb 是強大的 HTTPS 流量分析工具,可以捕捉、分析甚至修改流量,對於安全測試和漏洞研究非常有用。瞭解這些攻擊手法和工具,並配合適當的安全措施,才能有效提升網路安全性。

遠端命令注入攻擊

遠端命令注入攻擊與 SQL 注入攻擊相似,當網頁伺服器上的程式接收未經過濾或濾除不完全的輸入並將其執行為 Shell 命令時,這類別攻擊便可能發生。這種攻擊在 1990 年末至 2000 年初曾經流行,但隨著框架和 API 擴充套件的廣泛使用,其發生率大幅下降。過去,透過執行 os.system("echo "’ + msg + "’ mail user") 的方式來傳送電子郵件較為簡單,但現在則使用類別似於 smtplib 的程式函式庫。

命令注入攻擊的問題與 SQL 注入攻擊相同:使用者可以插入對子系統具有特殊意義的字元。在此情況下,這些字元包括分號 (;)、管道符號 (|)、邏輯與 (&&) 和邏輯或 (||) 用於連線命令,小於 (<) 和大於 (>) 用於重新導向程式輸出,而井號 (#) 用於註解程式碼。

例如,在上述範例中,包含 hacker::0:0:root:# /root:/bin/zsh' > /etc/passwd # 的電子郵件訊息將新增一個名為「hacker」且無密碼的新 root 使用者。這是因為網頁伺服器或被呼叫的指令碼以 root 身份執行,從而執行以下 Shell 命令:

echo hacker::0:0:root:/root:/bin/zsh > /etc./passwd #’ | mail user

嵌入式裝置中的命令注入攻擊

現在,命令注入攻擊主要發生在嵌入式裝置中,如交換機、印表機、家用路由器或監控攝像頭。這些裝置通常直接在作業系統層級上執行命令以顯示資料給使用者或啟用系統組態更改。由於系統管理員不會像常規系統那樣頻繁更新嵌入式裝置,因此這些裝置仍然吸引攻擊者。它們通常被視為僅僅是硬體,而忽略了其執行的程式碼可以透過網路存取的事實。

命令注入掃描器範例

以下是命令注入掃描器的 Python 程式碼範例:

#!/usr/bin/python3

# 載入模組
import sys
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse

# 全域變數
max_urls = 999
inject_chars = ["|", "&&", ";", "'"]
error_msgs = [
    "語法錯誤",
    "命令未找到",
    "許可權被拒",
]

# 其他程式碼(省略)

內容解密:

上述程式碼展示瞭如何使用 Python 建立一個基本的命令注入掃描器。以下是詳細解說:

  • 載入模組:首先匯入了必要的 Python 模組,包括 sysrequestsBeautifulSoupurlparse
  • 全域變數:定義了一些全域變數,如 max_urls 用於限制掃描的 URL 數量,inject_chars 用於定義可能會導致命令注入的特殊字元,以及 error_msgs 用於定義可能會出現的錯誤訊息。
  • 其他程式碼:由於這是範例程式碼的一部分,因此省略了其他實際操作部分。

嵌入式裝置安全掃描

嵌入式裝置的安全性需要特別注意。許多系統管理員認為嵌入式裝置僅僅是硬體,因此忽略了其執行的程式碼可以透過網路存取。然而,嵌入式裝置通常具有足夠的 CPU 功率、記憶體和磁碟空間來執行複雜的攻擊。攻擊者可能會首先發現並利用這些「低懸果實」。

自動化掃描與手動稽核

自動化掃描工具可以幫助檢測一些顯而易見的安全漏洞,但它們無法取代手動稽核。手動稽核可以深入分析系統並發現更複雜和隱蔽的漏洞。

總結來說,雖然命令注入攻擊在現代框架和 API 擴充套件下減少了很多,但在嵌入式裝置中仍然存在風險。系統管理員需要定期更新並進行手動稽核以確保這些裝置的安全性。

HTTPS 安全機制與攻擊手法

HTTPS 連線過程

HTTPS(HyperText Transfer Protocol Secure)是一種透過 SSL/TLS 協定加密的 HTTP 通訊協定,用來保護網路通訊的機密性與完整性。當瀏覽器連線到使用 HTTPS 的網頁時,會進行一個稱為 TLS 握手(TLS Handshake)的過程。以下是 TLS 握手的詳細步驟:

  1. Client Hello:客戶端(瀏覽器)傳送一個 Client Hello 訊息,包含其支援的 SSL/TLS 版本及加密/驗證機制。
  2. Server Hello:伺服器接收到 Client Hello 訊息後,選擇一個雙方都支援的 SSL/TLS 版本及加密/驗證機制,並回應一個 Server Hello 訊息,其中包含伺服器的數位憑證。
  3. 伺服器憑證驗證:客戶端使用瀏覽器內建的證書授權中心(CA)公鑰來驗證伺服器的憑證。如果驗證成功,客戶端會生成一個隨機數,並用伺服器公鑰加密後傳送給伺服器。
  4. 會話金鑰生成:伺服器使用其私鑰解密隨機數,然後雙方使用此隨機數來生成會話金鑰,用於後續通訊的加密。
  5. 完成握手:雙方確認握手成功,分別傳送 Client finished 和 Server finished 訊息。

這個過程確保了雙方通訊的機密性與完整性,但其安全性也依賴於 CA 的信任度。

CA 的信任與風險

CA 是承認和簽發數位憑證的實體。瀏覽器內建了一個可信任 CA 的清單,這些 CA 可以簽發合法的數位憑證。然而,CA 的安全性也是關鍵所在。歷史上有多起 CA 被攻擊或失誤的案例,例如 DigiNotar 和 KPN 的 Gemnet 分公司,這些事件導致了大量憑證被誤用或篡改,進而被用於中間人攻擊。

為了保護自己,使用者可以考慮調整瀏覽器中的可信任 CA 清單,移除不再信任的 CA。

自建 CA 實作

為了更深入瞭解 CA 的運作方式,我們可以使用 OpenSSL 或 LibreSSL 來建立自己的 CA 及自簽名憑證。以下是具體步驟:

生成私鑰

首先,生成一個私鑰,這將是我們 CA 的核心。

openssl genrsa -aes256 -out ca.key 4096

生成公鑰

接著,生成一對公鑰並將其匯入瀏覽器或其他客戶端軟體中。這個公鑰有效期為三年。

openssl req -x509 -new -key ca.key -days 1095 -out ca-root.crt -sha512

復原憑證

如果需要復原某個憑證的有效性,可以建立一個憑證復原清單(CRL)。

openssl ca -gencrl -keyfile ca.key -cert ca-root.crt -out crl.pem

若出現索引檔案不存在的錯誤,需要建立索引檔案和序號檔案:

touch <path_to_index_file>
echo 1 <path_to_crlnumber_file>
chmod 770 <path_to_crlnumber_file>

復原憑證後需要重新生成 CRL:

openssl ca -gencrl -keyfile ca.key -cert ca-root.crt -out crl.pem
cp crl.pem /path/to/your/web_root

檢視 CRL 內容

檢視當前 CRL 檔案的內容:

openssl crl -in crl.pem -noout -text

建立伺服器私鑰與 CSR

對於希望獲得自簽名憑證的人來說,首先需要建立一個私鑰:

openssl genrsa -aes256 -out server.key 4096

移除私鑰的密碼(僅在程式無法處理加密金鑰時使用):

openssl rsa -in server.key -out server.key

使用私鑰生成憑證簽署請求(CSR):

openssl req -new -key server.key -out server.csr

使用 CA 私鑰簽署 CSR:

openssl x509 -req -days 365 -in server.csr \
-signkey ca.key -out server.crt

最後將私鑰和憑證合併為 PEM 格式:

cp server.key server.pem
cat server.crt >> server.pem

檢視憑證內容:

openssl x509 -in server.pem -noout -text

TLS Sniffing 攻擊

在理想情況下,攻擊者擁有一個由受害者瀏覽器信任的 CA 簽發的憑證。這樣他們可以篡改加密流量並進行中間人攻擊。然而,大多數攻擊者沒有這樣的憑證。他們通常依賴使用者的天真或「快速點選」反應來繞過安全系統。

例如,可以使用 mitmproxy 工具來演示這種攻擊。mitmproxy 包含三個程式:mitmdump(類別似於 Tcpdump 的 HTTP 流量分析工具)、mitmproxy(控制檯客戶端)及 mitmweb(網頁介面)。這些工具可以捕捉和分析 HTTPS 流量。

攻擊防範

為了防範這些攻擊,使用者應該保持瀏覽器和作業系統更新至最新版本,並謹慎處理警告訊息。網站管理員應該確保使用強力、可信賴的 CA 來簽發其 HTTPS 憑證。

玄貓提醒大家,HTTPS 是保護網路通訊的一道重要屏障。瞭解其運作原理及潛在風險有助於提升整體安全性。

SSL / TLS Sniffing

在現代網路安全中,SSL/TLS sniffing 是一個重要的技術,允許我們攔截和分析 HTTPS 流量。這種技術不僅能夠顯示流量,還可以直接操縱流量。 Mitmproxy 和 Mitmweb 是這方面的強大工具,前者提供命令列介面,後者提供圖形化的網頁介面。此外,我們還可以利用自訂的 Python 指令碼來擴充套件和自動化這些代理伺服器的功能。

首先,我們將使用 Mitmproxy 來實作一個簡單的 HTTPS sniffing。Mitmproxy 會自動生成私鑰和證書,因此我們不需要自己生成。只需執行以下命令即可啟動代理伺服器:

mitmproxy

接下來,我們需要組態瀏覽器使用 localhost8080 埠進行 HTTP 和 HTTPS 流量的代理。現代瀏覽器會提示網頁不安全並拒絕載入它。一些瀏覽器會提供機會讓我們接受風險繼續存取。如果接受了,流量就會顯示在 Mitmproxy 中。

除了瀏覽器之外,許多程式也使用 HTTPS(甚至是 HTTP)連線進行各種任務,如接收軟體更新,這些程式通常不檢查證書的有效性。例如,智慧電視或其他物聯網裝置。

此圖示

  graph TD
    A[客戶端] --> B[Mitmproxy]
    B --> C[伺服器]
    A --> D[智慧電視]
    D --> B

對於這些裝置,我們不希望重新組態以驗證其安全行為。這時候透明模式就派上用場了。讓我們在 localhost1337 埠上以透明模式啟動 Mitmproxy:

mitmproxy --listen-host 127.0.0.1 -p 1337 --mode transparent

然後啟用 IP 轉發並重定向所有流量到 Mitmproxy 使用的埠:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 1337
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 1337

如果無法在 Mitmproxy 中看到流量,但確認了中間人攻擊成功並且確實有流量傳送到 Mitmproxy,則可以使用 OpenSSL 的 s_client 來檢查代理的 TLS 標頭。

剖析 HTTPS 流量

在某些情況下,可能會遇到代理不支援任何密碼套件的問題。這可以透過新增 --set ciphers_client=ALL 選項來解決。

在 Mitmproxy 視窗中輸入 i 以進入攔截篩選表示式模式,例如 ~u .* 攔截所有 URL。詳細的攔截表示式可以參考 Mitmproxy 概念與篩選器

當 Mitmproxy 收到請求或回應時,它會等待我們告訴它是否繼續轉發。我們可以按 e 編輯請求或回應,使用 TAB 在值之間移動,按 q 離開編輯模式。然後按 a 還原單個攔截流量或 A 還原所有攔截流量。要檢視完整的快捷鍵概述,只需輸入 ?

Drive-by-Download

接下來,我們將編寫一個小指令碼來自動攔截每個回應並替換 HTML 中的每張圖片為我們自己的圖片。這可以用來增加快樂(例如使用大量的笑臉圖片),也可以用來駭客攻擊(例如自動執行惡意程式碼)。推薦使用前者。

以下是指令碼範例:

#!/usr/bin/env python3

from mitmproxy import http
from bs4 import BeautifulSoup

MY_IMAGE_FILE = 'https://www.my_domain.tld/some_image.jpg'

def response(flow: http.HTTPFlow) -> None:
    if flow.response.headers.get("Content-Type") and "text/html" in flow.response.headers["Content-Type"]:
        soup = BeautifulSoup(flow.response.content, features="html.parser")
        for img in soup('img'):
            img['src'] = MY_IMAGE_FILE
        flow.response.text = soup.prettify()

內容解密:

這段指令碼主要用於修改伺服器回應中的 HTML 內容。具體步驟如下:

  1. 匯入所需模組:我們從 mitmproxy 中匯入了 http 模組,從 bs4 中匯入了 BeautifulSoup 模組。
  2. 定義圖片 URLMY_IMAGE_FILE 是我們要替換成的圖片 URL。
  3. 定義 response 函式:這個函式會在每次收到 HTTP 回應時被呼叫。
  4. 檢查 Content-Type:確保回應內容是 HTML。
  5. 解析 HTML:使用 BeautifulSoup 解析 HTML 內容。
  6. 替換圖片來源:遍歷所有 <img> 標籤並替換其 src 屬性為我們自己的圖片 URL。
  7. 更新回應內容:將修改後的 HTML 內容更新回回應中。

要載入這個指令碼,啟動 Mitmproxy 時需要使用 -s 引數指定指令碼檔案:

mitmproxy -s drive-by-download.py

如果修改了指令碼檔案內容,無需重啟 Mitmproxy 即可生效。