보안 전공생의 공부

Lord of SQL Injection#7 orge | Blind SQL Injection 본문

카테고리 없음

Lord of SQL Injection#7 orge | Blind SQL Injection

수잉 2021. 1. 15. 11:08

◆ Blind SQL Injection

서버에서 내부 오류 메시지를 외부에 공개되지 않도록 구성한 경우

Type 변환 오류 메시지를 사용한 Database구조 파악이 불가능

substring(문자열, 시작위치, 길이) 문자열의 특정 문자열을 한 글자씩 찾아가는 Blind SQL Injection 공격 시도

Query 결과에 따른 서버의 참/거짓 반응을 통해 공격을 수행한다.

(Target 사이트에서 참/거짓을 구분지을 수 있는 페이지가 존재해야함)

이를 통해 db명, 테이블명, 컬럼명 ID, PW 등을 알아낼 수 있다.

(출처 : https://peemangit.tistory.com/151 )


우선 눈에 보이는 것은

pw를 입력할 때 or이나 and를 사용하지 말라는 것이다.

||,%7c%7c&&,%26%26로 필터링 하면 된다.

정답을 해결하기 위해서는

입력받은 pw값과 db에 있는 pw값이 일치해야한다 !

(입력받은 pw는 id가 admin일 때의 pw )

이는 전에 풀었던 #4 문제와 비슷한 유형이다.

Blind SQL Injection을 이용해 db에 있는 pw에 대해 아무 힌트가 없는 채로 추정해나가야한다.

우선 참/거짓을 확인할 수 있는 출력문이 있는지 확인해보아야한다.

?pw='||1=1%23 을 입력하면

이 쿼리문은 참이고

이때, Hello guest를 출력한다.

이와 비교하여

?pw='||1!=1%23 을 입력하면

이 쿼리문은 거짓이고

아무것도 출력되지 않는다 !

Hello {사용자 id} ! 문구 출력 유무에 따라 참/거짓을 판단할 수 있게 되었다.

Hello admin 이 출력되는 것이면 참,

Hello guest 이 출력되거나 아무것도 출력되지 않는다면 거짓이라고 판별한다.

내가 입력하는 pw는 id가 admin이므로, pw에 대해 입력한 조건이 맞다면 id는 admin으로 인식될 것이기 때문이다.

( id='guest' and pw=' '는 pw가 공백이기 때문에 거짓임)

pw에 대해 알아야할점은 우선적으로 문자열의 길이이다 !

이는 length함수를 이용하면 된다.

?pw='||length(pw)=1%23

1 자리에 2,3,4,… 를 바꿔 넣어보며 query문이 참이 되도록 만든다.

하다보면 길이가 8일 떄 문구가 출력되며 참임을 알 수 있다.

pw의 길이가 8자리인 것을 알았고, 각 글자가 무엇인지 찾아나가야한다.

​​

ascii함수와 substr함수를 이용해 첫 글자부터 유추해나가야 한다

ascii()는 괄호 안에 입력하는 문자나 문자열에 대해 그에 해당하는 아스키코드 값을 반환한다. (0~9 : 48 - 57, A~Z : 65 - 91 , a~z : 97 - 172 )

substr( string, start [], length )는 문자열 string에 대해 start위치에서부터 length만큼 문자를 추출한다. length 값이 주어지지 않으면 문자열의 끝까지 추출한다.

<첫번째 글자>

첫번째 글자부터 추정해나간다.

문자인지 숫자인지부터 찾아내보려고 한다

ascii(substr(pw,1,1)) < 65

참이므로 숫자임을 알 수 있다.

이제 어떤 숫자인지 맞춰나갈 것이다.

ascii(substr(pw,1,1)) < 57 (57은 9이다) 부터

ascii(substr(pw,1,1)) < 48 (48은 0이다) 까지 줄여나가야한다.

도중에 거짓이 된다면 값을 찾아낼 수 있을 것이다.

ascii(substr(pw,1,1)) < 55부터 거짓이 되었다.

이로써 첫 번째 글자는 아스키코드 값이 55인 7임을 알 수 있다 !

이런 방식으로 마지막 글자까지 찾아내면 된다.

<두번째 글자>

아스키코드값 98 = b

<세번째 글자>​

아스키코드값 55 = 7

<네번째 글자>

아스키코드값 53 = 5

<다섯번째 글자>​

아스키코드값 49 =1

<여섯번째 글자>

아스키코드값 97 = a

<일곱번째 글자> 크기비교(<,>)로 추정하는데 계속 Hello guest가 출력되어서 한참 애를 먹었다. =으로 고쳐서 추정해나가니 Hello admin이 출력되었다. 크기비교를 했을 때 해당되는 pw가 id가 guest일 때의 pw에게도 참이어서 그런 것 같다. 여섯번째 글자까지는 운좋게 Hello admin만 출력된 것인것 같다. >,<보다 =이 더 정확하다는 걸 느꼈다.

아스키코드값 101 = e

<여덟번째 글자>

아스키코드값 99 = c

이렇게 해서 pw = 7b751aec 임을 알아내었다 !!

인증에 성공하였다 :)


#4와 문제유형이 비슷해서 내 손으로 직접 풀 수 있었다 !

다만 글자를 추정해가는데 문제가 생겨서 이는 구글링을 통해 해결하였다.

Comments