본문 바로가기

SWLUG/CTF

[CTF/ Dreamhack] error based sql injection

 

 

error based sql injection

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

dreamhack.io

 

 

 

 

 

문제 확인

 

 

 

 

SQL(Structured Query Language)이란?

데이터베이스에서 데이터를 추출하고 조작하는 데에 사용하는 데이터 처리 언어이다.

- 쉽게 말해 데이터베이스에 저장된 정보를 쉽게 찾고 정리하는 데에 도움을 주는 도구

- 시장 트렌드 분석이나 고객 행동 패턴 파악 등을 통해 적합한 전략을 수립할 수 있다.

- SQL을 통해 데이터베이스에서 원하는 정보를 추출하고, 데이터의 흐름이나 특정 조건에 따른 데이터 분석을 할 수 있다.

 

* SQL을 사용하기 위해서는 데이터베이스 관리 시스템(DBMS)을 설치하고, 해당 DBMS에 맞는 SQL 프로그램을 선택하여 사용한다.

* 대표적인 DBMS로는 Oracle, MySQL, MS SQL(Microsoft SQL Server) 등이 있으며, 이들 DBMS는 각각의 데이터베이스의 관리, 데이터 조작, 데이터 보안 등 다양한 기능을 제공하고 있어, 사용 목적에 맞게 선택하여 사용해야 한다.

 

 

대표적인 관리 시스템 3가지의 특징
Oracle, My SQL, MS SQL

Oracle
- 대규모 기업용 데이터베이스 시스템
- 유닉스/리눅스 환경에서 가장 많이 사용되는 DBMS
- 안정성과 확장성이 높음

MySQL
- 오픈 소스 기반의 관계형 데이터베이스 관리 시스템
- 빠른 속도와 높은 성능을 지원
- 가벼운 설치와 사용이 가능하며, 웹 애플리케이션과 소규모 비즈니스에 많이 사용됨

MY SQL(Microsoft SQL Server)
- Microsoft가 개발한 관계형 데이터베이스 관리 시스템
- Windows 운영 체제에 친화적인 시스템
- 편리한 관리 도구와 호환성이 높은 특징으로 기업용 솔루션으로 많이 사용됨 

 

 

Error based SQLi
데이터베이스 오류 메시지를 활용하여 데이터베이스에 대한 정보를 획득하는 SQL Injection 기법

  • 잘못된 SQL 문법이나 자료형 불일치 등으로 인해 데이터베이스가 발생시키는 오류 메시지를 이용하여 공격자는 데이터베이스의 구조와 정보를 파악할 수 있다. 
  •  XPath와 Double Query

 

 

XPath
extractvalue() 함수를 활용한 기법으로 MySQL 기준 5.1 버전 이상에서만 가능하다.

extractvalue(xml_frag, xpath_expr)

위와 같이 extractvalue()는 XML(xml_frag 인수)과 XPath 표현식(xpath_expr 인수), 두 개의 인수가 필요

두 개의 인수를 통해 XML에서 XPath 표현식에 일치하는 데이터를 추출하여 반환

 

이 함수는 xpath_expr이라는 두 번째 인수에 유효하지 않은 XPath 표현식이 사용된다면 다음과 같은 오류가 발생한다.

ERROR 1105 (HY000): XPATH syntax error: 'xpath_expr 인수의 값'

 

 

xpath_expr 인수로 임의의 SQL 쿼리를 지정했을 때 이 쿼리의 실행 결과가 오류 메시지에 포함된다.

이 점을 이용해 오류기반 SQLi를 수행할 수 있다.

두 번째 인수가 항상 유효하지 않은 XPath 표현식이 되도록 하기 위해 concat() 함수를 이용해 콜론(:)을 앞에 추가합니다. 0x3a는 콜론의 16진수 표기법입니다.

첫 번째 인수는 임의의 값을 지정하기 위해 rand() 함수를 사용합니다. 

 

그리고 마지막으로 후속 쿼리를 무효화하기 위해 가장 끝에 주석 문자(--)와 공백 문자(스페이스)를 추가한다.

주석 문자 뒤에 공백 문자를 추가하는 것을 잊으면 안 된다. 

AND extractvalue(rand(), concat(0x3a, Excutable-SQL-Query))--

 

 

위의 extractvalue() 함수의 오류 메시지는 단일 행(한 줄)으로 반환되므로 LIMIT을 사용하여 한 번에 하나의 행만 출력될 수 있도록 한다. 계속해서 다음 행의 데이터를 추출하기 위해서는 아래와 같이 반복하여 실행하면 된다.

