Blind Sql Injection MySQL 5.0 본문서는배포는누구나마음대로수정및배포하실수있습니다. 테스트환경 : MySQL 5.3, PHP 5.2 - 방립동 -
개요. MySQL 이 3.0 버전에서 4.0 버전으로업그레이되되면서 UNION 절을사용할수있게되었습니다. 따라서 UNION을이용한공격방법이소개되었죠. 또한블라인드인젝션기법을이용한공격방법이문서나, 툴을통해서소개가되었으나 MS-SQL이나 ORACLE에비해근본적으로한계가있었습니다. 서브쿼리 나 JOIN 이지원이되지않았기때문이죠. 그러나 5.0 버전이나오면서서브쿼리나 JOIN을지원하게되었고따라서보다다양한공격이가능해졌습니다. 5.0 버전이나온지는이미꽤오래되었습니다. 이미연구하고진행했어야할사항이었음에도불구하고그동안나름바쁜척, IFRAME, SCRIPT, EMBED, OBJECT 등을이용한악성코드배포의탐지와방어에더관심을가지다보니뒤로미루고있었는데깜짝놀랄만한일이있었습니다. IPS 로그에 MYSQL을공격하는로그가있었던것이죠. 그것도서브쿼리를이용한기법으로이미중국에서 5.0 버전을대상으로인젝션을시도하고있었습니다. 이문서를제작배포하는목적은 MYSQL 역시인젝션공격의중심에있으며 MYSQL을이용하여홈페이지를제작하는분들에게좀더관심과주의를당부하기위해서입니다. 중국발해킹시도는날이갈수록점점늘어나고지능화되고있다는것을느낍니다. 특히최근에는악성코드, DDOS등이가장큰이슈인데 SQL-Injection 또한점점그시도횟수가늘어나고있음을느낄수있네요
세부기법 MYSQL의메타테이블중에서대상이되는것은 INFORMATION_SCHEMA 테이블입니다. INFORMATION_SCHEMA 의하위테이블에는아래정보가있습니다. SCHEMATA TABLES //DB의테이블정보를담고있습니다. COLUMNS //DB의컬럼정보를담고있습니다. CHARACTER_SETS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY ROUTINES STATISTICS VIEWS USER_PRIVILEGES SCHEMA_PRIVILEGES TABLE_PRIVILEGES COLUMN_PRIVILEGES TABLE_CONSTRAINTS KEY_COLUMN_USAGE TRIGGERS DB에존재하는객체에대해저장하고있습니다. 단자신이사용하고있는 DB의스키마만을알수가있습니다. 여담으로 MYSQL을공부하면서느끼는것이 ORACLE을비슷하게따라간다는생각입니다. 물론 MS-SQL 과유사한점도있지만사용자에대한권한의부여는 ORACLE에더비슷한거같네요.. DB에존재하는테이블에는어떠한것이있는지조회하려면 TABLES 를이용하면됩니다. INFORMATION_SCHEMA.TABLES 라는테이블을입니다.
Select * from information_schema.tables 라는쿼리를통해서 information_schema.tables 에어떠한데이터가있는지확인해봅니다. 이중에서 TABLE_NAME 을통해테이블이름을알수있으며 TABLE_TYPE을 BASE TABLE로제한을하면사용자가생성한테이블만을가져올수있습니다.
블라인드기법은한자씩끊어서가져와야하기때문에 Limit 연산자를이용하여첫번째 ROW를가져옵니다. Limt 조건을 1,1 로주게되면두번째테이블을 2,1 로하면세번째테이블명만가져올수있습니다. address가리턴이되었습니다. 이제 address를 substr 연산자를이용하여자릅니다. Substr((select table_name from information_schema.tables where table_type= base table limit 0,1),1,1) 위처럼자르면 address중에서 a 만리턴이됩니다. 2,1 3,1 을통해서두번째세번째글자를가져오면됩니다. 한가지팁으로 where 절에서 table_type= base table 구문이들어가게되는데싱글쿼터를예외처리하는경우가많습니다. 특히 php의경우는매직쿼터옵션이자동으로설정되어있죠. 따라서 concat 연산자를사용하면싱클쿼터를사용하지않고도가능합니다. 예 ) table_type=concat(char(98), char(99)) 따라서문자형인아닌숫자형에서인젝션이된다면 magic_quotes_gpc 옵션만으로는방어가되지않습니다.
컬럼이나데이터정보를가져오는것도동일합니다. 컬럼은 information_schema.columns 테이블을이용합니다. 아래그림은간단한예입니다. 역시 limit 연산자를이용하면순서대로하나씩끊어올수가있습니다. 아래는툴로만들어서실행해본결과입니다. MS-SQL 이나 ORACLE 에서처럼 TABLE, COLUMN, DATA정보를획득하는것이가능했습니다.
대응방법 대응방법은서버사이드스크립트안에서예외처리를하는것이가장좋은방법입니다. 쉽게말해직접 JSP나 PHP 코드를수정하는것이죠. 싱글쿼터나세미콜론, 콤마, 중괄호정도만예외처리를해주어도대부분의인젝션공격은막을수있습니다. IPS 나웹방화벽이있지만개인적인생각으로는한계가많습니다. 가장큰이유로 IPS나웹방화벽은성능상의이유로패턴매칭을텍스트서치가아닌바이너리서치를한다는점입니다. 쉽게말해대소문자처리를하지못하는데예를들어패턴에 SELECT 를넣으면 SELECT 는잡아내지만 select 는잡아내지못한다는점입니다. 직접특수문자가아닌일반영문자까지 URL 인코딩한경우에는더더욱탐지율이떨어지게됩니다. DB는대소문자를구분하지않습니다. 또한웹서버는자동으로 URL 디코딩을합니다. 따라서아래의문자열들은모두 DB에서동일하게인식됩니다. 공격자 웹서버 DB SELECT SELECT SelecT SelecT select select %53%45%4C%45%43%54 SELECT select %53%65%6C%65%63%54 SelecT %73%65%6C%65%63%74 select S%45LECT SELECT s%45lect select IPS나웹방화벽은패킷이웹서버에도착하기전에먼저검사를합니다. 일반적으로바이너리패턴매칭을한다면 SELECT 문자열만으로도대소문자. URL인코딩문자등을조합한패턴은수만가지가나올수가있습니다.
따라서 SELECT 만으로도수만가지의패턴이필요합니다. 또웹의특성인파라메터 (GET, POST, COOKIE) 만을탐지하고검출해주어야하나실제로는그렇지못한경우가많습니다. GET, POST, COOKIE 등의파라메터부분만을스마트하게검출해주어야하는데그렇지못하고헤더전체나 BODY 전부분만을검출한다면오탐의비율이그만큼늘어날수밖에없죠 결국기본으로제공되는탐지정책보다사이트현실에맞는보다세밀한탐지정책을필요로하게되는것이죠. 그래서가장쉬운방법이개발소스안에서전송되는파라메터에대해싱글쿼터나세미콜론, 콤마, 중괄호정도를예외처리해주는것이간편합니다. 아니면 DB를개발할때 SP를사용하거나바인딩쿼리를사용하면 DB성능도좋아지고인젝션공격에도자유로울수있습니다. 아래는 PHP 에서간단한예외처리예입니다. $parameter = str_replace(,, $parameter) $parameter = str_replace(,,, $parameter) $parameter = str_replace( (,, $parameter) $parameter = str_replace( ),, $parameter) $parameter = str_replace( ;,, $parameter) 간단히함수로만들어서사용하면편하겠죠. 2005년 4월에키사에서홈페이지개발보안세미나 1회를개최하면서개발보안가이드를배포하였는데제가개인적으로생각하는최고의보안세미나였으며가이드역시가장좋은가이드가아닌가합니다. 홈페이지를개발하는개발자에게는필독서가아닌가합니다. 이상여기서마칩니다. 문의사항 -> bangrip@gmail.com