728x90

SQL injection


SQL 삽입은 데이터베이스를 엑세스하기 위해 동적 SQL 문을 사용하는 경우, 사용자로부터 입력된 값이 검증 작업없이 쿼리문을 생성하기 위한 일부로 사용할 때 발생한다. (동적 SQL 문이란 외부 입력값을 이용하여 SQL문을 실행하는 것을 말한다.)


모든 종류에 DBMS에 적용 가능한 공격기법으로, 이 공격을 통해 불법적인 로긴과 DB 엑세스, 프로시저를 통한 운영체제 명령어 수행이 가능해지므로 치명적 피해를 입을 수 있다.



비 정상적 입력값으로 인증 우회


사용자명 : ' or 'a'='a

비밀번호 : ' or 'a'='a





Error Based SQL Injection Check(에러 기반 SQL 삽입 체크)


서버에서의 에러 메시지가 브라우저가 그대로 출력된다면 공격자에게 많은 정보를 제공하게 된다.

MS-SQL로 가지고 이를 테스트해보겠다.


예 1) 싱글 쿼터( ' )를 사용했을 때의 에러 메시지

입력 값 : test'


에러 메시지 :

문자열 'test''의 따옴표가 짝이 맞지 않습니다.

'test'' 근처의 구문이 잘못되었습니다.



예 2)  테이블 명 추출 (집계함수를 가지고 조건 비교를 할 때 사용하는 having절 사용)

입력 값 : ' having 1=1 --


에러 메시지 : 

열 'tbl_user.name'이(가) 집계 함수나 GROUP BY 절에 없으므로 SELECT 목록에서 사용

할 수 없습니다.


select 문의 컬럼에 대한 GROUP BY절이 기술되어 있지 않을 때 위와 같은 에러가 발생한다.

위 에러 메시지에서 테이블 이름이 tbl_user이며 첫번째 칼럼 이름이 name인 것을 확인 가능하다.


예 3) DB 이름 추출
입력 값 : ' and db_name() =1 --

에러 메시지 :
nvarchar 값 'ADO'을(를) 데이터 형식 int(으)로 변환하지 못했습니다.

DB 이름과 숫자 1을 비교하도록 쿼리문을 조작해 에러 메시지를 발생 시킨다. 이를 통해 DB 이름이 ADO라는 것을 확인 가능하다.




SQL 인젝션을 방지하는 방법

C# 서버 기준 -  SqlParameter를 사용
SqlCommand cmd;
SqlDataReader sqlReader = null;
cmd.CommandText = @"SELECT * FROM tbl_user WHERE name=@userName AND pass=@password";
cmd.Parameters.AddWithValue("@userName", field[0]);
cmd.Parameters.AddWithValue("@password", field[1]); 
                                       
sqlReader = cmd.ExecuteReader();
로그인 완료 후나, 아이디 비밀번호 불일치 시에는 sqlReader를 닫고 parameter를 clear해준다.

sqlReader.Close();     cmd.Parameters.Clear();


"SQLSERVER SP 개체이름이 잘못되었습니다" 오류가 날 때 해결법
: You need to refresh the Intellisense cache (Ctrl + Shift + R). Or you can go to Edit -> IntelliSense -> Refresh Local Cache.


C# 서버 기준 - 저장 프로시저 사용

SQL-SERVER에서의 저장 프로시저

1
2
3
4
5
6
7
8
CREATE PROCEDURE FindName
( @name nchar(10) )
AS  
BEGIN
   DECLARE @sql nvarchar(255)
   SET @sql = 'SELECT * FROM tbl_user WHERE name = @userName'
   exec sp_executesql @sql, N'@userName nchar(10)', @name
END;
cs


C# 서버의 코드
1
2
3
4
cmd.CommandText = "FindName";
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter uInput = new SqlParameter("@name", field[0]);
cmd.Parameters.Add(uInput);
cs


C# 서버 기준 - 특수 문자 필터링

정규식을 사용해 특수문자를 필터링한다. (3~8자로 제한)
1
2
3
4
5
6
 bool idChecker = Regex.IsMatch(field[0], @"[0-9a-zA-Z]{3,8}$");
 
if (idChecker == false)
{
    return//Console.WriteLine("잘못된 아이디 형식 입니다.");
}
cs


'DB' 카테고리의 다른 글

[오라클 DB] 설치 및 접속  (0) 2017.07.08
데이터 베이스 기초  (0) 2017.06.14
MySQL 기초 공부  (0) 2017.05.30
SQL Server 2014 설치방법  (0) 2017.03.17
MySQL 설치 및 기초  (0) 2017.03.06

+ Recent posts