블로그 이미지
자유로운설탕

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2019. 5. 20. 17:08 보안

  이번 시간에는 보안 쪽에서 백신 프로그램 만큼 자주 볼수 있는 스캐너(Scanner)에 대해서 이야기 하고, 사람이 직접 수행하는 수동 테스트(Penetration Test)에 비해 어떤 측면에서 장점이 있고, 어떤 측면에서 단점이 있는지를 살펴 보려 한다. 그렇게 함으로써 사람으로서 잘 할 수 있는 테스트가 무엇일지 생각해 보는 시간이 될 수도 있을 것 같다.



[목차]

1. 보안을 바라보는 방법

2. 보안에서의 코드 읽기

3. 인젝션(Injection) 살펴보기 #1, #2

4. 암복호화

5. 클라이언트 코드

6. 업로드, 다운로드

7. 스크립트 문제

8. API

9. 하드닝(Hardening)
10. 보안 설계 문제
11. 스캐너 vs 수동 테스트

12. 자동화 잡

13. 리버싱과 포렌식

14. 모니터링 문제

15. 악성코드

16. 보안과 데이터

 


 


1. 들어가면서

  스캐너는 무언가를 쭉 훝어 가면서 필요한 정보를 체크하는 이미지가 있다. 해당 정보는 문자 인식등에 필요한 글자 영역(광학 스캐너)일 수도 있고, 이상한 징후가 보이는 위치(공항 수하물 스캐너)일수도 있다. 보안 쪽에서 많이 쓰이는 스캐너들 또한 비슷한 역활을 한다. 웹페이지나 서버 등을 스캔하면서 이상하게 열린 포트는 없는지, 알려진 취약점 들이 없는지 체크를 하고 리포팅을 한다.

 

  이런 이상적인 관점으로 봤을 때엔 스캐너를 사용하면 모든 문제가 해결될 것처럼 생각되지만, 현실상으로는 많은 부분에서 제약이 있을 수 있다. 이번 장에서는 github에 공개된 간단한 스캐너 프로그램을 기준으로 스캐너 엔진의 기본적인 동작 원리를 이해하고, 여러 상용, 비상용 스캐너들을 어떤 관점에서 접근하면 좋은지에 대한 이야기를 하려한다. 

 

 

 

 

 

 

2. 공개된 스캐너 돌려보기

  처음엔 Acunetix 같은 상용 웹 스캐너의 트라이얼 버전으로 얘기를 풀어볼까도 했는데, 그렇게 되면 메인 주제를 벗어나 세팅 등 너무 설명할 부분이 많아질 것 같은 생각이 들었다. 또 아래 OWASP 의 정리된 페이즈를 보면 알겠지만, 윈도우즈 환경의 무료 스캐너 툴은 거의 없다고 봐도 될듯 싶다. 윈도우, 리눅스 양쪽을 지원한다고 했던 툴도 몇 개 다운로드 받아봤는데, 점점 리눅스 쪽만을 정식으로 지원하는 분위기로 가는 듯 싶다.

 

[Vulnerability Scanning Tools - OWASP]

https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools

 

 

  그래서 "python 3 web scanner" 같은 키워드로 이리저리 찾다가 보니, 아래의 github 에 올려진 웹 스캐너가 괜찮아 보였다. 물론 상용 스캐너에 비해서는 좀 많이 어설프고(이 부분은 소스를 살펴보면서 얘기할까 싶다), 2017년 후에는 전혀 업데이트가 전혀 되지 않아 개선할 점이 많아보이는 소스이긴 하지만, 그 덕분에 소스가 복잡하지 않아 대략 전체적인 구조의 흐름을 따라갈 수 있을 것 같고 해서, 해당 스캐너를 다운받아 현재 진행 중인 파이썬 3.6.4 버전에 맞춰 고쳐서 실행해 보려고 한다.

 

[simple web scanner - lotusirous 님 github] 

https://github.com/lotusirous/simple-web-scanner

 

 

 

2.1 다운로드와 압축 풀기

  우선 해당 github 의 오른쪽에 있는 "Clone or download" 버튼을 클릭 한 후, "Download ZIP" 버튼을 클릭하여 zip 파일을 c:\Python\Code 폴더에 다운 받는다.  

 

 

   이후 바로 압축을 풀면 c:\Python\code 밑에 아래와 같은 폴더 구조가 될 것이다.

