AnhNg1410
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Web cache poisoning WCP là kỹ thuật tấn công mà atker đầu độc cache của máy chủ hoặc proxy bằng response độc hại. Ảnh hưởng của cuộc tấn công này dựa trên mức độ nguy hại của payload được chèn vào. Quá trình dựng một tấn công WCP: 1. Identify and evaluate unkeyed inputs 2. Elicit a harmful response from the back-end server 3. Get the response cached ## Exploiting cache design flaws Khai thác thiếu sót trong thiết kế cache. ## Exploiting cache implementation Khai thác sự kì quặc trong triển khai caching system. ### Cache key flaws URL path và query string không được xem là phù hợp cho WCP. Ví nó là dữ liệu động. Tuy nhiên, hành vi của cache system hoặc CDN có thể có sai sót. Ví dụ như: - Bỏ bớt query string - Lọc bỏ một số query param cụ thể. - Chuẩn hoá input trước khi tạo key. Khiến victim không cần nhập URL path hay query string tương ứng nhưng vẫn bị poison. ### Cache probing methodology probe: thăm dò Phương pháp thăm dò sai sót triển khai cache khác với phương pháp WCP cổ điển. Các website khác nhau triển khai và cấu hình cache khác nhau -> Hiểu sâu hành vi của cache. Các phương pháp bao gồm: - Identify a suitable cache oracle - Probe key handling - Idenify an exploitable gadget #### Identify a suitable cache oracle Bước đầu cần xác định cache oracle phù hợp. Cache oracle là page hoặc endpoint xác nhận hành vi của cache. Có thể thể hiện qua: - HTTP header chỉ rõ cache hit. - Sự thay đổi có thể quan sát của nội dung động. - Sự khác biệt trong response times. Lí tưởng, cache oracle có thể reflect toàn bộ URL và một query param trong response. Giúp xác định sự khác biệt trong parsing giữa cache và application. Khi xác định được cache bên thứ 3 được sử dụng, có thể khai thác qua tài liệu về nó. Ví dụ, Akamai hỗ trợ header `Pragma: akamai-x-get-cache-key`: ``` GET /?param=1 HTTP/1.1 Host: innocent-website.com Pragma: akamai-x-get-cache-key HTTP/1.1 200 OK X-Cache-Key: innocent-website.com/?param=1 ``` #### Probe key handling Cache có thể thực hiện xử lí với input khi tạo cache key. Thường là loại bỏ query param cụ thể, toàn bộ query string hoặc port khỏi "Host" header. ``` GET / HTTP/1.1 Host: vulnerable-website.com:1337 HTTP/1.1 302 Moved Permanently Location: https://vulnerable-website.com:1337/en Cache-Status: miss GET / HTTP/1.1 Host: vulnerable-website.com HTTP/1.1 302 Moved Permanently Location: https://vulnerable-website.com:1337/en Cache-Status: hit ``` #### Unkeyed query string Loại bỏ toàn bộ query string trong request line. ##### Detecting an unkeyed query string #### Identiry an exploiable gadget Sau khi hiểu rõ hành vi cache và thiết sót trong dựng cache key. Thực hiện tìm gadget phù hợp. Gadget thường là lỗ hổng client-side (XSS, open redirects, ...). ### Exploing cache key flaws Xem xét một số sai sót cache key tiêu biểu: #### Unkeyed port "Host" header thường là một phần của cache key. Nếu caching system parse và loại bỏ port khỏi cache thì có thể bị poison. Có thể chèn payload XSS thay vì port number nếu website không xử lí kĩ. ``` GET / HTTP/1.1 Host: vulnerable-website.com:1337 HTTP/1.1 302 Moved Permanently Location: https://vulnerable-website.com:1337/en Cache-Status: miss GET / HTTP/1.1 Host: vulnerable-website.com HTTP/1.1 302 Moved Permanently Location: https://vulnerable-website.com:1337/en Cache-Status: hit ``` #### Unkeyed query string Loại bỏ toàn bộ query string trong request line. Khiến query string không được dùng để xây dựng cache key ##### Detecting an unkeyed query string Cách phát hiện Query String bị bỏ qua trong cache key: 1. Có header cache feedback (ví dụ Cache-Status: hit/miss): Gửi request thay đổi `?param=abc` thành `?param=xyz` nếu luôn nhận được cached response. 2. Không có header phân biệt cache hit/miss: Sử dụng kỹ thuật cache buster: Thêm các header có khả năng được dùng trong cache key, nhưng không ảnh hưởng logic ứng dụng: ``` Accept-Encoding: gzip, deflate, cachebuster Accept: */*, text/cachebuster Cookie: cachebuster=1 Origin: https://cachebuster.vulnerable-website.com ``` 3. Path Normalization Khai thác sự khác biệt giữa cách cache và backend xử lý path. Dù đường dẫn có khác nhau: Apache: `GET //` Nginx: `GET /%2F` PHP: ```GET /index.php/xyz``` .NET: `GET /(A(xyz)/` Nhưng server backend có thể coi những path này là tương đương với `GET /`. ##### Exploiting an unkeyed query string Loại bỏ query string khỏi cache key khiến lỗ hổng rXSS nghiêm trọng hơn, vì victim nhận mã độc mà không cần tương tác trực tiếp với URL độc. #### Unkeyed query parameters so far: cho đến nay Nhiều website chỉ bỏ qua một số param cụ thể khi tạo cache key. Những tham số này thường: - Không ảnh hưởng logic xử lý backend. - Thường là tracking / quảng cáo / analytics param. Ví dụ như param "utm_content". Tuy những param này không ảnh hưởng trực tiếp nhưng vẫn có nguy cơ nếu ứng dụng sử dụng mà không xử lí. #### Cache parameter cloaking Lỗi trong sự đồng bộ xử lí param của Cache và Server. `GET /?example=123?excluded_param=mal` |||| |-----|--------|-----| |Cache parser|Phân tích 2 dấu `?` thành 2 param: `example=123` và `excluded_param=mal` |Bỏ qua `excluded_param`, tạo cache key cho `example=123`| |Server parser|Chỉ phân tích dấu `?` đầu tiên, nhận toàn bộ `example=123?excluded_param=mal` là giá trị của `example` param|Payload `mal` vẫn đến được server| ##### Exploiting parameter parsing quirks Server có param parser riêng biệt so với Cache. - Trong "Ruby on Rails" có sử dụng `;` như một kí tự phân tách tham số (tương tự `&`). Đồng thời, nếu có 2 param trùng lặp, nó sẽ sử dụng param phía sau. `GET /?keyed_param=abc&excluded_param=123;keyed_param=mal` |||| |-----|--------|-----| |Cache parser|Phân tích 2 dấu `&` thành 2 param: `keyed_param=abc` và `excluded_param=123;keyed_param=mal`|Bỏ qua `excluded_param`, tạo cache key cho `keyed_param=abc`| |Server parser (Ruby on Rails)|Phân tích dấu `&` và `;` đều là kí tự phân cách, nhận 3 param: `keyed_param=abc`, `excluded_param=123` và `keyed_param=mal`|Payload `mal` vẫn đến được server| ##### Exploiting fat GET support Server vô tình xử lí những dữ liệu vốn là không đúng logic. Ví dụ như việc dù là GET request nhưng Server vẫn nhận dữ liệu từ body. Nên khi trang được cache, phần payload có thể được đính kèm. Đôi khi có thể ghi đè HTTP method bằng `X-HTTP-Method-Override` header. ||| |-----|--------| |Cache|Chỉ đọc dòng đầu `GET /?param=innocent`, tạo cache key theo đó.| |Server|Đọc body `param=mal`, xử lý như POST (có thể cần X-HTTP-Method-Override).| ##### Exploiting dynamic content in resource imports Sai sót khi mà các file thường là tĩnh (như CSS, ...) lại bị tác động bởi các tham số động trong URL. Một số file tài nguyên như style.css có thể phản chiếu giá trị query string vào nội dung response: ``` GET /style.css?excluded_param=123);@import… HTTP/1.1 ``` ``` HTTP/1.1 200 OK … @import url(/site/home/index.part1.8a6715a2.css?excluded_param=123);@import… ``` Trang HTML không có `<!DOCTYPE html>` nên browser dễ thực thi các HTML response trong file CSS. Server lỗi trả về `Content-Type: text/html` thay vì `text/css`. `GET /style.css?excluded_param=alert(1)%0A{}*{color:red;}` - Server phản hồi lỗi, nhưng nội dung HTML chứa đoạn: `This request was blocked due to…alert(1) {}*{color:red;}` - Trình duyệt bắt nhầm CSS và cố gắng thực thi phần `*{color:red;}` trong context CSS. #### Normalized cache keys Kỹ thuật này lợi dụng việc cache server thực hiện normalization các param khi tạo cache key, dẫn đến nhiều URL khác nhau có thể tạo ra cùng một cache key. 1. Ví dụ Có lỗ hổng XSS reflected: `GET /example?param="><script>alert(1)</script>` Nhưng lỗ hổng khó khai thác vì: Trình duyệt tự động URL-encode các ký tự đặc biệt. Server không decode, nên phản hồi chỉ chứa chuỗi encode (`%22%3e...`), không thực thi được. Một số hệ thống cache (Varnish, CDN như Cloudflare, Reverse proxy tùy chỉnh) sẽ normalize tham số trước khi tạo cache key, ví dụ: `GET /example?param="><script>alert(1)</script>` `GET /example?param=%22%3e%3cscript%3ealert(1)%3c/script%3e` - Hai URL này có thể bị chuẩn hóa thành cùng một cache key! 2. Kịch bản tấn công Attacker gửi request "raw" chưa encode (qua Burp Repeater hoặc curl): `GET /example?param="><script>alert(1)</script>` - Server phản hồi với payload chưa encode, bị lưu vào cache (vì cache key normalize giống nhau). - Victim truy cập URL encode chuẩn (trình duyệt gửi): `GET /example?param=%22%3e%3cscript%3ealert(1)%3c/script%3e` - Do cache key giống nhau, victim nhận về response độc đã bị cache. - XSS xảy ra client-side dù request của victim là encode. #### Cache key injection Cách hệ thống tạo cache key Hệ thống lấy nhiều đoạn thông tin (ví dụ: URL, query string, header quan trọng như Origin hay User-Agent) Nối chúng lại thành một chuỗi theo định dạng cố định, ví dụ: `<URL>__Origin=<giá trị Origin>__...` Cache key là chuỗi này; mọi response với cùng key sẽ được lưu và tái sử dụng. ##### Lỗ hổng từ delimiter không được escape Nếu “delimiter” (ở đây là `__`) không được xử lý an toàn, kẻ tấn công có thể đóng vai trò làm chính khách hàng gửi đến server một giá trị header chứa luôn `__`. `Origin: '-alert(1)-'__` Khi nối thành cache key, chuỗi sẽ thành: `/path?param=123__Origin='-alert(1)-'__` Thậm chí nếu server không phân tách đúng, payload sẽ nằm ngay trong cache key. ##### Khai thác qua cache poisoning và collision Attacker gửi một request hợp lệ có header Origin chứa payload: ``` GET /path?param=123 HTTP/1.1 Origin: '-alert(1)-'__ ``` Server xử lý, trả về response có nội dung chứa payload (ví dụ script) và header: `X-Cache-Key: /path?param=123__Origin='-alert(1)-'__` Response này được lưu vào cache dưới key trên. Attacker lừa nạn nhân truy cập một URL đã bao gồm payload ngay trong đường dẫn, sao cho cache key của nó giống hệt key đã poison: `GET /path?param=123__Origin='-alert(1)-'__ HTTP/1.1` Hệ thống cache so sánh cache key (từ URL và header mặc định của nạn nhân) và nhận ra khớp với key đã có, nên trả về ngay response cũ (có chứa `<script>…'-alert(1)-'…</script>`). Nạn nhân bị chạy mã độc mà không hề biết. Minh họa cụ thể: ``` # Bước 1: Poison cache GET /path?param=123 HTTP/1.1 Host: vulnerable.example Origin: '-alert(1)-'__ ← Chèn payload + delimiter ▶ Server trả về (status 200) và lưu cache: HTTP/1.1 200 OK X-Cache-Key: /path?param=123__Origin='-alert(1)-'__ Content-Type: text/html <html> <body> <script> // Payload đã chèn alert('XSS via cache poisoning'); </script> </body> </html> ``` ``` # Bước 2: Thực thi collision trên máy nạn nhân GET /path?param=123__Origin='-alert(1)-'__ HTTP/1.1 Host: vulnerable.example # (Origin header bình thường hoặc vắng mặt) ▶ Cache hit, server trả lại response đã poisoned HTTP/1.1 200 OK X-Cache-Key: /path?param=123__Origin='-alert(1)-'__ X-Cache: hit Content-Type: ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully