특징

  • DB와 연동된 웹 애플리케이션에서 공격자가 삽입한 SQL 구문이 필터링, 이스케이프 되지 않고 DB를 조작할 수 있는 취약점
  • 클라이언트 측에서 입력된 신뢰할 수 없는 데이터가 SQL 쿼리 로직의 일부로 해석되어 DB에서 실행되는 공격

DVWA 실습

  • ID를 입력하면 해당 id 에 해당하는 이름을 출력

  • SQL Injectiond을 위해 or 뒤에 추가적인 조건을 입력하여 쿼리를 출력
  • 1’ or ‘1’=‘1을 입력하면 Id가 1인 것과 참이되는 모든 값을 출력

  • Where 절 뒤에 order by 사용 가능한 것을 이용하여 공격
  • Column이 두개인 것을 확인
  • 여기서 알게된 정보를 통해 union 구문공격에 이용

  • Column 정보를 활용하여 추가 DB정보 탈취

  • MY SQL에는 information_schema 라는 DB에서 이름 테이블 칼럼 정보를 관리
  • Information_schema 의 schemata 테이블로 부터  schema name을 가져오는 쿼리문을 이용하여 
    DB 이름확인

  • DB 이름을 활용하여 테이블 이름 확인

  • DB와 테이블을 활용하여 column 명까지 확인
  • 계정정보가 담겨 있을 것으로 추정되는 user와 password column 확인 가능

  • Column 을 통해 얻은 정보로 아이디와 패스워드에 접근
  • MD5 복호화
  • SQL Injection 을 통해 모든 아이디와 패스워드 탈취

소스코드 분석

<?php
if( isset( $_REQUEST[ 'Submit' ] ) ) {
    // Get input
    $id = $_REQUEST[ 'id' ];

    switch( $DVWA[ 'SQLI_DB' ] ) {
        case 'MySQL':
            // Check database
            $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
            $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );

            // Get results
            while( $row = mysqli_fetch_assoc( $result ) ) {
                // Get values
                $first = $row['first_name'];
                $last  = $row['last_name'];

                // Feedback for end user
                echo "<pre>ID: {$id}<br/>First name: {$first}<br />Surname: {$last}</pre>";
            }

            mysqli_close($GLOBALS["___mysqli_ston"]);
        break;

        case 'SQLite':
            global $sqlite_db_connection;

            //$sqlite_db_connection = new SQLite3($DVWA['SQLITE_DB']);
            //$sqlite_db_connection->enableExceptions(true);

            $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
            //$print $query;
            try {
                $results = $sqlite_db_connection->query($query);
            } catch (Exception $e) {
                echo "Caught exception: " . $e->getMessage();
                exit(1);
            }

            if ($results) {
                while ($row = $results->fetchArray()) {
                    // Get values
                    $first = $row['first_name'];
                    $last  = $row['last_name'];

                    // Feedback for end user
                    echo "<pre>ID: {$id}<br/>First name: {$first}<br />Surname: {$last}</pre>";
                }
            } else {
                echo "Error in fetch: ".$sqlite_db->lastErrorMsg();
            }
        break;
    }
}
?>
  1. 직접적인 사용자 입력 값 사용:
    $id 값이 사용자 입력을 통해 그대로 SQL 쿼리에 사용
  2. SQL 에러 메시지 노출:
    die() 함수로 인해 SQL 에러 메시지가 사용자에게 직접 노출 되어 시스템의 구조나 데이터베이스 스키마에 대한 중요한 정보 노출
  3. Prepared Statements미사용:
    SQL 쿼리를 직접 작성하며, 사용자의 입력 값이 바로 쿼리 내에 삽입되어 공격자가 SQL 구문을 삽입가능

대응방안

  1. Prepared Statements 사용:
    SQL 쿼리와 데이터를 분리하여 처리하는 방법인 Prepared Statements를 사용하여 데이터가 SQL 문법으로 해석되지 않도록 처리
  2. SQL 에러 정보 숨기기:
    에러 메시지를 사용자에게 직접 노출하지 말고, 시스템 로그 등에 기록하여 내부적으로만 관리
  3. 입력값 검증:
    입력 값이 숫자일 경우, 숫자인지 확인하는 등의 추가적인 검증을 통해 기본적인 보안 수준 증가

'CERT' 카테고리의 다른 글

웹 모의해킹: SQL Injection(Blind)  (2) 2024.10.05
웹 모의해킹: Reflected XSS  (0) 2024.10.05
웹 모의해킹: Stored XSS  (0) 2024.10.05
웹 모의해킹: DOM Based XSS  (2) 2024.10.05
웹 모의해킹: Weak Session IDs  (2) 2024.10.05

+ Recent posts