1
2
3
4
5
6
7
8
9
10
simple-web-scanner-master/
    xss_scanner.py
    crawler.py
    scanner_core.py
    scan_cli.py
    parser.py
    sqli_scanner.py
    vectors/
        sqli_vectors.txt
        xss_vectors.txt
cs

 

 

 

2.2 소스 조정 하기

  3.6.4 환경에서 돌려보니 에러가 나는 부분이 있어서, 소스를 조금 수정해야 한다.

 

 

  첫번째로 parser.py 이름이 파이썬 내부 모듈과 이름 충돌이 나서 HtmlParser 를 못찾는다고 나오는거 같으니, 파일 이름을 parser_x.py 라고 변경 한다.

 

 

  다음으로 해당 모듈을 불러오는 파일들도 같이 수정해야 한다. 우선 "xss_scanner.py" 와 "crawler.py" 파일을 열어, 처음에 모듈을 읽는 문장인 "from parser import HtmlParser" 문장을 "from parser_x import HtmlParser" 로 수정한다.

1
from parser_x import HtmlParser
cs

 

 

  이후 "scanner_core.py" 파일을 열어 import 문 아래에 "from urllib.error import URLError, HTTPError" 를 추가한다(돌릴 때 HTTPError 가 정의 안됬다는 에러가 났다).

1
2
3
from urllib.parse import urlparse, parse_qs, urlunparse, urlencode, unquote
import urllib.request
from urllib.error import URLError, HTTPError
cs

 

 

 

2.3 샘플 사이트 만들기

  이제 스캔 대상이 되는 사이트가 있어야 하는데, 3교시에 사용한 인젝션 페이지를 쓰면 될거 같은데, 이 스캐너가 몇가지 구조상 제약(개발이나 도메인 특성 반영이 덜 된 부분)이 있다.

 

  일단 처음에 HREF 태그를 기준으로 링크들을 크롤링 해서 가져오는데(상용 스캐너들은 이 스캐너와 달리 자바스크립트로 이루어진 동적인 링크 등도 모두 파싱해 가져온다), 테스트 할 페이지의 인자들을 리스트업 할때, Form 내의 값이나 헤더 값 등이 아닌, GET 으로 날라가는 인자(예: test.asp?name=tom) 를 기준으로 파싱한다. 그래서 "http://localhost/injection_test.asp" 식으로 링크 경로를 주게 되면, 페이지는 인지하지만, 따로 인자가 없다고 판단에 인자에 대한 스캐닝을 하지 않고 그냥 스캐닝이 종료되어 버린다.

 

  그래서 부득이하게 샘플 페이지를 스캐너에 맞추는 작업을 하려 한다. 3교시의 파일을 실습 했다는 가정하에(injection__test.asp 가 있다는 가정하에), c:\inetpub\wwwroot 에 ANSI 인코딩으로 "web_main.asp" 페이지를 하나 만든다. 해당 페이지는 크롤링시 injection_test.asp 페이지를 인지시키기 위해서 인자를 포함한 href 링크 하나만 달랑 가지고 있는 아래와 같은 페이지 이다.

1
<a href="http://localhost/injection_test.asp?txtBuyerID=tom">link</a>
cs

 

 

 

2.4 스캐너 소스 구조 설명

  일단 다른 사람이 만든 소스긴 하지만^^, 돌리기 전에 스캐너 구조에 대해서 이해는 하기위해 간단히 도표를 통해 설명하려 한다.

 

  전체적인 구조는 위의 그림과 같다고 보면 된다. 기능이 작은 쪽부터, 큰 쪽으로 보는게 날거라고 보는데, xss_vectors.txt, sqli_vectors.txt 파일을 보면 정말 간단하지만 XSS 취약점과, SQL Injection 취약점을 체크할 수 있는 몇 개의 인자 패턴들이 정의되어 있다(한번 열어서 내용을 보자). parser_x.py 는 페이지 소스에서 HREF 태그를 파싱하거나, <script> 태그 안의 내용을 가져오는 라이브러리로 크롤링이나 결과 판단시 사용된다.

 

  앞에 얘기한 2개의 txt 파일을 읽는 xss, sqli_scanner.py 파일에서는 txt 파일의 패턴을 가져다가 주어진 URL 뒤에 인자로 결합하는 작업을 하거나, 결과 값에서 공격이 맞다고 하는 패턴을 찾는 역활을 한다.

 

  Crawler.py 파일이 처음 명령어로 주어진 시작 URL 에서 유효한 링크들을 찾는 역활을 하며(확실친 않지만 depth 는 하나만 들어가는 걸로 보인다), 이후 scanner_core.py 파일에서 앞에 설명했던 기능들을 조합해 URL 에 공격 인자를 넣어 던진 후, 결과 페이지에서 해당 공격이 유효한지 소스 기반으로 체크하고 유효할 경우 결과를 화면에 뿌려준다.

 

 

 

