CTF/웹해킹

[HSCTF9] gallery - 웹해킹 / LFI

SecurityMan 2022. 7. 7. 11:00

 

쉬운 난이도의 웹해킹 문제였다.

 

문제 페이지 주소와 함께 문제 소스파일도 같이 주어지는데

 

약간의 센스만 있다면 사실 소스 안보고도 충분히 풀 수 있는 문제이다.

 

반응형

 

 

문제페이지에 들어가면 나오는 화면이다.

 

문제 제목인 Gallery에 맞게 각종 사진들을 볼 수 있다.

 

 

f12를 눌러 개발자도구로 메인페이지 HTML 코드를 살펴보았다.

 

각종 이미지들을 서버에서 가져올때

 

URL에 /image 경로에서 ?image= 변수에 이미지 파일 이름을 지정해서 가져오는 방식인 것을 확인했다.

(URL에서 ? 뒤에 오는것은 변수라고 보면 된다.)

 

만약 URL에 ?image=<이미지파일> 을 입력하는것이 아니라

 

서버에 있는 다른 파일이름을 입력한다면?

 

만약 적절하게 필터링이 되어있지 않을 경우 서버에 존재하는 아무 파일이나 가져와서 읽을 수 있게 된다.

 

이런 취약점을 LFI(Local File Inclusion) 이라고 한다.

 

 

위와 같이 URL에 ?image=flag 라고 입력하면

 

서버에서 이름이 flag인 파일을 가져와서 보여준다.

 

지금은 서버에 flag 라는 파일이 없기 때문에 Invaild filename 이라는 문구가 출력된 것이다.

 

import os
import re
from pathlib import Path
from flask import Flask, render_template, request, send_file

app = Flask(__name__)
IMAGE_FOLDER = Path("/images")

@app.route("/")
def index():
	images = [p.name for p in IMAGE_FOLDER.iterdir()]
	return render_template("index.html", images=images)

@app.route("/image")
def image():
	if "image" not in request.args:
		return "Image not provided", 400
	if ".jpg" not in request.args["image"]:
		return "Invalid filename", 400
	
	file = IMAGE_FOLDER.joinpath(Path(request.args["image"]))
	if not file.is_relative_to(IMAGE_FOLDER):
		return "Invalid filename", 400
	
	try:
		return send_file(file.resolve())
	except FileNotFoundError:
		return "File does not exist", 400

@app.route("/flag")
def flag():
	if 2 + 2 == 5:
		return send_file("/flag.txt")
	else:
		return "No.", 400

if __name__ == "__main__":
	app.run()

 

어떤 파일을 가져와야하는지 보기위해 

 

주어진 웹 소스코드를 살펴본다.

 

맨 밑에있는 flag() 함수를 보면 된다.

 

 

/flag 경로에서 flag.txt 파일의 내용을 읽어서 보여주도록 설정해놨는데

 

문제는 바로 위에있는 조건문이다.

 

2+2 가 5일때만 /flag 경로에서 flag.txt 파일을 읽어올수가 있다.

 

상식적으로 2+2는 절대로 5가 될 수 없으니 flag.txt의 내용은 정상적으론 볼 수가 없다.

 

하지만 LFI 취약점을 이용하면 가능하다.

 

 

읽어야할 파일의 이름을 알았으니,

 

URL에 ?image=flag.jpg../../../../../flag.txt 라고 입력해준다.

 

그러면 플래그가 출력된다.

 

flag.jpg는 임의로 아무 파일명이나 넣은것으로, 다른 이름으로 바꿔줘도 상관없다.

 

flag.txt가 루트( / ) 경로 아래에 있으니

 

../ 를 여러번 써서 최상위 경로로 이동한 뒤에 flag.txt 를 써줌으로써 파일이 내용을 읽을 수 있는것이다.

반응형