Rust 語言以其高效能和安全性,成為建構漏洞掃描器的理想選擇。本文著重於使用 Rust 實作 HTTP 模組,以掃描常見 Web 漏洞,例如 Kibana 未授權存取和目錄列表洩露。程式碼範例展示瞭如何利用非同步特性提升掃描效率,並透過正規表示式精確識別漏洞特徵。此外,文章也引入了非同步測試方法,確保程式碼品質,並結合 GitHub Actions 實作 CI 自動化測試流程,提升開發效率。更進一步,本文也探討了網路爬蟲技術、OSINT 資訊收集方法以及搜尋引擎原理,並介紹了 Google Dorks 等實用技巧,幫助讀者全面掌握漏洞掃描的相關知識。

使用Rust開發高效的漏洞掃描器

在現代網路安全領域,漏洞掃描器扮演著至關重要的角色。本文將探討如何使用Rust程式語言開發一個高效的漏洞掃描器,涵蓋其設計原理、實作細節以及測試方法。

4.6 實作HTTP模組

在開發漏洞掃描器的過程中,我們首先需要實作HTTP模組。這些模組負責掃描特定的漏洞,例如Kibana未經身份驗證的存取和目錄列表洩露。

4.6.2 Kibana未經身份驗證的存取

Kibana是一個流行的日誌分析和視覺化工具,但如果組態不當,可能會允許未經身份驗證的存取。以下是一個使用Rust實作的Kibana未經身份驗證存取掃描模組的範例:

#[async_trait]
impl HttpModule for KibanaUnauthenticatedAccess {
    async fn scan(
        &self,
        http_client: &Client,
        endpoint: &str,
    ) -> Result<Option<HttpFinding>, Error> {
        let url = format!("{}", &endpoint);
        let res = http_client.get(&url).send().await?;
        if !res.status().is_success() {
            return Ok(None);
        }
        let body = res.text().await?;
        if body.contains(r#"</head><body kbn-chrome id="kibana-body"><kbn-initial-state"#)
            || body.contains(r#"<div class="ui-app-loading"><h1><strong>Kibana</strong><small>&nbsp;is loading."#)
            || body.contains(r#"<div class="kibanaWelcomeLogo"></div></div></div><div class="kibanaWelcomeText">Loading Kibana</div></div>"#) {
            return Ok(Some(HttpFinding::KibanaUnauthenticatedAccess(url)));
        }
        Ok(None)
    }
}

#### 內容解密:

此段程式碼實作了一個名為KibanaUnauthenticatedAccess的HTTP模組,用於掃描Kibana未經身份驗證的存取漏洞。

  • scan函式是非同步的,接受一個http_client和一個endpoint作為引數。
  • 它首先向指定的endpoint傳送一個GET請求,並檢查回應狀態碼是否成功(200-299)。
  • 如果回應成功,則讀取回應體並檢查是否包含特定的Kibana HTML標籤或字串,以判斷是否存在未經身份驗證的存取漏洞。
  • 如果發現漏洞,則傳回HttpFinding::KibanaUnauthenticatedAccess,包含受影響的URL。

4.6.2.7 目錄列表洩露

目錄列表洩露是另一個常見的組態錯誤,可能導致伺服器上的檔案被未經授權的存取。以下是使用Rust實作的目錄列表洩露掃描模組的範例:

impl DirectoryListingDisclosure {
    pub fn new() -> Self {
        DirectoryListingDisclosure {
            dir_listing_regex: Regex::new(r"<title>Index of .*</title>")
                .expect("compiling http/directory_listing regexp"),
        }
    }

    async fn is_directory_listing(&self, body: String) -> Result<bool, Error> {
        let dir_listing_regex = self.dir_listing_regex.clone();
        let res = tokio::task::spawn_blocking(move || dir_listing_regex.is_match(&body)).await?;
        Ok(res)
    }
}

#[async_trait]
impl HttpModule for DirectoryListingDisclosure {
    async fn scan(
        &self,
        http_client: &Client,
        endpoint: &str,
    ) -> Result<Option<HttpFinding>, Error> {
        let url = format!("{}/", &endpoint);
        let res = http_client.get(&url).send().await?;
        if !res.status().is_success() {
            return Ok(None);
        }
        let body = res.text().await?;
        if self.is_directory_listing(body).await? {
            return Ok(Some(HttpFinding::DirectoryListingDisclosure(url)));
        }
        Ok(None)
    }
}

#### 內容解密:

此段程式碼實作了一個名為DirectoryListingDisclosure的HTTP模組,用於掃描目錄列表洩露漏洞。

  • DirectoryListingDisclosure結構體包含一個正規表示式,用於匹配目錄列表頁面的標題。
  • is_directory_listing函式檢查給定的HTML回應體是否包含目錄列表的特徵。
  • scan函式中,首先向指定的endpoint傳送GET請求,並檢查回應狀態碼。
  • 如果回應成功,則讀取回應體並使用is_directory_listing函式檢查是否存在目錄列表洩露。
  • 如果發現漏洞,則傳回HttpFinding::DirectoryListingDisclosure,包含受影響的URL。

4.7 測試

在開發漏洞掃描器的過程中,測試是至關重要的環節。良好的測試可以確保程式碼的正確性和可靠性。

4.7.1 非同步測試

Rust提供了對非同步測試的良好支援。以下是一個非同步測試的範例:

#[cfg(test)]
mod tests {
    use super::DirectoryListingDisclosure;

    #[tokio::test]
    async fn is_directory_listing() {
        let module = DirectoryListingDisclosure::new();
        let body = String::from("Content <title>Index of kerkour.com</title> test");
        let body2 = String::from(">ccece> Contrnt <tle>Index of kerkour.com</title> test");
        let body3 = String::from("");
        let body4 = String::from("test test test test test< test> test <title>Index</title> test");

        assert_eq!(true, module.is_directory_listing(body).await.unwrap());
        assert_eq!(false, module.is_directory_listing(body2).await.unwrap());
        assert_eq!(false, module.is_directory_listing(body3).await.unwrap());
        assert_eq!(false, module.is_directory_listing(body4).await.unwrap());
    }
}

#### 內容解密:

此段程式碼展示瞭如何為DirectoryListingDisclosure模組編寫非同步測試。

  • 使用tokio::test宏來標記非同步測試函式。
  • 建立了多個不同的HTML回應體範例,用於測試is_directory_listing函式。
  • 使用assert_eq!宏來驗證is_directory_listing函式的輸出是否符合預期。

4.7.2 自動化測試

為了提高開發效率,應該將測試自動化。持續整合(CI)系統可以在每次程式碼提交時自動執行測試。

以下是一個GitHub Actions CI工作流程的範例:

name: CI

on:
  push:
    branches:
      - main
      - 'feature-**'

jobs:
  test_phaser:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Update local toolchain
        run: |
          rustup update
          rustup component add clippy
          rustup install nightly
      - name: Toolchain info
        run: |
          cargo --version --verbose
          rustc --version
          cargo clippy --version
      - name: Lint
        run: |
          cd phaser
          cargo fmt -- --check
          cargo clippy -- -D warnings
      - name: Test
        run: |
          cd phaser
          cargo check
          cargo test --all
      - name: Build
        run: |
          cd phaser
          cargo build --release

#### 內容解密:

此CI工作流程在每次推播程式碼到指定分支時自動執行。

  • 更新Rust工具鏈並安裝必要的元件。
  • 顯示工具鏈版本資訊。
  • 執行程式碼格式檢查和Lint檢查。
  • 編譯並執行所有測試。
  • 以釋出模式編譯專案。

4.8 其他掃描器

在開發自己的漏洞掃描器時,可以參考現有的開源掃描器,例如:

  • KubiScan:用於掃描Kubernetes叢集中的漏洞。
  • SQLMap:用於檢測和利用SQL注入漏洞。
  • 其他在GitHub上搜尋到的相關專案。

第5章 網路爬蟲與公開來源情報(OSINT)

5.1 公開來源情報(OSINT)簡介

公開來源情報(OSINT,Open Source Intelligence)是指利用公開可用的資訊來支援情報分析的技術和方法。值得注意的是,這裡的「Open Source」與開源軟體中的「Open Source」含義不同。

OSINT 的核心是從大量公開資料中提取有意義的資訊,因此自動化是 OSINT 過程中不可或缺的一部分。隨著資料量的指數級增長,手動收集和處理資訊變得越來越困難,因此開發自動化工具和指令碼來輔助 OSINT 工作顯得尤為重要。

5.2 OSINT 工具

Maltego 是 OSINT 領域中最知名的工具之一,它提供了一個功能強大的桌面應用程式,能夠視覺化、指令碼化和自動化調查過程。然而,Maltego 的專業版價格較高,可能不適合偶爾使用的使用者。此外,Maltego 的 SDK 僅支援少數幾種程式語言,這使得與某些程式語言(如 Rust)的整合變得困難。

// 使用 Rust 語言編寫的簡單網頁爬蟲範例
use reqwest;

async fn fetch_url(url: &str) -> Result<String, reqwest::Error> {
    let response = reqwest::get(url).await?;
    let body = response.text().await?;
    Ok(body)
}

#[tokio::main]
async fn main() {
    let url = "https://example.com";
    match fetch_url(url).await {
        Ok(body) => println!("Fetched content: {}", body),
        Err(err) => println!("Error fetching URL: {}", err),
    }
}

內容解密:

這段 Rust 程式碼展示瞭如何使用 reqwest 函式庫來非同步抓取網頁內容。fetch_url 函式接收一個 URL 字串,並傳回該 URL 的內容。主函式使用 Tokio 執行非同步操作,並列印抓取到的網頁內容或錯誤訊息。

相比之下,使用簡單的 Markdown 筆記和自製指令碼可以提供更大的靈活性。指令碼的結果可以貼入 Markdown 報告,或匯出為 CSV 或 JSON 檔案。所有資料都備份在 Git 儲存函式庫中。

利用 Pandoc 這類別工具,可以將 Markdown 報告匯出為多種格式,如 PDF、HTML、Docx、Epub、PPTX 和 Latex 等。此外,還可以使用 markmap 將 Markdown 檔案轉換為思維導圖。

其他有用的 OSINT 工具包括:

  • Sherlock:用於在社交網路上搜尋特定使用者名稱的工具。
  • theHarvester:用於收集電子郵件、子網域和姓名的工具。
  • phoneinfoga:針對電話號碼的情報收集和 OSINT 框架。
  • gitrob:針對 GitHub 組織的偵察工具。

5.3 搜尋引擎原理

搜尋引擎的主要功能是將海量的資料轉換為可搜尋和可操作的資訊。一個搜尋引擎通常由以下幾個部分組成:

  1. 爬蟲(Crawlers):負責遍歷資料海洋並將其轉換為結構化資料。
  2. 索引(Index):用於儲存爬蟲提取的結構化資料。
  3. 搜尋介面(Search Interface):允許使用者查詢索引中的資料。
  graph LR
    A[爬蟲] -->|提取資料|> B[索引]
    B -->|提供資料|> C[搜尋介面]
    C -->|查詢|> B

圖表翻譯: 此圖示展示了搜尋引擎的基本架構。爬蟲負責從網路上提取資料,並將其存入索引中。搜尋介面允許使用者查詢索引,從而取得所需資訊。

OSINT 的本質是建立一個針對特定目標的專用搜尋引擎:從其他資料函式庫中爬取資料,並只索引與目標相關的有意義資訊,以便稍後進行搜尋。無論是使用 Markdown 報告、Maltego 還是傳統的資料函式庫(如 PostgreSQL),其背後的原理都是類別似的。

5.3.1 Google 搜尋引擎

Google 是全球最大的搜尋引擎,因此大部分所需資訊都可以在 Google 上找到。

5.3.1.1 Google 運算元

Google 提供了多種搜尋運算元來幫助使用者精確查詢,例如:

  • site:kerkour.com:限制搜尋範圍在特定網站內。
  • intitle:"Index of":搜尋標題中包含特定字串的頁面。
  • intext:kerkour:搜尋頁面內容中包含特定字串的頁面。
  • inurl:hacking:搜尋 URL 中包含特定字串的頁面。

5.3.1.2 Google dorks

Google dorks 是一些特殊的搜尋查詢,利用 Google 運算元來發現潛在的安全漏洞。例如:

  • intitle:"index of" ".env":用於發現洩露的 .env 檔案。
  • intitle:"Index of" "DCIM/camera":用於發現私人圖片。
  • inurl:"/app/kibana" intitle:"Kibana":用於發現開放的 Kibana 控制檯。

這些查詢可以幫助發現潛在的安全問題,但也需要謹慎使用,以免觸犯法律。

5.4 物聯網與網路搜尋引擎

除了傳統的網頁搜尋引擎,還有一些專門用於物聯網和網路裝置的搜尋引擎,例如:

  • Shodan
  • Censys

這些搜尋引擎允許使用者輸入 IP 位址、網域名稱或服務名稱,然後傳回相關的裝置或服務資訊。

5.5 社交媒體

社交媒體的選擇通常取決於目標區域。常見的社交媒體平台包括 Facebook、Twitter、VK、Instagram 和 Reddit 等。

5.6 地圖資訊

地圖資訊(如 Google Maps)可以用來進行物理層面的情報收集。例如,透過定位目標附近的餐廳,可能能夠發現目標公司的員工,並進一步收集相關資訊。

5.7 影片資訊

隨著影片格式的興起,每天都有越來越多的敏感資訊透過影片洩露。YouTube 和 Twitch 是兩個主要的影片平台。在分析目標公司的影片時,需要注意以下三點:

  1. 誰出現在影片中?
  2. 影片是在哪裡拍攝的?背景中有什麼建築或標誌?
  3. 背景中有沒有洩露敏感資訊,例如憑證或組織結構圖?

5.8 政府公開記錄

幾乎所有國家都有關於企業、專利、商標等的公開記錄,這些資訊可以幫助調查人員連線不同的資訊點,從而獲得更全面的情報。

總之,OSINT 是一項綜合性的技術,需要結合多種工具和方法來收集和分析公開可用的資訊。透過自動化指令碼和適當的工具,可以大大提高 OSINT 的效率和效果。