2.5 스캐너 돌려보기

  그럼 스캐너를 함 돌려보자. 단순히 스캐너만 돌려서 결과를 보는 것은 큰 의미가 없고, 실제 어떤 요청들이 날라가는지를 함께 보려고 한다. 대량 건이라면 IIS 로그를 남겨서도 확인 할 수 있지만, 몇 건 안날아 갈거기 때문에 피들러를 켜서 보려 한다.

 

 

  우선 필요한 모듈을 설치하자. 설명서에 나온것에 추가해 html5lib 하나를 더 설치해야 한다.

c:\Python\code\simple-web-scanner-master>pip install bs4

c:\Python\code\simple-web-scanner-master>pip install html5lib

 

 

  피들러를 실행 후, 아래와 같이 xss 테스트를 하는 명령어를 넣어보자.

c:\Python\code\simple-web-scanner-master>python scan_cli.py --seedurl http://localhost/web_main.asp --engine xss
SELECTED xss engine
Crawl: 
http://localhost/web_main.asp
Crawl:  http://localhost/injection_test.asp?txtBuyerID=tom
http://localhost/injection_test.asp?txtBuyerID=tom HTTP Error 500: Internal Server Error
http://localhost/injection_test.asp?txtBuyerID=tom HTTP Error 500: Internal Server Error

 !! REPORT !!
http://localhost/injection_test.asp?txtBuyerID=<script>alert("XSS")</script>

 

 

  결과를 보면 web_main.asp 에서 injection_test.asp 페이지를 크롤링 해서 가져오고, 뒤의 인자를 기준으로 공격할 포인트를 찾는다(앞에도 얘기했지만 원래는 페이지 자체를 분석해서 폼이나 AJAX 방식의 공격 인자들을 하나하나 찾는게 정석이다). 이후 공격 패턴(보통 고급스럽게 페이로드-payload 라고 많이 불린다)들을 하나하나 조합해서 보내면서, 결과의 script 태그 안에 XSS 라는 공격이 성공했다는 시그니쳐가 있는지 찾는다(xss_scanner.py).

 

 

  피들러로 보게 되면 아래와 같다.

 

 

 

2.6 스캐너 구조에 대한 문제 생각해 보기 

  자 여기서 스캐너가 잘 돌아가는거 같다고 덜컥 쓰는건 아마추어가 할 행동이다(물론 상용 스캐너인 경우는 프로인 사람들이 만들었기 때문에 스캐너 자체를 의심하기 보다는, 뒤에 얘기할 옵션들과 필터들을 잘 조정하는게 맞다)

 

  여기서 한번 생각해 봐야할 문제는 만약 원래 페이지의 스크립트 태크안에 "XSS" 라는 문구가 있다면 오탐이 나올 수가 있다는 것이다. 보통 그래서 시그니쳐는 우연히 겹치기 힘든 기괴한 문자열 일수록 더 좋긴 하다. "False Positive(진짜라고 하지만 실제 아닌 것)"가 생기는 문제가 된다.

 

 

  한발 더 나아가, 위의 필터 중 나머지 하나인 sql injection 을 테스트하는  필터를 돌려서 다른 문제를 봐보자.

c:\Python\code\simple-web-scanner-master>python scan_cli.py --seedurl http://localhost/web_main.asp --engine sqli
SELECTED sqli engine