...LIMIT 0, 1)))--      (SQL 쿼리에서 반환된 레코드셋의 첫번째 행 반환)
...LIMIT 1, 1)))--      (SQL 쿼리에서 반환된 레코드셋의 두번째 행 반환) 
...LIMIT 2, 1)))--      (SQL 쿼리에서 반환된 레코드셋의 세번째 행 반환)
...LIMIT 3, 1)))--      (SQL 쿼리에서 반환된 레코드셋의 네번째 행 반환)
... 생략 ...

 

위의 방식과 유사한 기법으로 updatexml() 함수를 이용할 수도 있다.

기본형은 아래와 같으며 추출하고자 하는 데이터에 따라 "실행할-SQL-쿼리" 부분만 위의 방식대로 변경해주면 된다.

AND updatexml(null, 실행할-SQL-쿼리, null)-- 

 

 

 

 

SQL Injection 관련 문제

 

[WebHack][Webhacking.kr] old-52

http://webhacking.kr:10008/ webhacking.kr:10008 사이트에 들어가면 아래와 같은 화면이 나온다.  admin page를 클릭하면아래와 같은 페이지가 나온다.  전 페이지에서 나와있던 것처럼 guest/guest를 입력하

keemnh.tistory.com

 

 

 

 

문제 풀이

 

파일을 다운받는다.

 

app.py

 

init.sql

MySQL 데이터베이스를 생성하고 사용자 권한을 설정하며, 테이블을 생성하고 데이터를 삽입하는 과정에 대한 SQL 스크립트이다.

이 스크립트를 자세히 살펴보도록 하겠다.

 

- users라는 이름의 데이터베이스가 존재하지 않으면 새로 생성

CREATE DATABASE IF NOT EXISTS `users`;

 

- users 데이터베이스에 대한 모든 권한을 'dbuser'라는 사용자에게 부여

- 이 사용자는 localhost에서 접속하며, 비밀번호는 'dbpass'.

GRANT ALL PRIVILEGES ON users.* TO 'dbuser'@'localhost' IDENTIFIED BY 'dbpass';

 

 

- users 데이터베이스를 활성화하여 이후의 모든 작업이 이 데이터베이스에 대해 실행되도록 설정

