ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Bugbounty Study] #Time-Based Blind SQL Injection
    Study/Bugbounty Study 2021. 1. 9. 18:58
    728x90

    # Time Based Blind SQL Injection _ \$3500

    marxchryz.medium.com/my-bug-bounty-journey-and-my-first-critical-bug-time-based-blind-sql-injection-aa91d8276e41

     

    My Bug Bounty Journey and My First Critical Bug — Time Based Blind SQL Injection

    Hello everyone, I am Marx Chryz and I am new to bug bounty hunting even though I do web penetration testing for more than a year.

    marxchryz.medium.com

    원작자는 처음에 XSS 취약점을 찾았으나, 관리자만 접근할 수 있다는 이유로 낮은 등급을 받았다. 이에 실망하여 같은 프로그램의 다른 XSS를 찾기 위해 노력하였다. 그러다 아래 사이트에서 제목(Referral ID, Type, etc...)을 클릭하면 정렬되는 기능을 발견하였다.

     

    해당 페이지의 제목을 클릭하여 정렬을 실행하면 아래의 URL로 Redirect 된다.

     

    URL?order=type&ordering=ASC&search=

     

    ASC 값은 보통 "SELECT * FROM referrals ORDER BY type ASC"와 같은 SQL 쿼리문에서 사용하는 것이기 때문에 싱글 쿼터(')를 입력하여 SQLi 테스트를 하였더니 500 Error가 발생하였다.

     

    order=type → order=type'

     

    이를 이용하여 Union Based SQL Injection을 시도하였으나 UNION SELECT문은 ORDER BY문 뒤에 오는 것이 불가능하다는 것을 깨달았다. 그래서 Error Based SQL InjectionTime Based SQL Injection으로 접근하였다.

     

    해당 사이트는 어떤 에러 메시지도 없는 빈 페이지와 함께 500이라는 상태만을 반환하기 때문에 Error Based SQL Injection은 불가능하다고 판단하여 Time Based SQL Injection을 시도하였다. 그래서 localhost에서 유효한 몇 개의 MySQL, MSSQL, PostgreSQL 페이로드를 전송하였으나 아무런 반응도 일어나지 않았다.

     

    [ 시도한 delay 함수 ]
    - sleep(10)--
    - benchmark(1000000000, md5(1))--
    - pg_sleep(10)--
    - ; WAITFOR DELAY '00:00:10';--

     

    어떻게 이러한 함수를 사용하지 않고 Time Based SQL Injection을 할 수 있을지 생각하다 아래 페이로드를 이용하여 Boolean Based Blind SQL Injection을 시도하였다.

     

    if(1=1, 1, (select 1 union select 2))

     

    이론적으로 추측한다면,

    if의 조건이 참인 경우는 "SELECT * FROM referrals ORDER BY 1 ASC"로 정상적인 응답인 200을 받아야 하고,

    조건이 거짓인 경우는 "SELECT * FROM referrals ORDER BY (select 1 union select 2) ASC"로

    'subquery returns more than 1 row'라는 에러가 발생하는 쿼리문이기에 500 Error가 발생하여야 한다.

     

    그러나 if(1>2, 1, (select 1 union select 2)) 를 이용하였지만 아무 일도 발생하지 않았다.

     

    하지만 다시 Time Based Blind SQL Injection로 접근하였고,

    이에 시도하는 페이로드를 줄이고자 데이터 베이스의 버전을 알아내기 위해 다음 구문을 이용하였다.

     

    SQL/*!50000 Comments*/
    SQL 서버의 버전이 5.00.00 이상일 경우 주석 내의 페이로드를 실행하는 구문

    /*!50000someInvallidSQLSyntax*/ 를 페이로드로 사용할 경우,
    SQL 서버의 버전이 5.0.0 이상이면 잘못된 SQL 구문이 실행되어 500 Error를 반환하고,
    5.0.0 미만이면 정상적인 페이지를 반환한다.

     

    해당 구문을 이용하여 Bruteforce를 시도하였고, SQL 서버의 버전을 알아냈다.

     

    /*!50731someInvalidSQLSyntax*/  →  Error 500
    /*!50732someInvalidSQLSyntax*/  →  Success 200

    => SQL Sever Version: 5.07.31

     

    버전을 통해 아래의 페이로드를 알아냈고, 응답이 지연되는 것도 확인하였다.

     

    (select*from(select(sleep(10)))a)

     

    혹시 네트워크의 문제로 지연된 것일까 봐 30초를 지연시켜 보았더니 여전히 잘 작동하였다.

     

     

    [취약점에서 배울 점]

    1. 포기하지 않고 여러 가지 시도를 하다 보면 좋은 결과를 얻을 수 있다.

    2. 원글을 보면 원작자 또한 실력이 부족하다고 생각하여 버그바운티를 시도하지 않았으나, 루트콘을 계기로 어떤 취약점이 발생하는 지에 대해 공부한 후, 버그바운티를 시작하였고 결국 XSS뿐만 아니라 SQL Injection도 찾았다. 이를 통해 버그바운티는 우선 시도하는 것, 끈기 있게 찾아보는 것이 중요하다는 것을 깨달을 수 있었다.

    반응형

    댓글 2

    • 프로필사진

      안녕하세요! 궁금한게 있습니다.

      select(sleep(10)))a 에서 저 a는 어떤 걸로 쓰이는건가요? 왜 쓰이는지 잘 모르겠어서 ㅠ

      2021.06.25 12:33 신고
      • 프로필사진

        안녕하세요! 댓글을 이제 봐서 답이 늦었습니다.

        공격 구문 전체에서 "select(sleep(10))a" 부분은 테이블 명을 의미하는 구문입니다.
        이때 a를 넣지 않으면, 전체 구문에서 테이블 명에 아무런 값이 들어가지 않게 되어 에러가 납니다.
        따라서, 전체 구문이 에러가 나지 않도록 정상적인 구문을 만들어 주어야 sleep함수가 제대로 실행되는지 확인할 수 있기 때문에 해당 취약점을 트리거할 때 테이블 명으로 아무 값인 'a'를 넣어준 것으로 생각됩니다.

        mysql에서 실행해보면 아래와 같이 결과가 나옵니다.
        select*from(select(sleep(10))); //에러
        select*from(select(sleep(10)))a; //10초 딜레이 후 결과 값 출력

        2021.06.27 16:22 신고
@Jo Grini's Blog