특징

  • 쿼리의 결과를 참 또는 거짓으로만 출력하는 페이지에서 사용할 수 있는 SQL Injection공격 기법
  • DB의 내용을 추측하는 공격 방식
  • 많은 경우의 수를 대입하여 공격을 수행하기 때문에 자동화 도구를 이용하여 공격을 수행

DVWA 실습

security level low 에서 진행

  • ID 입력란에 ID를 입력하면 계정의 유무를 판단해주는 기능이 있는 웹페이지
  • 위의 웹페이지를 통해 SQL에서 계정정보 탈취 시도

  • 왼쪽은 1’ and sleep(5)# 입력시 응답시간
  • 오른쪽은 6’ and sleep(5)# 입력시 응답시간
  • 응답시간 차이를 통해서도 참과 거짓을 구분 

  • 모든 값을 직접 대입해서 참/거짓을 판단해야하기 때문에 SQLmap이라는 자동화 프로그램 이용
  • IP 주소와 URL 을 입력하여 자동화 공격 실행
  • 첫번째 공격

  • Blind 공격 판단하고 실행
  • 첫번째 공격으로 Database 이름 확인

  • 두번째 공격
  • 위에서 알아낸 DB을 사용하여 테이블 명 확인

  • 앞의 공격에서 알아낸 DB와 테이블 이름을 가지고 모든 경우의 수를 분석
  • DB에 존재하는 모든 아이디와 비밀번호를 탈취

소스코드 분석

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

    switch ($DVWA['SQLI_DB']) {
        case 'MySQL':
            // Check database
            $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
            try {
                $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); // Removed 'or die' to suppress mysql errors
            } catch (Exception $e) {
                print "There was an error.";
                exit;
            }

            $exists = false;
            if ($result !== false) {
                try {
                    $exists = (mysqli_num_rows($result) > 0);
                } catch (Exception $e) {
                    $exists = false;
                }
            }

            ((is_null($__mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $__mysqli_res);
            break;

        case 'SQLite':
            global $sqlite_db_connection;

            $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
            try {
                $results = $sqlite_db_connection->query($query);
                $row = $results->fetchArray();
                $exists = $row !== false;
            } catch (Exception $e) {
                $exists = false;
            }
            break;
    }

    if ($exists) {
        // Feedback for end user
        echo "<pre>User ID exists in the database.</pre>";
    } else {
        // User wasn't found, so the page wasn't!
        header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');

        // Feedback for end user
        echo "<pre>User ID is MISSING from the database.</pre>";
    }
}
?>
  1. 직접적인 사용자 입력 값 사용:
    $id 값이 사용자 입력을 통해 그대로 SQL 쿼리에 사용
  2. SQL 에러 메시지 노출:
    SQL 에러 메시지가 사용자에게 직접 노출 되어 시스템의 구조나 데이터베이스 스키마에 대한 중요한 정보 노출

대응방안

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

'CERT' 카테고리의 다른 글

웹 모의해킹: SQL Injection  (1) 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