Dreamhack - csrf1 (Cross-Site Request Forgery) (수정)

2024. 4. 5. 11:34·DreamHack

 

 

CSRF 취약점을 이용하라고 한다.

 

CSRF 란 웹사이트 취약점 공격의 하나로 , 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 웹사이트에 요청하는 공격이라 말한다.

 

URL을 확인하는 봇이 구현된 서비스라고 한다.

 

그 부분에 대해서 공략하면 될 거 같다.

 

문제파일도 다운로드하고 , 웹 사이트를 한번 들어가 보자.

 

 

#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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:
        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()
        print(str(e))
        # return str(e)
        return False
    driver.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_text
    text = request.args.get("memo", None)
    if text:
        memo_text += text
    return render_template("memo.html", memo=memo_text)


@app.route("/admin/notice_flag")
def admin_notice_flag():
    global memo_text
    if 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("/vuln")
def vuln():
    param = request.args.get("param", "").lower()
    xss_filter = ["frame", "script", "on"]
    for _ in xss_filter:
        param = param.replace(_, "*")
    return param

 

해당 페이지에 대한 코드이다.

 

 

client로 전달된 'param' 파라미터를 받아온다.

 

xss에 대한 필터링이 있다.

"frame", "script", "on"

 

다음 페이지도 봐보자.

 

 

 

 

 

 

 

 

 

memo 페이지이다.

 

 

@app.route("/memo")
def memo():
    global memo_text
    text = request.args.get("memo", None)
    if text:
        memo_text += text
    return render_template("memo.html", memo=memo_text)

 

음... 별거 없다.

 

GET 요청을 받으면 파라미터를 받아 처리한다.

 

다음 페이지도 봐보자.

 

 

 

 

 

 

 

 

 

"notice_flag" 페이지이다.

 

@app.route("/admin/notice_flag")
def admin_notice_flag():
    global memo_text
    if 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"

 

 

client 가 loopback 주소인지 확인을 한다.

 

그리고 "userid" 값이 "admin" 인지 확인한다.

 

전부 조건이 맞을 경우 memo 페이지에 flag 값을 써 놓는 거 같다.

 

loopback 주소를 넣기에는 제한된 환경인 거 같다.

 

다음 페이지도 봐보자.

 

 

 

 

 

 

 

 

 

 

 

flag 페이지이다.

 

 

@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>'

 

"param"이라는 파라미터를 가져와 CSRF 토큰을 확인한다.

 

여기서 form을 쓰기에 여기다가 공격하는 게 맞는 거 같다.

 

 

 

 

 

 

 

 

 

 

 

 

 

이미지 태그인 '<img>'를 사용하면 문제를 풀 수 있다.

 

 

소스코드를 봐야 하는 곳은 notice_flag , vuln이다 notice_flag 에는 요청을 보내면 flag을 출력해 주는 게 있었고 vuln 은 필터링이 있었으니 그것만 봐도 나온다.

 

 

 

 

 

 

 

요청을 보내 memo 페이지를 확인하면 플래그값이 나온다.

 

 

 

'DreamHack' 카테고리의 다른 글

DreamHack - command-injection-1  (0) 2024.05.31
DreamHack - simple-ssti  (0) 2024.05.17
DreamHack - image-storage  (0) 2024.05.17
DreamHack - baby-sqlite  (0) 2024.04.30
Dreamhack - Csrf2 (수정)  (0) 2024.04.05
'DreamHack' 카테고리의 다른 글
  • DreamHack - simple-ssti
  • DreamHack - image-storage
  • DreamHack - baby-sqlite
  • Dreamhack - Csrf2 (수정)
G_OM
G_OM
최대한 설명 열심히 하려고 합니다. 궁금한 거 있으면 언제든지 물어보셔도 좋습니다.
  • G_OM
    끄적끄적
    G_OM
  • 전체
    오늘
    어제
    • 분류 전체보기 (139)
      • 모의해킹 (8)
      • Wargame (69)
        • Linux_bandit (33)
        • Webhacking.kr (36)
      • DreamHack (52)
        • WEB (14)
        • Reverising (9)
        • System (0)
        • CTF (22)
      • Android_security (5)
      • 정보보안기사 (2)
      • IT? (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • DreamHack 에 대한 문제들...
  • 인기 글

  • 태그

    bandit30
    Linux wargame
    Cookie
    overthewire
    sql injection
    insecurebankv2
    bandit20
    webhacking.kr
    Dreamhack
    Linux
    난독화
    union
    워게임
    php
    cookies
    리눅스 워게임
    lfi
    Android
    리눅스
    bandit17
    안드로이드
    url encode
    bandit
    정보보안기사
    php wrapper
    drozer
    wargame
    CTF
    bandit18
    webhacking
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
G_OM
Dreamhack - csrf1 (Cross-Site Request Forgery) (수정)
상단으로

티스토리툴바