드림핵 웹해킹 워게임 level 1 다 풀어보자!
첫 문제 BypassIF
서버에 접속하자 입력폼이 하나 존재한다. 코드를 보자.
#!/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)
admin과 guest는 각각 키값을 가진다. admin의 key는 flag이기 때문에 알 수 없고 guest는 guest를 md5 해시화한 값으로 주어진다.
/flag 엔드포인트에 POST 요청을 보낼 수 있다. 조건을 보면 약간 특이하게 비교가 진행되고 있다는 느낌을 받았다. 굳이 cmd가 없거나 key값이 일치할 때를 비교하고 있다. 아무튼 cmd는 쉘 명령어를 실행할 수 있고 이는 필터링을 진행한다. 필터 부분을 보자.
command_list라고 해서 flag.txt를 읽을만한 명령어들을 필터링하고 있다. filtered_cmd 부분에서 if문들은 참일 경우 모두 True를 리턴한다. flag함수를 보면 filter_cmd가 참일 때 if문이 실행되지 않으므로 두 if을 모두 우회해야한다.
if문을 우회하는 조건은 다음과 같다. command_list에 있는 키워드들이 존재하지 않아야하며, 영문자(소문자), 0 ~ 9까지의 숫자, 공백이 존재해야한다.
굳이 이렇게 꼬아놓은 이유는 모르겠지만 결론은 if문을 우회하면 된다.
ls명령어를 전달해보니 flag.txt가 있는 것이 확인이 됐다. 근데 문제는 읽을 수가 없다..
코드를 잘 보니 timeout이 발생하면 flag가 출력된다. 이제 timeout을 일으키는 쪽으로 게싱을 해보자.
sleep 명령어로 의도적으로 timeout을 일으키니 key값이 출력됐다.
gg
'Web Hacking > Dreamhack' 카테고리의 다른 글
[Dreamhack] Type c-j write up (2) | 2024.03.31 |
---|---|
[Dreamhack] baby-union write up (2) | 2024.03.31 |
[Dreamhack] File Vulnerability Advanced for linux write up (0) | 2024.03.24 |
[Dreamhack] Apache htaccess write up (0) | 2024.03.21 |
[Dreamhack] Command Injection Advanced write up (0) | 2024.03.18 |