웹 해킹/portswigger

버프슈트를 이용한 웹 해킹, 서버 측 취약점: SQL 인젝션(SQLi)

코드라니(CODERANY) 2026. 3. 31. 13:55

SQL 인젝션(SQLi)이란 무엇인가요?

 

  • 약자: SQL (Structured Query Language) + Injection (주입)
  • 뜻: 데이터베이스(DB)와 대화할 때 사용하는 언어인 SQL 문구를, 공격자가 악의적으로 주입(Injection)하여 DB를 조작하는 공격입니다.

 

SQL 인젝션(SQLi)은 공격자가 애플리케이션이 데이터베이스에 접근하는 쿼리를 조작할 수 있도록 하는 웹 보안 취약점입니다. 이를 통해 공격자는 일반적으로 접근할 수 없는 데이터를 볼 수 있습니다. 여기에는 다른 사용자의 데이터나 애플리케이션이 접근 가능한 모든 데이터가 포함될 수 있습니다. 많은 경우, 공격자는 이러한 데이터를 수정하거나 삭제하여 애플리케이션의 콘텐츠나 동작을 영구적으로 변경할 수 있습니다.

경우에 따라 공격자는 SQL 인젝션 공격을 확대하여 기본 서버 또는 기타 백엔드 인프라를 손상시킬 수 있습니다. 또한 이를 통해 서비스 거부 공격을 수행할 수도 있습니다.

SQL 인젝션 취약점을 탐지하는 방법

SQL 인젝션은 애플리케이션의 모든 진입점에 대해 체계적인 테스트를 수행하여 수동으로 탐지할 수 있습니다. 이를 위해 일반적으로 다음과 같은 테스트를 실행합니다.

  • 작은따옴표 문자를 '확인하고 오류나 기타 이상 징후가 있는지 살펴보세요.
  • SQL에 특정한 구문 중 일부는 진입점의 기본(원래) 값으로 평가되고, 다른 값으로 평가될 때는 다른 값으로 평가되며, 애플리케이션 응답에서 체계적인 차이를 찾습니다.
  • OR 1=1이나 OR 1=2와 같은 불린(boolean, 참/거짓) 조건을 입력해 보고, 그에 따라 애플리케이션의 응답이 어떻게 달라지는지 살펴보세요.
  • SQL 쿼리 내에서 실행될 때 시간 지연을 유발하도록 설계된 페이로드이며, 응답 시간 차이를 감지합니다.
  • OAST 페이로드는 SQL 쿼리 내에서 실행될 때 대역 외 네트워크 상호 작용을 유발하고, 그 결과로 발생하는 모든 상호 작용을 모니터링하도록 설계되었습니다.

또는 Burp Scanner를 사용하면 대부분의 SQL 인젝션 취약점을 빠르고 안정적으로 찾아낼 수 있습니다.

숨겨진 데이터 검색

다양한 카테고리의 상품을 보여주는 쇼핑 애플리케이션을 상상해 보세요. 사용자가 '선물' 카테고리를 클릭하면 브라우저는 다음과 같은 URL을 요청합니다.

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

이로 인해 애플리케이션은 데이터베이스에서 관련 제품의 세부 정보를 검색하기 위해 SQL 쿼리를 실행합니다.

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

이 SQL 쿼리는 데이터베이스에 다음을 반환하도록 요청합니다.

  • 모든 세부 정보 ( *)
  • products테이블 에서
  • 그 위치 category에Gifts
  • 그리고 released입니다 1.

released = 1이라는 제약 조건은 출시되지 않은 제품들을 숨기기 위해 사용되고 있습니다. 우리는 출시되지 않은 제품들의 경우 released = 0 값을 가질 것이라고 가정할 수 있습니다.

숨겨진 데이터 복구 - 계속

이 애플리케이션은 SQL 인젝션 공격에 대한 방어 기능을 구현하지 않았습니다. 즉, 공격자는 다음과 같은 공격을 구성할 수 있습니다.

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

