constWORLDant

prob2 하기 전 공부한 것 2 본문

0x09 WEB Hacking 기초공부

prob2 하기 전 공부한 것 2

data type ConS_tanT 2018.07.26 10:53

post 방식 일 때는 어떻게 SQL Injection을 해야 하는지 검색해보니 Blind SQL Injection이라는 기법이 있었다.


★ Blind SQL Injection ★

정의는 SQL Injection의 결과를 이용하여 참, 거짓 값을 구별할 수 있을 때 사용할 수 있는 방법 


Blind SQL Injection 할 때 알아야 하는 사항 


[1] substr 함수 

정의 : 문자열과 자를 문자열의 범위를 파라미터로 받아서 해당 부분의 문자열을 리턴해주는 함수.


example. substr("string",자르기 시작할 문자의 인덱스, 자를 문자 갯수)


USER 테이블에 ID,PW 필드(Column)가 존재하면서, ID는 c0nstant

PW는 hacker라는 것이 미리 세팅 되어있다고 가정해둡니다.


해커는 c0nstant유저의 PW를 현재 모릅니다.

이때 substr를 사용해서 슬쩍슬쩍 하나씩 가져오는 시나리오를 만들 수가 있습니다.


이 시나리오는 3단계로 나눌 수 있습니다.


1단계) 쿼리를 하나 실행한다. 

select PW from USER WHERE id='c0nstant'

해석하자면, USER 테이블의 id 칼럼에서 c0nstant를 찾은 후 c0nstant의 PW를 

출력하라고 된다.


2단계) 출력 된 문자열을 "한 바이트 씩" 가져올 수 있다.

substr('hacker',1,1) 


3단계) 출력 된 'h'를 아스키 코드로 반환 시킨다.

완벽한 시나리오다. 하지만 1단계에서 출력이 다 되는데 굳이 substr을 할 필요가 없다고 생각할 수 있다. 지금부터 그 생각을 깨보는 시간을 갖도록 해보자.


만약, 자신이 해커가 되어 상대방의 계정 정보를 탈취하고 싶을 때 DB의 정보를 모르고 있기 때문에 substr('특정 패스워드',1,1)에서 첫 번째 매개변수인 특정 패스워드를 

절대 알 수가 없다.


지극히 기본적인 개념이지만 정확하게 이해해야 한다.


이전 까지의 sql injection은 그냥 쿼리를 삽입 후 데이터를 얻고 싶은걸 얻는 것이었다. Blind SQL Injection은 'Blind' 라는 이름에 걸맞게 결과를 추출 할 수가 없다.

그렇기 때문에 참/거짓 이라는 '조건'을 통해 데이터를 얻어낼 수 있다.


내가 substr로 보내는 값은 브루트포싱으로 만들 것이고, 실제 서버에 있는 값의 한 바이트와 비교를 하는 프로그램을 만들어야 이 문제를 해결할 수 있다.


기본지식에 참고한 문서는 다음과 같다.

"http://www.hackerschool.org/HS_Boards/data/Lib_share/The_basic_of_Blind_SQL_Injection_PRIDE.pdf"


데이터베이스의 여러 정보가 들어있는 곳이 있는데 그것은 "information_schema"이다.

db의 모든 테이블 && 컬럼 정보가 들어있다. 

만약, 모든 정보를 탈취하고 싶으면 information_schema를 건들면 되지 않을까..

(하지만, webhacking.kr의 information_schema는 건들 수가 없다)


그 중에서 TABLES, COLUMNS 테이블이 중요하다고 한다.

이는 각 DB의 모든 테이블, 컬럼 정보를 가지고 있기 때문이다.


이 문서를 보고 나서 시나리오는 추가 되었다.


1단계) 쿼리를 하나 실행한다. 

select PW from USER WHERE id='c0nstant'

해석하자면, USER 테이블의 id 칼럼에서 c0nstant를 찾은 후 c0nstant의 PW를 

출력하라.


2단계) 출력 된 문자열을 "한 바이트 씩" 가져올 수 있다.

substr('hacker',1,1) 


3단계) 출력 된 'h'를 아스키 코드로 반환 시킨다.


4단계) 출력 된 문자가 무엇인지 해커 입장에서는 모르기 때문에 임의로 범위를 지정해둔뒤

그 범위에서 마치 술게임 업 다운을 하듯이 맞추어 가야 한다.


5단계) 서버에서 참인 데이터, 거짓인 데이터를 전송받았을 때 어떤 결과가 출력되는지 

분석. 


이는 리버싱을 할 때도 종종 도움이 된다. 참일 때, 거짓일 때 나오는 출력문이 다르기 때문이다.


만약, 내가 입력 한 결과가 'Z'미만 일 때 성공하게 되면 첫 번째 바이트의 범위는

data < '5a' 가 되는 것이다. 

예시에 사용 될 테이블은 user, 칼럼은 id,passwd id의 데이터는 admin이다.


예시를 직접 테스트할 환경은 아직 만들지 않은 상태라 슈도코드로 작성해보면서 원리를 이해해보았다. 


예시1. 첫 번째 바이트를 알아내어라! 


예시1-1. admin' and ascii(substr((select id from user where table_type='user' limit 0,1),1,1)) < 90#


이때, 로그인에 성공하게 되면 첫 바이트는 90보다 작을 때 참이라는 뜻이 된다.



그럼 첫 바이트는 0x5a(90) 이상은 아니기에 한번 걸러진다. 


그 후 이진 탐색처럼 중간 값을 다시 서버로 보내면서 아스키코드로 반환시켜 둔다.


예시1-2. 

admin' and ascii(substr((select id from user where table_type='user' limit 0,1),1,1)) < 45#


이때도 참이 되면 첫 바이트는 45보다 작은 값이 되는 것이고

이때 거짓이 되면 첫 바이트는 45 > x < 90이 되는 것이다.


항상 조건이 2개로 분기된다고 생각을 하고 로직을 짜야한다.

그러다가 참->거짓 이 되버리는 조건을 보면 과감하게 소거 하고 

참 -> 참 -> 참 -> .... -> 참 이렇게 되는 놈을 만날 때 까지 반복 수행해야 한다.


위에 적은 예시 hacker로 하고 있다고 가정하고 예시1을 재 설명해보면 

어찌 어찌 하다가 h를 얻게 되면, 이제 substr의 2번째인자의 카운트+1 하여 

또 다시 긴 여정을 떠나게 된다.


c언어에서와 마찬가지로 php에서 혹은 DB에서의 문자열도 마지막은 \x00이기 때문에

\x00을 만나게 되면 프로그램을 종료하고 이때 까지 획득한 문자를 이어 붙여버리면 

비로소 패스워드가 완성되어 계정 탈취에 성공하게 된다.



'0x09 WEB Hacking 기초공부' 카테고리의 다른 글

prob2 하기 전 공부한 것 2  (0) 2018.07.26
prob2 하기 전 공부한 것  (0) 2018.07.26
prob1  (0) 2018.07.26
Webhacking.kr 회원가입  (0) 2018.07.25
0 Comments
댓글쓰기 폼