차마 뭘 해야할지 모르겠어서.. 웹을 하게 되었습니다. 이것저것 다 잘하고싶은데 골고루 못하는게 아쉽네여
xss-1번 문제는 드림핵에 나와있는 설명대로 함께 풀어보면 되는데
xss-1을 풀고 바로 xss-2를 풀자니 갑자기 난이도가 급상승 하는 것 같았습니다.
분석
다운로드 한 소스코드에서 필요한 부분만을 봅시다.
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)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/vuln")
def vuln():
return render_template("vuln.html")
@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>'
메모는 이전 문제와 동일하고
사이트에 접속해서 vuln에 들어가면
분명 script 태그로 alert를 사용했는데 alert가 실행되지 않습니다.
이전 문제와 달라진 점이 뭘까
코드를 보면
vuln에서 request.args.get을 사용했느냐, render_template를 사용했느냐의 차이이다.
xss1에서는 바로 body에 삽입이 되는데
xss2는 빈 페이지가 아니고 뭔가가 많다.
그리고 중요해보이는 script문을 봤을 때 vuln이라는 id를 가지는 div 태그 내에 param을 집어넣는다는 걸 알겠는데...
이게 왜 script구문을 사용하지 못하게 하는건지는 뭘 봐야할지 모르겠다.
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0
위에서 innerHTML을 사용해서 param으로 받은 것을 넣어주는데
HTML5부터는 code injection을 방지하기 위해서 innerHTML로 받은 script를 실행시키지 않는다.
때문에 script가 아닌 다른 태그로 xss를 사용해야 한다.
풀이
xss는 script 구문만 넣는 것이 아니라 다른 방식으로도 공격이 가능하다. 계속 alert 문이 안되길래 다른 방법들을 시도해보면 된다.
저번 웹 스터디에서 사용했던 방법 중 하나로
이벤트 핸들러를 유용하게 사용했는데 이번에도 이걸 활용했다.
<img src=x onerror="location.href='/memo?memo='+document.cookie">
img 태그에서 에러가 발생하는 것을 의도적으로 만들고 에러가 발생했을 경우 이벤트 핸들러로 해당 스크립트 문을 실행하도록 한다.
그러면 정답을 구할 수 있다.