SQLi

강혜인·2025년 5월 29일

WEB_Hack

목록 보기
4/18

SQL Injection(SQLi)는 웹 애플리케이션의 보안 취약점 중 하나로, 공격자가 악의적인 SQL 쿼리를 입력해 데이터베이스를 조작하거나 불법적으로 접근할 수 있도록 만드는 공격 기법이다.

→ 웹 애플리케이션이 사용자 입력을 제대로 검증하지 않을 때 발생한다.


SQLi로 할 수 있는 것

  • 데이터 유출
    • 공격자는 데이터베이스에서 비밀번호, 신용카드 정보, 사용자 개인 정보 등 민감한 데이터를 추출할 수 있다.
  • 데이터 변조
    • 데이터베이스의 내용을 수정해 사용자가 접근하는 데이터를 변조할 수 있다.
  • 관리자 권한 탈취
    • 시스템의 관리자 권한을 탈취해 전체 데이터베이스를 제어할 수 있다.
  • 데이터베이스 서버의 기능 악용
    • 데이터베이스 서버의 파일 시스템에 접근하거나, OS 명령어를 실행하는 등의 행위를 할 수 있다.
  • 서비스 거부(DoS) 공격
    • 악의적인 쿼리를 통해 서버의 자원을 소모하게 해 서비스를 중단시킬 수 있다.

SQLi의 파급력

SQLi로 인해 민감한 데이터가 유출되면 개인 혹은 기업에 심각한 피해를 줄 수 있고, 공격자가 시스템을 완전히 장악할 수 있게 되며, 데이터베이스가 변조되면 서비스의 신뢰성이 손상되어 브랜드 이미지에 큰 타격을 줄 수 있다.


SQLi 종류

  • In-band SQLi
    • Error-based SQLi : 오류 메시지를 활용해 데이터베이스의 구조와 관련된 정보를 알아내는 방법
    • Union-based SQLi : 여러 SELECT 쿼리의 결과를 결합해 데이터베이스의 다른 정보를 추출하는 방법
  • Inferential SQLi(Blind SQLi)
    • Boolean-based Blind SQLi : 쿼리의 참/거짓 결과를 이용해 데이터를 추출하는 방법
    • Time-based Blind SQLi : 서버의 응답 시간 차이를 이용해 데이터를 추출하는 방법
  • Out-of-band SQLi : SQLi가 직접적인 서버 응답을 요구하지 않는 경우, DNS 요청 등을 통해 데이터를 수신하는 방법

SQLi 특징

  • 취약점 존재 → 보통 사용자 입력값을 SQL 쿼리에 삽입하는 과정에서 발생하며, 이는 주로 입력값을 제대로 필터링 하지 않거나 파라미터화 되지않은 SQL 쿼리에서 발생한다.
  • 쉬운 접근성 → SQLi 공격은 인터넷에 공개된 웹 애플리케이션을 대상으로 쉽게 시도할 수 있으며, 특정 기술 지식만으로도 공격이 가능하다.
  • 광범위한 영향 → 모든 SQL 데이터베이스 시스템에서 발생할 수 있고, 다양한 프로그래밍 언어와 프레임워크에서 나타날 수 있다.

기본적인 SOLi 공격 스크립트

  • 단일 인젝션
    • 단순히 SQL 쿼리를 조작해 사용자 인증을 우회하거나 데이터를 유출하는 것

    • 로그인 폼이 있을 때, 아래와 같은 입력을 사용해 공격이 가능하다.

      ' OR '1'='1';
      -> SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';
      -> '1'='1' 은 항상 참이므로, 데이터베이스는 모든 사용자를 선택할 수 있다.
  • 주석을 이용한 공격
    • 쿼리의 일부를 무시하고 나머지 부분을 조작해 원하는 결과를 얻는 것

    • 로그인 폼에서 아래와 같은 입력을 사용할 수 있다.

      ' OR '1'='1' --;
      -> ' -- ' 는 SQL에서 주석을 나타내므로 이후의 쿼리는 무시된다.
      -> 이 입력은 비밀번호 검증 부분을 무시해 인증을 우회 할 수 있다.

