벽뒤에 있는데 어캐알앗냐고 뭐라 칸다
문제화면을 보자
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)
user_ip에서 request.access_route 보면 클라이언트의 IP 주소를 가져온다.
try 안에 보면 "/bin/bash", "-c"를 이용하여 셸 명령어를 실행시킨다. user_ip를 가져와서 그래서 내 IP가 뜨는 것이다.
일단은 user_ip라는 변수에 들어있는 것을 고스란히 실행시킨다는 건 알겠다.
다른 파일들이 있어 그것도 한번 보자.
global
daemon
maxconn 256
defaults
mode http
timeout connect 50000ms
timeout client 50000ms
timeout server 50000ms
listen http-in
bind *:8000
option forwardfor
server app app:3000
haproxy.cfg 파일이다
HAproxy의 대한 설정파 일이라고 한다.
글로벌 설정은 최대 연결 수나 데몬 모드, 모드를 설정하는 거 같다.
기본 설정을 보면 연결 설정 시간대를 설정하는 거 같고
리스너 설정을 보면 모든 네트워크 8000 포트에서 요청을 수신하고
옵션을 보면 forwardfor이라고 클라이언트의 원본 IP 주소를 서버로 전달하는 X-Forwarded-For 헤더를 추가한다고 한다.
그러면 forwardfor 이 나의 IP를 서버로 전달해 주는 역할을 하니까 이 친구를 이용해 보자.
헤더 명칭은 X-Forwarded-For이라고 했으니 적어주고 IP전달을 확인하기 위해서 루프백 주소를 줘보자
잘 먹히는 걸 확인할 수 있다.
그러면 아무 필터링 없이 명령어를 받아들이는 부분을 보면...
result = run(
["/bin/bash", "-c", f"echo {user_ip}"],
곧장 받아들여 명령어를 쓰니 세미클론(;)을 이용해서 명령어를 추가시켜 flag를 출력해 보자
리눅스에서 세미 클론은 여러 명령어를 한 줄에 나열하고 실행시킨다.
f"echo {user_ip}"
f"echo {user_ip}; 명령어"
이렇게 될 수 있다 이것만 이용하면 플래그 값을 얻을 수 있다.
'DreamHack > CTF' 카테고리의 다른 글
(CTF 출제) Tomcat Manager (1) | 2024.09.05 |
---|---|
(CTF 출제) amocafe (2) | 2024.09.05 |
(CTF 출제) BypassIF (0) | 2024.09.04 |
(CTF 출제) Random-Test (0) | 2024.09.04 |
(CTF출제) mongoboard (1) | 2024.09.04 |