社交工程學攻擊利用人性的弱點,而非技術漏洞,來取得敏感資訊或系統存取許可權。攻擊者藉由操縱心理、偽造身份、誘導特定行為等方式,達到欺騙目標的目的。從亞裡士多德的修辭學三要素(評價、情感、邏輯)到現代的網路攻擊技巧,社交工程學的應用範圍廣泛且不斷演變。隨著技術的發展,攻擊手法也更加多元化,例如利用深度偽造技術進行電話詐騙、使用 WebAssembly 技術提升攻擊效率等。瞭解這些攻擊手法和技術原理,對於建立有效的防禦機制至關重要。

說服的藝術與社交工程學的應用

說服的三要素:亞裡士多德的修辭學理論

在兩千多年前,古希臘哲學家亞裡士多德在其著作《修辭學》中提出了說服的三個核心要素,分別是:

  • Ethos(評價):建立可信度
  • Pathos(情感):引發情感共鳴
  • Logos(邏輯):提供合理理由

這三個要素在現代的社交工程攻擊中同樣具有重要的參考價值。

建立評價(Ethos)

要成功說服目標物件,首先需要讓他們認可你的權威性或可信度。在社交工程學中,這意味著建立一個合理的角色身份。例如,攻擊者可能會冒充資料函式倉管理員向秘書提出請求,因為秘書通常不會質疑管理員的權威性。這種建立角色可信度的過程對於說服至關重要。

情感連結(Pathos)

一旦建立了可信度,接下來需要與目標物件建立情感上的聯絡。這通常可以透過故事講述來實作。攻擊者會編造一個可信的故事,其中包含一個只有目標物件才能解決的問題,從而引發對方的情感反應。

def create_emotional_connection(story):
    # 編造一個包含幹擾元素的故事
    disruptive_element = "系統故障"
    solution = "重設密碼"
    return f"由於{disruptive_element},你需要{solution}來繼續工作。"

# 示例用法
story = create_emotional_connection("系統故障")
print(story)

內容解密:

這段程式碼展示瞭如何構建一個簡單的故事來與目標物件建立情感連結。create_emotional_connection函式接收一個故事作為輸入,並加入了一個幹擾元素(系統故障)和一個解決方案(重設密碼)。這樣可以使故事更具說服力,引發目標物件的情感反應。

邏輯解釋(Logos)

在建立了情感連結之後,需要進一步解釋為什麼你的請求或想法是重要的。這涉及到提供合理的理由來說服目標物件。例如,向系統管理員請求重設帳戶憑證的連結時,可以解釋說因為被鎖定在系統外,無法繼續工作。

影響情緒的腦部機制

人類的大腦分為多個區域,分別負責不同的功能。其中三個關鍵區域是:

  • 新皮層(Neocortex):負責邏輯思維
  • 下丘腦(Hypothalamus):負責情緒和感受
  • 小腦和腦幹(Cerebellum and Brainstem):負責原始功能,如運動協調和基本生命功能

要影響他人,需要繞過新皮層,直接訴諸下丘腦。這就是為什麼民粹主義政治家的演講往往能引發強烈的情緒反應,而不是理性的思考。

  graph LR;
    A[新皮層] -->|邏輯思維|> B(理性決策);
    C[下丘腦] -->|情緒和感受|> D(情緒反應);
    E[小腦和腦幹] -->|原始功能|> F(運動協調和基本生命功能);

圖表翻譯: 此圖示展示了大腦的三個主要區域及其功能。新皮層負責邏輯思維,下丘腦負責情緒和感受,而小腦和腦幹則控制著原始功能,如運動協調和基本生命功能。瞭解這些區域的功能有助於我們更好地設計說服策略。

框架效應(Framing)

框架是指設定一個話語、辯論或情境的邊界。在說服過程中,框架的控制權至關重要。當你對他人做出反應時,對方掌握了框架;而當他人對你的行為和言論做出反應時,你則掌握了框架。框架的碰撞是一種「死亡競賽」,最終只有一個框架會佔據主導地位。

