티스토리 뷰

hacking/WEB hacking

Flask-dev

kiwiiiv 2021. 2. 9. 03:08

Flask-Dev | 워게임 | Dreamhack

 

Flask-Dev

취약점을 찾아 플래그를 획득해보세요. 플래그는 /flag 를 실행하면 얻을 수 있습니다. 해당 문제는 숙련된 웹해커를 위한 문제입니다.

dreamhack.io

 

개열받았던문제.

 

 

 

먼저 소스를 보면,

url에 입력된 파일 path를 통하여 파일을 읽어오는 것을 알 수 있음

 

문제에서는 /flag파일을 실행시키는 것이 목적이라 했으므로

일단 /flag에 접속해 보면

 

 

위와 같이 에러 로그가 출력된다..

 

debug_True

 

(디버그 모드로 설정되어 있기 때문)

 

일단 app.py로 접속해 보면

 

app.py

 

위와 같이 이미 알고 있는 ㄱ- app.py 의 소스를 읽어와 준다

 

app.py 소스와 더불어 같이 주어진 Dockerfile을 보면(사실 별로 안 중요함)

Dockerfile

 

flag 실행 파일을 만드는 과정이 보여지며, flag의 접근 권한은 111로 설정되어 읽는 작업은 불가능하고 실행만 가능하게 되어 있음

 

 

따라서 디버그 모드의 콘솔을 이용하는 방법만 가능해 보였는데

구글링 결과 flask의 debuggerPIN을 탈취하는 방식이 존재한다는 것을 알게 됨

 

일단 현재 경로를 파악해 보면

 

/app/app.py 를 통해

현재 경로는 /app인 것을 알 수 있음!!! (아까 app.py 를 입력하였을 때 파일이 출력되었으니까.)

 

따라서 먼저 __init__.py 파일을 열람해 보면

 

../usr/local/lib/python3.8/site-packages/werkzeug/debug/__init__.py

 

(burp 이용해야 함... ../ 가 자동으로 사라져서 ㅡㅡ)

필요한 부분만 봐보면..

 

 

위의 함수(get_machine_id)에서 machine-id 를 생성하고 있고

읽어오는 파일의 값들을 LFI공격을 통하여 읽어와 줄 수 있음

 

 

machine-id : /etc/machine-id

boot-id : /proc/sys/kernel/random/boot_id

 

cgroup : /proc/self/cgroup

 

 

 

 probably_public_bits = [
        username,
        modname,		#flask.app(고정)
        getattr(app, "__name__", app.__class__.__name__),	#Flask(고정)	
        getattr(mod, "__file__", None),	#app.py의 위치
    ]
 
    # 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 = [
    	str(uuid.getnode()),	#mac address
        get_machine_id()		#machine-id
        ]
 
    h = hashlib.md5()
    for bit in chain(probably_public_bits, private_bits):
        if not bit:
            continue
        if isinstance(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
    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.
    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
 
    return rv, cookie_name

 

 

위의 코드에서 PIN, cookie 가 생성된다

일단 PIN을 생성하기 위해서는 public_bits, private_bits 값을 구해와야 했는데,

 

먼저 mac 주소 값은

/sys/class/net/eth0/address 

에 존재했으며, 이 때에는 int로 변환하여 넣어줘야 함

 

따라서 다음과 같이 값을 넣어줄 수 있다

 

 

 

이를 실행시켜 PIN을 구할 수 있음

 

 

구한 PIN으로 콘솔을 다음과 같이 이용할 수 있다

 

 

 

 

flag 파일을 실행시키면

 

 

 

 

 

 

 

++

초반에 계산된 PIN 값이 계속 incorrect 가 떴었는데,,, 알고보니 machine id 생성 과정에서 파일을 읽어오지 못하고 있었음

그래서 파일의 내용을 읽어 오는 과정을 다음과 같이 바꾸어 주었음

 

 

 

 

+++

참고했던사이트

python flask debugger pin, find and exploit (lactea.kr)

 

Dockerfile 이란 ? 무엇인 가..

10장. 도커파일(Dockerfile) (velog.io)

'hacking > WEB hacking' 카테고리의 다른 글

regex  (0) 2021.03.24
mongoboard(MongoDB)  (0) 2021.03.22
web-ssrf  (0) 2021.01.31
CSP  (0) 2021.01.28
LFI (- RFI)  (0) 2021.01.22
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함