diff --git a/src/SUMMARY.md b/src/SUMMARY.md index abe382dcf..be4d4275a 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -837,9 +837,14 @@ - [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md) - [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md) - [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md) -- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md) - [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md) -- [iOS Exploiting](binary-exploitation/ios-exploiting.md) +- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md) + - [ios CVE-2020-27950-mach_msg_trailer_t](binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md) + - [ios CVE-2021-30807-IOMobileFrameBuffer](binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md) + - [ios Corellium](binary-exploitation/ios-exploiting/ios-corellium.md) + - [ios Heap Exploitation](binary-exploitation/ios-exploiting/ios-example-heap-exploit.md) + - [ios Physical UAF - IOSurface](binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md) + # ๐Ÿค– AI - [AI Security](AI/README.md) diff --git a/src/pentesting-web/race-condition.md b/src/pentesting-web/race-condition.md index 022f83f42..2e609c6d6 100644 --- a/src/pentesting-web/race-condition.md +++ b/src/pentesting-web/race-condition.md @@ -3,56 +3,56 @@ {{#include ../banners/hacktricks-training.md}} > [!WARNING] -> ์ด ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ๊นŠ์€ ์ดํ•ด๋ฅผ ์–ป์œผ๋ ค๋ฉด [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)์—์„œ ์›๋ณธ ๋ณด๊ณ ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. +> ์ด ๊ธฐ์ˆ ์„ ๊นŠ์ด ์ดํ•ดํ•˜๋ ค๋ฉด ์›๋ฌธ ๋ฆฌํฌํŠธ [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)๋ฅผ ํ™•์ธํ•˜์„ธ์š”. -## Race Condition ๊ณต๊ฒฉ ๊ฐ•ํ™” +## Race Condition ๊ณต๊ฒฉ ๊ณ ๋„ํ™” -Race condition์„ ์ด์šฉํ•˜๋Š” ๋ฐ ์žˆ์–ด ์ฃผ์š” ์žฅ์• ๋ฌผ์€ ์—ฌ๋Ÿฌ ์š”์ฒญ์ด ๋™์‹œ์— ์ฒ˜๋ฆฌ๋˜๋„๋ก ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. **์ฒ˜๋ฆฌ ์‹œ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ๋งค์šฐ ์ ์–ด์•ผ ํ•˜๋ฉฐ, ์ด์ƒ์ ์œผ๋กœ๋Š” 1ms ๋ฏธ๋งŒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** +์ฃผ์š” ์žฅ์• ๋ฌผ์€ ์—ฌ๋Ÿฌ ์š”์ฒญ์ด ๊ฑฐ์˜ ๋™์‹œ์— ์ฒ˜๋ฆฌ๋˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฒ˜๋ฆฌ ์‹œ๊ฐ„ ์ฐจ์ด๊ฐ€ ๋งค์šฐ ์ž‘์•„์•ผ ํ•˜๋ฉฐโ€”์ด์ƒ์ ์œผ๋กœ๋Š” 1ms ๋ฏธ๋งŒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์—ฌ๊ธฐ ์š”์ฒญ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ธฐ์ˆ ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์š”์ฒญ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: -#### HTTP/2 ๋‹จ์ผ ํŒจํ‚ท ๊ณต๊ฒฉ vs. HTTP/1.1 ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ ๋™๊ธฐํ™” +#### HTTP/2 Single-Packet Attack vs. HTTP/1.1 Last-Byte Synchronization -- **HTTP/2**: ๋‹จ์ผ TCP ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ๋‘ ๊ฐœ์˜ ์š”์ฒญ์„ ์ „์†กํ•  ์ˆ˜ ์žˆ์–ด ๋„คํŠธ์›Œํฌ ์ง€ํ„ฐ์˜ ์˜ํ–ฅ์„ ์ค„์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„ ์ธก์˜ ๋ณ€๋™์„ฑ์œผ๋กœ ์ธํ•ด ๋‘ ๊ฐœ์˜ ์š”์ฒญ๋งŒ์œผ๋กœ๋Š” ์ผ๊ด€๋œ race condition exploit์— ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **HTTP/1.1 '๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ ๋™๊ธฐํ™”'**: 20-30๊ฐœ์˜ ์š”์ฒญ์˜ ๋Œ€๋ถ€๋ถ„์„ ๋ฏธ๋ฆฌ ์ „์†กํ•˜๊ณ , ์ž‘์€ ์กฐ๊ฐ์„ ๋ณด๋ฅ˜ํ•œ ํ›„ ํ•จ๊ป˜ ์ „์†กํ•˜์—ฌ ์„œ๋ฒ„์— ๋™์‹œ์— ๋„์ฐฉํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. +- **HTTP/2**: ๋‹จ์ผ TCP ์—ฐ๊ฒฐ๋กœ ๋‘ ์š”์ฒญ์„ ์ „์†กํ•  ์ˆ˜ ์žˆ์–ด ๋„คํŠธ์›Œํฌ ์ง€ํ„ฐ์˜ ์˜ํ–ฅ์„ ์ค„์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„ ์ธก ๋ณ€๋™ ๋•Œ๋ฌธ์— ๋‘ ์š”์ฒญ๋งŒ์œผ๋กœ๋Š” ์ผ๊ด€๋œ race condition ์ต์Šคํ”Œ๋กœ์ž‡์„ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **HTTP/1.1 'Last-Byte Sync'**: 20~30๊ฐœ์˜ ์š”์ฒญ์˜ ๋Œ€๋ถ€๋ถ„์„ ๋ฏธ๋ฆฌ ์ „์†กํ•˜๊ณ  ์ž‘์€ ์กฐ๊ฐ์„ ๋ณด๋ฅ˜ํ•œ ๋‹ค์Œ, ๊ทธ ์กฐ๊ฐ๋“ค์„ ํ•จ๊ป˜ ์ „์†กํ•ด ์„œ๋ฒ„์— ๋™์‹œ์— ๋„์ฐฉํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. -**๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ์ค€๋น„**๋Š” ๋‹ค์Œ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค: +**Preparation for Last-Byte Sync** involves: -1. ์ŠคํŠธ๋ฆผ์„ ์ข…๋ฃŒํ•˜์ง€ ์•Š๊ณ  ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๋ฅผ ์ œ์™ธํ•œ ํ—ค๋”์™€ ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. -2. ์ดˆ๊ธฐ ์ „์†ก ํ›„ 100ms ๋™์•ˆ ์ผ์‹œ ์ •์ง€ํ•ฉ๋‹ˆ๋‹ค. -3. ์ตœ์ข… ํ”„๋ ˆ์ž„์„ ๋ฐฐ์น˜ํ•˜๊ธฐ ์œ„ํ•ด Nagle์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด TCP_NODELAY๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. -4. ์—ฐ๊ฒฐ์„ ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ํ•‘์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. +1. ์ŠคํŠธ๋ฆผ์„ ์ข…๋ฃŒํ•˜์ง€ ์•Š๊ณ  ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๋ฅผ ์ œ์™ธํ•œ ํ—ค๋”์™€ ๋ฐ”๋”” ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. +2. ์ดˆ๊ธฐ ์ „์†ก ํ›„ 100ms ๋™์•ˆ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค. +3. ์ตœ์ข… ํ”„๋ ˆ์ž„ ๋ฐฐ์น˜๋ฅผ ์œ„ํ•ด TCP_NODELAY๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜์—ฌ Nagle's algorithm์„ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. +4. ์—ฐ๊ฒฐ์„ ์›Œ๋ฐ์—…ํ•˜๊ธฐ ์œ„ํ•ด ping์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. -๋ณด๋ฅ˜๋œ ํ”„๋ ˆ์ž„์„ ์ดํ›„์— ์ „์†กํ•˜๋ฉด ๋‹จ์ผ ํŒจํ‚ท์œผ๋กœ ๋„์ฐฉํ•ด์•ผ ํ•˜๋ฉฐ, Wireshark๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ผ๋ฐ˜์ ์œผ๋กœ RC ๊ณต๊ฒฉ์— ๊ด€๋ จ๋˜์ง€ ์•Š๋Š” ์ •์  ํŒŒ์ผ์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๋ณด๋ฅ˜ํ•œ ํ”„๋ ˆ์ž„์„ ์ดํ›„์— ์ „์†กํ•˜๋ฉด ๋‹จ์ผ ํŒจํ‚ท์œผ๋กœ ๋„์ฐฉํ•˜๋Š” ๊ฒƒ์„ Wireshark๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ผ๋ฐ˜์ ์œผ๋กœ RC ๊ณต๊ฒฉ์— ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” static files์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -### ์„œ๋ฒ„ ์•„ํ‚คํ…์ฒ˜์— ์ ์‘ํ•˜๊ธฐ +### ์„œ๋ฒ„ ์•„ํ‚คํ…์ฒ˜์— ๋งž๊ฒŒ ์กฐ์ • -๋Œ€์ƒ์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ์„œ๋ฒ„๋Š” ์š”์ฒญ์„ ๋‹ค๋ฅด๊ฒŒ ๋ผ์šฐํŒ…ํ•  ์ˆ˜ ์žˆ์–ด ํƒ€์ด๋ฐ์— ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌด์˜๋ฏธํ•œ ์š”์ฒญ์„ ํ†ตํ•ด ์„œ๋ฒ„ ์ธก ์—ฐ๊ฒฐ์„ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜๋ฉด ์š”์ฒญ ํƒ€์ด๋ฐ์„ ์ •์ƒํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋Œ€์ƒ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ์„œ๋ฒ„๋Š” ์š”์ฒญ์„ ๋‹ค๋ฅด๊ฒŒ ๋ผ์šฐํŒ…ํ•  ์ˆ˜ ์žˆ์–ด ํƒ€์ด๋ฐ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์š”์ฒญ์œผ๋กœ ์‚ฌ์ „ ์„œ๋ฒ„ ์ธก ์—ฐ๊ฒฐ ์›Œ๋ฐ์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ์š”์ฒญ ํƒ€์ด๋ฐ์„ ์ •๊ทœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ž ๊ธˆ ์ฒ˜๋ฆฌ -PHP์˜ ์„ธ์…˜ ํ•ธ๋“ค๋Ÿฌ์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์„ธ์…˜๋ณ„๋กœ ์š”์ฒญ์„ ์ง๋ ฌํ™”ํ•˜์—ฌ ์ทจ์•ฝ์ ์„ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์š”์ฒญ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ์„ธ์…˜ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +PHP์˜ session handler์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์„ธ์…˜๋ณ„๋กœ ์š”์ฒญ์„ ์ง๋ ฌํ™”ํ•˜์—ฌ ์ทจ์•ฝ์ ์„ ๊ฐ€๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์š”์ฒญ์— ๋Œ€ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ session ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํšŒํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -#### ์†๋„ ๋˜๋Š” ์ž์› ์ œํ•œ ๊ทน๋ณต +#### Rate ๋˜๋Š” ์ž์› ์ œํ•œ ๊ทน๋ณต -์—ฐ๊ฒฐ ์ค€๋น„๊ฐ€ ํšจ๊ณผ์ ์ด์ง€ ์•Š์€ ๊ฒฝ์šฐ, ๋”๋ฏธ ์š”์ฒญ์˜ ํ™์ˆ˜๋ฅผ ํ†ตํ•ด ์›น ์„œ๋ฒ„์˜ ์†๋„ ๋˜๋Š” ์ž์› ์ œํ•œ ์ง€์—ฐ์„ ์˜๋„์ ์œผ๋กœ ์œ ๋ฐœํ•˜์—ฌ race condition์— ์œ ๋ฆฌํ•œ ์„œ๋ฒ„ ์ธก ์ง€์—ฐ์„ ์œ ๋„ํ•จ์œผ๋กœ์จ ๋‹จ์ผ ํŒจํ‚ท ๊ณต๊ฒฉ์„ ์šฉ์ดํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์—ฐ๊ฒฐ ์›Œ๋ฐ์—…์ด ํšจ๊ณผ์ ์ด์ง€ ์•Š๋‹ค๋ฉด, ๋”๋ฏธ ์š”์ฒญ์„ ๋Œ€๋Ÿ‰์œผ๋กœ ๋ณด๋‚ด ์›น ์„œ๋ฒ„์˜ rate ๋˜๋Š” ์ž์› ์ œํ•œ ์ง€์—ฐ์„ ์˜๋„์ ์œผ๋กœ ์œ ๋ฐœํ•˜๋ฉด ์„œ๋ฒ„ ์ธก ์ง€์—ฐ์ด ์ƒ๊ฒจ single-packet attack์— ์œ ๋ฆฌํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ๊ณต๊ฒฉ ์˜ˆ์‹œ -- **Tubo Intruder - HTTP2 ๋‹จ์ผ ํŒจํ‚ท ๊ณต๊ฒฉ (1 ์—”๋“œํฌ์ธํŠธ)**: ์š”์ฒญ์„ **Turbo intruder**์— ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), ์š”์ฒญ์—์„œ **`%s`**์— ๋Œ€ํ•ด ๊ฐ•์ œ๋กœ ๊ณต๊ฒฉํ•  ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ: `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` ๊ทธ๋ฆฌ๊ณ  ๋“œ๋กญ๋‹ค์šด์—์„œ **`examples/race-single-packer-attack.py`**๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค: +- **Tubo Intruder - HTTP2 single-packet attack (1 endpoint)**: ์š”์ฒญ์„ **Turbo intruder**๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`). ์š”์ฒญ์—์„œ ๋ธŒ๋ฃจํŠธํฌ์Šคํ•  ๊ฐ’์ธ **`%s`**๋ฅผ `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`์ฒ˜๋Ÿผ ๋ณ€๊ฒฝํ•œ ๋‹ค์Œ ๋“œ๋กญ๋‹ค์šด์—์„œ **`examples/race-single-packer-attack.py`**๋ฅผ ์„ ํƒํ•˜์„ธ์š”:
-**๋‹ค๋ฅธ ๊ฐ’์„ ์ „์†กํ• ** ๊ฒฝ์šฐ, ํด๋ฆฝ๋ณด๋“œ์—์„œ ๋‹จ์–ด ๋ชฉ๋ก์„ ์‚ฌ์šฉํ•˜๋Š” ์ด ์ฝ”๋“œ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๊ฐ’์„ **๋‹ค๋ฅด๊ฒŒ ์ „์†กํ•˜๋ ค๋Š” ๊ฒฝ์šฐ**, ํด๋ฆฝ๋ณด๋“œ์—์„œ ์›Œ๋“œ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค์Œ ์ฝ”๋“œ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: ```python passwords = wordlists.clipboard for password in passwords: engine.queue(target.req, password, gate='race1') ``` > [!WARNING] -> ์›น์ด HTTP2๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ(์˜ค์ง HTTP1.1๋งŒ ์ง€์›) `Engine.THREADED` ๋˜๋Š” `Engine.BURP`๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  `Engine.BURP2`๋Š” ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. +> ์›น์ด HTTP2๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ณ (์˜ค์ง HTTP1.1๋งŒ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ) `Engine.BURP2` ๋Œ€์‹  `Engine.THREADED` ๋˜๋Š” `Engine.BURP`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. -- **Tubo Intruder - HTTP2 ๋‹จ์ผ ํŒจํ‚ท ๊ณต๊ฒฉ (์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ)**: RCE๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด 1๊ฐœ์˜ ์—”๋“œํฌ์ธํŠธ์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ๊ทธ ํ›„ ์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ์— ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, `race-single-packet-attack.py` ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +- **Tubo Intruder - HTTP2 single-packet attack (Several endpoints)**: ๋งŒ์•ฝ RCE๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด 1๊ฐœ์˜ ์—”๋“œํฌ์ธํŠธ์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์ด์–ด์„œ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ์— ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, `race-single-packet-attack.py` ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: ```python def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, @@ -83,16 +83,16 @@ engine.queue(confirmationReq, gate=currentAttempt) # send all the queued requests for this attempt engine.openGate(currentAttempt) ``` -- Burp Suite์˜ ์ƒˆ๋กœ์šด '**Send group in parallel**' ์˜ต์…˜์„ ํ†ตํ•ด **Repeater**์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **limit-overrun**์˜ ๊ฒฝ์šฐ, ๊ทธ๋ฃน์— **๊ฐ™์€ ์š”์ฒญ์„ 50๋ฒˆ** ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **connection warming**์„ ์œ„ํ•ด, **๊ทธ๋ฃน**์˜ **์‹œ์ž‘** ๋ถ€๋ถ„์— ์›น ์„œ๋ฒ„์˜ ๋น„์ •์  ๋ถ€๋ถ„์— ๋Œ€ํ•œ **์š”์ฒญ**์„ **์ถ”๊ฐ€**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **์ง€์—ฐ**์„ ์œ„ํ•ด **ํ•˜๋‚˜์˜ ์š”์ฒญ๊ณผ ๋‹ค๋ฅธ ์š”์ฒญ** ์‚ฌ์ด์˜ ์ฒ˜๋ฆฌ **๊ณผ์ •**์„ 2๊ฐœ์˜ ํ•˜์œ„ ์ƒํƒœ ๋‹จ๊ณ„๋กœ ๋‚˜๋ˆ„์–ด, ๋‘ ์š”์ฒญ ์‚ฌ์ด์— **์ถ”๊ฐ€ ์š”์ฒญ์„** **์ถ”๊ฐ€**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- **multi-endpoint** RC์˜ ๊ฒฝ์šฐ, **์ˆจ๊ฒจ์ง„ ์ƒํƒœ**๋กœ ๊ฐ€๋Š” **์š”์ฒญ**์„ ๋จผ์ € ๋ณด๋‚ด๊ณ , ๊ทธ ๋’ค์— **์ˆจ๊ฒจ์ง„ ์ƒํƒœ๋ฅผ ์•…์šฉํ•˜๋Š” 50๊ฐœ์˜ ์š”์ฒญ**์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ๋˜ํ•œ Burp Suite์˜ **Repeater**์—์„œ ์ƒˆ๋กœ์šด '**Send group in parallel**' ์˜ต์…˜์„ ํ†ตํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **limit-overrun**์˜ ๊ฒฝ์šฐ ๊ทธ๋ฃน์— **๊ฐ™์€ request๋ฅผ 50๋ฒˆ** ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +- **connection warming**์„ ์œ„ํ•ด ๊ทธ๋ฃน์˜ **์‹œ์ž‘ ๋ถ€๋ถ„**์— ์›น ์„œ๋ฒ„์˜ ๋น„์ •์  ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๋ช‡ ๊ฐœ์˜ **requests**๋ฅผ **์ถ”๊ฐ€**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- 2 substates ๋‹จ๊ณ„์—์„œ ํ•œ **request**๋ฅผ ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ ๋‹ค๋ฅธ **request**๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณผ์ • ์‚ฌ์ด๋ฅผ **์ง€์—ฐ**์‹œํ‚ค๋ ค๋ฉด, ๋‘ **request** ์‚ฌ์ด์— ์ถ”๊ฐ€ **requests**๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **multi-endpoint** RC์˜ ๊ฒฝ์šฐ, **hidden state**๋กœ ๊ฐ€๋Š” **request**๋ฅผ ๋จผ์ € ๋ณด๋‚ด๊ณ  ๊ทธ ์งํ›„์— **50 requests**๋ฅผ ๋ณด๋‚ด์„œ **hidden state**๋ฅผ ์•…์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
-- **์ž๋™ํ™”๋œ ํŒŒ์ด์ฌ ์Šคํฌ๋ฆฝํŠธ**: ์ด ์Šคํฌ๋ฆฝํŠธ์˜ ๋ชฉํ‘œ๋Š” ์‚ฌ์šฉ์ž์˜ ์ด๋ฉ”์ผ์„ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ ์ƒˆ๋กœ์šด ์ด๋ฉ”์ผ์˜ ํ™•์ธ ํ† ํฐ์ด ๋งˆ์ง€๋ง‰ ์ด๋ฉ”์ผ๋กœ ๋„์ฐฉํ•  ๋•Œ๊นŒ์ง€ ์ง€์†์ ์œผ๋กœ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ด๋Š” ์ฝ”๋“œ์—์„œ ์ด๋ฉ”์ผ์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” RC๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ์ง€๋งŒ ํ™•์ธ์ด ์ด์ „ ์ด๋ฉ”์ผ๋กœ ์ „์†ก๋˜๋„๋ก ์ด๋ฉ”์ผ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ณ€์ˆ˜๊ฐ€ ์ด๋ฏธ ์ฒซ ๋ฒˆ์งธ ์ด๋ฉ”์ผ๋กœ ์ฑ„์›Œ์ ธ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค).\ -"objetivo"๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์ˆ˜์‹ ๋œ ์ด๋ฉ”์ผ์—์„œ ๋ฐœ๊ฒฌ๋˜๋ฉด ๋ณ€๊ฒฝ๋œ ์ด๋ฉ”์ผ์˜ ํ™•์ธ ํ† ํฐ์„ ์ˆ˜์‹ ํ–ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ณต๊ฒฉ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. +- **Automated python script**: ์ด ์Šคํฌ๋ฆฝํŠธ์˜ ๋ชฉํ‘œ๋Š” ์‚ฌ์šฉ์ž์˜ ์ด๋ฉ”์ผ์„ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ ์ƒˆ๋กœ์šด ์ด๋ฉ”์ผ์˜ ๊ฒ€์ฆ ํ† ํฐ์ด ๋งˆ์ง€๋ง‰ ์ด๋ฉ”์ผ๋กœ ๋„์ฐฉํ•  ๋•Œ๊นŒ์ง€ ์ง€์†์ ์œผ๋กœ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค (์ฝ”๋“œ ์ƒ์—์„œ ์ด๋ฉ”์ผ์„ ์ˆ˜์ •ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ๊ฒ€์ฆ์ด ์ด์ „ ์ด๋ฉ”์ผ๋กœ ์ „์†ก๋˜๋Š” RC๊ฐ€ ๊ด€์ฐฐ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ์ด๋Š” ์ด๋ฉ”์ผ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ณ€์ˆ˜๊ฐ€ ์ด๋ฏธ ์ฒซ ๋ฒˆ์งธ ์ด๋ฉ”์ผ๋กœ ์ฑ„์›Œ์ ธ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค).\ +์ˆ˜์‹ ๋œ ์ด๋ฉ”์ผ์—์„œ "objetivo"๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ๋ฐœ๊ฒฌ๋˜๋ฉด ๋ณ€๊ฒฝ๋œ ์ด๋ฉ”์ผ์˜ ๊ฒ€์ฆ ํ† ํฐ์„ ๋ฐ›์€ ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•˜๊ณ  ๊ณต๊ฒฉ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ```python # https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun # Script from victor to solve a HTB challenge @@ -217,21 +217,21 @@ h2_conn.close_connection() response = requests.get(url, verify=False) ``` -### Improving Single Packet Attack +### Single Packet Attack ๊ฐœ์„  -์›๋ž˜ ์—ฐ๊ตฌ์—์„œ๋Š” ์ด ๊ณต๊ฒฉ์ด 1,500 ๋ฐ”์ดํŠธ์˜ ํ•œ๊ณ„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ [**์ด ๊ฒŒ์‹œ๋ฌผ**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)์—์„œ๋Š” IP ๋ ˆ์ด์–ด ๋ถ„ํ• ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์ผ ํŒจํ‚ท ๊ณต๊ฒฉ์˜ 1,500 ๋ฐ”์ดํŠธ ์ œํ•œ์„ **TCP์˜ 65,535 B ์œˆ๋„์šฐ ์ œํ•œ์œผ๋กœ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•**์ด ์„ค๋ช…๋˜์—ˆ์Šต๋‹ˆ๋‹ค(๋‹จ์ผ ํŒจํ‚ท์„ ์—ฌ๋Ÿฌ IP ํŒจํ‚ท์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ์„œ๋กœ ๋‹ค๋ฅธ ์ˆœ์„œ๋กœ ์ „์†กํ•˜์—ฌ ๋ชจ๋“  ์กฐ๊ฐ์ด ์„œ๋ฒ„์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ํŒจํ‚ท ์žฌ์กฐ๋ฆฝ์„ ๋ฐฉ์ง€ํ•จ). ์ด ๊ธฐ์ˆ ์„ ํ†ตํ•ด ์—ฐ๊ตฌ์ž๋Š” ์•ฝ 166ms ๋งŒ์— 10,000๊ฐœ์˜ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. +์›๋ž˜ ์—ฐ๊ตฌ์—์„œ๋Š” ์ด ๊ณต๊ฒฉ์ด 1,500 bytes์˜ ์ œํ•œ์ด ์žˆ๋‹ค๊ณ  ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ [**this post**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)์—์„œ๋Š” IP layer fragmentation์„ ์‚ฌ์šฉํ•ด single packet attack์˜ 1,500-byte ์ œํ•œ์„ TCP์˜ **65,535 B window limitation**๊นŒ์ง€ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•(๋‹จ์ผ ํŒจํ‚ท์„ ์—ฌ๋Ÿฌ IP ํŒจํ‚ท์œผ๋กœ ๋ถ„ํ• ํ•˜๊ณ  ์„œ๋กœ ๋‹ค๋ฅธ ์ˆœ์„œ๋กœ ์ „์†กํ•˜์—ฌ ๋ชจ๋“  ํ”„๋ž˜๊ทธ๋จผํŠธ๊ฐ€ ์„œ๋ฒ„์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ์žฌ์กฐ๋ฆฝ์„ ๋ฐฉ์ง€)์ด ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ฒ•์„ ํ†ตํ•ด ์—ฐ๊ตฌ์ž๋Š” ์•ฝ 166ms ๋งŒ์— 10,000๊ฐœ์˜ ์š”์ฒญ์„ ์ „์†กํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. -์ด ๊ฐœ์„ ์ด ์ˆ˜๋ฐฑ/์ˆ˜์ฒœ ๊ฐœ์˜ ํŒจํ‚ท์ด ๋™์‹œ์— ๋„์ฐฉํ•ด์•ผ ํ•˜๋Š” RC์—์„œ ๊ณต๊ฒฉ์„ ๋” ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์ง€๋งŒ, ์ผ๋ถ€ ์†Œํ”„ํŠธ์›จ์–ด ์ œํ•œ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Apache, Nginx ๋ฐ Go์™€ ๊ฐ™์€ ์ผ๋ถ€ ์ธ๊ธฐ ์žˆ๋Š” HTTP ์„œ๋ฒ„๋Š” ๊ฐ๊ฐ 100, 128 ๋ฐ 250์œผ๋กœ ์„ค์ •๋œ ์—„๊ฒฉํ•œ `SETTINGS_MAX_CONCURRENT_STREAMS` ์„ค์ •์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ NodeJS ๋ฐ nghttp2์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์„œ๋ฒ„๋Š” ์ด๋ฅผ ๋ฌด์ œํ•œ์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.\ -์ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Apache๊ฐ€ ๋‹จ์ผ TCP ์—ฐ๊ฒฐ์—์„œ 100๊ฐœ์˜ HTTP ์—ฐ๊ฒฐ๋งŒ ๊ณ ๋ คํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค(์ด RC ๊ณต๊ฒฉ์„ ์ œํ•œํ•จ). +์ด ๊ฐœ์„ ์œผ๋กœ ์ˆ˜๋ฐฑ/์ˆ˜์ฒœ ๊ฐœ์˜ ํŒจํ‚ท์ด ๋™์‹œ์— ๋„์ฐฉํ•ด์•ผ ํ•˜๋Š” RC ๊ณต๊ฒฉ์˜ ์‹ ๋ขฐ์„ฑ์ด ๋†’์•„์ง€์ง€๋งŒ, ์†Œํ”„ํŠธ์›จ์–ด์  ํ•œ๊ณ„๋„ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Apache, Nginx and Go ๊ฐ™์€ ์ผ๋ถ€ ์ธ๊ธฐ ์žˆ๋Š” HTTP ์„œ๋ฒ„๋Š” `SETTINGS_MAX_CONCURRENT_STREAMS`๋ฅผ ๊ฐ๊ฐ 100, 128, 250์œผ๋กœ ์—„๊ฒฉํ•˜๊ฒŒ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด NodeJS์™€ nghttp2 ๋“ฑ์€ ์ œํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค. +์ด๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Apache๊ฐ€ ๋‹จ์ผ TCP ์—ฐ๊ฒฐ์—์„œ 100๊ฐœ์˜ HTTP ์—ฐ๊ฒฐ๋งŒ ๊ณ ๋ คํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋ฉฐ(์ด RC ๊ณต๊ฒฉ์„ ์ œํ•œํ•จ) ๊ฒฐ๊ตญ ๊ณต๊ฒฉ์˜ ํšจ๊ณผ๋ฅผ ๋–จ์–ด๋œจ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์˜ˆ๋Š” ๋ ˆํฌ์ง€ํ† ๋ฆฌ [https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main)์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•œ ์˜ˆ์ œ๋Š” ๋ ˆํฌ [https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## Raw BF -์ด์ „ ์—ฐ๊ตฌ ์ด์ „์— RC๋ฅผ ์œ ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด ํŒจํ‚ท์„ ๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅด๊ฒŒ ์ „์†กํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŽ˜์ด๋กœ๋“œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. +์ด์ „ ์—ฐ๊ตฌ ์ด์ „์—๋Š” RC๋ฅผ ์œ ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด ํŒจํ‚ท์„ ๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅด๊ฒŒ ์ „์†กํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŽ˜์ด๋กœ๋“œ๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -- **Repeater:** ์ด์ „ ์„น์…˜์˜ ์˜ˆ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. -- **Intruder**: **Intruder**์— **์š”์ฒญ**์„ ๋ณด๋‚ด๊ณ , **Options ๋ฉ”๋‰ด**์—์„œ **์Šค๋ ˆ๋“œ ์ˆ˜**๋ฅผ **30**์œผ๋กœ ์„ค์ •ํ•œ ํ›„, ํŽ˜์ด๋กœ๋“œ๋กœ **Null payloads**๋ฅผ ์„ ํƒํ•˜๊ณ  **30๊ฐœ**๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +- **Repeater:** ์ด์ „ ์„น์…˜์˜ ์˜ˆ์ œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. +- **Intruder**: **request**๋ฅผ **Intruder**๋กœ ์ „์†กํ•˜๊ณ , **Options menu**์—์„œ **number of threads**๋ฅผ **30**์œผ๋กœ ์„ค์ •ํ•œ ๋’ค, ํŽ˜์ด๋กœ๋“œ๋กœ **Null payloads**๋ฅผ ์„ ํƒํ•˜๊ณ  **30**์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. - **Turbo Intruder** ```python def queueRequests(target, wordlists): @@ -283,71 +283,71 @@ asyncio.run(main()) ### Limit-overrun / TOCTOU -์ด๊ฒƒ์€ **ํ–‰๋™์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํšŸ์ˆ˜๋ฅผ ์ œํ•œํ•˜๋Š”** ๊ณณ์—์„œ **๋‚˜ํƒ€๋‚˜๋Š” ์ทจ์•ฝ์ **์ด ์žˆ๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์œ ํ˜•์˜ ๊ฒฝ์Ÿ ์กฐ๊ฑด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์›น ์ƒ์ ์—์„œ ๋™์ผํ•œ ํ• ์ธ ์ฝ”๋“œ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. [**์ด ๋ณด๊ณ ์„œ**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) ๋˜๋Š” [**์ด ๋ฒ„๊ทธ**](https://hackerone.com/reports/759247)**์—์„œ ๋งค์šฐ ์‰ฌ์šด ์˜ˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** +This is the most basic type of race condition where **์ทจ์•ฝ์ ** that **appear** in places that **limit the number of times you can perform an action**. Like using the same discount code in a web store several times. A very easy example can be found in [**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) or in [**this bug**](https://hackerone.com/reports/759247)**.** -์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ๊ณต๊ฒฉ์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ณ€ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค: +There are many variations of this kind of attack, including: -- ๊ธฐํ”„ํŠธ ์นด๋“œ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•˜๊ธฐ -- ์ œํ’ˆ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ‰๊ฐ€ํ•˜๊ธฐ -- ๊ณ„์ขŒ ์ž”์•ก์„ ์ดˆ๊ณผํ•˜์—ฌ ํ˜„๊ธˆ์„ ์ธ์ถœํ•˜๊ฑฐ๋‚˜ ์ด์ฒดํ•˜๊ธฐ -- ๋‹จ์ผ CAPTCHA ์†”๋ฃจ์…˜ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ -- ์•ˆํ‹ฐ ๋ธŒ๋ฃจํŠธ ํฌ์Šค ์†๋„ ์ œํ•œ ์šฐํšŒํ•˜๊ธฐ +- ๊ธฐํ”„ํŠธ ์นด๋“œ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ +- ์ œํ’ˆ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ‰๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ +- ๊ณ„์ขŒ ์ž”์•ก์„ ์ดˆ๊ณผํ•˜์—ฌ ํ˜„๊ธˆ์„ ์ธ์ถœํ•˜๊ฑฐ๋‚˜ ์ด์ฒดํ•˜๋Š” ๊ฒฝ์šฐ +- ๋‹จ์ผ CAPTCHA ์†”๋ฃจ์…˜์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ +- ๋ธŒ๋ฃจํŠธํฌ์Šค ๋ฐฉ์ง€ rate limit์„ ์šฐํšŒํ•˜๋Š” ๊ฒฝ์šฐ ### **Hidden substates** -๋ณต์žกํ•œ ๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ์•…์šฉํ•˜๋Š” ๊ฒƒ์€ ์ข…์ข… ์ˆจ๊ฒจ์ง„ ๋˜๋Š” **์˜๋„ํ•˜์ง€ ์•Š์€ ๊ธฐ๊ณ„ ํ•˜์œ„ ์ƒํƒœ**์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์งง์€ ๊ธฐํšŒ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์ด๋ฅผ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค: +Exploiting complex race conditions often involves taking advantage of brief opportunities to interact with hidden or **์˜๋„์น˜ ์•Š์€ machine substates**. Hereโ€™s how to approach this: -1. **์ž ์žฌ์  ์ˆจ๊ฒจ์ง„ ํ•˜์œ„ ์ƒํƒœ ์‹๋ณ„** -- ์‚ฌ์šฉ์ž ํ”„๋กœํ•„์ด๋‚˜ ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ • ํ”„๋กœ์„ธ์Šค์™€ ๊ฐ™์€ ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์— ์ง‘์ค‘ํ•˜์„ธ์š”: -- **์ €์žฅ**: ํด๋ผ์ด์–ธํŠธ ์ธก ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์„œ๋ฒ„ ์ธก ์ง€์† ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. -- **์ž‘์—…**: ๊ธฐ์กด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…๋ณด๋‹ค ์•…์šฉ ๊ฐ€๋Šฅํ•œ ์กฐ๊ฑด์„ ์ƒ์„ฑํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋” ๋†’์Šต๋‹ˆ๋‹ค. -- **ํ‚ค์ž‰**: ์„ฑ๊ณต์ ์ธ ๊ณต๊ฒฉ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋™์ผํ•œ ์‹๋ณ„์ž(์˜ˆ: ์‚ฌ์šฉ์ž ์ด๋ฆ„ ๋˜๋Š” ์žฌ์„ค์ • ํ† ํฐ)์— ํ‚ค๊ฐ€ ์ง€์ •๋œ ์ž‘์—…์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. -2. **์ดˆ๊ธฐ ํƒ์ƒ‰ ์ˆ˜ํ–‰** -- ์‹๋ณ„๋œ ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•ด ๊ฒฝ์Ÿ ์กฐ๊ฑด ๊ณต๊ฒฉ์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์˜ˆ์ƒ ๊ฒฐ๊ณผ์—์„œ์˜ ํŽธ์ฐจ๋ฅผ ๊ด€์ฐฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์‘๋‹ต์ด๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋™์ž‘์˜ ๋ณ€ํ™”๋Š” ์ทจ์•ฝ์ ์„ ์‹ ํ˜ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -3. **์ทจ์•ฝ์  ์ž…์ฆ** -- ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ์š”์ฒญ ์ˆ˜๋กœ ๊ณต๊ฒฉ์„ ์ขํž™๋‹ˆ๋‹ค. ์ข…์ข… ๋‘ ๊ฐœ์˜ ์š”์ฒญ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ์ •๋ฐ€ํ•œ ํƒ€์ด๋ฐ์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ๋ฒˆ์˜ ์‹œ๋„๋‚˜ ์ž๋™ํ™”๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +1. **Identify Potential Hidden Substates** +- Start by pinpointing endpoints that modify or interact with critical data, such as user profiles or password reset processes. Focus on: +- **Storage**: ์„œ๋ฒ„์ธก ์˜์† ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋ณด๋‹ค ์šฐ์„ ์ ์œผ๋กœ ์‚ดํŽด๋ณด์„ธ์š”. +- **Action**: ๊ธฐ์กด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…์„ ์ฐพ์•„๋ณด์„ธ์š”. ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…๋ณด๋‹ค exploit ๊ฐ€๋Šฅํ•œ ์กฐ๊ฑด์„ ๋งŒ๋“ค ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค. +- **Keying**: ์„ฑ๊ณต์ ์ธ ๊ณต๊ฒฉ์€ ๋ณดํ†ต ๋™์ผํ•œ ์‹๋ณ„์ž(์˜ˆ: username ๋˜๋Š” reset token)์— ํ‚ค๊ฐ€ ๊ฑธ๋ฆฐ ์ž‘์—…์ด ๊ด€๋ จ๋ฉ๋‹ˆ๋‹ค. +2. **Conduct Initial Probing** +- ์‹๋ณ„ํ•œ ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•ด race condition ๊ณต๊ฒฉ์„ ์‹œ๋„ํ•˜์—ฌ ๊ธฐ๋Œ€ํ•œ ๊ฒฐ๊ณผ์™€์˜ ํŽธ์ฐจ๋ฅผ ๊ด€์ฐฐํ•˜์„ธ์š”. ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์‘๋‹ต์ด๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋™์ž‘์˜ ๋ณ€ํ™”๋Š” ์ทจ์•ฝ์ ์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +3. **Demonstrate the Vulnerability** +- ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ์š”์ฒญ ์ˆ˜๋กœ ๊ณต๊ฒฉ์„ ์ถ•์†Œํ•˜์„ธ์š”. ์ข…์ข… ํ•„์š”ํ•œ ๊ฒƒ์€ ๋‹จ ๋‘ ๋ฒˆ์˜ ์š”์ฒญ๋ฟ์ž…๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ์ •๋ฐ€ํ•œ ํƒ€์ด๋ฐ์ด ์š”๊ตฌ๋˜๋ฏ€๋กœ ์—ฌ๋Ÿฌ ๋ฒˆ์˜ ์‹œ๋„๋‚˜ ์ž๋™ํ™”๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -### ์‹œ๊ฐ„ ๋ฏผ๊ฐ ๊ณต๊ฒฉ +### Time Sensitive Attacks -์š”์ฒญ์˜ ํƒ€์ด๋ฐ ์ •๋ฐ€์„ฑ์€ ์ทจ์•ฝ์ ์„ ๋“œ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋ณด์•ˆ ํ† ํฐ์— ํƒ€์ž„์Šคํƒฌํ”„์™€ ๊ฐ™์€ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•์ด ์‚ฌ์šฉ๋  ๋•Œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ • ํ† ํฐ์„ ์ƒ์„ฑํ•˜๋ฉด ๋™์‹œ์— ์š”์ฒญ์— ๋Œ€ํ•ด ๋™์ผํ•œ ํ† ํฐ์ด ํ—ˆ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์š”์ฒญ ํƒ€์ด๋ฐ์˜ ์ •๋ฐ€์„ฑ์€ ์ทจ์•ฝ์ ์„ ๋“œ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ํƒ€์ž„์Šคํƒฌํ”„์™€ ๊ฐ™์ด ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ๋ฐฉ์‹์ด ๋ณด์•ˆ ํ† ํฐ์— ์‚ฌ์šฉ๋  ๋•Œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํƒ€์ž„์Šคํƒฌํ”„์— ๊ธฐ๋ฐ˜ํ•œ password reset tokens ์ƒ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋™์‹œ ์š”์ฒญ์— ๋Œ€ํ•ด ๋™์ผํ•œ ํ† ํฐ์ด ๋งŒ๋“ค์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -**์•…์šฉ ๋ฐฉ๋ฒ•:** +**To Exploit:** -- ๋‹จ์ผ ํŒจํ‚ท ๊ณต๊ฒฉ๊ณผ ๊ฐ™์€ ์ •๋ฐ€ํ•œ ํƒ€์ด๋ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ • ์š”์ฒญ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ํ† ํฐ์€ ์ทจ์•ฝ์ ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. +- ๋‹จ์ผ ํŒจํ‚ท ๊ณต๊ฒฉ๊ณผ ๊ฐ™์€ ์ •๋ฐ€ํ•œ ํƒ€์ด๋ฐ์„ ์‚ฌ์šฉํ•ด ๋™์‹œ password reset ์š”์ฒญ์„ ์ƒ์„ฑํ•˜์„ธ์š”. ๋™์ผํ•œ ํ† ํฐ์ด ๋ฐ˜ํ™˜๋˜๋ฉด ์ทจ์•ฝ์ ์ด ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -**์˜ˆ์‹œ:** +**Example:** -- ๋‘ ๊ฐœ์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ • ํ† ํฐ์„ ๋™์‹œ์— ์š”์ฒญํ•˜๊ณ  ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ์ผ์น˜ํ•˜๋Š” ํ† ํฐ์€ ํ† ํฐ ์ƒ์„ฑ์˜ ๊ฒฐํ•จ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค. +- ๋™์‹œ์— ๋‘ ๊ฐœ์˜ password reset tokens๋ฅผ ์š”์ฒญํ•˜์—ฌ ๋น„๊ตํ•˜์„ธ์š”. ํ† ํฐ์ด ์ผ์น˜ํ•˜๋ฉด token ์ƒ์„ฑ์— ๊ฒฐํ•จ์ด ์žˆ์Œ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค. -**์ด๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **์—์„œ ์‹œ๋„ํ•ด ๋ณด์„ธ์š”.** +์ด๊ฒƒ์„ ์‹œ๋„ํ•˜๋ ค๋ฉด [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities)๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ## Hidden substates case studies ### Pay & add an Item -์ด [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)๋ฅผ ํ™•์ธํ•˜์—ฌ ์ƒ์ ์—์„œ **์ง€๋ถˆ**ํ•˜๊ณ  **์ถ”๊ฐ€ ์•„์ดํ…œ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•**์„ ์•Œ์•„๋ณด์„ธ์š”. **์ง€๋ถˆํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.** +์ด [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)๋ฅผ ํ™•์ธํ•ด ์ƒ์ ์—์„œ ๊ฒฐ์ œํ•˜๊ณ  ์ถ”๊ฐ€ ํ•ญ๋ชฉ์„ ๊ฒฐ์ œํ•˜์ง€ ์•Š๊ณ  ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์„ธ์š”. ### Confirm other emails -์•„์ด๋””์–ด๋Š” **์ด๋ฉ”์ผ ์ฃผ์†Œ๋ฅผ ํ™•์ธํ•˜๊ณ  ๋™์‹œ์— ๋‹ค๋ฅธ ์ด๋ฉ”์ผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ**์ž…๋‹ˆ๋‹ค. ํ”Œ๋žซํผ์ด ๋ณ€๊ฒฝ๋œ ์ƒˆ ์ด๋ฉ”์ผ์„ ํ™•์ธํ•˜๋Š”์ง€ ์•Œ์•„๋ณด์„ธ์š”. +์•„์ด๋””์–ด๋Š” **์ด๋ฉ”์ผ ์ฃผ์†Œ๋ฅผ verifyํ•˜๊ณ  ๋™์‹œ์— ๋‹ค๋ฅธ ์ฃผ์†Œ๋กœ ๋ณ€๊ฒฝ**ํ•˜์—ฌ ํ”Œ๋žซํผ์ด ๋ณ€๊ฒฝ๋œ ์ƒˆ ์ฃผ์†Œ๋ฅผ ์‹ค์ œ๋กœ ์ธ์ฆํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ### Change email to 2 emails addresses Cookie based -[**์ด ์—ฐ๊ตฌ**](https://portswigger.net/research/smashing-the-state-machine)์— ๋”ฐ๋ฅด๋ฉด Gitlab์€ ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์ธ์ˆ˜ ๊ณต๊ฒฉ์— ์ทจ์•ฝํ–ˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด **ํ•˜๋‚˜์˜ ์ด๋ฉ”์ผ์˜ ์ด๋ฉ”์ผ ํ™•์ธ ํ† ํฐ์„ ๋‹ค๋ฅธ ์ด๋ฉ”์ผ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.** +According to [**this research**](https://portswigger.net/research/smashing-the-state-machine) Gitlab was vulnerable to a takeover this way because it might **send** the **email verification token of one email to the other email**. -**์ด๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **์—์„œ ์‹œ๋„ํ•ด ๋ณด์„ธ์š”.** +์ด๊ฒƒ์„ ์‹œ๋„ํ•˜๋ ค๋ฉด [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint)๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ### Hidden Database states / Confirmation Bypass -**2๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์“ฐ๊ธฐ**๊ฐ€ **๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค** ๋‚ด์— **์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ** ์‚ฌ์šฉ๋˜๋ฉด, **์ฒซ ๋ฒˆ์งธ ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๊ธฐ๋ก๋œ** ์งง์€ ์‹œ๊ฐ„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•  ๋•Œ **์‚ฌ์šฉ์ž ์ด๋ฆ„**๊ณผ **๋น„๋ฐ€๋ฒˆํ˜ธ**๊ฐ€ **๊ธฐ๋ก๋˜๊ณ ** **์ƒˆ๋กœ ์ƒ์„ฑ๋œ ๊ณ„์ •์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ํ† ํฐ**์ด ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์งง์€ ์‹œ๊ฐ„ ๋™์•ˆ **๊ณ„์ •์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ํ† ํฐ์ด null**์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +If **2 different writes** are used to **add** **information** inside a **database**, there is a small portion of time where **only the first data has been written** inside the database. For example, when creating a user the **username** and **password** might be **written** and **then the token** to confirm the newly created account is written. This means that for a small time the **token to confirm an account is null**. -๋”ฐ๋ผ์„œ **๊ณ„์ •์„ ๋“ฑ๋กํ•˜๊ณ  ๋นˆ ํ† ํฐ**(`token=` ๋˜๋Š” `token[]=` ๋˜๋Š” ๊ธฐํƒ€ ๋ณ€ํ˜•)์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด **์ด๋ฉ”์ผ์„ ์ œ์–ดํ•˜์ง€ ์•Š๋Š” ๊ณ„์ •์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** +๋”ฐ๋ผ์„œ **๊ณ„์ •์„ ๋“ฑ๋กํ•˜๊ณ  ๋นˆ token์œผ๋กœ ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ์ „์†กํ•˜๋Š” ๊ฒƒ**(`token=` or `token[]=` or any other variation`)์œผ๋กœ ๊ณ„์ •์„ ์ฆ‰์‹œ ํ™•์ธํ•˜๋ ค๊ณ  ํ•˜๋ฉด, ์ด๋ฉ”์ผ์„ ์ œ์–ดํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ณ„์ •์„ **ํ™•์ธ(confirm an account)** ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -**์ด๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **์—์„œ ์‹œ๋„ํ•ด ๋ณด์„ธ์š”.** +์ด๊ฒƒ์„ ์‹œ๋„ํ•˜๋ ค๋ฉด [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction)๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ### Bypass 2FA -๋‹ค์Œ ์˜์‚ฌ ์ฝ”๋“œ๋Š” ๊ฒฝ์Ÿ ์กฐ๊ฑด์— ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์„ธ์…˜์ด ์ƒ์„ฑ๋˜๋Š” ๋™์•ˆ **2FA๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š๋Š”** ๋งค์šฐ ์งง์€ ์‹œ๊ฐ„์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค: +The following pseudo-code is vulnerable to race condition because in a very small time the **2FA is not enforced** while the session is created: ```python session['userid'] = user.userid if user.mfa_enabled: @@ -357,22 +357,23 @@ session['enforce_mfa'] = True ``` ### OAuth2 ์˜๊ตฌ ์ง€์†์„ฑ -์—ฌ๋Ÿฌ [**OAUth ์ œ๊ณต์ž**](https://en.wikipedia.org/wiki/List_of_OAuth_providers)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์„œ๋น„์Šค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ์ œ๊ณต์ž๊ฐ€ ๋“ฑ๋กํ•œ ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด **ํด๋ผ์ด์–ธํŠธ**๋Š” **๊ท€ํ•˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜**์ด **OAUth ์ œ๊ณต์ž** ๋‚ด์˜ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก **ํ—ˆ์šฉํ•ด์•ผ** ํ•ฉ๋‹ˆ๋‹ค.\ -์—ฌ๊ธฐ๊นŒ์ง€๋Š” ๊ตฌ๊ธ€/๋งํฌ๋“œ์ธ/๊นƒํ—ˆ๋ธŒ ๋“ฑ์—์„œ "_์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ \์ด ๊ท€ํ•˜์˜ ์ •๋ณด์— ์ ‘๊ทผํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ํ—ˆ์šฉํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?_"๋ผ๋Š” ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋กœ๊ทธ์ธ์ž…๋‹ˆ๋‹ค. +There are several [**OAUth providers**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). ์ด๋Ÿฌํ•œ ์„œ๋น„์Šค๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ์ œ๊ณต์ž๊ฐ€ ๋“ฑ๋กํ•œ ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด **client**๋Š” **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด** ํ•ด๋‹น **OAUth provider** ๋‚ด๋ถ€์˜ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.\ +์—ฌ๊ธฐ๊นŒ์ง€๋Š” google/linkedin/github ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ๋กœ๊ทธ์ธ์œผ๋กœ, "_Application \๊ฐ€ ๊ท€ํ•˜์˜ ์ •๋ณด๋ฅผ ์•ก์„ธ์Šคํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค. ํ—ˆ์šฉํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?_"๋ผ๋Š” ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. -#### `authorization_code`์˜ ๊ฒฝํ•ฉ ์กฐ๊ฑด +#### Race Condition in `authorization_code` -**๋ฌธ์ œ**๋Š” **ํ—ˆ์šฉ**ํ–ˆ์„ ๋•Œ ๋ฐœ์ƒํ•˜๋ฉฐ, ์•…์˜์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— **`authorization_code`**๊ฐ€ ์ž๋™์œผ๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ OAUth ์„œ๋น„์Šค ์ œ๊ณต์ž์˜ ๊ฒฝํ•ฉ ์กฐ๊ฑด์„ ์•…์šฉํ•˜์—ฌ ๊ท€ํ•˜์˜ ๊ณ„์ •์— ๋Œ€ํ•ด **`authorization_code`**๋กœ๋ถ€ํ„ฐ ํ•˜๋‚˜ ์ด์ƒ์˜ AT/RT** (_์ธ์ฆ ํ† ํฐ/๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ_)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ท€ํ•˜์˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋„๋ก ํ—ˆ์šฉํ•œ ์‚ฌ์‹ค์„ ์•…์šฉํ•˜์—ฌ **์—ฌ๋Ÿฌ ๊ณ„์ •์„ ์ƒ์„ฑ**ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ท€ํ•˜์˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ **์ค‘์ง€ํ•˜๋ฉด AT/RT ์Œ ์ค‘ ํ•˜๋‚˜๋Š” ์‚ญ์ œ๋˜์ง€๋งŒ, ๋‚˜๋จธ์ง€๋Š” ์—ฌ์ „ํžˆ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค**. +๋ฌธ์ œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฅผ **ํ—ˆ์šฉ**ํ•˜๋ฉด ์ž๋™์œผ๋กœ **`authorization_code`**๊ฐ€ ์•…์„ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์ „์†ก๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ OAUth ์„œ๋น„์Šค ์ œ๊ณต์ž์—์„œ Race Condition์„ ์•…์šฉํ•ด ํ•ด๋‹น ๊ณ„์ •์˜ **`authorization_code`**๋กœ๋ถ€ํ„ฐ ๋‘˜ ์ด์ƒ์˜ AT/RT (_Authentication Token/Refresh Token_)์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ–ˆ๋‹ค๋Š” ์ ์„ ์•…์šฉํ•ด **์—ฌ๋Ÿฌ ๊ณ„์ •**์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์ทจ์†Œํ•˜๋ฉด ํ•œ ์Œ์˜ AT/RT๋Š” ์‚ญ์ œ๋˜์ง€๋งŒ, ๋‹ค๋ฅธ ํ† ํฐ๋“ค์€ ์—ฌ์ „ํžˆ ์œ ํšจํ•œ ์ƒํƒœ๋กœ ๋‚จ์•„ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -#### `Refresh Token`์˜ ๊ฒฝํ•ฉ ์กฐ๊ฑด +#### Race Condition in `Refresh Token` -**์œ ํšจํ•œ RT๋ฅผ ์–ป์€ ํ›„** ์—ฌ๋Ÿฌ AT/RT๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด **์•…์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ**, **์‚ฌ์šฉ์ž๊ฐ€ ์•…์˜์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ถŒํ•œ์„ ์ทจ์†Œํ•˜๋”๋ผ๋„, ์—ฌ๋Ÿฌ RT๋Š” ์—ฌ์ „ํžˆ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค.** +์œ ํšจํ•œ RT๋ฅผ ์–ป์œผ๋ฉด ์ด๋ฅผ ์•…์šฉํ•ด ์—ฌ๋Ÿฌ AT/RT๋ฅผ ์ƒ์„ฑํ•˜๋ ค ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์•…์„ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์ทจ์†Œํ•ด๋„ ์—ฌ๋Ÿฌ RT๊ฐ€ ์—ฌ์ „ํžˆ ์œ ํšจํ•œ ์ƒํƒœ๋กœ ๋‚จ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## **์›น์†Œ์ผ“์˜ RC** +## **RC in WebSockets** -[**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC)์—์„œ **์›น์†Œ์ผ“** ๋ฉ”์‹œ์ง€๋ฅผ **๋ณ‘๋ ฌ๋กœ** ์ „์†กํ•˜์—ฌ **์›น์†Œ์ผ“์—์„œ๋„ ๊ฒฝํ•ฉ ์กฐ๊ฑด์„ ์•…์šฉํ•˜๋Š”** PoC๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- In [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) you can find a PoC in Java to send websocket messages in **parallel** to abuse **Race Conditions also in Web Sockets**. +- With Burpโ€™s WebSocket Turbo Intruder you can use the **THREADED** engine to spawn multiple WS connections and fire payloads in parallel. Start from the official example and tune `config()` (thread count) for concurrency; this is often more reliable than batching on a single connection when racing serverโ€‘side state across WS handlers. See [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py). -## ์ฐธ๊ณ  ๋ฌธํ—Œ +## References - [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247) - [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html) @@ -380,5 +381,8 @@ session['enforce_mfa'] = True - [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) - [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions) - [https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/) +- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) +- [WebSocketTurboIntruder โ€“ GitHub](https://github.com/d0ge/WebSocketTurboIntruder) +- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/websocket-attacks.md b/src/pentesting-web/websocket-attacks.md index 2452d5aea..575d43fab 100644 --- a/src/pentesting-web/websocket-attacks.md +++ b/src/pentesting-web/websocket-attacks.md @@ -2,19 +2,19 @@ {{#include ../banners/hacktricks-training.md}} -## WebSocket์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€ +## WebSocket๋ž€ ๋ฌด์—‡์ธ๊ฐ€ -WebSocket ์—ฐ๊ฒฐ์€ ์ดˆ๊ธฐ **HTTP** ํ•ธ๋“œ์…ฐ์ดํฌ๋ฅผ ํ†ตํ•ด ์„ค์ •๋˜๋ฉฐ, **์žฅ๊ธฐ ์ง€์†**์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์–ด ์–ธ์ œ๋“ ์ง€ ์–‘๋ฐฉํ–ฅ ๋ฉ”์‹œ์ง•์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜์—ฌ ๊ฑฐ๋ž˜ ์‹œ์Šคํ…œ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” WebSocket์ด **๋‚ฎ์€ ๋Œ€๊ธฐ ์‹œ๊ฐ„ ๋˜๋Š” ์„œ๋ฒ„ ์‹œ์ž‘ ํ†ต์‹ **์ด ํ•„์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ์˜ˆ๋ฅผ ๋“ค์–ด ์‹ค์‹œ๊ฐ„ ๊ธˆ์œต ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ํŠนํžˆ ์œ ๋ฆฌํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. +WebSocket ์—ฐ๊ฒฐ์€ ์ดˆ๊ธฐ **HTTP** ํ•ธ๋“œ์…ฐ์ดํฌ๋ฅผ ํ†ตํ•ด ์„ค์ •๋˜๋ฉฐ **์žฅ๊ธฐ๊ฐ„ ์œ ์ง€**๋˜๋„๋ก ์„ค๊ณ„๋˜์–ด ํŠธ๋žœ์žญ์…˜ ์‹œ์Šคํ…œ ์—†์ด๋„ ์–ธ์ œ๋“  ์–‘๋ฐฉํ–ฅ ๋ฉ”์‹œ์ง•์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด WebSocket์€ ์‹ค์‹œ๊ฐ„ ๊ธˆ์œต ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ๊ณผ ๊ฐ™์ด **์ €์ง€์—ฐ ๋˜๋Š” ์„œ๋ฒ„-๋ฐœ์‹  ํ†ต์‹ **์ด ํ•„์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํŠนํžˆ ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -### WebSocket ์—ฐ๊ฒฐ์˜ ์„ค์ • +### WebSocket ์—ฐ๊ฒฐ ์„ค์ • -WebSocket ์—ฐ๊ฒฐ ์„ค์ •์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ [**์—ฌ๊ธฐ**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์•ฝํ•˜์ž๋ฉด, WebSocket ์—ฐ๊ฒฐ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ํด๋ผ์ด์–ธํŠธ ์ธก JavaScript๋ฅผ ํ†ตํ•ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค: +WebSocket ์—ฐ๊ฒฐ ์ˆ˜๋ฆฝ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ [**here**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์•ฝํ•˜๋ฉด, WebSocket ์—ฐ๊ฒฐ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ํด๋ผ์ด์–ธํŠธ ์ธก JavaScript๋ฅผ ํ†ตํ•ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค: ```javascript var ws = new WebSocket("wss://normal-website.com/ws") ``` -`wss` ํ”„๋กœํ† ์ฝœ์€ **TLS**๋กœ ๋ณดํ˜ธ๋œ WebSocket ์—ฐ๊ฒฐ์„ ์˜๋ฏธํ•˜๋ฉฐ, `ws`๋Š” **๋ณด์•ˆ๋˜์ง€ ์•Š์€** ์—ฐ๊ฒฐ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. +`wss` ํ”„๋กœํ† ์ฝœ์€ **TLS**๋กœ ๋ณดํ˜ธ๋˜๋Š” WebSocket ์—ฐ๊ฒฐ์„ ์˜๋ฏธํ•˜๋ฉฐ, `ws`๋Š” **๋ณด์•ˆ๋˜์ง€ ์•Š์€** ์—ฐ๊ฒฐ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. -์—ฐ๊ฒฐ ์„ค์ • ์ค‘์— ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„ ๊ฐ„์— HTTP๋ฅผ ํ†ตํ•ด ํ•ธ๋“œ์…ฐ์ดํฌ๊ฐ€ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ํ•ธ๋“œ์…ฐ์ดํฌ ๊ณผ์ •์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ, ๋‹ค์Œ ์˜ˆ์‹œ์—์„œ ์„ค๋ช…๋ฉ๋‹ˆ๋‹ค: +์—ฐ๊ฒฐ์„ ์„ค์ •ํ•  ๋•Œ ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„๋Š” HTTP๋ฅผ ํ†ตํ•ด ํ•ธ๋“œ์…ฐ์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ•ธ๋“œ์…ฐ์ดํฌ ๊ณผ์ •์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•˜๋Š” ๊ณผ์ •์œผ๋กœ, ๋‹ค์Œ ์˜ˆ์‹œ์— ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค: ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ธ๋“œ์…ฐ์ดํฌ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค: ```javascript @@ -33,46 +33,45 @@ Connection: Upgrade Upgrade: websocket Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk= ``` -์—ฐ๊ฒฐ์ด ์„ค์ •๋˜๋ฉด ์–‘๋ฐฉํ–ฅ์œผ๋กœ ๋ฉ”์‹œ์ง€ ๊ตํ™˜์„ ์œ„ํ•ด ์—ด๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. +์—ฐ๊ฒฐ์ด ์ˆ˜๋ฆฝ๋˜๋ฉด ์–‘๋ฐฉํ–ฅ์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๊ตํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ์—ฐ๊ฒฐ์ด ์—ด๋ฆฐ ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. -**WebSocket ํ•ธ๋“œ์…ฐ์ดํฌ์˜ ์ฃผ์š” ์‚ฌํ•ญ:** +**WebSocket Handshake์˜ ํ•ต์‹ฌ ํฌ์ธํŠธ:** -- `Connection` ๋ฐ `Upgrade` ํ—ค๋”๋Š” WebSocket ํ•ธ๋“œ์…ฐ์ดํฌ์˜ ์‹œ์ž‘์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. +- `Connection` ๋ฐ `Upgrade` ํ—ค๋”๋Š” WebSocket handshake์˜ ์‹œ์ž‘์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. - `Sec-WebSocket-Version` ํ—ค๋”๋Š” ์›ํ•˜๋Š” WebSocket ํ”„๋กœํ† ์ฝœ ๋ฒ„์ „์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์ผ๋ฐ˜์ ์œผ๋กœ `13`์ž…๋‹ˆ๋‹ค. -- Base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฌด์ž‘์œ„ ๊ฐ’์ด `Sec-WebSocket-Key` ํ—ค๋”์— ์ „์†ก๋˜์–ด ๊ฐ ํ•ธ๋“œ์…ฐ์ดํฌ๊ฐ€ ๊ณ ์œ ํ•˜๋„๋ก ๋ณด์žฅํ•˜๋ฉฐ, ์ด๋Š” ์บ์‹ฑ ํ”„๋ก์‹œ์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ์ธ์ฆ์„ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‘๋‹ต์ด ์ž˜๋ชป ๊ตฌ์„ฑ๋œ ์„œ๋ฒ„๋‚˜ ์บ์‹œ์—์„œ ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜์Œ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -- ์„œ๋ฒ„์˜ ์‘๋‹ต์— ์žˆ๋Š” `Sec-WebSocket-Accept` ํ—ค๋”๋Š” `Sec-WebSocket-Key`์˜ ํ•ด์‹œ๋กœ, WebSocket ์—ฐ๊ฒฐ์„ ์—ด๋ ค๋Š” ์„œ๋ฒ„์˜ ์˜๋„๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. +- `Sec-WebSocket-Key` ํ—ค๋”์—๋Š” Base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฌด์ž‘์œ„ ๊ฐ’์ด ์ „์†ก๋˜์–ด ๊ฐ handshake๊ฐ€ ๊ณ ์œ ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์บ์‹ฑ ํ”„๋ก์‹œ์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ์ธ์ฆ์šฉ์ด ์•„๋‹ˆ๋ผ ์‘๋‹ต์ด ์ž˜๋ชป ๊ตฌ์„ฑ๋œ ์„œ๋ฒ„๋‚˜ ์บ์‹œ์—์„œ ์ƒ์„ฑ๋œ ๊ฒƒ์ด ์•„๋‹˜์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +- ์„œ๋ฒ„ ์‘๋‹ต์˜ `Sec-WebSocket-Accept` ํ—ค๋”๋Š” `Sec-WebSocket-Key`์˜ ํ•ด์‹œ๋กœ, ์„œ๋ฒ„๊ฐ€ WebSocket ์—ฐ๊ฒฐ์„ ์—ด ์˜๋„๊ฐ€ ์žˆ์Œ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ํ•ธ๋“œ์…ฐ์ดํฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์•ˆ์ „ํ•˜๊ณ  ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•˜์—ฌ ํšจ์œจ์ ์ธ ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•œ ๊ธธ์„ ์—ด์–ด์ค๋‹ˆ๋‹ค. +์ด๋Ÿฌํ•œ ํŠน์ง•๋“ค์€ handshake ๊ณผ์ •์ด ์•ˆ์ „ํ•˜๊ณ  ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•˜์—ฌ ํšจ์œจ์ ์ธ ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ### Linux ์ฝ˜์†” -`websocat`์„ ์‚ฌ์šฉํ•˜์—ฌ websocket๊ณผ์˜ ์›์‹œ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`websocat`์„ ์‚ฌ์šฉํ•ด websocket๊ณผ์˜ ์›์‹œ ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฆฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```bash websocat --insecure wss://10.10.10.10:8000 -v ``` -์›น์†Œ์ผ“ ์„œ๋ฒ„๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด: +๋˜๋Š” websocat ์„œ๋ฒ„๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด: ```bash websocat -s 0.0.0.0:8000 #Listen in port 8000 ``` ### MitM websocket ์—ฐ๊ฒฐ -ํ˜„์žฌ ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ **HTTP websocket**์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ•˜๋ฉด, ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ MitM ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด [ARP Spoofing Attack](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing)์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.\ -ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•  ๋•Œ, ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +ํ˜„์žฌ ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ **HTTP websocket**์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ•˜๋ฉด [ARP Spoofing Attack ](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing)์„ ์‹œ๋„ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด์— MitM ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.\ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: ```bash websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v ``` -### Websockets enumeration +### Websockets ์—ด๊ฑฐ -**๋„๊ตฌ** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) **๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น์†Œ์ผ“์—์„œ ์•Œ๋ ค์ง„** **์ทจ์•ฝ์ **์„ ์ž๋™์œผ๋กœ ๋ฐœ๊ฒฌํ•˜๊ณ , ์ง€๋ฌธ์„ ์ฐ๊ณ , ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +You can use the **tool** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) **๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ websockets์—์„œ ์•Œ๋ ค์ง„** **์ทจ์•ฝ์ **์„ ์ž๋™์œผ๋กœ ๋ฐœ๊ฒฌ, fingerprint ๋ฐ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ### Websocket Debug tools -- **Burp Suite**๋Š” ์ผ๋ฐ˜ HTTP ํ†ต์‹ ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์œผ๋กœ MitM ์›น์†Œ์ผ“ ํ†ต์‹ ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -- [**socketsleuth**](https://github.com/snyk/socketsleuth) **Burp Suite ํ™•์žฅ**์€ **ํžˆ์Šคํ† ๋ฆฌ**๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , **๊ฐ€๋กœ์ฑ„๊ธฐ ๊ทœ์น™**์„ ์„ค์ •ํ•˜๊ณ , **์ผ์น˜ ๋ฐ ๊ต์ฒด** ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๊ณ , **Intruder** ๋ฐ **AutoRepeater**๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Burp์—์„œ ์›น์†Œ์ผ“ ํ†ต์‹ ์„ ๋” ์ž˜ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. -- [**WSSiP**](https://github.com/nccgroup/wssip)**:** "**WebSocket/Socket.io Proxy**"์˜ ์•ฝ์ž๋กœ, Node.js๋กœ ์ž‘์„ฑ๋œ ์ด ๋„๊ตฌ๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ๋ชจ๋“  WebSocket ๋ฐ Socket.IO ํ†ต์‹ ์„ **์บก์ฒ˜, ๊ฐ€๋กœ์ฑ„๊ธฐ, ์‚ฌ์šฉ์ž ์ •์˜** ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -- [**wsrepl**](https://github.com/doyensec/wsrepl)๋Š” ์นจํˆฌ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ์„ค๊ณ„๋œ **๋Œ€ํ™”ํ˜• ์›น์†Œ์ผ“ REPL**์ž…๋‹ˆ๋‹ค. **๋“ค์–ด์˜ค๋Š” ์›น์†Œ์ผ“ ๋ฉ”์‹œ์ง€๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  ์ƒˆ๋กœ์šด ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†ก**ํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์ด ํ†ต์‹ ์„ **์ž๋™ํ™”**ํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -- [**https://websocketking.com/**](https://websocketking.com/)๋Š” **์›น์†Œ์ผ“**์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ์›น๊ณผ ํ†ต์‹ ํ•˜๋Š” **์›น**์ž…๋‹ˆ๋‹ค. -- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket)๋Š” ๋‹ค๋ฅธ ์œ ํ˜•์˜ ํ†ต์‹ /ํ”„๋กœํ† ์ฝœ ์ค‘์—์„œ **์›น์†Œ์ผ“**์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ์›น๊ณผ ํ†ต์‹ ํ•˜๋Š” **์›น**์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +- **Burp Suite**๋Š” ์ผ๋ฐ˜ HTTP ํ†ต์‹ ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์œผ๋กœ MitM websockets ํ†ต์‹ ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +- The [**socketsleuth**](https://github.com/snyk/socketsleuth) **Burp Suite extension**์€ Burp์—์„œ Websocket ํ†ต์‹ ์„ ๋” ์ž˜ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ๋ฉฐ, **history**๋ฅผ ํ™•์ธํ•˜๊ณ  **interception rules**๋ฅผ ์„ค์ •ํ•˜๋ฉฐ **match and replace** ๊ทœ์น™์„ ์ ์šฉํ•˜๊ณ  **Intruder**์™€ **AutoRepeater**๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. +- [**WSSiP**](https://github.com/nccgroup/wssip)**:** ์•ฝ์นญ "**WebSocket/Socket.io Proxy**"์ธ ์ด ๋„๊ตฌ๋Š” Node.js๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜์—ฌ **capture, intercept, send custom** ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ๋ชจ๋“  WebSocket ๋ฐ Socket.IO ํ†ต์‹ ์„ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. +- [**wsrepl**](https://github.com/doyensec/wsrepl) ์€ penetration testing์„ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ์„ค๊ณ„๋œ **interactive websocket REPL**์ž…๋‹ˆ๋‹ค. ์ด ๋„๊ตฌ๋Š” **incoming websocket messages and sending new ones**๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  ์ „์†กํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์ด ํ†ต์‹ ์„ **automating**ํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +- [**https://websocketking.com/**](https://websocketking.com/) ์€ **๋‹ค๋ฅธ ์›น๊ณผ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ ์›น ์ธํ„ฐํŽ˜์ด์Šค**๋กœ websockets๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ค๋ฅธ ์›น๊ณผ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) ๋Š” ์—ฌ๋Ÿฌ ํ†ต์‹ /ํ”„๋กœํ† ์ฝœ ์ค‘ ํ•˜๋‚˜๋กœ websockets๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ค๋ฅธ ์›น๊ณผ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋Š” **์›น ์ธํ„ฐํŽ˜์ด์Šค**๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ## Decrypting Websocket @@ -81,33 +80,150 @@ websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v ## Websocket Lab -[**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course)์—์„œ ์›น์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜์—ฌ ์›น์„ ์‹œ์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, [**์ด ๊ฒŒ์‹œ๋ฌผ**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/)์—์„œ ์„ค๋ช…์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +In [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) ์—๋Š” websockets๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์›น์„ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์œผ๋ฉฐ, [**this post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) ์—์„œ ์„ค๋ช…์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## Websocket Fuzzing -Burp ํ™•์žฅ [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner)๋Š” ์ด์ œ ์›น์†Œ์ผ“ ๋ฉ”์‹œ์ง€๋„ ํผ์ง•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋Š” [**์—ฌ๊ธฐ**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner)์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +The burp extension [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) ์ด์ œ WebSocket ๋ฉ”์‹œ์ง€๋„ ํผ์ง•ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [**here**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner)์—์„œ ํ™•์ธํ•˜์„ธ์š”. + +### WebSocket Turbo Intruder (Burp extension) + +PortSwigger's WebSocket Turbo Intruder๋Š” Turbo Intruderโ€“style Python ์Šคํฌ๋ฆฝํŒ…๊ณผ ๊ณ ์† ํผ์ง•์„ WebSockets์— ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. BApp Store ๋˜๋Š” ์†Œ์Šค์—์„œ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค: + +- Turbo Intruder: custom engines๋ฅผ ์‚ฌ์šฉํ•ด ๋‹จ์ผ WS endpoint์— ๊ณ ์šฉ๋Ÿ‰ ๋ฉ”์‹œ์ง•์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. +- HTTP Middleware: ๋กœ์ปฌ HTTP endpoint๋ฅผ ๋…ธ์ถœํ•˜์—ฌ ๋ฐ”๋””๋ฅผ persistent ์—ฐ๊ฒฐ์„ ํ†ตํ•ด WS ๋ฉ”์‹œ์ง€๋กœ ํฌ์›Œ๋”ฉํ•˜๋ฏ€๋กœ, ๋ชจ๋“  HTTP ๊ธฐ๋ฐ˜ ์Šค์บ๋„ˆ๊ฐ€ WS ๋ฐฑ์—”๋“œ๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. + +Basic script pattern to fuzz a WS endpoint and filter relevant responses: +```python +def queue_websockets(upgrade_request, message): +connection = websocket_connection.create(upgrade_request) +for i in range(10): +connection.queue(message, str(i)) + +def handle_outgoing_message(websocket_message): +results_table.add(websocket_message) + +@MatchRegex(r'{\"user\":\"Hal Pline\"') +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +๋‹จ์ผ ๋ฉ”์‹œ์ง€๊ฐ€ ์—ฌ๋Ÿฌ ์‘๋‹ต์„ ์œ ๋ฐœํ•  ๋•Œ ๋…ธ์ด์ฆˆ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด `@MatchRegex(...)` ๊ฐ™์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. + +### HTTP ๋’ค์˜ WS ๋ธŒ๋ฆฌ์ง€ (HTTP Middleware) + +์ง€์†์ ์ธ WS ์—ฐ๊ฒฐ์„ ๋ž˜ํ•‘ํ•˜๊ณ  HTTP ๋ณธ๋ฌธ์„ WS ๋ฉ”์‹œ์ง€๋กœ ์ „๋‹ฌํ•˜์—ฌ HTTP scanners๋กœ ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค: +```python +def create_connection(upgrade_request): +connection = websocket_connection.create(upgrade_request) +return connection + +@MatchRegex(r'{\"user\":\"You\"') +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +๊ทธ๋Ÿฐ ๋‹ค์Œ ๋กœ์ปฌ๋กœ HTTP๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค; ๋ณธ๋ฌธ์€ WS ๋ฉ”์‹œ์ง€๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค: +```http +POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1 +Host: 127.0.0.1:9000 +Content-Length: 16 + +{"message":"hi"} +``` +์ด ๋ฐฉ๋ฒ•์œผ๋กœ WS ๋ฐฑ์—”๋“œ๋ฅผ ์ œ์–ดํ•˜๋ฉด์„œ โ€œํฅ๋ฏธ๋กœ์šดโ€ ์ด๋ฒคํŠธ(์˜ˆ: SQLi errors, auth bypass, command injection behavior)๋ฅผ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +### Socket.IO ์ฒ˜๋ฆฌ (ํ•ธ๋“œ์…ฐ์ดํฌ, ํ•˜ํŠธ๋น„ํŠธ, ์ด๋ฒคํŠธ) + +Socket.IO๋Š” WS ์œ„์— ์ž์ฒด์ ์ธ ํ”„๋ ˆ์ด๋ฐ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ•„์ˆ˜ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ `EIO`(์˜ˆ: `EIO=4`)๋กœ ์ด๋ฅผ ๊ฐ์ง€ํ•˜์„ธ์š”. Ping (`2`)์™€ Pong (`3`)์œผ๋กœ ์„ธ์…˜์„ ์œ ์ง€ํ•˜๊ณ  ๋Œ€ํ™”๋ฅผ `"40"`์œผ๋กœ ์‹œ์ž‘ํ•œ ๋’ค `42["message","hello"]` ๊ฐ™์€ ์ด๋ฒคํŠธ๋ฅผ emitํ•˜์„ธ์š”. + +Intruder ์˜ˆ์‹œ: +```python +import burp.api.montoya.http.message.params.HttpParameter as HttpParameter + +def queue_websockets(upgrade_request, message): +connection = websocket_connection.create( +upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4"))) +connection.queue('40') +connection.queue('42["message","hello"]') + +@Pong("3") +def handle_outgoing_message(websocket_message): +results_table.add(websocket_message) + +@PingPong("2", "3") +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +HTTP ์–ด๋Œ‘ํ„ฐ ๋ณ€ํ˜•: +```python +import burp.api.montoya.http.message.params.HttpParameter as HttpParameter + +def create_connection(upgrade_request): +connection = websocket_connection.create( +upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4"))) +connection.queue('40') +connection.decIn() +return connection + +@Pong("3") +def handle_outgoing_message(websocket_message): +results_table.add(websocket_message) + +@PingPong("2", "3") +def handle_incoming_message(websocket_message): +results_table.add(websocket_message) +``` +### Socket.IO๋ฅผ ํ†ตํ•œ ์„œ๋ฒ„ ์ธก prototype pollution ํƒ์ง€ + +PortSwigger์˜ ์•ˆ์ „ํ•œ ํƒ์ง€ ๊ธฐ๋ฒ•์„ ๋”ฐ๋ผ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ payload๋ฅผ ์ „์†กํ•ด Express ๋‚ด๋ถ€๋ฅผ ์˜ค์—ผ์‹œ์ผœ ๋ณด์„ธ์š”: +```json +{"__proto__":{"initialPacket":"Polluted"}} +``` +๋งŒ์•ฝ ์ธ์‚ฌ๋ง์ด๋‚˜ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜๋ฉด(์˜ˆ: echo์— "Polluted"๊ฐ€ ํฌํ•จ๋˜๋Š” ๊ฒฝ์šฐ), ์„œ๋ฒ„ ์ธก ํ”„๋กœํ† ํƒ€์ž…์„ ์˜ค์—ผ์‹œํ‚จ ๊ฒƒ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค. ์˜ํ–ฅ์€ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ sinks์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋ฉฐ, Node.js prototype pollution ์„น์…˜์˜ gadgets์™€ ์—ฐ๊ด€์ง€์–ด ๋ณด์„ธ์š”. ์ฐธ๊ณ : + +- Check [NodeJS โ€“ __proto__ & prototype Pollution](deserialization/nodejs-proto-prototype-pollution/README.md) for sinks/gadgets and chaining ideas. + +### WebSocket race conditions with Turbo Intruder + +๊ธฐ๋ณธ ์—”์ง„์€ ํ•œ ์—ฐ๊ฒฐ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค(์ฒ˜๋ฆฌ๋Ÿ‰์€ ์šฐ์ˆ˜ํ•˜์ง€๋งŒ ๋ ˆ์ด์Šค์—๋Š” ๋ถ€์ ํ•ฉ). THREADED ์—”์ง„์„ ์‚ฌ์šฉํ•ด ์—ฌ๋Ÿฌ WS ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•˜๊ณ  ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ „์†กํ•˜๋ฉด ๋…ผ๋ฆฌ์  ๋ ˆ์ด์Šค(doubleโ€‘spend, token reuse, state desync)๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ์‹œ์ž‘ํ•ด `config()`์˜ ๋™์‹œ์„ฑ ์„ค์ •์„ ์กฐ์ •ํ•˜์„ธ์š”. + +- Learn methodology and alternatives in [Race Condition](race-condition.md) (see โ€œRC in WebSocketsโ€). + +### WebSocket DoS: malformed frame โ€œPing of Deathโ€ + +ํ—ค๋”์— ๊ฑฐ๋Œ€ํ•œ ํŽ˜์ด๋กœ๋“œ ๊ธธ์ด๋ฅผ ์„ ์–ธํ•˜์ง€๋งŒ ๋ณธ๋ฌธ์€ ์ „์†กํ•˜์ง€ ์•Š๋Š” WS ํ”„๋ ˆ์ž„์„ ์ œ์ž‘ํ•˜์„ธ์š”. ์ผ๋ถ€ WS ์„œ๋ฒ„๋Š” ๊ธธ์ด๋ฅผ ์‹ ๋ขฐํ•˜๊ณ  ๋ฒ„ํผ๋ฅผ ๋ฏธ๋ฆฌ ํ• ๋‹นํ•˜๋ฏ€๋กœ `Integer.MAX_VALUE`์— ๊ฐ€๊น๊ฒŒ ์„ค์ •ํ•˜๋ฉด Outโ€‘Ofโ€‘Memory๋ฅผ ์ผ์œผ์ผœ ์›๊ฒฉ unauth DoS๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. + +### CLI ๋ฐ ๋””๋ฒ„๊น… + +- Headless fuzzing: `java -jar WebSocketFuzzer-.jar ` +- ๋‚ด๋ถ€ ID๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”์‹œ์ง€๋ฅผ ์บก์ฒ˜ํ•˜๊ณ  ์—ฐ๊ด€์‹œํ‚ค๋ ค๋ฉด WS Logger๋ฅผ ํ™œ์„ฑํ™”ํ•˜์„ธ์š”. +- ๋ณต์žกํ•œ ์–ด๋Œ‘ํ„ฐ์—์„œ ๋ฉ”์‹œ์ง€ ID ์ฒ˜๋ฆฌ๋ฅผ ์กฐ์ •ํ•˜๋ ค๋ฉด `Connection`์˜ `inc*`/`dec*` ํ—ฌํผ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. +- `@PingPong`/`@Pong` ๊ฐ™์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ `isInteresting()` ๊ฐ™์€ ํ—ฌํผ๋Š” ๋…ธ์ด์ฆˆ๋ฅผ ์ค„์ด๊ณ  ์„ธ์…˜์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€๋ฉ๋‹ˆ๋‹ค. + +### ์šด์˜ ์•ˆ์ „์„ฑ + +๊ณ ์† WS fuzzing์€ ๋งŽ์€ ์—ฐ๊ฒฐ์„ ์—ด๊ณ  ์ดˆ๋‹น ์ˆ˜์ฒœ ๊ฐœ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ํ”„๋ ˆ์ž„๊ณผ ๋†’์€ ์ „์†ก๋ฅ ์€ ์‹ค์ œ DoS๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ—ˆ๊ฐ€๋œ ๊ณณ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜์„ธ์š”. ## Cross-site WebSocket hijacking (CSWSH) -**๊ต์ฐจ ์‚ฌ์ดํŠธ ์›น์†Œ์ผ“ ํ•˜์ด์žฌํ‚น**์€ **๊ต์ฐจ ์ถœ์ฒ˜ ์›น์†Œ์ผ“ ํ•˜์ด์žฌํ‚น**์œผ๋กœ๋„ ์•Œ๋ ค์ ธ ์žˆ์œผ๋ฉฐ, ์›น์†Œ์ผ“ ํ•ธ๋“œ์…ฐ์ดํฌ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” **[๊ต์ฐจ ์‚ฌ์ดํŠธ ์š”์ฒญ ์œ„์กฐ (CSRF)](csrf-cross-site-request-forgery.md)**์˜ ํŠน์ • ์‚ฌ๋ก€๋กœ ์‹๋ณ„๋ฉ๋‹ˆ๋‹ค. ์ด ์ทจ์•ฝ์ ์€ ์›น์†Œ์ผ“ ํ•ธ๋“œ์…ฐ์ดํฌ๊ฐ€ **CSRF ํ† ํฐ**์ด๋‚˜ ์œ ์‚ฌํ•œ ๋ณด์•ˆ ์กฐ์น˜ ์—†์ด ์˜ค์ง **HTTP ์ฟ ํ‚ค**๋ฅผ ํ†ตํ•ด ์ธ์ฆ๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +**Cross-site WebSocket hijacking**, also known as **cross-origin WebSocket hijacking**, ์€ WebSocket ํ•ธ๋“œ์…ฐ์ดํฌ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” **[Cross-Site Request Forgery (CSRF)](csrf-cross-site-request-forgery.md)**์˜ ํŠน์ • ์‚ฌ๋ก€๋กœ ๋ถ„๋ฅ˜๋ฉ๋‹ˆ๋‹ค. ์ด ์ทจ์•ฝ์ ์€ WebSocket ํ•ธ๋“œ์…ฐ์ดํฌ๊ฐ€ **HTTP cookies**๋งŒ์œผ๋กœ ์ธ์ฆํ•˜๊ณ  **CSRF tokens**๋‚˜ ์œ ์‚ฌํ•œ ๋ณด์•ˆ ์ˆ˜๋‹จ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. -๊ณต๊ฒฉ์ž๋Š” **์ทจ์•ฝํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜**์— ๋Œ€ํ•œ ๊ต์ฐจ ์‚ฌ์ดํŠธ ์›น์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ์‹œ์ž‘ํ•˜๋Š” **์•…์„ฑ ์›น ํŽ˜์ด์ง€**๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜์—ฌ ์ด๋ฅผ ์•…์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ด ์—ฐ๊ฒฐ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ์˜ ํ”ผํ•ด์ž์˜ ์„ธ์…˜์˜ ์ผ๋ถ€๋กœ ๊ฐ„์ฃผ๋˜๋ฉฐ, ์„ธ์…˜ ์ฒ˜๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์—์„œ CSRF ๋ณดํ˜ธ๊ฐ€ ๋ถ€์กฑํ•œ ์ ์„ ์•…์šฉํ•ฉ๋‹ˆ๋‹ค. +๊ณต๊ฒฉ์ž๋Š” ์ทจ์•ฝํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ cross-site WebSocket ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋Š” **malicious web page**๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜์—ฌ ์ด๋ฅผ ์•…์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ด ์—ฐ๊ฒฐ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํ”ผํ•ด์ž ์„ธ์…˜์˜ ์ผ๋ถ€๋กœ ์ทจ๊ธ‰๋˜์–ด ์„ธ์…˜ ์ฒ˜๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์—์„œ CSRF ๋ณดํ˜ธ๊ฐ€ ์—†๋Š” ์ ์„ ์•…์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -์ด ๊ณต๊ฒฉ์ด ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค: +In order for this attack to work, these are the requirements: -- ์›น์†Œ์ผ“ **์ธ์ฆ์€ ์ฟ ํ‚ค ๊ธฐ๋ฐ˜์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** -- ์ฟ ํ‚ค๋Š” ๊ณต๊ฒฉ์ž์˜ ์„œ๋ฒ„์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ **`SameSite=None`**์„ ์˜๋ฏธํ•˜๋ฉฐ, Firefox์—์„œ **Firefox Total Cookie Protection**์ด ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์•„์•ผ ํ•˜๊ณ  Chrome์—์„œ **์ฐจ๋‹จ๋œ ์ œ3์ž ์ฟ ํ‚ค**๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค). -- ์›น์†Œ์ผ“ ์„œ๋ฒ„๋Š” ์—ฐ๊ฒฐ์˜ ์ถœ์ฒ˜๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค (๋˜๋Š” ์ด๋ฅผ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค). +- websocket ์ธ์ฆ์€ **cookie ๊ธฐ๋ฐ˜**์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- cookie๋Š” ๊ณต๊ฒฉ์ž์˜ ์„œ๋ฒ„์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ผ๋ฐ˜์ ์œผ๋กœ **`SameSite=None`**์„ ์˜๋ฏธ). ๋˜ํ•œ Firefox์—์„œ **Firefox Total Cookie Protection**์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์ง€ ์•Š๊ณ  Chrome์—์„œ **blocked third-party cookies**๊ฐ€ ์ฐจ๋‹จ๋˜์–ด ์žˆ์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- websocket ์„œ๋ฒ„๊ฐ€ ์—ฐ๊ฒฐ์˜ origin์„ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜(๋˜๋Š” ์ด๋ฅผ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ). -๋˜ํ•œ: +Also: -- ์ธ์ฆ์ด ๋กœ์ปฌ ์—ฐ๊ฒฐ(๋กœ์ปฌํ˜ธ์ŠคํŠธ ๋˜๋Š” ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ)์— ๊ธฐ๋ฐ˜ํ•˜๋Š” ๊ฒฝ์šฐ ๊ณต๊ฒฉ์ด **๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค**. ํ˜„์žฌ ๋ณดํ˜ธ ์กฐ์น˜๊ฐ€ ์ด๋ฅผ ๊ธˆ์ง€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค (์ž์„ธํ•œ ์ •๋ณด๋Š” [์—ฌ๊ธฐ](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)์—์„œ ํ™•์ธํ•˜์„ธ์š”). +- If the authentication is based on a local connection (to localhost or to a local network) the attack **will be possible** as no current protection forbids it (check [more info here](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)) ### Simple Attack -์›น์†Œ์ผ“ ์—ฐ๊ฒฐ์„ **์„ค์ •ํ•  ๋•Œ** **์ฟ ํ‚ค**๊ฐ€ **์„œ๋ฒ„**๋กœ **์ „์†ก**๋œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. **์„œ๋ฒ„**๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ **ํŠน์ •** **์‚ฌ์šฉ์ž**์™€ ๊ทธ์˜ **์›น์†Œ์ผ“** **์„ธ์…˜์„ ์ „์†ก๋œ ์ฟ ํ‚ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ** **์—ฐ๊ด€**์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ฐธ๊ณ ๋กœ **websocket** ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•  ๋•Œ **cookie**๊ฐ€ ์„œ๋ฒ„๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์ „์†ก๋œ cookie๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ ํŠน์ • ์‚ฌ์šฉ์ž์˜ **websocket session**์„ ์—ฐ๊ด€์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ทธ๋Ÿฐ ๋‹ค์Œ, ์˜ˆ๋ฅผ ๋“ค์–ด **์›น์†Œ์ผ“** **์„œ๋ฒ„**๊ฐ€ ์‚ฌ์šฉ์ž์˜ ๋Œ€ํ™” **ํžˆ์Šคํ† ๋ฆฌ**๋ฅผ **์ „์†ก**ํ•˜๋Š” ๊ฒฝ์šฐ, "**READY**"๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ์ „์†ก๋˜๋ฉด, **๊ฐ„๋‹จํ•œ XSS**๊ฐ€ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•˜๊ณ  (์ด๋•Œ **์ฟ ํ‚ค**๊ฐ€ ํ”ผํ•ด์ž ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆํ•˜๊ธฐ ์œ„ํ•ด **์ž๋™์œผ๋กœ ์ „์†ก**๋จ) "**READY**"๋ฅผ ์ „์†กํ•˜๋ฉด ๋Œ€ํ™”์˜ **ํžˆ์Šคํ† ๋ฆฌ**๋ฅผ **๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค**. +์˜ˆ๋ฅผ ๋“ค์–ด websocket ์„œ๋ฒ„๊ฐ€ "READY"๋ผ๋Š” msg๊ฐ€ ์ „์†ก๋˜๋ฉด ์‚ฌ์šฉ์ž ๋Œ€ํ™” ๊ธฐ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ, ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฆฝํ•˜๋Š” ๊ฐ„๋‹จํ•œ XSS(์ฟ ํ‚ค๊ฐ€ ํ”ผํ•ด์ž ์‚ฌ์šฉ์ž๋ฅผ ์ธ์ฆํ•˜๊ธฐ ์œ„ํ•ด ์ž๋™์œผ๋กœ ์ „์†ก๋จ)๊ฐ€ "READY"๋ฅผ ์ „์†กํ•˜๋ฉด ๋Œ€ํ™” ๊ธฐ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.: ```html ``` -### Cross Origin + Cookie with a different subdomain +### ๋‹ค๋ฅธ subdomain์—์„œ์˜ Cross Origin + Cookie -์ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/)์—์„œ ๊ณต๊ฒฉ์ž๋Š” **์›น ์†Œ์ผ“ ํ†ต์‹ ์ด ๋ฐœ์ƒํ•˜๋Š” ๋„๋ฉ”์ธ์˜ ์„œ๋ธŒ๋„๋ฉ”์ธ์—์„œ ์ž„์˜์˜ Javascript๋ฅผ ์‹คํ–‰**ํ•˜๋Š” ๋ฐ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. **์„œ๋ธŒ๋„๋ฉ”์ธ**์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์— **์ฟ ํ‚ค**๊ฐ€ **์ „์†ก**๋˜์—ˆ๊ณ , **์›น์†Œ์ผ“์ด Origin์„ ์ œ๋Œ€๋กœ ํ™•์ธํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์—**, ์ด๋ฅผ ํ†ตํ•ด ํ†ต์‹ ํ•˜๊ณ  **ํ† ํฐ์„ ํ›”์น˜๋Š”** ๊ฒƒ์ด ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. +In this blog post [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/)์—์„œ๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ ์›น์†Œ์ผ“ ํ†ต์‹ ์ด ๋ฐœ์ƒํ•˜๋˜ ๋„๋ฉ”์ธ์˜ **execute arbitrary Javascript in a subdomain**์— ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋„๋ฉ”์ธ์ด **subdomain**์˜€๊ธฐ ๋•Œ๋ฌธ์— **cookie**๊ฐ€ **sent**๋˜์—ˆ๊ณ , **Websocket didn't check the Origin properly** ๋•Œ๋ฌธ์— ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•ด **steal tokens from it**ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. -### Stealing data from user +### ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ํ›”์น˜๊ธฐ -๋‹น์‹ ์ด ๊ฐ€์žฅํ•˜๊ณ  ์‹ถ์€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ณต์‚ฌํ•˜์„ธ์š” (์˜ˆ: .html ํŒŒ์ผ) ๊ทธ๋ฆฌ๊ณ  ์›น์†Œ์ผ“ ํ†ต์‹ ์ด ๋ฐœ์ƒํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ์•ˆ์— ์ด ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”: +์‚ฌ์นญํ•˜๋ ค๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์˜ˆ: .html ํŒŒ์ผ)์„ ๋ณต์‚ฌํ•œ ๋‹ค์Œ, websocket ํ†ต์‹ ์ด ๋ฐœ์ƒํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ถ€์— ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”: ```javascript //This is the script tag to load the websocket hooker ; @@ -148,42 +264,50 @@ xhttp.send() return messageEvent } ``` -์ด์ œ `wsHook.js` ํŒŒ์ผ์„ [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook)์—์„œ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  **์›น ํŒŒ์ผ์ด ์žˆ๋Š” ํด๋”์— ์ €์žฅํ•˜์„ธ์š”**.\ -์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋…ธ์ถœ์‹œํ‚ค๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์—ฐ๊ฒฐํ•˜๊ฒŒ ํ•˜๋ฉด websocket์„ ํ†ตํ•ด ์ „์†ก๋œ ๋ฉ”์‹œ์ง€์™€ ์ˆ˜์‹ ๋œ ๋ฉ”์‹œ์ง€๋ฅผ ํ›”์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์ด์ œ [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook)์—์„œ `wsHook.js` ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  **์›น ํŒŒ์ผ์ด ์žˆ๋Š” ํด๋” ์•ˆ์— ์ €์žฅํ•˜์„ธ์š”**.\ +์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋…ธ์ถœ์‹œํ‚ค๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘์†ํ•˜๊ฒŒ ํ•˜๋ฉด websocket์„ ํ†ตํ•ด ์†ก์ˆ˜์‹ ๋œ ๋ฉ”์‹œ์ง€๋ฅผ ํ›”์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: ```javascript sudo python3 -m http.server 80 ``` ### CSWSH ๋ณดํ˜ธ -CSWSH ๊ณต๊ฒฉ์€ **์‚ฌ์šฉ์ž๊ฐ€ ์•…์„ฑ ํŽ˜์ด์ง€์— ์—ฐ๊ฒฐ**ํ•˜์—ฌ **์›น์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ์—ด**๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ์—ฐ๊ฒฐ๋œ ์›น ํŽ˜์ด์ง€์— ์ธ์ฆํ•˜๋Š” ์‚ฌ์‹ค์— ๊ธฐ๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. ์š”์ฒญ์€ ์‚ฌ์šฉ์ž์˜ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. +CSWSH ๊ณต๊ฒฉ์€ **์‚ฌ์šฉ์ž๊ฐ€ ์•…์„ฑ ํŽ˜์ด์ง€์— ์ ‘์†**ํ•˜๊ณ  ๊ทธ ํŽ˜์ด์ง€๊ฐ€ ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ์ ‘์†ํ•œ ์›นํŽ˜์ด์ง€์— **websocket ์—ฐ๊ฒฐ์„ ์—ด์–ด** ์š”์ฒญ์— ์‚ฌ์šฉ์ž์˜ cookies๊ฐ€ ํฌํ•จ๋˜์–ด ์‚ฌ์šฉ์ž์ธ ๊ฒƒ์ฒ˜๋Ÿผ ์ธ์ฆ๋˜๊ฒŒ ํ•œ๋‹ค๋Š” ์ ์— ๊ธฐ๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. -ํ˜„์žฌ ์ด ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค: +์š”์ฆ˜์—๋Š” ์ด ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค: -- **์›น์†Œ์ผ“ ์„œ๋ฒ„์˜ ์ถœ์ฒ˜ ํ™•์ธ**: ์›น์†Œ์ผ“ ์„œ๋ฒ„๋Š” ํ•ญ์ƒ ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋””์—์„œ ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ํŽ˜์ด์ง€๊ฐ€ ์—ฐ๊ฒฐ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -- **์ธ์ฆ ํ† ํฐ**: ์ธ์ฆ์„ ์ฟ ํ‚ค์— ๊ธฐ๋ฐ˜ํ•˜๊ธฐ๋ณด๋‹ค๋Š”, ์›น์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ๊ณต๊ฒฉ์ž์—๊ฒŒ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ ํ† ํฐ์— ๊ธฐ๋ฐ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์˜ˆ: anti-CSRF ํ† ํฐ). -- **SameSite ์ฟ ํ‚ค ์†์„ฑ**: `SameSite` ๊ฐ’์ด `Lax` ๋˜๋Š” `Strict`์ธ ์ฟ ํ‚ค๋Š” ์™ธ๋ถ€ ๊ณต๊ฒฉ์ž์˜ ํŽ˜์ด์ง€์—์„œ ํ”ผํ•ด์ž ์„œ๋ฒ„๋กœ ์ „์†ก๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์ฟ ํ‚ค ๊ธฐ๋ฐ˜ ์ธ์ฆ์ด ์„ฑ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Chrome์€ ์ด์ œ ์ด ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ์ฟ ํ‚ค์— **`Lax`** ๊ฐ’์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ๋” ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ฟ ํ‚ค๊ฐ€ ์ƒ์„ฑ๋œ ์ฒซ 2๋ถ„ ๋™์•ˆ์€ **`None`** ๊ฐ’์„ ๊ฐ€์ง€๋ฏ€๋กœ ๊ทธ ์ œํ•œ๋œ ์‹œ๊ฐ„ ๋™์•ˆ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค (์ด ์กฐ์น˜๊ฐ€ ์–ธ์  ๊ฐ€๋Š” ์ œ๊ฑฐ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค). -- **Firefox ์ „์ฒด ์ฟ ํ‚ค ๋ณดํ˜ธ**: ์ „์ฒด ์ฟ ํ‚ค ๋ณดํ˜ธ๋Š” ์ฟ ํ‚ค๋ฅผ ์ƒ์„ฑ๋œ ์‚ฌ์ดํŠธ์— ๊ฒฉ๋ฆฌํ•˜์—ฌ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ ๊ฐ ์‚ฌ์ดํŠธ๋Š” ์ œ3์ž๊ฐ€ ์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ง• ๊ธฐ๋ก์„ ์—ฐ๊ฒฐํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์ž์ฒด ์ฟ ํ‚ค ์ €์žฅ์†Œ ํŒŒํ‹ฐ์…˜์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ด๋Š” **CSWSH๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ** ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž์˜ ์‚ฌ์ดํŠธ๋Š” ์ฟ ํ‚ค์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -- **Chrome ์ œ3์ž ์ฟ ํ‚ค ์ฐจ๋‹จ**: ์ด๋Š” `SameSite=None`์ผ์ง€๋ผ๋„ ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์˜ ์ฟ ํ‚ค๊ฐ€ ์›น์†Œ์ผ“ ์„œ๋ฒ„๋กœ ์ „์†ก๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **Websocket server checking the origin**: websocket ์„œ๋ฒ„๋Š” ํ•ญ์ƒ ์—ฐ๊ฒฐํ•˜๋Š” ์ถœ์ฒ˜(origin)๋ฅผ ํ™•์ธํ•˜์—ฌ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ํŽ˜์ด์ง€๊ฐ€ ์—ฐ๊ฒฐ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +- **Authentication token**: ์ธ์ฆ์„ cookie์— ๊ธฐ๋ฐ˜ํ•˜์ง€ ์•Š๊ณ , websocket ์—ฐ๊ฒฐ์„ ์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉ์ž์šฉ์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ๊ณต๊ฒฉ์ž๊ฐ€ ๋ชจ๋ฅด๋Š” token(์˜ˆ: anti-CSRF token)์— ๊ธฐ๋ฐ˜ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **SameSite Cookie attribute**: `SameSite` ๊ฐ’์ด `Lax` ๋˜๋Š” `Strict`์ธ cookies๋Š” ์™ธ๋ถ€ ๊ณต๊ฒฉ์ž ํŽ˜์ด์ง€์—์„œ ํ”ผํ•ด ์„œ๋ฒ„๋กœ ์ „์†ก๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ cookie ๊ธฐ๋ฐ˜ ์ธ์ฆ์€ ์„ฑ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Chrome์€ ์ด์ œ ์ด ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ์ฟ ํ‚ค์— ๊ธฐ๋ณธ์ ์œผ๋กœ **`Lax`** ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋” ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ฟ ํ‚ค๊ฐ€ ์ƒ์„ฑ๋œ ์ฒ˜์Œ 2๋ถ„ ๋™์•ˆ์€ ๊ฐ’์ด **`None`**์ด ๋˜์–ด ๊ทธ ์ œํ•œ๋œ ๊ธฐ๊ฐ„ ๋™์•ˆ ์ทจ์•ฝํ•ด์ง€๋ฉฐ(๋˜ํ•œ ์ด ์กฐ์น˜๊ฐ€ ์–ธ์  ๊ฐ€ ์ œ๊ฑฐ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค). +- **Firefox Total Cookie Protection**: Total Cookie Protection์€ ์ฟ ํ‚ค๋ฅผ ์ƒ์„ฑ๋œ ์‚ฌ์ดํŠธ์— ๊ฒฉ๋ฆฌ์‹œ์ผœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ ๊ฐ ์‚ฌ์ดํŠธ๋Š” ์ œ3์ž๊ฐ€ ์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ง• ๊ธฐ๋ก์„ ์—ฐ๊ฒฐํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์ž์ฒด cookie ์ €์žฅ ํŒŒํ‹ฐ์…˜์„ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๊ณต๊ฒฉ์ž ์‚ฌ์ดํŠธ๋Š” cookies์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์–ด **CSWSH ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค**. +- **Chrome third-party cookies block**: Chrome์˜ third-party cookies ์ฐจ๋‹จ์€ `SameSite=None`์ธ ๊ฒฝ์šฐ์—๋„ ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์˜ cookie๊ฐ€ websocket ์„œ๋ฒ„๋กœ ์ „์†ก๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## ๊ฒฝ์Ÿ ์กฐ๊ฑด +## Race Conditions -์›น์†Œ์ผ“์˜ ๊ฒฝ์Ÿ ์กฐ๊ฑด๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค, [์ž์„ธํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜์„ธ์š”](race-condition.md#rc-in-websockets). +WebSockets์—์„œ์˜ Race Conditions๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [์—ฌ๊ธฐ](race-condition.md#rc-in-websockets)๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ## ๊ธฐํƒ€ ์ทจ์•ฝ์  -์›น์†Œ์ผ“์€ **์„œ๋ฒ„ ์ธก๊ณผ ํด๋ผ์ด์–ธํŠธ ์ธก์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜**์ด๋ฏ€๋กœ, ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ผ **์›น์†Œ์ผ“์€ XSS, SQLi ๋˜๋Š” ์›น์—์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋‹ค๋ฅธ ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** +Web Sockets๋Š” ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์–‘์ชฝ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด๋ฏ€๋กœ, ์„œ๋ฒ„ยทํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ผ **Web Sockets๋ฅผ ํ†ตํ•ด websocket์œผ๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ๋˜๋Š” ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ด์šฉํ•ด XSS, SQLi ๋“ฑ ๊ธฐํƒ€ ์ผ๋ฐ˜์ ์ธ ์›น ์ทจ์•ฝ์ ์„ ์•…์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** -## **์›น์†Œ์ผ“ ์Šค๋จธ๊ธ€๋ง** +## **WebSocket Smuggling** -์ด ์ทจ์•ฝ์ ์€ **์—ญ๋ฐฉํ–ฅ ํ”„๋ก์‹œ ์ œํ•œ์„ ์šฐํšŒ**ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, **์›น์†Œ์ผ“ ํ†ต์‹ ์ด ์„ค์ •๋˜์—ˆ๋‹ค๊ณ  ๋ฏฟ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค** (์‚ฌ์‹ค์ด ์•„๋‹์ง€๋ผ๋„). ์ด๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ **์ˆจ๊ฒจ์ง„ ์—”๋“œํฌ์ธํŠธ์— ์ ‘๊ทผ**ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์ •๋ณด๋Š” ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•˜์„ธ์š”: +์ด ์ทจ์•ฝ์ ์€ **reverse proxies ์ œํ•œ์„ ์šฐํšŒ**ํ•˜๋„๋ก ๋งŒ๋“ค์–ด (์‹ค์ œ๋กœ ๊ทธ๋ ‡์ง€ ์•Š๋”๋ผ๋„) **websocket ํ†ต์‹ ์ด ์„ฑ๋ฆฝ๋œ ๊ฒƒ์œผ๋กœ ๋ฏฟ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** ์ด๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ **์ˆจ๊ฒจ์ง„ ์—”๋“œํฌ์ธํŠธ์— ์ ‘๊ทผ**ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•˜์„ธ์š”: {{#ref}} h2c-smuggling.md {{#endref}} -## ์ฐธ๊ณ  ๋ฌธํ—Œ +## References - [https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages](https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages) - [https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/) +- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) +- [WebSocket Turbo Intruder โ€“ BApp Store](https://portswigger.net/bappstore/ba292c5982ea426c95c9d7325d9a1066) +- [WebSocketTurboIntruder โ€“ GitHub](https://github.com/d0ge/WebSocketTurboIntruder) +- [Turbo Intruder background](https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack) +- [Server-side prototype pollution โ€“ safe detection methods](https://portswigger.net/research/server-side-prototype-pollution#safe-detection-methods-for-manual-testers) +- [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC) +- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) +- [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py) {{#include ../banners/hacktricks-training.md}}