[web]SQL injection

zzsla·2023년 7월 1일
0
post-custom-banner

SQL injection 이란

SQL injection(SQLi)은 웹 보안 취약점으로, 공격자가 application을 이용하여, 데이터베이스에 보내는 쿼리를 간섭하여 공격을 수행할 수 있는 취약점이다. 일반적으로 공격자는 일반적으로 검색을 통해 볼 수 없는 데이터를 볼 수 있다. 여기서 데이터는 다른 사용자가 가지고 있는 데이터이거나, applicaation 자체로 접근할 수 있는 다른 데이터가 포함되어 있을 수 있다. 대부분은 공격자는 이 데이터를 수정하거나, 삭제하여 application의 동작이나 content을 지속적으로 바꿀 수 있다.

경우에 따라 공격자는 SQL injection을 확대하여 기본 서버나 백엔드 인프라를 손상시키거나, 서비스 거부 공격을 수행할 수 있다.

SQL injection 공격에 대한 영향

SQL injection 공격이 성공하면 암호, 신용 카드 세부 내역, 개인 사용자 정보 등과 같은 중요한 데이터를 무단으로 접근할 수 있다. 최근 몇 년동안 발생한 많은 사건의 이목을 끈 데이터 침해는 SQL injection 공격의 인한 것이었고, 이로 인해 피해 회사들은 평판이 낮아지고, 벌금을 부과하게 되었다.(외국기준) 몇몇 경우에는 공격자가 조직 시스템에 영구적인 백도어를 획득해서 오랜 기간동안 장기적인 손상을 입힐 수 있다.

SQL injection 취약점 탐지 방법

  • 따옴표'를 넣어서 오류 또는 기타 이상이 있는지 확인한다.
  • SQL injection에 사용되는 특정한 구문을 넣어서, 해당 구문이 원래 값이 다른 값으로 나오는지 확인하며, 그 에 따라 application의 응답에 시스템적으로 차이가 있는지 확인한다.
  • or 1=1, or 1=2과 같은 boolean조건을 넣어서 application의 응답에 차이가 있는지 확인한다.
  • SQL 쿼리 내에서 실행될 때 시간 지연이 작동되도록 하는 페이로드를 보내고, 응답하는 데 걸리는 시간이 차이가 있는지 확인한다.

SQL injection이 발생하는 위치

대부분의 SQL injeciton 취약점은 selectwhere절에서 발생한다.
그러나 SQL injection 취약점은 원칙적으로 쿼리 내의 모든 위치와 다양한 쿼리 유형 내에서 발생할 수 있다.

  • update문에서, 업데이트 값 또는 where
  • insert문에서, 삽입된 값
  • select문에서, 테이블이나 column 이름
  • select문에서, order by

SQL injection 예시

다양한 상황에서 발생하는 다양한 SQL injection 취약점 공격과 기술이 있다. 일반적인 SQL injection 예는 다음과 같다.

  • 숨겨진 데이터 검색(Retrieving hidden data) : 쿼리를 수정하여 추가적으로 결과를 반환하는 방법
  • application 로직 파괴(Subverting application logic) : 쿼리를 수정하여 application 로직에 간섭하는 것
  • UNION 공격(UNION attacks) : 여러 데이터베이스 테이블에서 데이터를 검색하는 방법
  • Blind SQL injection : 공격자가 제어하는 쿼리 결과가 application의 응답에 표시 되는 않는 것

Retrieving hidden data

다양한 카테고리의 제품을 표시하는 쇼핑 application을 생각했을 때, 사용자가 Gifts 카테고리를 클릭하면 브라우저에서에서 다음 URL을 요청한다.

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

요청되면 application이 데이터베이스에서 관련 제품을 검색하기 위해 다음 SQL 쿼리를 실행한다.

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

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

  • 모든 세부 정보(*)
  • products 테이블에서
  • category는 ‘Gifts’
  • 그리고 released = 1

released = 1 제한에 적용되어 출시하지 않은 제품을 숨기는데 사용되고, 출시되지 않은 제품의 경우 released = 0 로 가정된다.

