import os
from flask import Flask, request, render_template
from flask_mysqldb import MySQL
app = Flask(__name__)
app.config['MYSQL_HOST'] = os.environ.get('MYSQL_HOST', 'localhost')
app.config['MYSQL_USER'] = os.environ.get('MYSQL_USER', 'user')
app.config['MYSQL_PASSWORD'] = os.environ.get('MYSQL_PASSWORD', 'pass')
app.config['MYSQL_DB'] = os.environ.get('MYSQL_DB', 'secret_db')
mysql = MySQL(app)
@app.route("/", methods = ["GET", "POST"])
def index():
if request.method == "POST":
uid = request.form.get('uid', '')
upw = request.form.get('upw', '')
if uid and upw:
cur = mysql.connection.cursor()
cur.execute(f"SELECT * FROM users WHERE uid='{/*}' and upw='{*/}';")
data = cur.fetchall()
if data:
return render_template("user.html", data=data)
else: return render_template("index.html", data="Wrong!")
return render_template("index.html", data="Fill the input box", pre=1)
return render_template("index.html")
if __name__ == '__main__':
app.run(host='0.0.0.0')
CREATE DATABASE secret_db;
GRANT ALL PRIVILEGES ON secret_db.* TO 'dbuser'@'localhost' IDENTIFIED BY 'dbpass';
USE `secret_db`;
CREATE TABLE users (
idx int auto_increment primary key,
uid varchar(128) not null,
upw varchar(128) not null,
descr varchar(128) not null
);
INSERT INTO users (uid, upw, descr) values ('admin', 'apple', 'For admin');
INSERT INTO users (uid, upw, descr) values ('guest', 'melon', 'For guest');
INSERT INTO users (uid, upw, descr) values ('banana', 'test', 'For banana');
FLUSH PRIVILEGES;
CREATE TABLE fake_table_name (
idx int auto_increment primary key,
fake_col1 varchar(128) not null,
fake_col2 varchar(128) not null,
fake_col3 varchar(128) not null,
fake_col4 varchar(128) not null
);
INSERT INTO fake_table_name (fake_col1, fake_col2, fake_col3, fake_col4) values ('flag is ', 'DH{sam','ple','flag}');
위 sql 코드를 보면 USE 'secret_db';를 통해 secret_db를 사용하는 것을 알 수 있음.
또한 secret_db에는 users테이블과 fake_table_name테이블이 존재한다.
→ 각 테이블 구조이다.
admin' or '1'='1를 uid에 넣고 upw에는 아무 값을 넣고 제출하면 아래 처럼 나오므로 sql인젝션이 가능한 사이트 라는 것을 알 수 있음.
→ 그렇다면 union구문과 information_schema 함수를 사용하여 플래그가 저장된 테이블과 컬럼명을 알아 낼 수 있을 것 같다.
uid에 **admin' union select table_name,null,null,null from information_schema.tables where table_schema = 'secret_db'-- -**를 넣으면 secret_db에 있는 테이블이 출력된다.
위 코드에서 null이 들어가는 이유는 union 구문은 컬럼 개수가 일치해야하기 때문이다.
위에서 출력된 테이블 중 플래그가 있는 테이블은 ‘onlyflag’ 라는 테이블이란 것을 알 수 있다
그렇다면 위의 코드를 살짝 바꾸어 ‘onlyflag’ 테이블의 컬럼을 출력하는 코드를 작성할 수 있다.
**admin' union select column_name,null,null,null from information_schema.columns where table_name = 'onlyflag'-- -**이를 uid에 넣고 제출하게 되면
이렇게 나오게 된다.
그렇다면 ①‘onlyflag’에 플래그가 있다는 사실을 알았고, ②‘onlyflag’테이블에 있는 칼럼은 idx, sname, svalue, sflag, sclose 인것을 알 수 있다.
그렇다면 모은 정보를 종합하면 ‘onlyflag’ 테이블에 있는 컬럼을 출력하면 플래그를 얻을 수 있겠구나 라는 생각이 든다.
→ gruop_contact 함수를 사용하여 모든 각 컬럼에 저장된 플래그 조각을 출력할 수 있다.
admin' union select sname,group_concat(svalue,sflag,sclose),null,null from onlyflag-- -
코드는 위와 같고 이 코드를 uid에 넣고 제출을 하게 되면 플래그 값이 나오게 된다.
'DreamHack > Web hacking' 카테고리의 다른 글
[LEVEL-1] simple_sqli_chatgpt (1) | 2023.11.27 |
---|---|
[LEVEL-1] session-basic (0) | 2023.11.20 |
[LEVEL-1] Type c-j (0) | 2023.11.15 |
[LEVEL-1] [wargame.kr] strcmp (0) | 2023.11.09 |
[LEVEL-Beginner] session (2) | 2023.11.09 |