Crawl:  http://localhost/web_main.asp
Crawl:  http://localhost/injection_test.asp?txtBuyerID=tom
http://localhost/injection_test.asp?txtBuyerID=tom HTTP Error 500: Internal Server Error
http://localhost/injection_test.asp?txtBuyerID=tom HTTP Error 500: Internal Server Error

 !! REPORT !!

 

 

  문제가 없다고 나온다. 그런데 해당 페이지는 사실 예전에 SQL Injection 을 시연하기 위해 만들었던 페이지므로 SQL Injection 이 있을 수는 없다. 그럼 왜 일까? 실제 해당 페이지를 열어 홑따옴표(') 를 넣어보면 아래와 같은 에러 페이지가 나온다.

 

 

  해당 원인은 sqli_scanner.py 페이지를 보면 알 수 있다. 거기 정의된 SQL Injection 을 판단하는 시그니처는 아래 3가지 이다.

'SQL syntax', 'MySQL server', 'mysql_num_row',

 

  위의 에러 페이지에는 해당 문구가 포함되지 않기 때문에 안 나나 싶다면, 페이지에 나타난 "SQL Server 오류" 같은 시그니처를 하나 더 추가해 볼수도 있겠지만, 피들러로 호출된 내용을 보게 되면 근본적인 문제는 현재 페이지는 SQL Injection 이 나게 되면 500(Internal Server Error) 에러가 나게 되는데, 현재 해당 웹 스캐너의 코드(scanner_core.py 의 analyze 메서드)를 보면 에러가 나면 그냥 화면에 출력을 하고 멈춰 버린다(False Negative-괜찮다 하지만 실제 안괜찮은 것).

 

 

  이 경우는 아래와 같은 코드에서 에러가 난 경우에도 에러 상세 결과를 변수로 받아서 시그니처를 찾아보거나(해당 페이지에서 사용한 urllib 이 에러시에도 결과를 얻을 수 있는지는 고민해 봐야한다. 최악의 경우 사용하는 라이브러리를 다른 걸로 교체해야 될수도 있다), 그게 안된다면 차라리 500 에러가 났을 때 SQL Injection 이라고 판단하는게 좀더 합리적이지 않을까 싶다. 

1
2
3
4
5
6
7
8
9
    def analyze(self, url):
        # This function will get requests each vulnerable url to server to get response
        for mal_url in self.build_malicious_url(url):
 
            try:
                res = urllib.request.urlopen(mal_url)
            except HTTPError as e: # http status is not 200, continue next malcious url
                print(url, e)
                continue
cs

 

 

  마지막으로 해당 SQL Injection 의 시그니처를 만나게 되려면 에러가 발생시 데이터베이스 오류에 대한 자세한 에러 페이지를 보여줘야 한다. 에러시 공통 에러 페이지로 가게 되다면 안전하다고 판단 하는 오류를 가지게 된다(물론 SQL Injection 도 처리 안된 사이트라면 저렇게 라이브한 에러가 날 가능성도 높긴하지만 --;)

 

 

 

 

3. 상용 툴(또는 사람들이 많이 쓰는 오픈소스)과의 비교

  위의 간략한 POC 개념의 스캐너를 기준으로 상용툴과 비교하는 것은 좀 그렇긴 하지만, 어차피 상용툴도 첨에 이렇게 작은 프로그램 으로부터 시작되어 왔을꺼기 때문에 한번 비교를 해보자. 개인적으로 사용해 본 Aucnetix 를 기준으로 말해 보지만, 사용한지 몇년이 지났기도 하고, 툴마다 장단점들도 서로 있긴 한테니 참고만 하길 바란다. 

 

[Acunetix 페이지]

https://www.acunetix.com/ordering/ 

 

 

 

3.1 크롤링 측면 

  우선 크롤링 측면을 보자. 페이지 안의 링크에 걸린 페이지를 무조건 따라가는 것은 조금 위험한 측면이 있다. 사이트 외부로 링크가 나가게 되면, 외부 페이지의 링크를 다시 추적하게 되는 과정에서 과장한다면 www 전체를 돌아다닐 수도 있게 된다. 보통 스캐닝 툴에선 크롤링 시 따라가는 도메인의 제한과, 처음 페이지에서 들어가는 깊이의 제한으로 이슈를 풀어가는 듯 싶다. 

 

  또한 앞에서 얘기한 스크립트 기반으로 동적으로 생성이 되는 링크(폼 버튼을 누를 때의 validation 후  전송하는 스크립트 라든지),  AJAX 기반의 기능 호출의 경우는 단순히 HREF 만을 파싱해서는 찾아낼 수 있다. 좀더 자바스크립트 문법을 이해하는 정교한 크롤링 코드가 필요할 듯 싶다. 

 

 

 

3.2 스캐닝 측면 

  다음은 스캐닝 측면이다.

 

 

  첫 째, 스캐닝 측면에서는 차원의 축소 문제가 있다. 보통 큰 페이지에서는 인자로 취급될 수 있는 form 값이나, http header 값들이 수백개가 되는 경우가 있다. 그런 규모의 페이지가 100개라면 XSS 하나의 필터에 관해서만 500개의 테스트를 한다면 5만개의 리퀘스트가 날라가게 된다. 그런 필터가 수십개라면 몇 백만개의 쿼리가 날라가는 사태도 벌어지게 된다.

 

  그래서 얼마나 효율적으로 인자와 필터를 선택하고, 필터 안에서도 해당 도메인이나 페이지에 유효한 필터만을 날리느냐에 대한 문제가 있다. 그런 부분을 위해서 인자들을 정규식 패턴 등으로 예외처리 하거나, 해당 도메인에 의미있는 필터만을 선택하거나, 도메인 특성에 따라(예 ASP 라면 PHP 용 SQL Injection 을 날릴 필요가 없을 것이다) 자동으로 날릴 Payload 들을 선정 하기도 한다. 다만 해당 부분은 툴 자체에만은 맡길 순 없고, 도메인을 소스 레벨에서 이해한 상태에서 조정을 해야하는 부분 같다.

 

 

 둘 째, 앞과 연결되지만 크롤링된 모든 파일에 모든 필터를 꼭 점검해야 하느냐 하는 이슈가 있다. 점검할 가치가 없는 파일들을 적절한 도메인 지식하에 제외하거나, 특정 필터만을 돌리는 작업도 꼭 필요하다. 예를 들어 SQL 호출을 안하는 페이지에 SQL Injection 필터를 돌리는 것은 시간 낭비이다. 다만 그렇게 정교하게 필터 정책을 주는 것과 어차피 기계가 돌리는 거는 시간이 걸리더라도 덜 제외하는 데 필요한 노력을 들이지 않고 돌리느냐에 대해 유리한 쪽을 잘 판단해야 한다. 어디서나 ROI 문제는 생긴다.

 

 

  셋 째, 아무리 앞에 말한데로 조정을 하더라도 사이트가 크거나 복잡한 페이지가 많을 수록 필연적으로  많은 쿼리가 날라가게 됨을 피할 수는 없다. 그 경우 적절히 병렬로 쿼리를 날리면서도 부하 조절을 하는 등의 경감 정책도 필요할 것 같다(조그만 사이트는 DDOS 공격을 맞은 듯이 뻗을 수도 있고, 개발 팀이나 모니터링 팀에서 장애가 난다고 문의가 날라올 수도 있다)

 

 

  넷 째 필터에 포함된 쿼리가 얼마나 객관적이고 많은 이슈들을 담았느냐도 중요하다. 자질구레한 레벨의 실제 위협을 가져올 가능성이 거의 없어 수정하기 애매한 취약점들을 모두 찾기 위해서 모든 필터를 돌리는게 의미 있는지도 생각해 봐야한다(이건 사람마다 입장에 따라 의견이 다를 듯은 싶다). 상용 프로그램의 경우 상용이라는 부담감 때문에 기존에 나왔던 모든 이슈에 대한 필터가 너무 과도하게 진행되는 감도 있다. 특히 오픈 소스를 쓰는 것이라면 해당 스캐너의 동작을 깊진 않더라도 가능한 소스 레벨에서 이해해서, 앞에서 생기는 여러 문제들을 해결할 수 있도록 조정하고, 적절히 개조해 보려 하는 것도 나쁘진 않을 것 같다.

 

 

  다섯 째, 스캐너의 결과가 통과되었다고 100% 안전하다는 보장은 하진 못할수도 있다. 예를 들어 디폴트 패스워드나 디렉토리 검사를 통과했다고 하더라도, 사용자가 패스워드를 "안녕" 이라고 만들거나 폴더를 01022223333(본인 핸드폰 번호) 이런식으로 만들어 놨다면 스캐너가 통과됬다고 본질적인 디폴드 패스워드 개념에서는 안전하다고는 못할 것이다. 어찌보면 많은 필터들이 사전적 Brute Force 같은 성향을 가지고 있기 때문에 적절히 결과의 유효성을 판단해야 한다. 

 

 

  여섯 째, 비단 스캐너뿐 아니라 유명한 보안 상용 솔루션이나 장비를 쓰는 경우는 인증 및 감사 측면에서 유리한 면도 있는 듯 하다(감사시 ** 스캐너를 사용해서 매번 스캔하고 있어요 같이...). 실제로 많은 보안 장비가 해당 장비 자체가 이미 법이나 인증 획득에 필요한 기능을 구현해 인증 받아놓았기 때문에 여러 감사 측면에 유리하게 대응하기 위해서 도입 하는 경우도 있다. 다만 아무리 그렇더 라도 유명도나 인증, 레퍼런스가 해당 스캐너의 효율성과 등가라고는 할수 없기 때문에, 실무자 입장에서는 해당 필터가 정말로 의미있는 건지, 해당 디폴트 방식의 스캐닝이 의미 있는 건지는 잘 이해하고 따져봐야 한다.

 

 

  마지막으로 사이트에 로그인과 비로그인 시에도 미묘한 문제가 생긴다. 로그인 후 스캐너를 돌리다가 게시판 같은데 이상한 게시물을 잔뜩 달아 열심히 지워본 기억은 한번씩쯤 겪게 될 것이다. 반대로 로그인을 안한 상태에서 돌리게 되면 테스트 하는 페이지가 확연하게 줄어 실효성에 의문이 생길 수도 있다. 여러 상황에 맞춰 선택을 해야한다(테스트 환경에서만 로그인해 돌린다든지...).

 

  또한 스캐너가 날리는 페이로드는 기괴한 문법 문자가 많기 때문에, 당하는 프로그램 입장에서 에러처리가 안되서 프로그램이 죽거나 에러가 빵빵 나 버릴 수도 있다. 해당 부분은 페이로드를 바꾸던지 에러가 나는 쪽을 설득해 에러처리를 제대로 하게 해야한다.

 

 

 

4. 스캐닝 결과 검증 자체의 이슈

  위에서 봤듯이 스캐너의 원리는 적절한 인자를 찾아 페이로드를 보내고, 결과 페이지에서 내가 의도한 패턴을 찾는 것이다. 이것은 비단 웹 뿐만 아니라 네트워크나 다른 물리적인 스캐너도 마찬가지 이다(예를 들어 공항 투시 스캐너는 약한 X선이나 자기를 보내서 반사되는 형태를 기반으로 판단한다고 한다).

 

  앞의 스캐너 소스에서 봤듯이 어떤 가정을 하느냐에 따라서 결과가 의미가 있을 수도 없을 수도 있다. 막상 스캐너를 처음 돌려본 사람들은 쏟아지는 취약점 숫자에 깜짝 놀라다가도, 실제 의미 있는 결과인가를 체크해 보면서 스캐너가 얘기하는 수많은 False Postive 에 또 한번 놀라게 된다. 

 

  하지만 이건 스캐너가 판단 할수 있는 영역이 블랙박스라서 어쩔 수 없다고 봐야 된다. 사람처럼 블랙박스 테스트를 한다는 의미가 아니라, 리퀘스트와 해당 결과로 브라우저에 전달된(리스폰스) HTML 소스를 기반으로 열심히 판단하긴 하지만, 서버 내의 로직을 보거나 이해할 수 없다는 태생적 한계를 가지고 있다는 것이다. 다만 블랙박스 측면에서도 제대로 테스트를 하면 서버의 내부 로직을 유추할 수 있듯이, 스캐너도 필요한 측면에서 잘쓰면 마찬가지의 효과는 있다.

 

  또한 여기에서도 도메인, 프로그래밍적 지식이 필요한데, 왜 스캐너가 해당 페이지에서 해당 패턴의 취약점을 발견했다고 주장하는 지를 스캐너와 페이지 측면 양쪽 모두에서 이해하고, 유죄를 선고할지, 무죄를 선고할지를 판단할 수 있어야 한다. 해당 지식이 앞 시간에 나온 여러 주제들에 대한 지식에 추가해, 스캐너가 테스트를 할수 있다고 주장하는 필터에 대한 동작 원리에 대한 지식이다.

 

  많은 부분 판단이 힘든 경우 스캐너가 어떤 요청을 날렸고 어떤 결과를 받았는지 부터 자세히 살펴보는 것도 도움이 된다고 생각한다. 그게 스캐너가 바라보는 세상의 전부이니까 말이다. 

 

 

 

 

5. 수동 테스트(펜테스트)와의 차이

  그럼 사람들이 펜테스트 하는 방식이 이런 스캐닝 툴과 다른 점은 뭘까?

 

 

3.1 수동 테스트의 장점 

  첫 째, 6교시에서 얘기했던 업로드 같은 부분을 생각해보자. 페이지를 분석하고, 업로드할 악성 파일을 탑재하고, 프록시 단계에서 파일 이름이나 자바스크립트를 바꾸면서 이런저런 조작을 하는 부분을 스캐너 판단하에 자동으로 일어나도록 만들기는 참 어려울 것이다.

 

  일단 업로드 하기 전까지를 구현하는 것도 어렵지만, 업로드된 파일이 실제 어떤 경로에 저장되었음을 판단하는 것도, 업로드 후 업로드된 경로를 명시적으로 알려주는 사이트가 아니라면 자동으로는 많이 힘들 듯 싶다. 물론 100% 불가능 하게는 안보이지만 페이지에서 업로드 기능을 찾아내고, 웹 프록시를 이용하는 과정을 자동으로 구현한다고 생각하면 머리가 많이 아프다. 이런 측면은 수동 테스트가 휠씬 효율적인 부분이라고 생각한다.

 

 

  둘 째, 위와 비슷하게 여러개의 중간 단계를 거치면서 각 중간 단계에서 계속적으로 validation 을 하는 설계를 가진 페이지에는 적용하기 힘들다(요즘은 마이크로 서비스나, 도메인으로 나눠진 서비스가 많아서 페이지 호출이 복잡한 구조가 많다. 많이 가는 큰 사이트를 가서 피들러로 한번 살펴보면 하나의 페이지를 들어갈때 눈이 아플 정도로 많은 호출이 있을 것이다).

 

  위의 어려움 더하기 모든 validatio 포인트를 클라이언트 코드를 통해 회피해주는 작업이 필요하기 때문이다. 일반적으로 스캐너는 요청과 최종적으로 대상쪽에서 온 응답에 기반에 동작하기 때문에, 서버에서 일어나는 여러 단계의 중간 단계에는 관심이 없다. 사실 자동화의 복잡성 대응의 한계 때문에 그렇다고 보는게 맞을 듯도 싶다. 뭐 AI 를 이용한 보안 테스트가 많이 연구된다니 혹시 패턴이 많이 모인다면 나중엔 어쩔진 모르겠지만 말이다.

 

 

  셋 째, 마찬가지로 위와 연결되는 이슈인데, 수동 테스트는 블랙박스와 그레이, 화이트 박스의 조합을 적절히 취할 수 있다. 웹 호출을 보다가 데이터베이스의 변화를 관찰 할 수도 있고, 미심적은 처리 부분의 프로그램 소스를 열어서 볼수도 있다. 물론 자동화된 테스트도 디비를 참고하거나 프로그램 내부를 참조할수 있겠지만 그건 저런 스캐너 같은 도구는 아니고, 테스트를 위해 잘 디자인된 프로그램을 직접 제작하는 경우일 것이다. 또한 이해가 잘 안된다면 개발자와 의논할수도 있다^^.

 

 

  넷 째, 수동 테스트는 단순히 페이지의 분석에서 벗어나, 기존 도메인에 대한 지식과 경험이 녹아있는 테스트를 통해 실시간으로 전략을 바꿀 수도 있다. 이것은 언젠가 AI 가 따라 잡을 분야일진 모르겠지만, 지금 상태로는 죽기전엔 구경 못할 듯은 싶다.

 

 

 

3.2 자동 테스트의 장점 

  첫 째, 자동은 우선 빠른 실행 속도가 장점이다. 서버의 부하나 에러가 허용되는 만큼 병렬로 돌릴 수도 있고, 명확히 문제와 검증 방식이 정의된 영역 부분에 대해서는 장점이 있다.  

 

 

  둘 째, 파이썬 마지막 교시에 얘기했던 five orders of ignorance 에서 얘기한것 처럼 모든 소프트웨어는 지식의 결정체 이다. 솔루션이라는 것은 우리가 가진 보안 지식을 정리하여 소프트웨어 형태로 만들어, 컴퓨터의 파워를 이용해서(어찌보면 밝음을 구현하는 손전등을 위해 건전지를 사용하는 것과 비슷하다) 자동화된 지식을 반복적으로 재사용 하는 것이다.

 

  지식이나 물리적인 힘(물리적 장치와 연결되면 힘의 움직임도 에너지는 다르겠지만 재사용 할수 있다)을 재사용 한다는 측면에서의 자동화는 정말 우수한것 같다. 여러 공장 자동화들의 예에서 이런 것들을 많이 볼수 있고, 몇몇 천재들이 자신의 지식을 잘 담아서 상용화 시킨 편하고 감탄이 나는 소프트웨어들을 많이 볼수 있다.

 

 

  셋 째, 변경이 적은 지식의 영역에서는 일단 세팅이 완료되면 우수한 ROI 가 이루어 진다. 예전 회사에서 같이 일하던 사람이 여러 나라의 언어로 이루어진 설치 프로그램을 자동화 툴을 이용해 검증해 돌렸는데, 한번 만들어 놓으면 약간의 코드 수정만으로 본전을 뽑는 다는 느낌이 들었었다. 게다가 자꾸 만들다 보면 자신만의 라이브러리도 쌓이고, 이미 해결해 놓은 지식들이 많기 대문에 ROI 의 I(Investment) 부분이 점점 줄어들 것이다. 

 

  IT 쪽에서 사람들을 겪어 본 사람들은 프로그래머나 다른 인력이나 사람들마다 많은 속도나 품질, 타인의 대한 좋은 태도의 차이가 난다는 것을 많이 느꼈을 거다. 자신이 평균 이상의 속도나 품질, 타인의 대한 좋은 태도를 가지도록 계속 노력해 보자.

 

 

  넷 째, 객관적인 증명이 된다. 사람은 피곤하면 잘못 보기도 하고, 실수도 하고, 슬쩍 해야될 점검을 모르는 척 빼먹을 수도 있지만(생각보다 종종 일어나는 일이다),  기계의 장점은 항상 객관적이라는 것이다. 물론 설계를 잘못했거나 어설프게 검증하도록 만들었을 경우에도 지나치게 객관적이여서 문제다(gabage in garbage out 이 여기도 적용된다). 앞에서 얘기한 소프트웨어를 구성해야할 올바른 지식들이 필터나 스캐너 프로그램의 철학에 잘 담겨져 있는지를 꼭 확인해 보자. 

 

 

 

3.2 자동 테스트 vs 수동 테스트 

  이건 "엄마가 좋아 아빠가 좋아" 문제이다. 서로의 단점을 보안해줄 좋은 수단이 동시에 있는데 굳이 하나를 외면 해야할 필요가 있는가? 수동 테스트에 익숙한 사람은 스캐너를 잘 다루도록 노력하고 자기만의 스캐닝 정책을 커스터마이즈 하거나, 불편한 부분을 개선하거나 하는 노력을 해야한다. 스캐너는 어찌보면 수동 테스트에서 귀찮았던 부분을 해결하기 위해 만들었기 때문에 업무의 중요한 부분에 집중하는데 많은 도움이 될것이다.

 

  반대로 스캐너에 주로 익숙한 사람들은, 테스트 페이지를 제작해 스캐너가 날리는 쿼리에 대해 웹서버 로그로 저장하거나 피들러로 살펴보면서, 하나하나의 필터가 하는 일을 명확하게 이해해야 한다. 해당 부분을 이해하는 과정에서 결국은 스캐너의 한계를 깨닳고 수동 테스트로 어떻게 보강을 해야될지를 고민하면서 자동으로 공부를 많이 하게 될 것 같다.

 

  양쪽 다 서로 자신을 알면 알수록 상대방을 잘 이해할 수 있고, 상대방을 잘 이해할 수록 자신의 일도 더 잘 이해할 수 있게되는 측면이 있다고 본다.

 

 

 

 

6. 마무리 하면서

  스캐너 쪽이나 펜 테스트 쪽이나 아주 깊게 아는 편은 아니기 때문에, 어설프게 얘기하거나 빠뜨린 부분이 있는지도 모르겠다. 하지만 결국 소프트웨어는 지식을 담아 재사용하는(나아가 제작의도와 다르게 응용해 사용하기도 하는) 부분이기 때문에 스캐너를 해당 관점으로 보면서 스캐너 자체의 빤짝거림 보다는 안에 담긴 지식의 알맹이들에 관심을 가졌음 하는 바램을 가지며 이 글을 마치려 한다.

 

 

 

2019.5.23 by 자유로운설탕
cs

 

 

 

 

 

 

posted by 자유로운설탕