Union-based SQLi

  • Union Select 사용
    • 데이터베이스의 다른 테이블이나 컬럼에서 데이터를 유출하는 것

      ' UNION SELECT null, username, password FROM users --;
      -> 이 입력은 쿼리 결과와 함께 'users' 테이블의 'username'과 'password'를 가져온다.
      -> 이 스크립트는 취약한 애플리케이션이 쿼리 결과를 화면에 출력할 때 유용하다.

Blind SQLi(Boolean-based)

  • 참/거짓을 이용한 데이터 추출
    • 데이터베이스의 구조나 특정 데이터를 추출하기 위해 참/거짓 결과를 반복적으로 확인하는 것

      ' AND (SELECT SUBSTRING(version(), 1, 1)) = '5' -- ;
      -> 이 스크립트는 데이터베이스 버전이 5로 시작하는지 확인한다.
      -> 응답이 달라진다면, 이를 통해 데이터베이스 버전을 추론할 수 있다.

Time-based Blind SQLi

  • 조건이 참일 때 서버 지연
    • 서버의 응답 시간을 이용해 데이터베이스의 정보를 추출하는 것

      ' AND IF((SELECT DATABASE()) + 'mydb', SLEEP(5), 0) -- ;
      -> 만약 데이터베이스의 이름이 'mydb'라면, 서버는 5초동안 지연된다.
      -> 응답 시간의 차이를 통해 조건의 참/거짓을 확인할 수 있다.

Error-based SQLi

  • 오류 메시지에서 정보 추출
    • 데이터베이스의 구조를 오류 메시지를 통해 추출하는 것

      ' OR 1-1 ORDER BY 100 -- ;
      -> 'ORDER BY 100'은 실제 존재하지 않는 컬럼을 참조해 오류를 발생시킨다.
      -> 오류 메시지를 통해 테이블의 컬럼 개숟 등을 알아낼 수 있다.

Data Extraction

  • 특정 테이블의 데이터 추출
    • 특정 테이블의 데이터를 직접 추출하는 것

      ' UNION SELECT 1, table_name FROM information_schema.tables WHERE table_schema=DATABASE() -- ;
      -> 'inforamtion_schema.tables' 에서 현재 데이터베이스의 모든 테이블 이름을 가져온다.
      -> 이후 이 정보를 기반으로 추가적 공격을 행할 수 있다.

Database Fingerprinting

  • 데이터베이스 버전 확인
    • 사용 중인 데이터베이스의 버전을 확인해 추가적인 공격 전략을 계획할 수 있다.

      ' UNION SELECT null, null, @@version -- ;
      -> '@@version'은 데이터베이스의 버전을 반환한다.
      -> 공격자는 버전 정보를 바탕으로 취약한 기능이나 설정을 찾아낼 수 있다.

Bypassing Authentication

  • 로그인 우회
    • 사용자 인증을 우회해 시스템에 무단 접근하는 것

      admin' --
      -> 로그인 폼에 'admin' -- '를 입력하면, 'admin' 계정으로 로그인할 수 있다.

SQLi의 동작 원리

