TigerDemon

SQL Injection 정의 및 공격 기법 본문

2025-SWLUG/웹해킹

SQL Injection 정의 및 공격 기법

호랑2D 2025. 9. 24. 00:30

SQL Injection

  • 대표적인 웹 취약점으로 이 취약점을 통해 공격자가 일반적이지 않은 데이터를 검색해서 볼 수 있게한다.
  • 대부분은 수정, 삭제, 어플리케이션 콘텐츠와 행동에 지속적인 변화를 일으킨다. 

* SQL - 구조적 쿼리 언어(Structured Query Language)

데이터베이스 시스템과 상호 작용하여 데이터를 쿼리하고, 데이터베이스 스키마를 생성하거나 수정하며, 데이터에 대한 접근 권한을 관리하는 등 다양한 작업을 수행한다. 

* Injection - 주입하다

 

SQL Injection 공격 기법

1. 숨겨진 데이터 가져오기 - sql 쿼리를 수정하여 추가적인 결과를 반환하게 만드는 것

시나리오A

취약한 쿼리

SELECT id, name, price
FROM products
WHERE category = '$categoty' AND is_hiddenn = 0;

- 개발자의 목표 : 숨겨진 목록은 볼 수 없게 하고 카테고리 안에서 상품들을 가져와 그 id, name, price를 띄우는 것

- 의미 : 카테고리 목록에 속하면서 (AND) 숨겨지지 않은 상품만 가져와라

 

공격 입력

$category = electronics' OR 1=1 --

위와 같이 공격하게 되면 개발자가 원래 의도했던 숨겨진 목록 부분이 주석 처리되면서 숨기려고 했던 의도와는 다르게 --로 뒤를 주석처리 -> is_hidden = 0 조건이 무력화되어 숨겨진 상품까지 노출되게 된다.

 

결과

SELECT id, name, price
FROM products
WHERE category = 'electronics' OR 1=1 --' AND is_hiddenn = 0;

- 싱글 쿼터 '로 문자열을 닫아버린 뒤, OR 1=1 이라는 항상 참인 조건을 추가하고, --를 통해서 뒤에 내용을 주석 처리하게 되면서 'is_hidden=0' 조건은 무시되게 된다.

- 이렇게 되면 항상 참인 조건이 생기게 되면서 카테고리 조건도 무시하게 되는 것(카테고리 구분 X)

 

시나리오B

https://insecure-website.com/products?category=Gifts

- 어떤 쇼핑 애플리케이션이 있고, 사용자가 'Gifts' 카테고리를 클릭하면 브라우저는 다음 URL을 요청

- 이때 애플리케이션은 DB에 다음 SQL 쿼리를 보냄

SELECT * FROM products WHERE category ='Gifts' AND released = 1

- products 테이블에서 categoty가 Gifts이고, released 값이 1(공개된 상품)인 데이터만 가져오도록 설계

(released=0은 미공개 상품)

 

공격 1) 주석 처리 이용

https://insecure-website.com/products?category=Gifts'--

- 공격자가 위와 같이 입력하면 아래와 같이 실행됨

SELECT * FROM products WHERE category ='Gifts'--' AND released = 1

- '--' 이후는 주석 처리됨 -> 'AND released=1'조건이 무시되며 미공개 상품까지 포함한 모든 Gifts 상품이 다 노출됨

 

공격 2) OR 조건 이용

https://insecure-website.com/products?category=Gifts'+OR+1=1--

- 공격자가 위와 같이 입력하면 아래와 같이 실행됨

SELECT * FROM products WHERE category ='Gifts' OR 1=1--' AND released = 1

- 'OR 1=1' -> 항상 참이기에 카테고리가 'Gifts'이든 아니든 상관없이 모든 상품이 다 출력됨.

 

주의

- 'OR 1=1' 같은 구문은 SELECT 문에서만 위험한 게 아니라, UPDATE나 DELETE 문에 들어가면 더 심각한 피해가 발생할 수 있다. ex) 'DELETE FROM users WHERE id=5 OR 1=1;' -> 전체 유저 데이터 삭제

 

2. 애플리케이션 로직을 교란하기 - 쿼리를 변경하여 애플리케이션의 동작 로직을 방해하거나 바꾸는 것

시나리오A

취약한 쿼리

SELECT id FROM users
WHERE username = '$u' AND password = '$p';

- 해당 내용은 로그인을 위한 쿼리이고, 취약하게 구성되어 있다.

 

