DB인젝션 & SQL 인젝션

Jihoon·2023년 2월 12일
2

DB & SQL Study

목록 보기
3/8
post-thumbnail
post-custom-banner

🌟 SQL Injection

코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 DB를 공격할 수 있는 공격방식

  • SQL : 관계형 데이터베이스 관리 시스템의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어

  • Injection : 주입 및 삽입, 즉 SQL를 주입함으로써 보통 DB를 공격하는 것이 SQL Injection

✅ 공격 방법

🎈 방법 1 - LOGIN

일반적인 LOGIN 상황

SELECT user
FROM user_table
WHERE id = '입력한아이디' AND password = '입력한비밀번호'

일반적인 유저의 LOGIN

SELECT user
FROM user_table
WHERE id = '수원불주먹' AND password = '영통불주먹'

SQL Injection을 시도하려는 공격자의 LOGIN

SELECT user
FROM user_table
WHERE id = '입력한아이디' AND password = '' OR '1' = '1';
  • 공격 SQL문을 분석해보자
  1. AND 절은 비번 입력이 안됐으니 FALSE
  2. 뒤에 절은 당연히 TRUE
  3. 따라서, WHERE 절은 TRUE가 됌 !
  4. 즉, DB에서 정보를 가져올 수 있게 되는 거임
  • JOIN이나 UNION 같은 구문을 통해서 공격자가 원하는 코드 실행 가능

🎈 방법 2 - LOGIN 이외

로그인 폼도 결국엔 서버에 요청을 해서 받는 거시익 때문에, HTTP 헤더를 보면 응답 헤더에 서버의 종류와 버전이 나옴
DB엔진을 알아내서 해당 시스템에 맞는 명령어 이용해 데이터 추출 가능
EX) Apache 서버 - MySQL 서버, IIS 서버 - MSSQL

🎈 방법 3 - 블라인드 SQL 인젝션

에러 메시지가 정보와 아무런 도움이 되지 않거나 아예 에러 페이지를 보여주지 않을 때 사용

  • 간단하게 몇 초 정도의 time for delay 이용해서 원하는 시간 만큼 DB가 움직여준다면 취약하다고 볼 수 있음
SELECT * 
FROM CLIENT 
WHERE id = 'abc123' OR (LENGTH(DATABASE()) = 1 AND SLEEP(2)) 

✅ 방어 방법

  • 유저에게 받은 값을 직접 SQL로 넘기면 안된다? 왜?

  • 요즘 모든 DB 엔진은 유저 입력이 의도치 않은 동작을 하는 걸 방지하는 escape함수와 prepared statement를 제공

  • prepared statement는 변수를 문자열로 바꾸는 것이라 안전 why?

  • 뭐 둘다 변환하는 함수인듯한데, 변환해서 어떻게 방어한다는거지?

🎈 추천 방어법 - 이해 OK

  1. 클라이언트 측의 입력을 받을 웹 사이트에서 JS로 폼 입력값을 한 번 검증하고, 서버 측은 클라이언트 측의 자바스크립트 필터가 없다고 가정하고, 한 번 더 입력값을 필터한다.

  2. 이때 정규표현식등으로 한 번 걸러내고, SQL 쿼리로 넘길 때 해당 파라미터를 prepared statement로 입력받고 이를 프로시저로 처리함 (프로시저가 뭐냐? 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리의 집합)

  3. 쿼리의 출력값을 한 번 더 필터하고 유저에게 전송

  4. 이렇게하면 해당 폼에 대해서는 SQL Inejction 공격이 완전히 차단됌. 물론, 이것이 공격 기법의 전부가 아니므로 정보 유출에 민감한 사이틀르 운영할 생각이라면 보안 회사의 컨설팅을 꼭 받아야 함

profile
장난감이 데이터인 사람
post-custom-banner

0개의 댓글