→ 웹 애플리케이션이 데이터베이스와 상호작용 하는 방식에서 비롯된 취약점을 악용하는 것이다. 즉, 애플리케이션이 사용자로부터 입력 받은 데이터를 SQL 쿼리의 일부로 사용하면서, 그 입력 데이터를 제대로 검증하지 않으면 발생한다.

  1. 사용자의 입력과 SQL 쿼리의 상호작용

    • 웹 애플리케이션은 일반적으로 사용자로부터 입력을 받아 이 데이터를 바탕으로 SQL 쿼리를 생성한다.
    SELECT * FROM users WHERE username = '사용자 입력' AND password = '사용자 입력';
  2. 쿼리의 취약점

    • 만약 애플리케이션이 사용자의 입력을 검증하거나 처리하지 않고 그대로 SQL 쿼리에 삽입하면, 공격자가 입력 데이터에 SQL 문법을 포함해 의도하지 않은 쿼리를 실행하게 할 수 있다.
    SELECT * FROM users WHERE username = 'admin' -- 'AND password = '비밀번호';

    → ‘--’ 이후의 내용은 주석 처리 되기 때문에, 비밀번호 조건이 무시되고, 데이터베이스는 사용자 이름이 ‘admin’인 계정을 반환한다.

  3. 쿼리 조작

    • 공격자는 SQL 쿼리의 일부를 조작해 데이터베이스에서 정보를 유출하거나 데이터를 수정할 수 있다.
    ' OR '1'='1'
    -> SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';

    → ‘1’=’1’는 항상 참이므로, 쿼리는 조건을 무시하고 모든 사용자 정보를 반환한다.

  4. 결과 및 피해

    • 이러한 조작을 통해 공격자는 데이터베이스의 구조를 탐색하고, 민감한 데이터를 추출하거나 시스템에 대한 제어권을 탈취할 수 있다.
    • 나아가 데이터베이스 서버에 대한 완전한 접근 권한을 얻어 파일 시스템을 조작하거나, 데이터베이스 관리자의 권한 탈취가 가능하다.

SQLi 공격 포인트

공격자는 애플리케이션이 SQL 쿼리를 처리하는 모든 지점을 목표로 삼을 수 있으며, 주로 사용자 입력이 데이터베이스와 상호작용 하는 부분이 공격의 초점이 된다.

  • 로그인 폼 공격 포인트 : 사용자 이름(username)과 비밀번호(password)를 입력받는 필드
    ' OR '1'='1' --
    -> 모든 로그인 조건을 무력화해 인증 절차를 우회한다.
  • 검색 필드 공격 포인트 : 사용자가 특정 조건으로 데이터를 검색할 때 사용하는 입력 필드
    ' UNION SELECT null, username, password FROM users --
    -> 검색 결과와 함께 데이터베이스의 다른 데이터를 결합해 출력이 가능하다.
  • URL 파라미터 공격 포인트 : URL에서 쿼리 문자열로 전달되는 파라미터
    http://example.com/item?id=1' OR '1'='1
    -> SQL 쿼리에서 'id' 파라미터를 통해 SQLi 공격을 시도한다.
  • 쿠키 공격 포인트 : 웹 브라우저에 저장된 쿠키 데이터 → 쿠키 값으로 ‘admin’ --’을 설정하면, 애플리케이션이 쿠키를 SQL 쿼리의 일부로 사용할 때 공격이 발생할 수 있다.
  • HTTP 헤더 공격 포인트 : HTTP 요청 헤더(’User-Agent’, ‘Referer’ 등)
    User-Agent: 'OR '1'='1
    -> 애플리케이션이 'User-Agent' 헤더를 SQL 쿼리에 포함시킬 때 
    문제를 발생시킬 수 있다.
  • 폼 데이터 공격 포인트 : 웹 폼을 통해 전송되는 데이터(POST 요청)
    <input type="text" name="name" value="' OR '1'='1">
    -> SQLi 공격 유도 가능
  • XML 또는 JSON 기반 API 공격 포인트 : XML 또는 JSON 데이터를 사용하는 API 엔드포인트
    {"name": "' OR '1'='1"}
    -> SQLi 유도 가능
  • 파일 업로드 및 파일 이름 처리 공격 포인트 : 파일 업로드 기능에서 파일 이름을 처리하는 부분 → 파일 이름을 ‘test.php’ OR ‘1’=’1’로 설정해 파일 업로드 요청을 보내는 경우 SQLi 유도 가능
  • 레거시 코드 및 관리 인터페이스 공격 포인트 : 오래된 코드나 관리자용 인터페이스
  • 이메일 주소나 기타 식별자 입력 필드 공격 포인트 : 이메일 주소, 사용자 ID, 주문 번호 등으로 검색하는 기능 → 데이터베이스 쿼리에서 자주 사용되며, 입력이 필터링 되지 않으면 SQLi의 대상이 될 수 있다.

0개의 댓글