社交工程學中常見的框架型別包括:

  • 權力框架(Power Frame):根據社會規範或職權建立的權力關係。
  • 神秘框架(Intrigue Frame):透過神秘或有趣的故事吸引對方。
  • 時間框架(Time Frame):對方試圖將自己的時間安排強加於你。
  • 分析框架(Analyst Frame):目標物件關注資料和數字。
  • 獎賞框架(Prizing Frame):讓對方明白他們是商品,而你是獎品。
def own_the_frame(frame_type, message):
    if frame_type == "權力框架":
        return f"以權威的方式表達:{message}"
    elif frame_type == "神秘框架":
        return f"以神秘的故事吸引對方:{message}"
    else:
        return f"其他框架型別:{message}"

# 示例用法
message = "這是一個範例訊息"
print(own_the_frame("權力框架", message))

內容解密:

這段程式碼展示瞭如何根據不同的框架型別來構建訊息。own_the_frame函式根據輸入的框架型別,傳回相應的訊息內容。例如,使用權力框架時,會以權威的方式表達訊息。這樣的設計有助於在社交工程攻擊中掌握主動權。

非技術性攻擊手法

除了技術手段之外,還有多種非技術性的社交工程攻擊手法可以用來取得目標物件的有用資訊。這些方法包括但不限於:

  • 利用心理學原理影響目標物件
  • 透過社交媒體收集目標物件的資訊
  • 使用電話或面對面交流來取得敏感資訊

瞭解這些非技術性的攻擊手法有助於我們更好地防範社交工程攻擊。

社交工程攻擊的各種手法與技術解析

在進行滲透測試或紅隊演練時,攻擊者經常使用各種社交工程技巧來取得敏感資訊或進入目標系統。這些方法不僅依賴技術手段,還需要心理操控和社會工程學知識。

垃圾桶搜尋(Dumpster Diving)

攻擊者透過翻找目標公司的垃圾,可能會找到一些未被銷毀的重要檔案,如發票、契約、人力資原始檔,甚至是列印出的私人電子郵件或憑證。這種方法看似簡單,卻可能帶來意想不到的收穫。

偷窺(Shoulder Surfing)

偷窺是指觀察不應該看見的東西,例如在火車或咖啡店裡偷看他人的電腦螢幕,或者觀察員工的識別徽章。這種方法需要一定的隱蔽性和觀察力。

實體入侵(Physical Intrusion)

實體入侵是一種高度技術性的攻擊,但其技能與數位技術無直接關係。主要方法包括:

  1. 撬鎖(Lockpicking):如同電影情節,但現實中大多數情況下並不實用。可以參考MIT的鎖匠來學習基本技巧。
  2. 尾隨(Tailgating):跟隨員工進入建築物。最好的方法是與員工在煙區聊天,裝成也是員工的樣子,然後跟隨他們進入建築。如果需要識別徽章,可以藉口忘記徽章而請求幫助。

網路釣魚攻擊(Phishing)

網路釣魚攻擊類別似於行銷中的出站行銷,直接接觸目標。常見的方法是傳送看似來自同事或家人的電子郵件或簡訊,要求更新銀行密碼等。

網路釣魚活動的一些想法

  1. 檢視您的年度獎金:讓受害者相信需要檢查公司內部網站以領取年度獎金,實際上連結到網路釣魚網站以收集憑證。
  2. 這是您要求的檔案:假裝是公司內部人員傳送受害者請求的檔案,特別適用於流程混亂的大公司。但如果受害者沒有請求檔案,可能會引發懷疑。

水坑攻擊(Watering Holes)

水坑攻擊是讓受害者自投羅網,類別似於行銷中的入站行銷。方法包括:

  1. 拼寫錯誤佔用(Typos Squatting):註冊與常見網站拼寫錯誤相似的網域名稱,例如將mybank.com註冊為mybamk.com,建立相似的網站來收集憑證。
  2. Unicode網域名稱攻擊:利用不同字元集中的同形異義字進行攻擊,例如使用西里爾字母￿代替ASCII字母a
  3. 位元翻轉攻擊(Bit Squatting):利用電腦記憶體錯誤導致的位元翻轉現象。例如,如果攻擊者控制了acc.com,可能會收到原本傳送給abc.com的請求。

