-
[DreamHack] csrf-12022/Write-Ups 2022. 9. 20. 21:14
1팀 정유진
CSRF 취약점이란
CSRF(Cross-Site Request Forgery)
사이트 간 요청 위조 공격은
브라우저가 웹 사이트의 사용자를 신용하고 있는 상태를 이용한 공격을 말한다.
역시 간단하게 예를 들면, 제가 관리자인 https://falsy.me 라는 사이트가 있고, falsy.me는 쿠키로 사용자 인증을 하고 있고 저는 로그인이 되어 있다고 했을때, 그리고 사용자의 비밀번호를 변경하는 api가 ‘https://falsy.me/user?id=…&pw=…’ 이러한 형태로 되어 있을때.
해당 사이트에 들어가면 4개의 항목이 보인다.
주어진 파이썬 코드를 보면
#!/usr/bin/python3from flask import Flask, request, render_templatefrom selenium import webdriverimport urllibimport 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()print(str(e))# return str(e)return Falsedriver.quit()return True
def check_csrf(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():param = request.args.get("param", "").lower()xss_filter = ["frame", "script", "on"]for _ in xss_filter:param = param.replace(_, "*")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_csrf(param):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_texttext = request.args.get("memo", None)if text:memo_text += textreturn render_template("memo.html", memo=memo_text)
@app.route("/admin/notice_flag")def admin_notice_flag():global memo_textif request.remote_addr != "127.0.0.1":return "Access Denied"if request.args.get("userid", "") != "admin":return "Access Denied 2"memo_text += f"[Notice] flag is {FLAG}\n"return "Ok"
app.run(host="0.0.0.0", port=8000)플래그 페이지에 들어가면 빈칸이 보인다.
@app.route("/admin/notice_flag")def admin_notice_flag():global memo_textif request.remote_addr != "127.0.0.1":return "Access Denied"if request.args.get("userid", "") != "admin":return "Access Denied 2"memo_text += f"[Notice] flag is {FLAG}\n"return "Ok"해당 코드를 보면1) 127.0.0.1로 접근할 것
2) userid = admin 라는 두 가지 조건이 있다.
<img src="/admin/notice_flag?userid=admin"> 을 flag의 빈칸에 넣어준다.
memo 페이지에 들어가면 플래그가 뜬 것을 확인할 수 있다.
참고
https://lemon-soju.tistory.com/43
느낀점:
소스코드를 잘 뜯어보자...
flag 페이지가 아닌 memo페이지에서 정답(플래그)이 나오고..
공격 코드를 flag 페이지에 입력하는 것.
특정 페이지에서는 xss 공격은 안 되는 것...
'2022 > Write-Ups' 카테고리의 다른 글
[ctf-d] broken (0) 2022.09.20 [DigitalForensic_with CTF] mystery1 - mystery2 (0) 2022.09.20 [ctf-d] 그림을 보아라 (0) 2022.09.20 [ctf-d] 그림을 보아라 (0) 2022.09.20 [webhacking.kr] old-14 (0) 2022.09.20