SQL 인젝션: Difference between revisions
From IT위키
No edit summary |
No edit summary |
||
Line 4: | Line 4: | ||
* 웹 페이지의 입력값을 통해서 SQL명령어를 주입하여 오동작을 일으키는 해킹방법 | * 웹 페이지의 입력값을 통해서 SQL명령어를 주입하여 오동작을 일으키는 해킹방법 | ||
* [[OWASP|OWASP TOP10]]에서 꾸준히 상위권을 유지하는, 가장 흔한 웹해킹 기법 중 하나 | * [[OWASP|OWASP TOP10]]에서 꾸준히 상위권을 유지하는, 가장 흔한 웹해킹 기법 중 하나 | ||
= 공격 유형 및 예제 = | |||
== 로그인 하기 == | |||
* 대상 | |||
<pre> | |||
select * from users where username = ' +username+ ' and password = ' +password+' | |||
</pre> | |||
* 공격 | |||
<pre> | |||
username : 1' or 1=1 -- | |||
</pre> | |||
* 결과 | |||
** username이 1이거나 1=1인 경우의 결과가 출력된다. | |||
** 1=1은 항상 참이고 그 뒷부분은 -- 를 통해 주석처리되므로 항상 결과가 출력된다. | |||
** 결과가 있는지 여부를 통해 로그인을 검증하는 경우 로그인이 통과된다. | |||
<pre> | |||
select * from users where username = '1' or 1=1 -- ' and password = '' | |||
</pre> | |||
== 테이블 명 알아내기 == | |||
* 대상 | |||
<pre> | |||
select * from users where username = ' +username+ ' and password = ' +password+' | |||
</pre> | |||
* 공격 | |||
<pre> | |||
username : ' having 1=1-- | |||
</pre> | |||
* 결과 | |||
** 에러를 발생시켜 테이블 명이 users 라는 것을 확인할 수 있다. | |||
<pre> | |||
[Error] 'users.id' 열이 집계 함수에 없고 GROUP BY 절이 없으므로 SELECT 목록에서 사용할 수 없습니다. | |||
</pre> | |||
== 로그인 하기 == | |||
== 블라인드 SQL 인젝션 == | == 블라인드 SQL 인젝션 == | ||
* SQL 인젝션을 통해 단순히 참 거짓을 판단할 수 있는 상황에서 실제 값을 파악하기 위한 공격 | * SQL 인젝션을 통해 단순히 참 거짓을 판단할 수 있는 상황에서 실제 값을 파악하기 위한 공격 | ||
* 일반적인 SQL 인젝션에 대해 방어가 잘 되어 있는 경우라도 블라인드 SQL이 동작하는 경우가 많다. | |||
* ex) | * ex) | ||
<pre> | <pre> | ||
Line 13: | Line 50: | ||
* 본 SQL 인젝션을 통해 admin 계정 비밀번호의 첫번째 글자 아스키 코드가 100 이하인지 알 수 있다. | * 본 SQL 인젝션을 통해 admin 계정 비밀번호의 첫번째 글자 아스키 코드가 100 이하인지 알 수 있다. | ||
* 이런 공격을 반복하면 한글자 한글자 파악 가능하다. | * 이런 공격을 반복하면 한글자 한글자 파악 가능하다. | ||
= 대응 방법 = | |||
* 입력값 검증 | |||
** 데이터 타입: 예를 들어 숫자만 입력되어야 하는 필드에 숫자가 아닌 것이 입력되었으면 에러 처리를 한다. | |||
** 길이 검증: 5글자만 입력되어야 하는 필드라면 5글자로 제한한다. | |||
** addslashes: 입력값에 ' 와 같은 특수문자가 있으면 ''로 처리하여 특수문자로 동작하지 않도록 한다. | |||
* Prepared Statement | |||
** 가장 확실한 방법이다. | |||
** DBMS 드라이버에서 입력값은 SQL 문장이 아닌 오직 입력값으로만 동작되도록 구분하여 처리한다. | |||
<pre> | |||
query("SELECT * FROM user WHERE id=:id", $bind["id"]=$_GET['id']) | |||
</pre> | |||
* [[웹 방화벽]] 이용 | |||
** 서버에 웹 방화벽 제품을 설치하여 공격을 탐지 및 차단한다. | |||
** 패턴 기반으로 분석하여 SQL 인젝션으로 보이는 요청이 있으면 차단한다. |
Revision as of 21:48, 26 September 2019
- SQL Injection
- 웹 페이지의 입력값을 통해서 SQL명령어를 주입하여 오동작을 일으키는 해킹방법
- OWASP TOP10에서 꾸준히 상위권을 유지하는, 가장 흔한 웹해킹 기법 중 하나
공격 유형 및 예제
로그인 하기
- 대상
select * from users where username = ' +username+ ' and password = ' +password+'
- 공격
username : 1' or 1=1 --
- 결과
- username이 1이거나 1=1인 경우의 결과가 출력된다.
- 1=1은 항상 참이고 그 뒷부분은 -- 를 통해 주석처리되므로 항상 결과가 출력된다.
- 결과가 있는지 여부를 통해 로그인을 검증하는 경우 로그인이 통과된다.
select * from users where username = '1' or 1=1 -- ' and password = ''
테이블 명 알아내기
- 대상
select * from users where username = ' +username+ ' and password = ' +password+'
- 공격
username : ' having 1=1--
- 결과
- 에러를 발생시켜 테이블 명이 users 라는 것을 확인할 수 있다.
[Error] 'users.id' 열이 집계 함수에 없고 GROUP BY 절이 없으므로 SELECT 목록에서 사용할 수 없습니다.
로그인 하기
블라인드 SQL 인젝션
- SQL 인젝션을 통해 단순히 참 거짓을 판단할 수 있는 상황에서 실제 값을 파악하기 위한 공격
- 일반적인 SQL 인젝션에 대해 방어가 잘 되어 있는 경우라도 블라인드 SQL이 동작하는 경우가 많다.
- ex)
SELECT * FROM users where id='admin' and ascii(substr(select pw from users where id = 'admin', 1, 1)) < 100 -- and pw='nomatter'
- 본 SQL 인젝션을 통해 admin 계정 비밀번호의 첫번째 글자 아스키 코드가 100 이하인지 알 수 있다.
- 이런 공격을 반복하면 한글자 한글자 파악 가능하다.
대응 방법
- 입력값 검증
- 데이터 타입: 예를 들어 숫자만 입력되어야 하는 필드에 숫자가 아닌 것이 입력되었으면 에러 처리를 한다.
- 길이 검증: 5글자만 입력되어야 하는 필드라면 5글자로 제한한다.
- addslashes: 입력값에 ' 와 같은 특수문자가 있으면 로 처리하여 특수문자로 동작하지 않도록 한다.
- Prepared Statement
- 가장 확실한 방법이다.
- DBMS 드라이버에서 입력값은 SQL 문장이 아닌 오직 입력값으로만 동작되도록 구분하여 처리한다.
query("SELECT * FROM user WHERE id=:id", $bind["id"]=$_GET['id'])
- 웹 방화벽 이용
- 서버에 웹 방화벽 제품을 설치하여 공격을 탐지 및 차단한다.
- 패턴 기반으로 분석하여 SQL 인젝션으로 보이는 요청이 있으면 차단한다.