이로 인해 다음과 같은 SQL 쿼리가 생성됩니다.

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

Crucially, note that -- is a comment indicator in SQL.

결정적으로, SQL에서 --(하이픈 두 개)는 주석의 시작을 알리는 기호라는 점에 유의하세요.

In this example, this means the query no longer includes AND released = 1

이 예시에서, 이것은 (주석 처리로 인해) 쿼리에 더 이상 AND released = 1이라는 조건이 포함되지 않음을 의미합니다.

As a result, all products are displayed, including those that are not yet released.

그 결과, 아직 출시되지 않은 제품들을 포함하여 모든 제품이 화면에 표시됩니다.

 

이와 유사한 공격을 사용하여 애플리케이션이 알지 못하는 카테고리를 포함하여 모든 카테고리의 모든 제품을 표시하도록 만들 수 있습니다.

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

이로 인해 다음과 같은 SQL 쿼리가 생성됩니다.

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

The modified query returns all items where either the category is Gifts, or 1 is equal to 1.

수정된 쿼리는 category는 Gifts 혹은 1=1과 같은 모든 항목을 반환합니다. 

As 1=1 is always true, the query returns all items.

1=1은 항상 참(True)이기 때문에, 쿼리는 모든 항목을 반환합니다.

경고

SQL 쿼리에 조건 OR 1=1을 삽입할 때는 주의해야 합니다. 삽입하려는 컨텍스트에서는 무해해 보일지라도, 애플리케이션에서 단일 요청의 데이터를 여러 쿼리에서 사용하는 경우가 흔합니다. 예를 들어, 조건이 UPDATE나 DELETE문에 도달하면 데이터 손실과 같은 의도치 않은 결과가 발생할 수 있습니다.

1. 카테고리 중 아무거나(예: Gifts) 클릭하세요.

2. 주소창에 아래 내용 삽입

category=Gifts' +OR+1=1--

3. 성공,  미출시 제품 공개

 

왜 이렇게 하나요? 

서버는 원래 이런 명령을 내리려고 했습니다

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

하지만 우리가 수정한 값을 넣으면 서버는 이렇게 오해합니다:

SELECT * FROM products WHERE category = 'Gifts' OR 1=1 --' AND released = 1
  • ' : 앞의 Gifts를 감싸는 따옴표를 강제로 닫아버립니다.
  • OR 1=1: "카테고리가 Gifts가 아니더라도, 1=1(참)이면 데이터를 다 가져와!"라는 치트키를 씁니다.
  • --: 그 뒤에 붙어있던 AND released = 1(출시된 것만 보여주라는 조건)을 주석 처리합니다.

애플리케이션 로직을 전복시키다

사용자가 사용자 이름과 비밀번호로 로그인할 수 있는 애플리케이션을 상상해 보세요.

사용자가 사용자 이름 wiener과 비밀번호 bluecheese를 제출하면 애플리케이션은 다음과 같은 SQL 쿼리를 실행하여 자격 증명을 확인합니다.

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

쿼리 결과가 사용자 정보를 반환하면 로그인이 성공한 것이고, 그렇지 않으면 로그인이 거부된 것입니다.

이 경우 공격자는 비밀번호 없이도 어떤 사용자로든 로그인할 수 있습니다. SQL 주석 시퀀스를 사용하여 쿼리 절   --  에서 비밀번호 확인 부분을 제거함으로써 이를 가능하게 합니다. 예를 들어, 사용자 이름  administrator'--  과 빈 비밀번호를 입력하면 다음과 같은 쿼리가 실행됩니다. 

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

This query returns the user whose username is administrator

이 쿼리는 username이 administrator인 사용자를 (데이터베이스에서) 찾아내어 반환합니다.

and successfully logs the attacker in as that user.

그리고 공격자를 해당 사용자(관리자)로 성공적으로 로그인시킵니다.

1. 로그인 페이지에서 아래 내용 입력 후 로그인

administrator'--'

2. 로그인 성공