電話詐騙

隨著機器學習和深度偽造技術的進步,詐騙者越來越容易在電話中偽裝身份。可以預期這類別攻擊將在未來造成更大的影響。

WebAssembly技術

WebAssembly(Wasm)是一種二進位制指令格式,允許在大多數瀏覽器中執行高效的低階程式碼。它是編譯目標,而不是手寫程式碼。可以將高階語言(如Rust)編譯為WebAssembly,從而在網頁上執行。這項技術未來可能改變客戶端網頁應用的開發方式。

程式碼範例:產生位元翻轉網域名稱

use std::env;

fn bitflip(charac: u8, pos: u8) -> u8 {
    let shiftval = 1 << pos;
    charac ^ shiftval
}

fn is_valid(charac: char) -> bool {
    charac.is_ascii_alphanumeric() || charac == '-'
}

fn main() {
    let args = env::args().collect::<Vec<String>>();
    if args.len() != 3 {
        println!("Usage: dnsquat domain .com");
        return;
    }
    let name = args[1].to_lowercase();
    let tld = args[2].to_lowercase();
    for i in 0..name.len() {
        let charac = name.as_bytes()[i];
        for bit in 0..8 {
            let bitflipped = bitflip(charac.into(), bit);
            if is_valid(bitflipped as char)
                && bitflipped.to_ascii_lowercase() != charac.to_ascii_lowercase()
            {
                let mut bitsquatting_candidat = name.as_bytes()[..i].to_vec();
                bitsquatting_candidat.push(bitflipped);
                bitsquatting_candidat.append(&mut name.as_bytes()[i + 1..].to_vec());
                println!(
                    "{}{}",
                    String::from_utf8(bitsquatting_candidat).unwrap(),
                    tld
                );
            }
        }
    }
}

內容解密:

這段程式碼用於產生目標網域名稱的所有可能的位元翻轉變體。首先,它檢查輸入引數是否正確,然後遍歷網域名稱中的每個字元,並對每個位元進行翻轉。如果翻轉後的字元仍然是有效的網域名稱字元,則輸出該變體。

使用Rust實作電子郵件傳送與網路釣魚頁面佈署

電子郵件傳送功能實作

電子郵件傳送在Rust中可以透過兩種主要方式實作:使用SMTP伺服器或透過第三方服務的API(如AWS SES或Mailgun)。本章節將重點介紹如何使用Rust實作電子郵件傳送功能。

9.7.1 建立回應式電子郵件範本

建立具有回應式設計的電子郵件範本是成功傳送電子郵件的關鍵。雖然理論上電子郵件是由簡單的HTML組成,但實際上由於不同電子郵件客戶端對HTML的解析方式不同,使得手動編寫電子郵件範本變得困難。

