아쉽게도 안드로이드 5.1.5 버전에서는 개인정보를 가져가는 부분을 확인할 수 없었다.
하지만 앱이 업데이트 되면서 수정되었을 수 있으므로 이전 버전을 분석하기로 결정했다.
1. 어플리케이션 정보
이름 : 플래쉬라이트 버전 : 4.9.4 패키지 이름 : com.devuni.flashlight 설치SDK 버전 : 17 |
2. 시그니처 정보
CN : Nikolay Ananiev timeFrom : 090525191210 (Tue Nov 14 02:53:11 KST 1972) timeTo : 20590513191210 (Fri Jun 28 11:59:51 KST 2622) |
3. 해쉬값
SHA256 : 469fa3f1102ecbcae99b6166c7bb8cbe7fc29a48a5656380d16c1302ae36c9c3 MD5 : dceb4f387b6108296becb538e2c5aa97 |
4.퍼미션 정보
1) android.permission.CAMERA - 어플리케이션에서 언제든 카메라를 사용하여 사진과 동영상을 촬영하는 것을 허용합니다. 2) android.permission.FLASHLIGHT - 어플리케이션에서 플래시를 조절하는 것을 허용합니다. 3) android.permission.VIBRATE - 어플리케이션에서 진동을 조절하는 것을 허용합니다. 4) android.permission.WAKE_LOCK - 어플리케이션이 휴대폰이 잠자기 모드로 전환하지 않게 설정할 수 있도록 허용합니다. 5) android.permission.INTERNET - 어플리케이션에서 네트워크 소켓을 추가하는 것을 허용합니다. 6) android.permission.ACCESS_NETWORK_STATE - 어플리케이션에서 모든 네트워크의 상태를 볼 수 있도록 허용합니다. 7) android.permission.READ_PHONE_STATE <-이부분이 수정되었다. - 어플리케이션에서 전화 기능을 사용하는 것을 허용합니다. - 이 권한이 허가된 애플리케이션은 전화번호, 디바이스의 일련번호, 통화 실행 여부, 통화가 연결된 전화번호 등을 알아낼 수 있습니다. |
5. Activity
1) com.devuni.flashlight.MainActivity 2) com.devuni.light.LightActivity 3) com.devuni.flashlight.WidgetConfigureActivity 4) com.google.ads.AdActivity <- 최신 버전에서 제거 되었다. 5) com.millennialmedia.android.MMAdViewOverlayActivity <-최신 버전에서 제거 되었다. 6) com.millennialmedia.android.VideoPlayer <- 최신 버전에서 제거 되었다. |
6. Service
1) com.devuni.flashlight.WidgetService <- 최신 버전에서 제거 되었다. 2) com.devuni.flashlight.ShakeService <- 최신 버전에서 제거 되었다. |
7. Receiver
1) com.devuni.flashlight.WidgetProvider 2) com.devuni.flashlight.ShakeProvider <- 최신 버전에서 제거 되었다. |
8. So 파일
1) armeabi/libnative.so 2) armeabi-v7a/libnative.so 3) mips/libnative.so 4) x86/libnative.so |
9. 바이러스 토탈 분석 결과
바이러스 토탈(www.virustotal.com) 홈페이지에서 어플리케이션의 분석결과를 확인했습니다. 항상 느끼는 거지만 정적분석의 한계를 느끼게 해줍니다. 결국 사람이 분석을 해야한다는 것....
1) 바이러스 확인 (1/55)
2) 위험 분석
DEX 파일에는 API의 reflection 를 이용합니다. DEX 파일은 공유 라이브러리를 로드합니다. DEX 파일은 암호화 기능을 이용합니다. APK 패키지에는 공유 ELF 라이브러리가 포함되어 있습니다. 애플리케이션이 인터넷에 액세스 할 수 있도록 권한이 되어있습니다. 애플리케이션이 개인 정보에 액세스 할 수 있도록 권한이 되어있습니다. 그 외에 위험을 생각할 수 있는 권한이 있습니다. |
3) 퍼미션 기반의 api
WRITE_SETTINGS |
Landroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver; Ljava/lang/String; I)Z called from Lcom/devuni/flashlight/BaseLayout;->setBrightnessMode(I)V |
ACCESS_NETWORK_STATE |
Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; called from Lcom/google/ads/util/AdUtil;->d(Landroid/content/Context;)Ljava/lang/String; Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; called from Lcom/millennialmedia/android/MMAdViewSDK;->getConnectionType(Landroid/content/Context;)Ljava/lang/String; Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; called from Lcom/millennialmedia/android/MMAdViewSDK;->getConnectionType(Landroid/content/Context;)Ljava/lang/String; Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; called from Lcom/millennialmedia/android/MMAdViewSDK;->getConnectionType(Landroid/content/Context;)Ljava/lang/String; Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; called from Lcom/millennialmedia/android/MMAdViewSDK;->getConnectionType(Landroid/content/Context;)Ljava/lang/String; Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; called from Lcom/millennialmedia/android/MMAdViewSDK;->isConnected(Landroid/content/Context;)Z Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; called from Lcom/millennialmedia/android/MMAdViewSDK;->isConnected(Landroid/content/Context;)Z |
INTERNET |
Ljava/net/ServerSocket;-><init>()V called from Lcom/millennialmedia/android/VideoPlayer$VideoServer;-><init>(Lcom/millennialmedia/android/VideoPlayer; Ljava/lang/String; Z)V Ljava/net/ServerSocket;->bind(Ljava/net/SocketAddress;)V called from Lcom/millennialmedia/android/VideoPlayer$VideoServer;-><init>(Lcom/millennialmedia/android/VideoPlayer; Ljava/lang/String; Z)V Ljava/net/URL;->openConnection()Ljava/net/URLConnection; called from Lcom/google/ads/b;->run()V Ljava/net/URL;->openConnection()Ljava/net/URLConnection; called from Lcom/google/ads/w;->run()V Ljava/net/URL;->openConnection()Ljava/net/URLConnection; called from Lcom/millennialmedia/android/HttpHeadRequest;->sendRequest(Ljava/lang/String;)Ljava/lang/String; Ljava/net/URL;->openConnection()Ljava/net/URLConnection; called from Lcom/millennialmedia/android/MMAdViewController$5;->run()V Ljava/net/URL;->openConnection()Ljava/net/URLConnection; called from Lcom/millennialmedia/android/MMAdViewController;->downloadComponent(Ljava/lang/String; Ljava/lang/String; Ljava/io/File;)Z Ljava/net/URL;->openConnection()Ljava/net/URLConnection; called from Lcom/millennialmedia/android/VideoPlayer$NetworkingThread;->run()V Ljava/net/URL;->openConnection()Ljava/net/URLConnection; called from Lcom/millennialmedia/android/MMFileManager;->downloadFile(Ljava/util/HashMap;)Lcom/millennialmedia/android/MMJSResponse; Ljava/net/HttpURLConnection;->connect()V called from Lcom/google/ads/b;->run()V Ljava/net/HttpURLConnection;->connect()V called from Lcom/google/ads/w;->run()V Ljava/net/HttpURLConnection;->connect()V called from Lcom/millennialmedia/android/HttpHeadRequest;->sendRequest(Ljava/lang/String;)Ljava/lang/String; Ljava/net/HttpURLConnection;->connect()V called from Lcom/millennialmedia/android/MMAdViewController$5;->run()V Ljava/net/HttpURLConnection;->connect()V called from Lcom/millennialmedia/android/MMAdViewController;->downloadComponent(Ljava/lang/String; Ljava/lang/String; Ljava/io/File;)Z Ljava/net/HttpURLConnection;->connect()V called from Lcom/millennialmedia/android/VideoPlayer$NetworkingThread;->run()V Lorg/apache/http/impl/client/DefaultHttpClient;-><init>(Lorg/apache/http/conn/ClientConnectionManager; Lorg/apache/http/params/HttpParams;)V called from Lcom/flurry/android/FlurryAgent;->a(Lorg/apache/http/params/HttpParams;)Lorg/apache/http/client/HttpClient; Lorg/apache/http/impl/client/DefaultHttpClient;-><init>(Lorg/apache/http/params/HttpParams;)V called from Lcom/flurry/android/FlurryAgent;->a(Lorg/apache/http/params/HttpParams;)Lorg/apache/http/client/HttpClient; Lorg/apache/http/impl/client/DefaultHttpClient;-><init>()V called from Lcom/flurry/android/u;->d(Ljava/lang/String;)Ljava/lang/String; Lorg/apache/http/impl/client/DefaultHttpClient;-><init>()V called from Lcom/millennialmedia/android/HttpGetRequest;-><init>()V Landroid/webkit/WebView;-><init>(Landroid/content/Context;)V called from Lcom/flurry/android/CatalogActivity;->onCreate(Landroid/os/Bundle;)V Landroid/webkit/WebView;-><init>(Landroid/content/Context;)V called from Lcom/google/ads/h;-><init>(Landroid/content/Context; Lcom/google/ads/AdSize;)V Landroid/webkit/WebView;-><init>(Landroid/content/Context;)V called from Lcom/google/ads/util/AdUtil;->i(Landroid/content/Context;)Ljava/lang/String; Landroid/webkit/WebView;-><init>(Landroid/content/Context;)V called from Lcom/millennialmedia/android/MMAdViewController;-><init>(Lcom/millennialmedia/android/MMAdView;)V Landroid/webkit/WebView;-><init>(Landroid/content/Context;)V called from Lcom/millennialmedia/android/MMAdViewWebOverlay;-><init>(Landroid/content/Context; I J Ljava/lang/String; Z Ljava/lang/String; Z Z Z)V Ljava/net/Socket;-><init>()V called from Lcom/devuni/flashlight/CustomExceptionHandler$1;->run()V Ljava/net/Socket;-><init>()V called from Lcom/devuni/light/Light$2;->run()V |
WAKE_LOCK |
Landroid/media/MediaPlayer;->start()V called from Lcom/millennialmedia/android/MillennialMediaView;->start()V Landroid/media/MediaPlayer;->stop()V called from Lcom/millennialmedia/android/MillennialMediaView;->stopPlayback()V Landroid/media/MediaPlayer;->start()V called from Lcom/millennialmedia/android/MMMedia;->playAudio(Ljava/util/HashMap;)Lcom/millennialmedia/android/MMJSResponse; |
VIBRATE |
Landroid/app/NotificationManager;->notify(I Landroid/app/Notification;)V called from Lcom/devuni/light/Light;->showNotification()V Landroid/media/AudioManager;->getRingerMode()I called from Lcom/google/ads/util/AdUtil;->g(Landroid/content/Context;)Lcom/google/ads/util/AdUtil$a; Landroid/os/Vibrator;->vibrate(J)V called from Lcom/devuni/light/Light$3;->run()V Landroid/os/Vibrator;->vibrate(J)V called from Lcom/millennialmedia/android/MMAdViewController$MMJSInterface;->vibrate(I)V Landroid/os/Vibrator;->vibrate(J)V called from Lcom/millennialmedia/android/MMAdViewWebOverlay$OverlayJSInterface;->shouldVibrate(J)V Landroid/os/Vibrator;->cancel()V called from Lcom/devuni/flashlight/widgets/BaseWidget;->vibrate(J)V Landroid/os/Vibrator;->vibrate(J)V called from Lcom/devuni/flashlight/widgets/BaseWidget;->vibrate(J)V Landroid/os/Vibrator;->vibrate(J)V called from Lcom/millennialmedia/android/MMNotification;->vibrate(Ljava/util/HashMap;)Lcom/millennialmedia/android/MMJSResponse; |
WRITE_SETTINGS |
Landroid/hardware/Camera;->open()Landroid/hardware/Camera; called from Lcom/devuni/light/LightCamera;->isAvailable()I Landroid/hardware/Camera;->open()Landroid/hardware/Camera; called from Lcom/devuni/light/LightCameraAutofocus;->isAvailable()I Landroid/hardware/Camera;->open()Landroid/hardware/Camera; called from Lcom/devuni/light/LightHTC;->isAvailable()I |
10. 소스분석 (분석 tool: jd-gui)
5.1.5버전과 다르게 광고 라이브러리 파일이 난독화가 되어있지 않았습니다. 물론 완벽하게 디컴파일하지는 못했지만 저번보다는 쉽게 확인할 수 있을 듯 합니다.
저번과 달리 퍼미션 READ_PHONE_STATE가 추가되어서 개인정보가 수집할 확률이 높아졌으므로 좀 더 정밀하게 확인을 할려고 합니다. 아래 그림과 같이 2개의 퍼미션이 있으면 개인정보를 수집할 확률이 높기 때문입니다.
확인할 함수는 다음과 같습니다.
(참고논문 : Permlyzer: Analyzing Permission Usage in Android Applications, Wei Xu, Fangfang Zhang, and Sencun Zhu)
보통 악성앱은 다음과 같은 패턴으로 악성행위를 합니다.
(참고논문 : DroidMiner: Automated Mining and Characterization of Fine-grained Malicious
Behaviors in Android Applications, Chao Yang, Zhaoyan Xu, Guofei Gu, Vinod Yegneswaran, Phillip Porras)
여기서 걸러낼 API는 다음과 같습니다.
android.telephony java.net org.apache.http |
입니다. 이 API를 호출하는 소스를 필터링합니다.
해당 어플은 READ_PHONE_STATE 퍼미션을 사용했지만 개인정보 유출의 핵심 API인 android.telephony를 사용하는 파일은 없었습니다. 광고를 위해 다음과 같은 퍼미션을 등록해야하기 때문에 READ_PHONE_STATE를 사용한 것으로 보입니다. |
android.app.Activity.MMAdView |
|
네트워크 관련해 위험한 소스파일을 분석한 결과는 다음과 같습니다.
파일이름 | com.devuni.light.Light.java |
중요한 사용 API | android.app.Notification android.app.NotificationManager android.content.pm.PackageManager java.net.InetSocketAddress java.net.Socket |
의심목록 | Notification을 이용해 앱을 프로세스가 실행시킬 수 있고 패키지매니저를 이용해 사용자가 설치한 앱 목록을 확인할 수 있다. 또한 소켓을 이용해 인터넷에 접속할 수 있다. |
분석결과 | 만약 어플리케이션이 문제가 생겼을 때 디바이스의 정보를 보내는 소스이다. 이것도 유출이라면 유출일 수 있겠지만... 버그리포팅이 과연 유출일까 싶다. |
|
파일이름 | com.flurry.android.FlurryAgent.java |
중요한 사용 API | android.content.pm.PackageInfo android.content.pm.PackageManager android.location.Location android.location.LocationListener android.location.LocationManager org.apache.http.client.HttpClient |
의심목록 | 패키지매니저를 이용해 사용자가 설치한 앱 목록을 확인할 수 있다. 만약 퍼미션이 있다면 사용자의 위치정보를 가져갈 수 있다. 웹에 통신할 수 있다. |
분석결과 | 5.1.5 최신버전에서 있었던 문제가 되었던 코드이다. 하지만 퍼미션이 없으므로 정보를 가져갈 수 없다. |
|
파일이름 | com.google.ads.util.AdUtil.java |
중요한 사용 API | android.content.BroadcastReceiver android.content.pm.ActivityInfo android.content.pm.PackageInfo android.content.pm.PackageInfo android.location.Location android.media.AudioManager android.net.ConnectivityManager android.net.NetworkInfo java.net.HttpURLConnection javax.crypto.Cipher javax.crypto.spec.SecretKeySpec |
의심목록 | 알람을 이용해 앱을 실행할 수 있다. 패키지매니저를 이용해 사용자가 설치한 앱 목록을확인할 수 있다. 퍼미션이 있다면 위치정보를 확인할 수 있다. 음악정보를 가져갈 수 있다. 인터넷에 연결할 수 있다. 암호화할 수 있다. |
분석 결과 | 이건 구글에서 제공하는 것이다. |
파일이름 | com.millennialmedia.android.MMAdViewController.java |
중요한 사용 API | android.content.pm.PackageManager android.location.Location android.os.Environment android.webkit.WebView java.net.HttpURLConnection |
의심목록 | 패키지매니저를 이용해 사용자가 설치한 앱 목록을확인할 수 있다. 퍼미션이 있다면 위치정보를 확인할 수 있다. 사용자 설정 정보를 가져갈 수 있다. 인터넷에 연결할 수 있다. |
분석결과 | 만약 광고에 위치정보 및 개인 정보를 넣었다면 문제가 되었을 수 있다. 하지만 com.devuni.ads.MMProvider의 init() 함수를 본 결과 넣은 정보는 width와 height (광고의 크기) 정보만 넣었다. 따라서 문제가 없다. |
com.millennialmedia.android.MMAdViewController의 getURLMetaValues() 함수 com.devuni.ads.MMProvider의 init() 함수 |
파일이름 | com.millennialmedia.android.VideoPlayer.java |
중요한 사용 API | android.content.BroadcastReceiver android.os.Environment java.net.ServerSocket java.net.HttpURLConnection |
의심목록 | 알람을 이용해 앱을 실행할 수 있다. 사용자 설정 정보를 가져갈 수 있다. 인터넷에 연결할 수 있다. |
분석 결과 | 여기에서는 비디오 광고를 다운받아 캐쉬메모리에 저장하고 보여주기 위한 용도이다. |
|
10. 결론
난독화가 되어있지 않아서 쉽게 분석할 수 있었다. 우선 결론만 말하면 광고라이브러리는 많은 개인정보를 엄유출할 수 있는 코드가 포함되어있다. 만약 개발자가 그러한 정보(성별, 나이, 위치정보 등)를 넣었다면 개인정보를 유출할 수 있었다. 하지만 이 어플리케이션은 그러한 정보를 넣지 않았다. 따라서 사용자가 광고를 클릭하더라도 개인정보가 유출되지 않는다.
'보안 > 안드로이드' 카테고리의 다른 글
AndroidManifest.xml 바이너리 파일 파싱 (1) | 2014.12.09 |
---|---|
안드로이드 악성앱 사용 API (0) | 2014.12.06 |
com.devuni.flashlight v5.1.5 안드로이드 어플리케이션 분석 (0) | 2014.12.03 |
busybox, nc를 이용한 ADB로 이미지 뜨기! (1) | 2014.12.02 |
내가 설치한 앱의 정보를 보여주는 앱 (0) | 2014.12.01 |