# 4. Application Layer Protocols ## โปรโตคอลชั้นแอปพลิเคชัน: อีเมล เว็บ และบริการเครือข่าย **ผู้จัดทำ:** อรรถพล คงหวาน --- # Outline * 4.1 Email Protocols: SMTP, POP3, IMAP — หลักการทำงานและความเสี่ยง * 4.2 ระบบอีเมลที่ปลอดภัย (Secure E-mail System): S/MIME, STARTTLS * 4.3 HTTP vs. HTTPS: TLS Handshake และ Certificate Validation * 4.4 Web Application Security เบื้องต้น: OWASP Top 10 Overview * 4.5 Email Authentication Mechanisms: SPF, DKIM, DMARC * 4.6 ความเสี่ยงจาก Phishing, Spam, และ Email Spoofing * 4.7 DNS Security Extensions (DNSSEC) --- ## 4.1 Email Protocols: SMTP, POP3, IMAP — หลักการทำงานและความเสี่ยง --- ## 4.1.1 ภาพรวมสถาปัตยกรรมระบบอีเมล ระบบอีเมลสมัยใหม่ประกอบด้วยโปรโตคอล 3 ตัวที่ทำหน้าที่ต่างกันอย่างชัดเจน: * **SMTP** — ใช้ **ส่ง** อีเมลจาก MUA ไปยัง MTA และส่งต่อระหว่าง MTA ด้วยกันเอง (relay) * **POP3** — ใช้ **ดึง** อีเมลจากเซิร์ฟเวอร์มาเก็บที่เครื่องผู้ใช้ (download-and-delete โดยปริยาย) * **IMAP** — ใช้ **ซิงค์** สถานะอีเมลระหว่างเซิร์ฟเวอร์กับไคลเอนต์หลายเครื่องพร้อมกัน (server-side state) --- ## 4.1.1 สถาปัตยกรรมระบบอีเมล (ต่อ) ```mermaid graph LR A[MUA
Mail User Agent
เช่น Thunderbird] -->|SMTP :587| B[MTA ต้นทาง
Outgoing Mail Server] B -->|SMTP :25 relay| C[MTA ปลายทาง
Incoming Mail Server] C -->|เก็บใน Mailbox| D[(Mail Storage
Maildir/mbox)] D -->|POP3 :110| E[MUA ผู้รับ
ดึงแล้วลบ] D -->|IMAP :143| F[MUA ผู้รับ
ซิงค์สถานะ] style A fill:#282828,stroke:#fabd2f,color:#ebdbb2 style B fill:#3c3836,stroke:#83a598,color:#ebdbb2 style C fill:#3c3836,stroke:#83a598,color:#ebdbb2 style D fill:#504945,stroke:#b8bb26,color:#ebdbb2 style E fill:#282828,stroke:#fb4934,color:#ebdbb2 style F fill:#282828,stroke:#8ec07c,color:#ebdbb2 ``` --- ## 4.1.2 กลไกการทำงานของ SMTP SMTP เป็นโปรโตคอลแบบ **text-based command-response** ทำงานบนพอร์ต 25 (relay), 587 (submission พร้อม STARTTLS), และ 465 (SMTPS แบบ implicit TLS) ลำดับคำสั่งพื้นฐานของ SMTP: 1. **HELO/EHLO** — ไคลเอนต์แนะนำตัวเองพร้อม hostname 2. **MAIL FROM** — ระบุผู้ส่ง (envelope sender) 3. **RCPT TO** — ระบุผู้รับ (envelope recipient) — ทำซ้ำได้หลายครั้ง 4. **DATA** — เริ่มส่งเนื้อหาอีเมล จบด้วยบรรทัดที่มีจุด `.` เดี่ยว ๆ 5. **QUIT** — ปิดการเชื่อมต่อ --- ## 4.1.2 ลำดับการทำงานของ SMTP (Sequence Diagram) ```mermaid sequenceDiagram participant C as Client (MUA) participant S as Server (MTA) C->>S: EHLO client.example.com S-->>C: 250-mail.example.com Hello
250-STARTTLS
250 AUTH LOGIN PLAIN C->>S: STARTTLS S-->>C: 220 Ready to start TLS Note over C,S: TLS Handshake เกิดขึ้นที่นี่ (ดู 4.3) C->>S: AUTH LOGIN S-->>C: 334 VXNlcm5hbWU6 C->>S: 'MAIL FROM:<moo@rmutsv.ac.th>' S-->>C: 250 OK C->>S: RCPT TO:<student@rmutsv.ac.th> S-->>C: 250 OK C->>S: DATA S-->>C: 354 End data with <CR><LF>.<CR><LF> C->>S: Subject: ประกาศคะแนน...
เนื้อหาอีเมล...
. S-->>C: 250 Message accepted C->>S: QUIT ``` --- ## 4.1.3 การทดสอบ SMTP ด้วยเครื่องมือ Linux จริง ตัวอย่างการเชื่อมต่อ SMTP ด้วย `openssl s_client` และ `telnet` เพื่อทดสอบ hand-shaking ด้วยตนเอง: ```bash # ทดสอบเชื่อมต่อ SMTP submission port พร้อม STARTTLS openssl s_client -connect mail.rmutsv.ac.th:587 -starttls smtp # หลังเชื่อมต่อสำเร็จ พิมพ์คำสั่งด้วยมือ EHLO test.local AUTH LOGIN # (ป้อน base64 ของ username/password) MAIL FROM:
RCPT TO:
DATA Subject: Test . QUIT ``` --- ## 4.1.3 การทดสอบอัตโนมัติด้วย swaks หากต้องการทดสอบเชิงอัตโนมัติมากขึ้น สามารถใช้เครื่องมือ `swaks` (Swiss Army Knife for SMTP) ซึ่งเป็นมาตรฐานของนักทดสอบระบบอีเมล: ```bash sudo pacman -S swaks # หรือ apt install swaks บน Debian/Ubuntu swaks --to student@rmutsv.ac.th \ --from moo@rmutsv.ac.th \ --server mail.rmutsv.ac.th:587 \ --tls \ --auth LOGIN \ --auth-user moo@rmutsv.ac.th ``` --- ## 4.1.4 ความเสี่ยงของ SMTP แบบดั้งเดิม * **Plaintext Transmission**: SMTP ดั้งเดิม (ไม่มี STARTTLS) ส่งทั้ง credentials และเนื้อหาอีเมลแบบไม่เข้ารหัส ผู้โจมตีที่ดักฟังบนเครือข่าย (network sniffing) สามารถอ่านได้ทั้งหมด * **Open Relay**: MTA ที่กำหนดค่าไม่รัดกุมอาจถูกใช้เป็น relay ส่ง spam โดยบุคคลภายนอก * **No Sender Verification โดยธรรมชาติ**: envelope `MAIL FROM` สามารถปลอมได้ง่าย (ดูหัวข้อ 4.5 และ 4.6) * **Command Injection ผ่าน Header**: หากแอปพลิเคชันเว็บสร้างอีเมลจาก user input โดยไม่กรอง CRLF อาจเกิด **Email Header Injection** --- ## 4.1.5 เปรียบเทียบ POP3 กับ IMAP | คุณสมบัติ | POP3 | IMAP | |---|---|---| | **พอร์ตมาตรฐาน** | 110 (plaintext) / 995 (POP3S) | 143 (plaintext) / 993 (IMAPS) | | **ตำแหน่งเก็บอีเมลหลัก** | ดาวน์โหลดมาที่เครื่องไคลเอนต์ | เก็บที่เซิร์ฟเวอร์เป็นหลัก | | **การซิงค์หลายอุปกรณ์** | ทำได้ยาก (ค่าเริ่มต้นลบจากเซิร์ฟเวอร์) | รองรับดีเยี่ยม (server-side state) | | **การทำงานแบบออฟไลน์** | ดี (มีข้อมูลในเครื่องเต็ม) | ต้องมี local cache | | **โครงสร้างโฟลเดอร์** | ไม่รองรับ (mailbox เดียว) | รองรับหลายโฟลเดอร์/labels | | **ความเสี่ยงเชิง Security** | credential + data สัมผัสน้อยกว่า | พื้นผิวโจมตีกว้างกว่าเพราะ session คงอยู่นาน | > **Best Practice**: บังคับใช้ POP3S/IMAPS (implicit TLS) หรือ STARTTLS เสมอ และปิดพอร์ตแบบ plaintext (110/143) ที่ระดับไฟร์วอลล์ --- ## 4.2 ระบบอีเมลที่ปลอดภัย (Secure E-mail System): S/MIME, STARTTLS --- ## 4.2.1 STARTTLS: การยกระดับการเชื่อมต่อแบบ Opportunistic **STARTTLS** เป็นกลไก **opportunistic encryption** ที่ให้การเชื่อมต่อเริ่มต้นแบบ plaintext บนพอร์ตมาตรฐาน แล้วจึง "อัปเกรด" เป็น TLS กลางการสนทนา ข้อดี: ใช้พอร์ตเดียวกับโปรโตคอลเดิม จุดอ่อนสำคัญ: **STARTTLS Stripping Attack** — ผู้โจมตีที่ทำ MITM สามารถลบคำสั่ง `STARTTLS` ออกจากการตอบสนองของเซิร์ฟเวอร์ ทำให้ไคลเอนต์เข้าใจผิดว่าเซิร์ฟเวอร์ไม่รองรับ TLS แล้วสื่อสารต่อแบบ plaintext โดยไม่รู้ตัว --- ## 4.2.1 STARTTLS Stripping Attack (Diagram) ```mermaid sequenceDiagram participant C as Client participant M as Attacker (MITM) participant S as Real Server C->>M: EHLO M->>S: EHLO (forwarded) S-->>M: 250-STARTTLS supported M--xC: 250 OK (STARTTLS line stripped!) Note over C: Client คิดว่าเซิร์ฟเวอร์ไม่รองรับ TLS C->>M: MAIL FROM (plaintext) M->>S: forward plaintext Note over M: ผู้โจมตีอ่าน/แก้ไขข้อมูลได้ทั้งหมด ``` **แนวทางป้องกัน**: ใช้ **MTA-STS** หรือ **DANE** เพื่อบังคับว่าโดเมนปลายทางต้องรองรับ TLS เสมอ ไม่ยอมให้ downgrade --- ## 4.2.2 S/MIME: การเข้ารหัสระดับเนื้อหาอีเมล ต่างจาก STARTTLS ที่เข้ารหัสเฉพาะ **transport** (ช่วงการส่ง) **S/MIME** เข้ารหัสที่ระดับ **content** (ตัวเนื้อหาอีเมลเอง) ทำให้ข้อมูลยังคงถูกเข้ารหัสแม้ถูกจัดเก็บบนเซิร์ฟเวอร์ที่ไม่น่าเชื่อถือ S/MIME ใช้ **Hybrid Encryption** ผสมข้อดีของทั้ง Symmetric และ Asymmetric Encryption --- ## 4.2.2 สมการ Hybrid Encryption ของ S/MIME
ขั้นที่ 1:
K
sym
=
generateRandomKey()
ขั้นที่ 2:
C
=
E
K
sym
(
M
)
ขั้นที่ 3:
C
key
=
E
PK
recipient
(
K
sym
)
โดยที่
M
= ข้อความต้นฉบับ,
K
sym
= กุญแจสมมาตรที่สุ่มสร้างขึ้นใหม่ (session key),
E
K
sym
= ฟังก์ชันเข้ารหัสแบบสมมาตร (AES-256-CBC/GCM),
PK
recipient
= กุญแจสาธารณะของผู้รับ (X.509),
C
= เนื้อหาที่เข้ารหัสแล้ว,
C
key
= กุญแจสมมาตรที่ถูกเข้ารหัส **เหตุผลที่ใช้ Hybrid**: Asymmetric encryption ช้ากว่า Symmetric หลายร้อยเท่าเมื่อข้อมูลใหญ่ จึงใช้ asymmetric เข้ารหัสเฉพาะ "กุญแจ" แล้วใช้ symmetric เข้ารหัสเนื้อหาจริง --- ## 4.2.2 แผนภาพการเข้ารหัส S/MIME ```mermaid graph TB subgraph Sender["ฝั่งผู้ส่ง (Sender)"] A[Plaintext Message] --> B[AES Encrypt
ด้วย Session Key] C[Session Key
สุ่มใหม่ทุกฉบับ] --> D[RSA Encrypt
ด้วย Public Key ผู้รับ] B --> E[Encrypted Body] D --> F[Encrypted Session Key] end subgraph Envelope["S/MIME Envelope"] E --> G[รวมเป็น Email Package] F --> G end subgraph Receiver["ฝั่งผู้รับ (Receiver)"] G --> H[RSA Decrypt
ด้วย Private Key ตนเอง] H --> I[Session Key ที่ถอดแล้ว] G --> J[AES Decrypt
ด้วย Session Key] I --> J J --> K[Plaintext Message] end style Sender fill:#282828,stroke:#fabd2f,color:#ebdbb2 style Envelope fill:#3c3836,stroke:#8ec07c,color:#ebdbb2 style Receiver fill:#282828,stroke:#83a598,color:#ebdbb2 ``` --- ## 4.2.3 การลงลายเซ็นดิจิทัลใน S/MIME นอกจากการเข้ารหัส S/MIME ยังรองรับการลงลายเซ็นเพื่อยืนยันตัวตนผู้ส่งและความถูกต้องของเนื้อหา (รายละเอียดเต็มในบทที่ 6) โดยสรุปขั้นตอน: 1. คำนวณค่าแฮชของเนื้อหาอีเมล:
h
=
SHA-256
(
M
)
2. เข้ารหัสค่าแฮชด้วย **private key** ของผู้ส่ง:
σ
=
E
SK
sender
(
h
)
3. แนบ
σ
พร้อมใบรับรอง (certificate) ของผู้ส่งไปกับอีเมล 4. ผู้รับถอดรหัส
σ
ด้วย public key ของผู้ส่ง ได้
h
'
แล้วเปรียบเทียบกับค่าแฮชที่คำนวณเองจากเนื้อหาที่ได้รับ หาก
h
=
h
'
แสดงว่าเนื้อหาไม่ถูกแก้ไขและมาจากผู้ส่งจริง --- ## 4.2.4 ตัวอย่างการใช้งาน S/MIME จริงด้วย OpenSSL ```bash # สร้าง key pair และ self-signed certificate สำหรับทดสอบ openssl req -x509 -newkey rsa:2048 -keyout moo_private.pem \ -out moo_cert.pem -days 365 -nodes \ -subj "/CN=Moo/emailAddress=moo@rmutsv.ac.th" # เข้ารหัสอีเมล (encrypt) ด้วย public key ของผู้รับ openssl smime -encrypt -aes256 -in email_body.txt \ -out email_encrypted.p7m student_cert.pem # ลงลายเซ็นอีเมล (sign) ด้วย private key ของผู้ส่ง openssl smime -sign -in email_body.txt -out email_signed.p7s \ -signer moo_cert.pem -inkey moo_private.pem # ฝั่งผู้รับ: ตรวจสอบลายเซ็น openssl smime -verify -in email_signed.p7s \ -CAfile moo_cert.pem -out verified_output.txt ``` --- ## 4.3 HTTP vs. HTTPS: TLS Handshake และ Certificate Validation --- ## 4.3.1 ความแตกต่างพื้นฐานระหว่าง HTTP และ HTTPS **HTTP** ส่งข้อมูลเป็น plaintext บนพอร์ต 80 ส่วน **HTTPS** คือ HTTP ที่ห่อหุ้มด้วยชั้น **TLS** บนพอร์ต 443 ทำให้ได้คุณสมบัติ 3 ประการที่ HTTP ไม่มี: * **Confidentiality**: ข้อมูลถูกเข้ารหัสระหว่างทาง ผู้ดักฟังอ่านไม่ได้ * **Integrity**: ตรวจจับได้หากข้อมูลถูกแก้ไขระหว่างทาง (ผ่าน MAC/AEAD) * **Authentication**: ยืนยันได้ว่ากำลังคุยกับเซิร์ฟเวอร์ตัวจริง ผ่านการตรวจสอบใบรับรอง (certificate) --- ## 4.3.2 TLS 1.3 Handshake โดยละเอียด TLS 1.3 (มาตรฐานปัจจุบัน) ลดจำนวน round-trip ลงเหลือเพียง **1-RTT** (เร็วกว่า TLS 1.2 ที่ใช้ 2-RTT) โดยใช้ **Ephemeral Diffie-Hellman (ECDHE)** เป็นกลไกหลักในการแลกเปลี่ยนกุญแจ ```mermaid sequenceDiagram participant C as Client participant S as Server C->>S: ClientHello
(Supported Ciphers, Key Share ECDHE) S-->>C: ServerHello
(Chosen Cipher, Key Share ECDHE) Note over S: Server คำนวณ Shared Secret ได้ทันที S-->>C: EncryptedExtensions, Certificate,
CertificateVerify, Finished Note over C: Client ตรวจสอบ Certificate Chain
และคำนวณ Shared Secret C->>S: Finished Note over C,S: Application Data เริ่มส่งได้
(เข้ารหัสด้วย Session Keys ที่ได้จาก Shared Secret) ``` --- ## 4.3.3 ตัวอย่างการคำนวณ Diffie-Hellman (แบบง่าย) ในการใช้งานจริง TLS 1.3 ใช้ **ECDHE** ซึ่งซับซ้อนกว่านี้มาก แต่หลักการทางคณิตศาสตร์เดียวกันสามารถอธิบายได้ด้วย **Classic Diffie-Hellman** ที่ใช้ตัวเลขเล็ก ๆ **พารามิเตอร์สาธารณะ** (ทุกฝ่ายรู้):
g
=
5
,
p
=
23
Client เลือก private key:
a
=
6
Server เลือก private key:
b
=
15
--- ## 4.3.3 DH — ขั้นที่ 1: คำนวณ Public Value
A
client
=
g
a
mod
p
=
5
6
mod
23
=
15625
mod
23
=
8
B
server
=
g
b
mod
p
=
5
15
mod
23
=
19
ทั้งสองฝ่ายแลกเปลี่ยนค่า
A
client
=
8
และ
B
server
=
19
ผ่านเครือข่าย (ผู้ดักฟังเห็นได้ แต่ไม่มีประโยชน์หากไม่รู้
a
หรือ
b
) --- ## 4.3.3 DH — ขั้นที่ 2: คำนวณ Shared Secret
Client:
S
=
B
server
a
mod
p
=
19
6
mod
23
=
2
Server:
S
=
A
client
b
mod
p
=
8
15
mod
23
=
2
ทั้งสองฝ่ายได้ **shared secret = 2** ตรงกันโดยไม่เคยส่งค่านี้ผ่านเครือข่ายเลย หัวใจของ DH:
g
a
b
mod
p
คำนวณได้จากทั้งสองทิศทาง แต่ย้อนกลับหา
a
,
b
(Discrete Logarithm Problem) ยากมากเมื่อ
p
มีขนาดหลักพันบิตจริง --- ## 4.3.3 ตรวจสอบด้วย Python ```python def dh_shared_secret(g: int, p: int, my_private: int, their_public: int) -> int: """คำนวณ shared secret ของ Diffie-Hellman g: generator สาธารณะ p: จำนวนเฉพาะ (modulus) สาธารณะ my_private: กุญแจส่วนตัวของฝ่ายเรา their_public: กุญแจสาธารณะที่ได้รับจากอีกฝ่าย """ return pow(their_public, my_private, p) g, p = 5, 23 a, b = 6, 15 A = pow(g, a, p) # public value ของ client = 8 B = pow(g, b, p) # public value ของ server = 19 secret_client = dh_shared_secret(g, p, a, B) # -> 2 secret_server = dh_shared_secret(g, p, b, A) # -> 2 assert secret_client == secret_server print(f"Shared secret ตรงกัน: {secret_client}") ``` --- ## 4.3.4 Certificate Validation Chain ```mermaid graph TD A["Root CA
(Self-signed, ฝังใน OS/Browser Trust Store)"] -->|ลงนามให้| B["Intermediate CA
(เช่น Let's Encrypt R3)"] B -->|ลงนามให้| C["Server Certificate
CN=example.rmutsv.ac.th"] D[Browser/Client] -->|1\. ได้รับ Certificate Chain จาก Server| C D -->|2\. ตรวจสอบลายเซ็นย้อนขึ้นไป| B D -->|3\. ตรวจสอบ Root อยู่ใน Trust Store| A D -->|4\. ตรวจสอบวันหมดอายุ + CRL/OCSP| E{Valid?} E -->|Yes| F[แสดงไอคอนกุญแจ ✓
เชื่อมต่อสำเร็จ] E -->|No| G[Certificate Error
เตือนผู้ใช้] style A fill:#282828,stroke:#fb4934,color:#ebdbb2 style B fill:#3c3836,stroke:#fabd2f,color:#ebdbb2 style C fill:#3c3836,stroke:#8ec07c,color:#ebdbb2 style F fill:#282828,stroke:#b8bb26,color:#ebdbb2 style G fill:#282828,stroke:#fb4934,color:#ebdbb2 ``` --- ## 4.3.5 การตรวจสอบ TLS/Certificate ด้วยเครื่องมือ Linux ```bash # ตรวจสอบ TLS handshake และรายละเอียด certificate chain ของเว็บไซต์จริง openssl s_client -connect codemoomoo.dev:443 -servername codemoomoo.dev < /dev/null # ดูรายละเอียด certificate เฉพาะฟิลด์สำคัญ echo | openssl s_client -connect codemoomoo.dev:443 -servername codemoomoo.dev 2>/dev/null \ | openssl x509 -noout -subject -issuer -dates # ทดสอบ cipher suite ที่เซิร์ฟเวอร์รองรับด้วย nmap nmap --script ssl-enum-ciphers -p 443 codemoomoo.dev # ตรวจสอบเกรดความปลอดภัย TLS ของเว็บไซต์ (ใช้ testssl.sh) testssl.sh --protocols --vulnerable codemoomoo.dev ``` --- ## 4.4 Web Application Security เบื้องต้น: OWASP Top 10 Overview --- ## 4.4.1 OWASP Top 10 คืออะไร **OWASP (Open Web Application Security Project) Top 10** คือรายการช่องโหว่ (vulnerabilities) ของเว็บแอปพลิเคชันที่พบบ่อยและมีผลกระทบสูงที่สุด จัดทำและปรับปรุงเป็นระยะโดยชุมชนนักวิจัยด้านความมั่นคงปลอดภัยทั่วโลก ใช้เป็นมาตรฐานอ้างอิงสากลสำหรับการพัฒนาซอฟต์แวร์อย่างปลอดภัย (Secure Software Development Lifecycle) --- ## 4.4.2 สรุปหมวดหมู่หลัก OWASP Top 10 (2021) — ตอนที่ 1 | อันดับ | หมวดหมู่ | คำอธิบายโดยย่อ | ตัวอย่างการโจมตี | |---|---|---|---| | A01 | Broken Access Control | การควบคุมสิทธิ์เข้าถึงบกพร่อง | แก้ URL parameter เพื่อดูข้อมูลผู้ใช้อื่น (IDOR) | | A02 | Cryptographic Failures | ใช้/จัดการการเข้ารหัสผิดพลาด | เก็บรหัสผ่านแบบ plaintext, ใช้ TLS เวอร์ชันเก่า | | A03 | Injection | แทรกโค้ด/คำสั่งผ่าน input | SQL Injection, Command Injection, XSS | | A04 | Insecure Design | ออกแบบระบบไม่คำนึงถึงความมั่นคงตั้งแต่ต้น | ไม่มี rate limiting บนฟอร์ม login | | A05 | Security Misconfiguration | ตั้งค่าระบบไม่รัดกุม | เปิด debug mode, default credentials | --- ## 4.4.2 สรุปหมวดหมู่หลัก OWASP Top 10 (2021) — ตอนที่ 2 | อันดับ | หมวดหมู่ | คำอธิบายโดยย่อ | ตัวอย่างการโจมตี | |---|---|---|---| | A06 | Vulnerable and Outdated Components | ใช้ library/framework เวอร์ชันมีช่องโหว่ | ใช้ Log4j เวอร์ชันที่มี Log4Shell | | A07 | Identification and Authentication Failures | กลไกยืนยันตัวตนอ่อนแอ | ไม่มี MFA, session fixation | | A08 | Software and Data Integrity Failures | ไม่ตรวจสอบความถูกต้องของโค้ด/ข้อมูล | CI/CD pipeline ถูกแทรกโค้ดร้าย | | A09 | Security Logging and Monitoring Failures | บันทึก log ไม่เพียงพอ ตรวจจับเหตุการณ์ผิดปกติไม่ทัน | โจมตีสำเร็จแต่ไม่มีใครรู้เป็นเดือน | | A10 | Server-Side Request Forgery (SSRF) | หลอกเซิร์ฟเวอร์ให้ยิง request ไปยังเป้าหมายที่ผู้โจมตีกำหนด | เข้าถึง internal metadata service ผ่านช่องโหว่ SSRF | --- ## 4.4.3 ตัวอย่าง SQL Injection เชิงลึก **SQL Injection** ตัวอย่าง query ที่ต่อสตริงโดยตรงจาก input โดยไม่ผ่านการ sanitize: ```sql -- Query เดิมที่แอปสร้างจาก user input โดยตรง (ไม่ปลอดภัย) SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1'; ``` หาก input ผู้ใช้คือ `' OR '1'='1` เงื่อนไข WHERE จะเป็นจริงเสมอ ทำให้ bypass การตรวจสอบรหัสผ่านได้ (เชื่อมโยงกับบทที่ 13) --- ## 4.4.3 แนวทางป้องกัน: Prepared Statements **แนวทางป้องกัน**: ใช้ **Prepared Statements / Parameterized Queries** เสมอ ```python # ไม่ปลอดภัย (string concatenation) query = f"SELECT * FROM users WHERE username = '{username}'" # ปลอดภัย (parameterized query) cursor.execute("SELECT * FROM users WHERE username = %s", (username,)) ``` --- ## 4.4.4 การทดสอบเบื้องต้นด้วยเครื่องมือ Linux ```bash # สแกนหาช่องโหว่เว็บแอปพลิเคชันเบื้องต้นด้วย nikto nikto -h https://lab.rmutsv.ac.th # ตรวจสอบ HTTP security headers ที่ขาดหายไป curl -sI https://codemoomoo.dev | grep -Ei "strict-transport|content-security|x-frame|x-content-type" # ใช้ OWASP ZAP แบบ headless scan (baseline scan) docker run -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \ -t https://lab.rmutsv.ac.th -r zap_report.html ``` --- ## 4.5 Email Authentication Mechanisms: SPF, DKIM, DMARC --- ## 4.5.1 ปัญหาที่ต้องแก้: SMTP ไม่มีการยืนยันผู้ส่งโดยธรรมชาติ ฟิลด์ `MAIL FROM` และ header `From:` ใน SMTP สามารถปลอมแปลงได้ง่ายมาก (**Email Spoofing**) กลไก 3 ชั้นต่อไปนี้ถูกออกแบบมาเสริมกันเพื่อแก้ปัญหานี้: **SPF**, **DKIM**, **DMARC** --- ## 4.5.1 ผังการตรวจสอบ SPF/DKIM/DMARC ```mermaid graph TB A["อีเมลขาเข้า"] --> B{"SPF Check
IP ผู้ส่งอยู่ใน DNS record หรือไม่?"} B -->|Pass| C{"DKIM Check
ลายเซ็นดิจิทัลถูกต้องหรือไม่?"} B -->|Fail| D["DMARC Policy
ตัดสินใจ: none/quarantine/reject"] C -->|Pass| E["Alignment Check
โดเมนใน From: ตรงกับ SPF/DKIM domain หรือไม่"] C -->|Fail| D E -->|Aligned| F["✓ อีเมลผ่านการยืนยัน
ส่งเข้า Inbox"] E -->|Not Aligned| D D -->|reject| G["✗ ปฏิเสธอีเมล"] D -->|quarantine| H["⚠ ส่งเข้า Spam/Junk"] D -->|none| I["บันทึก Log เท่านั้น
ยังส่งเข้า Inbox"] style F fill:#282828,stroke:#b8bb26,color:#ebdbb2 style G fill:#282828,stroke:#fb4934,color:#ebdbb2 style H fill:#282828,stroke:#fabd2f,color:#ebdbb2 ``` --- ## 4.5.2 SPF (Sender Policy Framework) SPF ให้เจ้าของโดเมนประกาศรายชื่อ IP/เซิร์ฟเวอร์ที่ **ได้รับอนุญาต** ให้ส่งอีเมลในนามโดเมนนั้น ผ่าน DNS TXT record: ``` rmutsv.ac.th. TXT "v=spf1 ip4:203.113.0.0/24 include:_spf.google.com -all" ``` * `v=spf1` — ระบุเวอร์ชันของ SPF * `ip4:203.113.0.0/24` — อนุญาต IPv4 range นี้ให้ส่งอีเมลได้ * `include:_spf.google.com` — รวมรายการ IP ของ Google Workspace ด้วย * `-all` — **Hard Fail**: ปฏิเสธ IP อื่นทั้งหมด (`~all` = Soft Fail) --- ## 4.5.2 ตรวจสอบ SPF record จริงด้วย Linux ```bash dig TXT rmutsv.ac.th +short # หรือใช้ host host -t TXT rmutsv.ac.th ``` --- ## 4.5.3 DKIM (DomainKeys Identified Mail) DKIM ใช้ **Asymmetric Cryptography** ลงลายเซ็นดิจิทัลในส่วน header ของอีเมล เจ้าของโดเมนเผยแพร่ **public key** ผ่าน DNS TXT record (selector-based) และเซิร์ฟเวอร์ต้นทางเซ็นด้วย **private key** ที่เก็บไว้เป็นความลับ
1. เลือก header ที่จะเซ็น เช่น From, To, Subject, Date
2. คำนวณค่าแฮช:
h
=
SHA-256(headers ที่เลือก + body hash)
3. เซ็นด้วย private key:
σ
=
Sign
RSA
(
h
)
4. แนบเป็น header:
DKIM-Signature: v=1; a=rsa-sha256; d=rmutsv.ac.th; s=selector1; b=
σ
--- ## 4.5.3 DKIM: DNS Record และการตรวจสอบ ตัวอย่าง DNS record ที่เผยแพร่ public key ของ selector ชื่อ `selector1`: ``` selector1._domainkey.rmutsv.ac.th. TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GN..." ``` **ตรวจสอบ DKIM record จริง**: ```bash dig TXT selector1._domainkey.rmutsv.ac.th +short # ตรวจสอบ syntax และความถูกต้องของ DKIM key ด้วยเครื่องมือเฉพาะ opendkim-testkey -d rmutsv.ac.th -s selector1 -vvv ``` เมื่อเซิร์ฟเวอร์ปลายทางได้รับอีเมล จะดึง public key จาก DNS ด้วย selector และโดเมน แล้วตรวจสอบค่าแฮชว่าตรงกับที่ถอดรหัสจากลายเซ็นหรือไม่ — หลักการเดียวกับบทที่ 6 --- ## 4.5.4 DMARC (Domain-based Message Authentication) DMARC ทำหน้าที่เป็น **policy layer** ที่อยู่เหนือ SPF และ DKIM โดยกำหนดว่าหากอีเมลไม่ผ่านการตรวจสอบควรจัดการอย่างไร พร้อมขอรายงานผลกลับมา ``` _dmarc.rmutsv.ac.th. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-report@rmutsv.ac.th; pct=100; adkim=s; aspf=s" ``` | พารามิเตอร์ | ความหมาย | |---|---| | `p=reject` | นโยบายหลัก: ปฏิเสธอีเมลที่ไม่ผ่าน (`none`, `quarantine` เป็นทางเลือกอื่น) | | `rua=mailto:...` | ที่อยู่สำหรับส่งรายงานสรุปรวม (aggregate report) รายวัน | | `pct=100` | เปอร์เซ็นต์ของอีเมลที่จะบังคับใช้นโยบายนี้ | | `adkim=s` / `aspf=s` | โหมด alignment แบบเข้มงวด ต่างจาก relaxed (`r`) ที่ยอมรับ subdomain | --- ## 4.5.5 ทดสอบทั้งสามกลไกพร้อมกัน ```bash dig TXT _dmarc.rmutsv.ac.th +short # ส่งอีเมลทดสอบไปยังบริการตรวจสอบมาตรฐาน แล้วดูรายงาน SPF/DKIM/DMARC swaks --to check-auth@verifier.port25.com \ --from moo@rmutsv.ac.th \ --server mail.rmutsv.ac.th # หรือใช้ mail-tester.com ผ่าน swaks เช่นกัน แล้วดูคะแนนที่เว็บไซต์ ``` --- ## 4.6 ความเสี่ยงจาก Phishing, Spam, และ Email Spoofing --- ## 4.6.1 นิยามและความแตกต่าง * **Spam**: อีเมลไม่พึงประสงค์จำนวนมาก มักเป็นการโฆษณา ไม่จำเป็นต้องมีเจตนาร้ายเสมอไป * **Phishing**: อีเมลหลอกลวงที่มีเจตนาให้เหยื่อเปิดเผยข้อมูลสำคัญ (รหัสผ่าน, เลขบัตรเครดิต) หรือติดตั้งมัลแวร์ โดยปลอมตัวเป็นองค์กร/บุคคลที่น่าเชื่อถือ * **Spear Phishing**: Phishing ที่เจาะจงเป้าหมายรายบุคคล/องค์กร ปรับแต่งเนื้อหาให้ตรงกับบริบทของเหยื่อ (เชื่อมโยงกับบทที่ 13) * **Email Spoofing**: การปลอมแปลง header `From:` ให้ดูเหมือนมาจากผู้ส่งที่น่าเชื่อถือ เป็นเทคนิคพื้นฐานที่ phishing มักใช้ร่วมด้วย --- ## 4.6.2 เทคนิค Spoofing ที่พบบ่อย | เทคนิค | คำอธิบาย | |---|---| | **Display Name Spoofing** | ปลอมชื่อที่แสดง เช่น "อธิการบดี RMUTSV" แต่ email address จริงเป็นโดเมนอื่น | | **Lookalike Domain** | ใช้โดเมนคล้ายของจริง เช่น `rmutsv-th.ac.th` แทน `rmutsv.ac.th` (Typosquatting) | | **Homograph Attack** | ใช้ Unicode character ที่หน้าตาเหมือนตัวอักษรละติน (เช่น Cyrillic "а" แทน Latin "a") | | **Compromised Account** | บัญชีจริงถูกแฮ็กแล้วใช้ส่งอีเมลหลอกลวงจากภายในองค์กร ตรวจจับยากที่สุดเพราะ SPF/DKIM/DMARC ผ่านหมด | --- ## 4.6.3 ตัวอย่างการวิเคราะห์ Email Header จริง ```bash # ดึง raw header ของอีเมลที่บันทึกไว้ (.eml file) cat suspicious_email.eml | formail -X "" # ตรวจสอบผลการยืนยัน SPF/DKIM/DMARC ที่เซิร์ฟเวอร์รับได้บันทึกไว้ grep -i "Authentication-Results" suspicious_email.eml ``` ตัวอย่างผลลัพธ์ที่ควรสังเกต: ``` Authentication-Results: mx.rmutsv.ac.th; spf=fail smtp.mailfrom=rmutsv-th.ac.th; dkim=none; dmarc=fail (p=reject) header.from=rmutsv.ac.th ``` `smtp.mailfrom` เป็นโดเมนปลอม ในขณะที่ `header.from` แสดงโดเมนจริง — สัญญาณชัดเจนของการ spoof และ DMARC ทำงานถูกต้องด้วยการ reject --- ## 4.6.4 แนวทางป้องกันเชิงเทคนิคและเชิงบุคคล * **เชิงเทคนิค**: บังคับใช้ SPF/DKIM/DMARC (`p=reject`), ใช้ Secure Email Gateway ที่มี anti-phishing filter, เปิด MFA สำหรับบัญชีอีเมลทุกบัญชี * **เชิงบุคคล (Security Awareness)**: ฝึกอบรมให้สังเกต display name ผิดปกติ, ตรวจสอบ URL ก่อนคลิก (hover เพื่อดู URL จริง), ไม่กรอกข้อมูลสำคัญผ่านลิงก์ในอีเมลโดยตรง --- ## 4.7 DNS Security Extensions (DNSSEC) --- ## 4.7.1 ปัญหาของ DNS ดั้งเดิม DNS ดั้งเดิมไม่มีกลไกยืนยันความถูกต้องของข้อมูล ทำให้เสี่ยงต่อ **DNS Cache Poisoning / DNS Spoofing** — ผู้โจมตีปลอมแปลง response เพื่อหลอกให้ resolver เก็บ (cache) ข้อมูล IP ปลอมไว้ ผู้ใช้จึงถูกพาไปยังเซิร์ฟเวอร์ปลอมโดยไม่รู้ตัว (เชื่อมโยงกับหัวข้อ 2.7) --- ## 4.7.2 หลักการของ DNSSEC: Chain of Trust DNSSEC แก้ปัญหานี้ด้วยการเพิ่ม **Digital Signature** เข้าไปใน DNS record โดยสร้างสายโซ่ความเชื่อถือ (chain of trust) ตั้งแต่ Root Zone ลงมาจนถึงโดเมนย่อย ```mermaid graph TD A["Root Zone (.)
Root DNSKEY"] -->|"DS record ลงนามให้"| B["TLD: .th
Zone Signing Key"] B -->|"DS record ลงนามให้"| C["ac.th
Zone Signing Key"] C -->|"DS record ลงนามให้"| D["rmutsv.ac.th
Zone Signing Key (ZSK)"] D -->|"RRSIG ลงนามให้"| E["A record:
www\.rmutsv.ac.th \-> 203.113.x.x"] F[Resolver] -->|"ตรวจสอบย้อนขึ้นไปทีละชั้น"| E F --> D F --> C F --> B F -->|"Root Trust Anchor
ฝังในระบบ resolver"| A style A fill:#282828,stroke:#fb4934,color:#ebdbb2 style B fill:#3c3836,stroke:#fabd2f,color:#ebdbb2 style C fill:#3c3836,stroke:#fabd2f,color:#ebdbb2 style D fill:#3c3836,stroke:#8ec07c,color:#ebdbb2 style E fill:#504945,stroke:#83a598,color:#ebdbb2 ``` --- ## 4.7.3 องค์ประกอบสำคัญของ DNSSEC * **DNSKEY**: บันทึกที่เก็บ public key ของโซนนั้น มี **ZSK (Zone Signing Key)** สำหรับเซ็น record ทั่วไป และ **KSK (Key Signing Key)** สำหรับเซ็น DNSKEY record เอง * **RRSIG (Resource Record Signature)**: ลายเซ็นดิจิทัลที่แนบไปกับ record แต่ละชุด (RRset) * **DS (Delegation Signer)**: บันทึกใน zone แม่ที่เก็บค่าแฮชของ KSK ของ zone ลูก ใช้เชื่อมโยง chain of trust ระหว่างชั้น * **NSEC/NSEC3**: ใช้พิสูจน์ **การไม่มีอยู่จริง (authenticated denial of existence)** ของ record — ป้องกันการปลอมแปลงคำตอบ "ไม่พบโดเมนนี้" --- ## 4.7.4 การตรวจสอบ RRSIG (แนวคิดเดียวกับ Digital Signature)
1. Resolver ดึง RRset (เช่น A record) และ RRSIG มาพร้อมกัน
2. คำนวณค่าแฮชของ RRset เอง:
h
computed
=
SHA-256(RRset ที่ได้รับ)
3. ถอดรหัส RRSIG ด้วย public key (ZSK) จาก DNSKEY record:
h
from-sig
=
Verify
RSA
(
RRSIG
)
4. เปรียบเทียบ: หาก
h
computed
=
h
from-sig
→ record ถูกต้องและไม่ถูกแก้ไข
5. ตรวจสอบ ZSK เองด้วย KSK, และ KSK ด้วย DS record ใน zone แม่ ไล่ขึ้นไปจนถึง Root Trust Anchor
--- ## 4.7.5 ทดสอบ DNSSEC จริงด้วยเครื่องมือ Linux ```bash # ตรวจสอบว่าโดเมนเปิดใช้ DNSSEC หรือไม่ (ดู flag ad = Authenticated Data) dig +dnssec rmutsv.ac.th # ตรวจสอบ DNSKEY record ของโดเมน dig DNSKEY rmutsv.ac.th +short # ตรวจสอบ DS record ที่ registry เก็บไว้ (เชื่อมโยง chain of trust) dig DS rmutsv.ac.th +short # ใช้ delv (มาพร้อม BIND) ตรวจสอบ validation แบบละเอียดทุกขั้นตอน delv rmutsv.ac.th @8.8.8.8 +vtrace # ตรวจสอบผ่านเว็บเซอร์วิสมาตรฐาน DNSViz curl -s "https://dnsviz.net/d/rmutsv.ac.th/dnssec/" | grep -i "secure" ``` ผลลัพธ์ที่ควรสังเกตจาก `dig +dnssec` คือ flag **`ad`** (Authenticated Data) ใน header ของ response — หาก resolver รองรับ DNSSEC validation และ flag นี้ปรากฏ แสดงว่าคำตอบผ่านการตรวจสอบลายเซ็นทั้งสายโซ่เรียบร้อยแล้ว --- ## Timeline: วิวัฒนาการของโปรโตคอลอีเมลและเว็บ ```mermaid graph LR subgraph Era1["ยุคเริ่มต้น (1980s)"] direction TB A1~~~A2 A1["1981-1982
SMTP (RFC 821)
กำเนิดมาตรฐานส่งอีเมล"] A2["1984
POP (Post Office Protocol)"] end subgraph Era2["ยุคขยายตัวของอินเทอร์เน็ต (1990s)"] direction TB B1~~~B2~~~B3~~~B4 B1["1991
WWW + HTTP/0.9
Tim Berners-Lee"] B2["1994
SSL 2.0 โดย Netscape"] B3["1995-1996
IMAP2/IMAP4, HTTP/1.0, SSL 3.0"] B4["1999
HTTP/1.1, TLS 1.0"] end subgraph Era3["ยุคความมั่นคงปลอดภัยเข้มข้นขึ้น (2000s)"] direction TB C1~~~C2~~~C3~~~C4 C1["2003
SPF เริ่มถูกเสนอ"] C2["2006
DKIM (รวม DomainKeys + Identified Mail)"] C3["2005-2008
DNSSEC เริ่มใช้งานจริง, TLS 1.1/1.2"] end subgraph Era4["ยุค OWASP และ Standardization (2010s)"] direction TB D1~~~D2~~~D3~~~D4 D1["2012
DMARC เผยแพร่อย่างเป็นทางการ"] D2["2013
OWASP Top 10 ฉบับสำคัญ"] D3["2015
HTTP/2"] D4["2018
TLS 1.3 (RFC 8446)"] end subgraph Era5["ยุคปัจจุบัน (2020s)"] direction TB E1~~~E2~~~E3~~~E4 E1["2020-2021
MTA-STS, OWASP Top 10 (2021)"] E2["2022
HTTP/3 (บน QUIC/UDP)"] E3["ปัจจุบัน
Zero Trust Email + DNSSEC บังคับใช้กว้างขึ้น"] end Era1 --> Era2 --> Era3 --> Era4 --> Era5 style Era1 fill:#282828,stroke:#fb4934,color:#ebdbb2 style Era2 fill:#3c3836,stroke:#fabd2f,color:#ebdbb2 style Era3 fill:#282828,stroke:#8ec07c,color:#ebdbb2 style Era4 fill:#3c3836,stroke:#83a598,color:#ebdbb2 style Era5 fill:#282828,stroke:#b8bb26,color:#ebdbb2 ``` --- ## สรุปโดยรวม (Summary) บทนี้ครอบคลุมโปรโตคอลชั้นแอปพลิเคชันที่ใช้งานบ่อยที่สุด คือ **อีเมล** และ **เว็บ** ซึ่งเป็นเป้าหมายหลักของการโจมตีเนื่องจากเชื่อมโยงโดยตรงกับผู้ใช้ปลายทาง ประเด็นสำคัญ: 1. **SMTP/POP3/IMAP** ดั้งเดิมไม่มีการเข้ารหัสหรือยืนยันตัวตนในตัวเอง จำเป็นต้องเสริมด้วย STARTTLS หรือ implicit TLS เสมอ 2. **S/MIME** ให้การเข้ารหัสและลงลายเซ็นระดับเนื้อหา (content-level) ต่างจาก STARTTLS ที่คุ้มครองเฉพาะระดับการขนส่ง (transport-level) — ทั้งสองใช้ **Hybrid Encryption** 3. **TLS 1.3** ใช้ **Ephemeral Diffie-Hellman** เป็นแกนหลักของการแลกเปลี่ยนกุญแจ ทำให้ได้คุณสมบัติ **Forward Secrecy** --- ## สรุปโดยรวม (Summary) — ต่อ 4. **OWASP Top 10** เป็นกรอบอ้างอิงสากลสำหรับเข้าใจช่องโหว่เว็บแอปพลิเคชันที่พบบ่อยที่สุด 5. **SPF, DKIM, DMARC** ทำงานร่วมกันเป็นระบบ 3 ชั้นเพื่อยืนยันตัวตนผู้ส่งอีเมลและป้องกัน spoofing/phishing โดย DMARC เป็นชั้นนโยบายที่ควบคุมการตัดสินใจสุดท้าย 6. **DNSSEC** เพิ่มการเซ็นลายเซ็นดิจิทัลให้กับ DNS record สร้าง chain of trust ตั้งแต่ Root Zone จนถึงโดเมนปลายทาง ป้องกัน DNS cache poisoning หลักการทางคณิตศาสตร์ที่ปรากฏซ้ำในบทนี้ — **Hash Function + Asymmetric Signature** และ **Diffie-Hellman Key Exchange** — คือรากฐานเดียวกันที่จะถูกอธิบายเชิงลึกยิ่งขึ้นในบทที่ 5 และบทที่ 6 --- ## เอกสารอ้างอิง (References) — ตอนที่ 1 1. Klensin, J. (2008). *Simple Mail Transfer Protocol*. RFC 5321. IETF. 2. Ramsdell, B., & Turner, S. (2010). *Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.2*. RFC 5751. IETF. 3. Rescorla, E. (2018). *The Transport Layer Security (TLS) Protocol Version 1.3*. RFC 8446. IETF. 4. OWASP Foundation. (2021). *OWASP Top 10:2021*. Retrieved from https://owasp.org/Top10/ 5. Kitterman, S. (2014). *Sender Policy Framework (SPF)*. RFC 7208. IETF. --- ## เอกสารอ้างอิง (References) — ตอนที่ 2 6. Crocker, D., Hansen, T., & Kucherawy, M. (2011). *DomainKeys Identified Mail (DKIM) Signatures*. RFC 6376. IETF. 7. Kucherawy, M., & Zwicky, E. (2015). *Domain-based Message Authentication, Reporting, and Conformance (DMARC)*. RFC 7489. IETF. 8. Arends, R., et al. (2005). *DNS Security Introduction and Requirements*. RFC 4033–4035. IETF. 9. Diffie, W., & Hellman, M. (1976). New directions in cryptography. *IEEE Transactions on Information Theory*, 22(6), 644-654. 10. Foster, I., et al. (2015). Security by Any Other Name: On the Effectiveness of Provider Based Email Security. *ACM CCS*. --- # คำถาม - ข้อสงสัย