application에 SQL injection 공격에 대한 방어를 구현하지 않으면, 공격자는 이런 공격을 구성할 수 있다.

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

SQL 쿼리 결과

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

여기서 중요한 건 이중 대시 시퀀스 --가 SQL의 주석 표시이며, 쿼리의 나머지 부분이 주석으로 해석되었다는 것을 의미한다. 이렇게 하면 나머지 부분이 제거되어서 더 이상 AND released = 1을 포함하지 않는다. 즉 출시하지 않은 제품을 포함하여 모든 제품이 표시 된다는 의미이다.

더 나아가 공격자는 자신이 알지 못했던 카테고리를 포함하여 모든 카테고리의 모든 제품을 표시하도록 할 수 있다.

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

SQL 쿼리 결과

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

수정된 쿼리는 category가 Gifts이거나 1이 1일 때 모든 항목을 반환한다. 1=1는 항상 true이므로 쿼리는 모든 항목을 반환한다.

경고
조건문 OR 1=1을 SQL 쿼리에 넣을 때 주의한다. 위 문맥에서는 저 조건이 해를 끼치지 않을 수 있지만, 한 요청의 데이터를 여러 다른 쿼리에 사용되는 경우가 많다. 예를 들어 UPDATE문이나 DELETE문에 도달하면 데이터가 손실이 발생할 수 있다.

Subverting application logic

사용자가 사용자 이름과 비밀번호로 로그인할 수 있는 application을 생각했을 때, 사용자가 wiener라는 사용자 이름과 bluecheese라는 비밀번호를 제출하면 application은 다음 SQL 쿼리를 실행하여 credentials을 확인한다.

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

쿼리가 사용자의 세부 정보를 반환하면 로그인에 성공한 것이고, 그게 아니면 거부된 것이다.

여기서 공격자가 SQL 주석 시퀀스--를 사용하여 쿼리 WHERE절에서 암호 부분만 제거하면 암호 없이 모든 사용자로 로그인할 수 있다. 예를 들어 사용자 이름에 administrator'--를 넣고 비밀번호 없이 제출하면 다음 쿼리가 생성된다.

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

이 쿼리는 사용자 이름이 administrator인 사용자를 반환한다. 즉 공격자는 해당 사용자로 로그인을 성공한다.

UNION attacks

SQL 쿼리의 결과가 application의 응답에 반환되는 경우, SQL injection 취약점을 이용해서 데이터베이스 내 다른 테이블에서 데이터를 검색할 수 있다. UNION을 사용하여 추가적인 SELECT문을 실행하고, 그 결과로 원본 쿼리에 추가되는 방식으로 작동된다.

예를 들어 application에서 사용자 입력에 “Gifts”가 들어가는 다음 쿼리가 실행될 경우

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

그러면 공격자는 이렇게 입력값을 넣을 수 있다.

' UNION SELECT username, password FROM users--

이렇게 하면 application이 제품 이름, 설명과 모든 사용자의 이름, 비밀번호를 반환한다.

참고
[web]SQL injection UNION attacks

Blind SQL injection

SQL injection의 대부분은 Blind 취약점이다. 즉 application의 응답 내에서 SQL 쿼리의 결과나 데이터베이스 오류에 대한 세부 정보를 반환하지 않는다는 것을 의미한다. Blind 취약점으로 데이터를 접근하는데 이용할 수 있지만, 그것에 사용되는 기술은 일반적으로 복잡하고 실행하기 어렵다.

취약점의 특성과 관련 데이터베이스에 따라 Blind SQL injection 취약점을 악용하는데 다음 기술을 사용할 수 있다.

  • 쿼리의 논리를 변경하여 단일 조건의 True/false에 따라 application의 응답이 감지 가능하게 유도할 수 있다. 이를 위해 boolean 로직에 새로운 조건을 넣거나, 0으로 나누기과 같은 조건부 에러를 이용할 수 있다.
  • 조건부로 쿼리 처리 시간 지연을 발생해서 application의 응답 시간을 기반으로 True/false를 추론할 수 있다.

SQL injection cheat sheet

참고
[web]SQL injection cheat sheet

profile
[README]newbi security hacker :p
post-custom-banner

0개의 댓글