기본적으로 소스코드를 제공해준다.
- """
- Web App with file based ACL.
- """
- import os
- import struct
- from flask import Flask, request, render_template, abort, flash, redirect, url_for
- """
- Flask Config
- """
- app = Flask(__name__)
- app = Flask(__name__)
- app.config['DEBUG'] = False
- app.secret_key = ""
- FLAG = '??'
- class ACL(object):
- """
- Intent:
- ACL for the Application
- Responsibilities:
- - Add New Records to ACL
- - Verify existing records in ACL
- Data Structures
- - record
- {
- 'username': <str>username[100],
- 'password': <str>password[100],
- 'admin': <str:`true/false`>admin
- }
- """
- DEFAULT_ACL_FILE = 'acl.data'
- def __init__(self, *args, **kwargs):
- """
- ACL(, [file_name, ])
- :param str file_name kwarg
- """
- self.acl_file = kwargs.get('acl_file', self.DEFAULT_ACL_FILE)
- self.acl_lines = self._read_acl_file()
- """
- Writing Methods
- """
- @staticmethod
- def _pack_data(data_dict):
- """
- Pack data with data_structure.
- """
- return '{}:{}:{}'.format(
- data_dict['username'],
- data_dict['password'],
- data_dict['admin']
- )
- @staticmethod
- def _append_data(filename, data):
- """
- write `data` to filename as binary data.
- """
- with open(filename, 'a') as f:
- f.write(data)
- f.write('\n') # New Line Delimiter
- def _append_record(self, data_dict, *args, **kwargs):
- """
- Pack data and append to file.
- """
- bin_data = self._pack_data(data_dict)
- self._append_data(self.acl_file, bin_data)
- def add_record(self, username, password, admin, *args, **kwargs):
- """
- Add record to ACL.
- - Client Facing
- """
- record = {
- 'username': username,
- 'password': password,
- 'admin': admin
- }
- self._append_record(data_dict=record)
- return record
- def _read_acl_file(self):
- """
- Read all the lines in `self.acl_file`
- """
- if not os.path.exists(self.acl_file):
- return None
- with open(self.acl_file, 'r') as f:
- lines = f.readlines()
- return lines
- def _unpack_data(self, buffer):
- """
- Unpack the buffer and extract contents.
- """
- unpacked_data = buffer.strip()
- unpacked_data = unpacked_data.split(':')
- record = {
- 'username': unpacked_data[0],
- 'password': unpacked_data[1],
- 'admin': unpacked_data[2],
- }
- return record
- def verify(self, username, password):
- """
- Verify if username and password exist in ACL.
- - Client Facing
- """
- for line in self.acl_lines:
- try:
- data = self._unpack_data(line)
- except:
- continue
- if username == data['username'] and password == data['password']:
- return True, data
- return False
- acl = ACL()
- @app.route('/', methods=['GET', 'POST'])
- def index():
- if request.method == 'GET':
- return render_template('index.html', admin=False, flag=FLAG)
- elif request.method == 'POST':
- try:
- username = request.form.get('username')
- password = request.form.get('password')
- is_user, record = acl.verify(username, password)
- print(is_user)
- if is_user:
- admin = True if record['admin'] == 'true' else False
- else:
- raise Exception()
- return render_template('index.html', admin=admin, flag=FLAG, record=record)
- except:
- return redirect(url_for('index'))
- @app.route('/register', methods=['GET', 'POST'])
- def register():
- if request.method == 'GET':
- return render_template('register.html')
- elif request.method == 'POST':
- username = request.form.get('username')
- password = request.form.get('password')
- acl.add_record(username, password, 'false')
- return redirect(url_for('index'))
- if __name__ == '__main__':
- app.run(port=5000, debug=True)
_unpack_data 함수 내에서 데이터를 언패킹하는 과정에서 취약점이 터진다. 간단히 : 문자를 기분으로 split하기 때문에 회원가입 시 패스워드를 youngin:true 형태로 가입해 주면 된다.
그러면 기본적으로 youngin:youngin:false와 같은 구조가 youngin:youngin:true:false가 된다.
위와 같은 형태로 가입 후 id:youngin,pw:youngin 으로 로그인 해주면 되는데 이때 회원가입시 요청한 데이터가 들어가 있는 self.acl_lines 요 값이 로컬에서 테스트해보니 항상 일정하지가 않아서 내가 삽입한 데이터가 존재하지 않는 경우가 있었다.. 그래서 위와 같은 로그인을 여러번 반복해서 해주니 플래그가 나왔다.
Flag = evlz{T#3_W34K_$N4K3}ctf
'CTF > Writeup' 카테고리의 다른 글
Trust CTF 2019 Web Writeup (0) | 2019.02.16 |
---|---|
Evlz CTF 2019 FindMe (0) | 2019.02.06 |
NCSC CTF 2019 Web Wrietup (0) | 2019.02.04 |
Codegate CTF 2019 Preliminary Rich Project (0) | 2019.01.27 |
INSOMNIHACK CTF TEASER 2019 Phuck2 :( (0) | 2019.01.22 |