Dreamhack/Dreamhack Wargame (Challenge)

[83] IT 비전공자 [dreamhack]BypassIF문제 풀기

imaginefuture-1 2024. 12. 1. 09:23

bypassif

 

안녕 드림아. 대략 키값을 입력해야 flag가 보일 것 같다

 

 

 

소스코드 보러가자

 

 

#!/usr/bin/env python3
import subprocess
from flask import Flask, request, render_template, redirect, url_for
import string
import os
import hashlib

app = Flask(__name__)

try:
    FLAG = open("./flag.txt", "r").read()
except:
    FLAG = "[**FLAG**]"

KEY = hashlib.md5(FLAG.encode()).hexdigest()
guest_key = hashlib.md5(b"guest").hexdigest()

# filtering
def filter_cmd(cmd):
    alphabet = list(string.ascii_lowercase)
    alphabet.extend([' '])
    num = '0123456789'
    alphabet.extend(num)
    command_list = ['flag','cat','chmod','head','tail','less','awk','more','grep']

    for c in command_list:
        if c in cmd:
            return True
    for c in cmd:
        if c not in alphabet:
            return True

@app.route('/', methods=['GET', 'POST'])
def index():
    # GET request
    return render_template('index.html')



@app.route('/flag', methods=['POST'])
def flag():
     # POST request
    if request.method == 'POST':
        key = request.form.get('key', '')
        cmd = request.form.get('cmd_input', '')
        if cmd == '' and key == KEY:
            return render_template('flag.html', txt=FLAG)
        elif cmd == '' and key == guest_key:
            return render_template('guest.html', txt=f"guest key: {guest_key}")
        if cmd != '' or key == KEY:
            if not filter_cmd(cmd):
                try:
                    output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
                    return render_template('flag.html', txt=output.decode('utf-8'))
                except subprocess.TimeoutExpired:
                    return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')
                except subprocess.CalledProcessError:
                    return render_template('flag.html', txt="Error!")
            return render_template('flag.html')
        else:
            return redirect('/')
    else: 
        return render_template('flag.html')


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, debug=True)

 

 

 

 

이 Python 코드는 플래스크(Flask) 웹 애플리케이션으로, 사용자가 제공한 키와 명령어를 통해 플래그를 얻거나 명령어를 실행할 수 있는 인터페이스를 제공합니다. 보안 필터링과 명령어 실행 로직이 포함되어 있으며, 아래는 코드의 주요 부분에 대한 상세 설명입니다.


1. 주요 동작 구조

(1) 파일 및 상수 로드

  • FLAG:
    • flag.txt 파일의 내용을 읽어서 변수 FLAG에 저장.
    • 파일을 읽을 수 없을 경우 기본값으로 [**FLAG**]를 설정.
  • KEY와 guest_key:
    • KEY: FLAG를 MD5 해시하여 생성된 키.
    • guest_key: 문자열 guest를 MD5 해시하여 생성된 키.

(2) 명령어 필터링

def filter_cmd(cmd):
    alphabet = list(string.ascii_lowercase)
    alphabet.extend([' '])
    num = '0123456789'
    alphabet.extend(num)
    command_list = ['flag','cat','chmod','head','tail','less','awk','more','grep']

    for c in command_list:
        if c in cmd:
            return True
    for c in cmd:
        if c not in alphabet:
            return True
  • 입력된 명령어(cmd)를 필터링하여 보안성을 확보:
    • 허용된 문자:
      • 소문자 알파벳, 숫자, 공백.
    • 금지된 명령어:
      • flag, cat, chmod, head, tail, less, awk, more, grep 등.
    • 필터링 논리:
      • 금지된 명령어가 포함되거나 허용되지 않은 문자가 포함된 경우 True를 반환(필터링 적용).

(3) 라우팅

/ - 메인 페이지

@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template('index.html')
  • 메인 페이지(index.html)를 렌더링.
  • 주로 입력 폼을 사용자에게 제공.

/flag - 플래그 페이지