幸運的是,有優秀的mjml框架可供使用。透過其線上編輯器(https://mjml.io/try-it-live),可以輕鬆建立回應式電子郵件範本。

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text font-size="36px" font-family="helvetica" align="center">{{ title }}</mj-text>
        <mj-divider border-color="#4267B2"></mj-divider>
        <mj-text font-size="20px" font-family="helvetica">{{ content }}</mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

內容解密:

  1. mjml是一種專門用於建立回應式電子郵件的標記語言,能夠簡化HTML電子郵件的開發過程。
  2. 範本中使用了{{ title }}{{ content }}作為變數,這些將在後續步驟中被實際的標題和內容替換。
  3. mj-divider用於建立分隔線,以增強電子郵件的可讀性。

9.7.2 渲染電子郵件範本

建立好範本後,需要使用tera crate來填充實際內容。

// ch_09/emails/src/template.rs
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmailData {
    pub title: String,
    pub content: String,
}

pub const EMAIL_TEMPLATE: &str = r#"""
<!doctype html>
// ...
"""#;
// ch_09/emails/src/main.rs
let from = "evil@hacker.com".to_string();
let to = "credule@kerkour.com".to_string();
let subject = "".to_string();
let title = subject.clone();
let content = "".to_string();

let mut templates = tera::Tera::default();
templates.autoescape_on(Vec::new());
templates.add_raw_template("email", template::EMAIL_TEMPLATE)?;

let email_data = tera::Context::from_serialize(template::EmailData { title, content })?;
let html = templates.render("email", &email_data)?;

let email = Message::builder()
    .from(from.parse()?)
    .to(to.parse()?)
    .subject(subject)
    .body(html.to_string())?;

內容解密:

  1. 使用tera範本引擎來渲染HTML電子郵件內容。
  2. EmailData結構體用於儲存要填充到範本中的資料。
  3. tera::Tera例項用於載入和渲染範本。
  4. 透過add_raw_template方法將範本字串加入到Tera例項中。
  5. 使用render方法將資料填充到範本中,生成最終的HTML內容。

9.7.3 使用SMTP傳送電子郵件

SMTP是傳送電子郵件的標準協定,因此是最具可移植性的方法。

// ch_09/emails/src/main.rs
let smtp_credentials = Credentials::new("smtp_username".to_string(), "smtp_password".to_string());
let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay("smtp.email.com")?
    .credentials(smtp_credentials)
    .build();

smtp::send_email(&mailer, email.clone()).await?;
// ch_09/emails/src/smtp.rs
use lettre::{AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor};

pub async fn send_email(
    mailer: &AsyncSmtpTransport<Tokio1Executor>,
    email: Message,
) -> Result<(), anyhow::Error> {
    mailer.send(email).await?;
    Ok(())
}

內容解密:

  1. 使用lettre crate來建立SMTP連線並傳送電子郵件。
  2. AsyncSmtpTransport用於建立非同步的SMTP傳輸。
  3. Credentials用於儲存SMTP驗證所需的使用者名稱和密碼。
  4. send_email函式封裝了傳送電子郵件的邏輯。

9.7.4 使用AWS SES傳送電子郵件

除了SMTP,還可以使用AWS SES等第三方服務來傳送電子郵件。

// ch_09/emails/src/main.rs
let ses_client = SesClient::new(rusoto_core::Region::UsEast1);
ses::send_email(&ses_client, email).await?;
// ch_09/emails/src/ses.rs
use lettre::Message;
use rusoto_ses::{RawMessage, SendRawEmailRequest, Ses, SesClient};

pub async fn send_email(ses_client: &SesClient, email: Message) -> Result<(), anyhow::Error> {
    let raw_email = email.formatted();
    let ses_request = SendRawEmailRequest {
        raw_message: RawMessage {
            data: base64::encode(raw_email).into(),
        },
        ..Default::default()
    };
    ses_client.send_raw_email(ses_request).await?;
    Ok(())
}

內容解密:

  1. 使用rusoto_ses crate與AWS SES互動。
  2. SesClient用於建立與AWS SES的連線。
  3. send_raw_email方法用於傳送原始電子郵件內容。

9.7.5 提高電子郵件傳遞率

提高電子郵件傳遞率是一個複雜的話題,涉及多個因素。以下是一些實用的建議:

  1. 使用獨立網域:為每個活動使用不同的網域,以避免被標記為垃圾郵件。
  2. 避免批次傳送:針對特定目標傳送電子郵件,以降低被識別為垃圾郵件的風險。
  3. 關注IP評價:伺服器的IP位址評價會影響電子郵件的傳遞率。
  4. 檢查拼寫錯誤:確保電子郵件內容無拼寫錯誤,以提高可信度。

9.8 在Rust中實作網路釣魚頁面

網路釣魚頁面是一種模模擬實網站的表單,用於竊取使用者憑證。實作網路釣魚頁面需要仔細設計,以避免被受害者識別。

9.10 Cargo工作空間

當專案變得越來越大時,使用Cargo工作空間可以更好地管理多個crate。

[workspace]
members = [
    "webapp",
    "server",
    "common",
]
default-members = [
    "webapp",
    "server",
]

[profile.release]
lto = true
debug = false
debug-assertions = false
codegen-units = 1

內容解密:

  1. Cargo工作空間允許多個crate分享相同的目標資料夾和Cargo.lock檔案。
  2. Cargo.toml中定義工作空間的成員和預設成員。
  3. 可以在工作空間層級組態編譯設定,如最佳化級別和除錯資訊。