USE `users;

 

 

- user라는 테이블을 생성

  • idx 필드는 정수형이며 자동으로 증가(auto_increment)하고 기본 키(primary key)로 설정됨
  • uid 필드는 사용자 ID로 varchar(128) 데이터 형식을 가지며, NULL 값을 허용하지 않음
  • upw 필드는 사용자 비밀번호로 varchar(128) 데이터 형식을 가지며, NULL 값을 허용하지 않음
CREATE TABLE user(
  idx int auto_increment primary key,
  uid varchar(128) not null,
  upw varchar(128) not null
);

 

 

- user 테이블에 세 개의 레코드를 삽입

  • 첫 번째 레코드: uid가 'admin'이고 upw가 'DH{FLAG}'인 사용자가 추가됨
  • 두 번째 레코드: uid가 'guest'이고 upw가 'guest'인 사용자가 추가됨
  • 세 번째 레코드: uid가 'test'이고 upw가 'test'인 사용자가 추가됨

-> admin 유저의 upw를 알아야내야 하는 것 같다.

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

 

 

- 권한 변경 사항을 즉시 적용하여 MySQL 서버가 변경된 권한을 인식하도록 함

FLUSH PRIVILEGES;

 

 

 

run.sh

 

 

 

 

서버를 생성한다.

 

 

그래도 1단계이니.. 혼자 힘으로 해보려고 나름 이런저런 시도들을 해보았으나 아무것도 되지 않았다. 

그래서 질문을 보니 이러한 게 있었고 '에러를 일부러 발생시킨다.' 에 초점을 맞추어 풀어보도록 하겠다.

 

EXTRACTVALUE()를 사용해 user 테이블에서 upw 값을 추출하는 방법이다.

- SQL 인젝션을 이용해 데이터베이스의 응답 에러 메시지에 중요한 정보를 노출시키는 방식

 

 

1' : 이 부분은 user_input처럼 사용자가 입력할 수 있는 값으로, SQL 인젝션 공격에서 기존의 SQL 문을 닫는 역할을 한다. 쿼리가 닫히고 새로운 조건이 추가되도록 만들 수 있다.

 

and extractvalue() :
extractvalue() 함수는 원래 XML 데이터를 추출하는 데 사용되는 함수지만, 여기서는 에러 기반 SQL 인젝션을 유발하는 데 사용된다. 잘못된 XPath를 전달하여 데이터베이스 에러 메시지에 중요한 정보를 출력하게 하는 방식이다.

 

0x3a 
0x3a는 16진수로 : (콜론) 문자에 해당한다. 즉, 에러 메시지를 출력할 때 데이터 앞에 콜론을 붙여서 가독성을 높이기 위한 목적으로 사용된다.

 

concat(0x3a, ...) :
concat() 함수는 여러 문자열을 결합하는 함수이다. 여기서는 0x3a(16진수로 콜론 :에 해당)와 쿼리의 결과를 결합하려고 한다. 에러 메시지에 콜론과 함께 데이터를 출력할 수 있도록 한 것이다.


(SELECT upw FROM user LIMIT 0,1) :
이 서브쿼리는 user 테이블에서 첫 번째 레코드의 upw(비밀번호)를 선택하려고 한다.

  • SELECT upw FROM user LIMIT 0,1:
    user 테이블에서 첫 번째 사용자의 upw 값을 선택한다. LIMIT 0,1은 첫 번째 레코드만 반환하라는 의미이다.
    이 쿼리는 첫 번째 사용자의 비밀번호(upw) 값을 추출한다.

 

1' and extractvalue(1,concat(0x3a,(SELECT upw FROM user LIMIT 0,1)));

 

위와 같이 입력을 하니 Flag 가 잘려서 출력된다.

질문들을 보았을 때 잘린다는 게 꽤 많았는데 나도 피해갈 수 없었나보다..

답변을 보면 xml 내장함수가 에러를 출력할 때 길이 제한을 갖고있기 때문이라고 한다,

 

->  에러 출력시 32글자 제한이 있기에 substr과 같은 함수로 출력되는값을 잘 나누어 값을 얻어낸다.

 

 

1' and extractvalue(1,concat(0x3a,(SELECT substr(upw,29,20) FROM user LIMIT 0,1)));

 

SELECT substr(upw,29,20) FROM user LIMIT 0,1:

  • substr(upw,29,20)는 upw(비밀번호)에서 29번째 문자부터 20자를 추출하려고 한다.
  • 비밀번호 전체를 가져오는 대신, 비밀번호의 일부만 추출한다.
  • 결과: 비밀번호의 일부만 추출할 수 있다.

 

 

 

위의 방법으로 시도했는데 이제는 방화벽 때문인지 사이트에 연결이 되지 않아 질문을 찾아보니 나와 같은 상황의 사람이 있어서 다른 네트워크 이것저것 시도해보았다. 그럼에도 연결되지 않아 혹시나 싶어 시크릿모드로 들어가보니 플래그를 확인할 수 있었다! 아직 1단계도 어떻게 풀어야 하는지 감이 잘 잡히지 않는 걸 보니 한참 더 공부를 많이 해야할 것 같다.. 

 

 

 

 

 

 

연결하면 -> DH{c3968c78840750168774ad951fc98bf788563c4d}

 

 

 

 

[참고]

 

SQL 이란? 정의부터 특징까지 SQL을 사용하는 이유를 알려드립니다! I 이랜서 블로그

데이터 베이스에서 필요한 데이터를 추출하고 분석하는데 사용하는 '데이터 처리 언어 SQL'의 정의부터 특징과 사용하는 이유까지 자세하게 알려 드립니다. I sql, sql developer, sql join, sql 자격증, sq

www.elancer.co.kr

 

 

Error 기반 SQL 인젝션

💡해당 내용은 pentestqym의 내용을 다시 한 번 정리한 내용이며, 모든 저작권은 해당 사이트에게 있습니다. 오류기반 SQLi에 대하여 배워봅시다. Error based SQLi 데이터베이스 오류 메시지를 활용하

dystopia050119.tistory.com

 

'SWLUG > CTF' 카테고리의 다른 글

[CTF/ Dreamhack] weblog-1  (0) 2024.10.30
[WebHack][WebGoat] SQL Injection (intro)  (3) 2024.10.02
[CTF/ Dreamhack] blind sql injection advanced  (0) 2024.09.30
[CTF/ Dreamhack] CProxy: Inject  (0) 2024.09.25
[WebHack][Webhacking.kr] old-52  (1) 2024.09.23