@app.route('/flag', methods=['POST'])
def flag():
  • 동작 방식:
    • 사용자로부터 key와 cmd_input을 POST 방식으로 입력받음.
    • 조건에 따라 플래그를 보여주거나 명령어를 실행.
  1. 플래그 출력:
    • 키가 KEY와 일치:
      • 플래그 파일의 내용을 출력.
    • 키가 guest_key와 일치:
      • 게스트 키와 관련된 메시지 출력.
  2. 명령어 실행:
    • cmd_input이 비어 있지 않은 경우:
      • 필터링(filter_cmd)에 통과한 명령어만 실행.
      • /bin/sh를 사용해 명령어 실행:
        output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
        
        • 명령어 실행 성공: 실행 결과를 출력.
        • 실행 시간 초과: 타임아웃 메시지 반환.
        • 오류 발생: 오류 메시지 반환.
  3. 필터링 실패:
    • 명령어에 금지된 문자가 포함되거나 조건에 맞지 않는 경우, 명령어 실행 없이 페이지 리로드.
  4. 기타:
    • 키와 명령어가 모두 없는 경우 메인 페이지(/)로 리다이렉트.

2. 보안 취약점 분석

(1) 명령어 필터링 우회 가능성

  • 필터링된 명령어 목록이 비교적 제한적이며, 허용된 문자 조합으로 우회 가능.
  • 예: cat 대신 c a t처럼 공백으로 분리하여 우회 가능성 존재.

(2) 명령어 실행 제한 부족

  • 명령어가 /bin/sh에서 실행되므로, 명령어 체인(;, &&)을 통해 악의적 명령어 실행 가능.

(3) 민감한 정보 유출 위험

  • FLAG와 관련된 키(KEY)가 코드에서 직접 사용되므로, 만약 코드가 노출되면 MD5 해시를 복호화하여 플래그 유출 가능.

3. 해결 방안

(1) 필터링 강화

  • 허용된 문자만 남기고 모든 특수 문자와 숫자열 제한.
  • 예: 정규식을 사용하여 특정 패턴만 허용:
    import re
    def filter_cmd(cmd):
        return not re.match(r'^[a-z0-9 ]+$', cmd)
    

(2) 명령어 실행 환경 제한

  • 서브 프로세스 대신 파이썬 내부 로직으로 처리.
  • 명령어 실행이 반드시 필요한 경우, 컨테이너 또는 가상 환경에서 실행.

(3) 플래그 관리 보안 강화

  • FLAG와 관련된 데이터는 별도 암호화된 파일로 저장하고 동적으로 로드.
  • MD5 대신 SHA256 또는 Argon2와 같은 더 강력한 해시 알고리즘 사용.

4. 요약

  • 이 코드의 주요 기능은:
    1. 특정 키 입력 시 플래그 노출.
    2. 제한된 명령어 실행.
  • 그러나 필터링 및 실행 환경의 보안이 취약하여 명령어 우회와 정보 유출 가능성이 존재.
  • 이를 강화하려면 필터링 개선, 명령어 실행 제한, 플래그 관리 보안성을 높이는 것이 중요합니다.

 

 

 


 

 

 

우회 방법일 것 같네. 문제 제목처럼 if문을 바이패스 해야할 것 같다 

 

 

 

KEY = hashlib.md5(FLAG.encode()).hexdigest()
guest_key = hashlib.md5(b"guest").hexdigest()

 

"guest"라는 문자열을 바이트로 변환 후, hexdigest로 16진수로 문자열 변환 이 후 hashlib.md5를 사용해서

해싱한 값을 guest_key에 저장한다

 

guest_key를 찾아보자

 

비쥬얼코드 저장경로 오류떠서 리눅이 켰다

윈도우말고 리눅이가 최고다...ㄹㅇ

 

 

import hashlib

hashtext = hashlib.md5(b"guest").hexdigest()

print(hashtext)

 

 

084e0343a0486ff05530df6c705c8bb4

 

 

 

캬 ㅋㅋ

 

하씨 burpsuit 아직도 사용방법 모르겠다 ㅋㅋㅋ아 ㅋㅋ내일 선생님한테 당장 달려가고싶으면 개추..

 

https://minnggyuu.tistory.com/10

 

[Dreamhack] BypassIF 풀이

BypassIF이다. 제목만 봐서는 IF문을 바이패스 해야될 것 같다. 문제 페이지이다. 맞는 key를 submit 하면 될 것 같다. 아무 값이나 넣어봤는데 아무 반응이 없다. 감이 안잡히므로 소스코드를 보도록