공격 입력

$u = admin' --
$p = (아무거나)

- admin을 치고 싱글쿼터 '를 입력해서 문자열을 닫아버린 뒤, 위 예시와 마찬가지로 -- 통해서 주석처리

- 주석처리한 부분은 무시되므로 아무거나 입력하더라도 로그인이 가능해진다.

 

결과

SELECT id FROM users
WHERE username = 'admin' -- ' AND password = 'whatever' ;

- 이로인해 인증 로직이 무력화되어 권한 상승

 

시나리오B

SELECT * FROM users WHERE username = 'wiener' AND password = 'bluechees'

- 어떤 애플리케이션에서 사용자가 로그인할 때, 아이디와 비밀번호를 입력하면 다음과 같은 sql 쿼리가 실행

- 만약 쿼리 결과가 존재하면 로그인 성공, 없으면 로그인 실패

 

공격

username = 'adminstrator'--'
password = (빈값) 또는 아무거나

- 공격자는 특정 사용자 계정으로 로그인할 때 비밀번호 검증을 우회할 수 있다.

- 방법 : sql 주석('-')을 이용해서 비밀번호 확인 부분 제거

 

결과

SELECT * FROM users WHERE username = 'administrator'--' AND password = ''

- '-' 뒤는 전부 주석 처리 -> AND password = ' ' 조건이 무효화됨

- 데이터베이스는 username이 administrator인 계정을 찾아 반환

- 애플리케이션은 비밀번호를 확인하지 않고도 해당 계정으로 로그인 처리

- 공격자는 관리자 계정으로 로그인 성공

 

3. 다른 테이블에서 데이터 가져오기 - UNION 키워드를 이용해 다른 데이터베이스 테이블의 데이터를 가져오는 것

- 어떤 애플리케이션이 SQL 쿼리 결과를 그대로 사용자에게 보여줄때, 공격자는 SQL 인젝션 취약점을 이용해 데이터베이스 안의 다른 테이블에서 데이터를 가져올 수 있음.

- 이를 위해 'UNION' 키워드를 사용 -> 기존 쿼리에 추가 SELECT 쿼리를 붙여서 결과를 합침

 

# UNION 이란

- UNION = 두 SELECT 결과를 합치는 SQL 기능

- 원래는 여러 조건/테이블 데이터를 합쳐서 볼 때 사용

- 하지만 입력값이 안전하게 처리되지 않으면 -> 공격자가 마음대로 다른 SELECT를 붙여서 민감 정보까지 노출시킬 수 있음

 

시나리오A

SELECT name, description FROM products WHERE category = 'Gifts'

- 원래는 products 테이블에서 name과 description만 가져옴

 

공격

' UNION SELECT username, password FROM users--

 

결과

SELECT name, description FROM products WHERE category = 'Gifts'
UNION
SELECT username, password FROM users--'

- ' -- '로 뒤 조건을 주석 처리

- 'UNION'으로 'users' 테이블에서 'username', 'password' 칼럼을 가져옴.

- 칼럼 수와 데이터 타입을 맞춰야 공격이 성공.(여기선 2개 컬럼)

- 애플리케이션은 상품 이름 + 설명뿐만 아니라, 모든 사용자 계정(username)과 비밀번호(password)까지 출력하게 됨

 

4. 블라인드 SQL 인젝션 - 조작한 쿼리의 결과가 애플리케이션 응답에 직접적으로 나타나지 않는 경우(즉, 결과를 눈으로 볼 수 없을 때) 사용하는 기법

공격 기법

1. Boolean-based Blind(논리 기반)

- 쿼리의 논리를 바꿔서 애플리케이션 응답이 참/거짓에 따라 달라지게 만듦.

ex) 조건을 넣어 TRUE일 때만 페이지가 정상 표시, FALSE일 때는 에러 페이지 표시 -> 이 차이로 데이터 유추

+또는 에러를 조건적으로 발생시키는 방식(예:0으로 나누기)

 

2. Time-base Blind(시간 기반)

- 쿼리 실행에 인위적으로 지연을 넣음

ex) 조건이 참일때는 SLEEP(5) 실행시켜 응답 지연 발생, 조건이 거짓일 때는 지연 없음

+ 응답 속도 차이로 데이터 값을 추론할 수있음

 

3. Out-of-band(OAST, 대역 외 기법)

- 네트워크 상의 부수 채널을 활용

ex) 공격자가 제어하는 도메인으로 DNS 조회를 하도록 유도