minnggyuu.tistory.com

 

https://velog.io/@cherry613/Dreamhack-CTF-BypassIF

 

Dreamhack CTF-BypassIF

이 문제 풀었다. 나름 간단한 문제였다!문제 페이지이다. app.py 코드 확인해보면필터링하는 함수를 좀 더 자세히 살펴보자.흠. alphabet에는 소문자, 공백, 숫자만 포함된다. 'flag','cat','chmod','head','ta

velog.io

https://tjrrb4551.tistory.com/entry/Dreamhack-BypassIF-write-up

 

[Dreamhack] BypassIF write up

드림핵 웹해킹 워게임 level 1 다 풀어보자! 첫 문제 BypassIF 서버에 접속하자 입력폼이 하나 존재한다. 코드를 보자. #!/usr/bin/env python3 import subprocess from flask import Flask, request, render_template, redirect, url

tjrrb4551.tistory.com

https://yun-2.tistory.com/entry/CTFSeason5Round4-BypassIF

 

[Dreamhack] CTF Season 5 Round #4 - BypassIF

🛎️ Access Admin의 KEY가 필요합니다! 알맞은 KEY값을 입력하여 플래그를 획득하세요. 플래그 형식은 DH{...} 입니다. 👾 Exploit Algorithm & Payload > ./app.py 더보기 #!/usr/bin/env python3 import subprocess from flask

yun-2.tistory.com

 


 

 

다른 사람들 풀이글 보면, burpsuit이용해서 패킷 가로채쇼 cmd_input에 ls를 전달하면

flag.txt

requirements.txt

static

templates

가 뜨는걸 확인할 수 있는데 문제는 명령어 필터링 때문에 읽을 수가 없다

 

방법은?

 

if cmd != '' or key == KEY:
    if not filter_cmd(cmd):
        try:
            output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
            return render_template('flag.html', txt=output.decode('utf-8'))
        except subprocess.TimeoutExpired:
            return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')
        except subprocess.CalledProcessError:
            return render_template('flag.html', txt="Error!")
    return render_template('flag.html')
else:
    return redirect('/')

 

 

 

Timout! Your key: {key}



타임아웃되면 flag키값이 나온다 엌ㅋ



 

 

 

이런 부분이 있다. 
filter_cmd 에서 바이패스에 성공하면, 밑의 구문을 실행한다. 
try 첫 번째는 cmd 커맨드를 실행한다. timeout=5을 써서 명령이 실행되는 시간을 5초로 제한했다. 5초를 넘어가면, Timeout 시킨다.
 
그럼 Timeout되면 어떻게 되냐?
밑에 달린 except 구문을 보면, timeout이 발생하면, 'Timeout! Your key: {KEY}' 를 반환한다.
ㅇ... 그냥 KEY.. FLAG를 던져준다. 

출처 ㅣhttps://minnggyuu.tistory.com/10

이분도 당황하신듯 ㅋㅋ

 

 


: cmd가 필터링 함수에 해당하는 것이 있는지 확인하게 된다. 통과된다면 try문으로 이동한다.
: try문에서 cmd에서 작성했던 쉘 명령어가 실행되고 출력 결과를 가져오게 된다. 이때, 명령어 실행에 5초 이상 지연이 발생하면 에러문을 발생하는 것을 확인할 수 있다.
: except subprocess.TimeoutExpired는 timeout 에러가 발생하면 flag.html 페이지를 렌더링하고 KEY(Admin의 KEY)를 전달함을 알 수 있다.
: 따라서 지연시키면 Admin의 KEY를 얻을 수 있을 것이다.

출처 ㅣ https://yun-2.tistory.com/entry/CTFSeason5Round4-BypassIF

 

큰일났다 burpsuit 이용해야하네;; 도움 도움;;;

 

dkdkdㅏㄴㅁ암나안ㅁ아

 

내일 선생님한테 도움 요청해야겠다..버프 너무 어렵네

 

 


 

 

2024-12-02

 

 

캬 ㅋㅋㅋ3달만에 버프수트 사용법 깨달음ㅋㅋㅋ

앜ㅋㅋㅋㅋ

 

 

 

 ㅋㅋㅋㅋㅋㅋㅋㅋ