앱 진단 중 테스트 할 것이 있어, 안드로이드 스튜디오에서 빌드하고 apk파일을 추출하려고 하니 다음과 같은 상황이 발생하였습니다.



apk파일이 split_lib_~~~~로 쪼개져서 있는 것인데 base.apk를 추출해 보면 다음과 같습니다.



원본 소스는 버튼하나 있고, 함수 호출하는 소스인데 이상하게 변경되어 있네요


찾아보니 해당 기능은 안드로이드 스튜디오의 Instant run이라는 기능이었습니다.


간단하게 설명하면 안드로이드 스튜디오에서 앱 최초 빌드 후 수정할 경우 다시 앱 빌드해서 넣어줬었는데 이때문에 시간이 오래걸렸습니다.


이를 해결하기 위해 split로 나눠 필요한 부분만 빌드한다는 것 같은데... 저에게는 딱히 쓸일이 없을 것 같네요


Instant Run 옵션을 제거하는 방법은 다음과 같습니다.


[File] - [Settings]


[Build, Execution, Deployment] - [Instant Run] 에서 첫번째 옵션을 제거해 주시면 됩니다.


다시 단말로 들어가서 보니 split가 없어지고 base.apk만 덩그러니 남아 있네요.


복호화도 잘 됩니다 :)






'Mobile' 카테고리의 다른 글

Uncrackable2 - Radare2  (0) 2018.01.23
Android Anti-Debugging  (1) 2018.01.23
Frida를 이용한 앱 실행 중 로드하는 클래스 확인  (2) 2018.01.03
Apktool Error (apktool.yml)  (0) 2018.01.03
IOS SSL(HTTPS)통신하기  (0) 2018.01.02

앱 실행시 어떤 class가 로드되는지 앱 진단 중 필요해서 뒤적이다가 

Java.enumerateLoadedClasses라는 함수를 발견했습니다.


아래 내용은 프리다 공홈에서 가져왔습니다.



Java.enumerateLoadedClasses를 이용한 앱 실행 중 로드되는 클래스를 출력하는 함수입니다.


Usage : python <하단소스저장파일이름>.py <패키지이름>


import sys
import frida

def on_message(message,data):
    print "[%s] -> %s" % (message, data)


PACKAGE_NAME = sys.argv[1]

jscode = """
Java.perform(function(){
    Java.enumerateLoadedClasses(
    {
      onMatch: function(className)
      {
        send(className);
      },
      onComplete:function(){}
    });

});
"""
   
try:
    device = frida.get_usb_device(timeout=10)
    pid = device.spawn([PACKAGE_NAME]) 
    print("App is starting ... pid : {}".format(pid))
    process = device.attach(pid)
    device.resume(pid)
    script = process.create_script(jscode)
    script.on('message',on_message)
    print('[*] Running Frida')
    script.load()
    sys.stdin.read()
except Exception as e:
    print(e)




코드 실행 시 화면이며, 안드로이드 내장 클래스까지 출력되어 상당히 지저분합니다.


시간 날때 실행 패키지의 클래스만 출력되도록 다듬도록 하겠습니다.



================================= 18.01.08 추가 ========================================================


난독화되어 있는 앱으로 확인한 결과, 실행시 난독화가 풀리는게 아니고 난독화가 진행되면 앱에서 해당 클래스 및 함수의 이름이 바뀌어서 저장되는 것 같습다.


실행 시 클래스 로드 할때도 변경된 함수로 로드하네요.


솔루션을 이용하는 앱의 경우 솔루션이 .dex의 헤더를 망가트려 디컴파일이 안되게 하는데 이를 믿고 난독화를 안하는 앱이 대다수입니다.


이런 앱들은 해당 스크립트로 함수 내부 클래스 네임을 불러올 수 있으므로 난독화는 필수로 해야 할 듯 하네요



'Mobile' 카테고리의 다른 글

Android Anti-Debugging  (1) 2018.01.23
Instant Run(Split apk)  (1) 2018.01.10
Apktool Error (apktool.yml)  (0) 2018.01.03
IOS SSL(HTTPS)통신하기  (0) 2018.01.02
Android Proxy Check 우회(Frida)  (0) 2017.12.28

apktool을 이용하여 앱 리패키징 시 아래와 같은 에러가 발생했습니다.


Exception in thread "main" brut.androlib.AndrolibException: brut.directory.PathNotExist: apktool.yml
    at brut.androlib.Androlib.readMetaFile(Androlib.java:164)
    at brut.androlib.Androlib.build(Androlib.java:183)
    at brut.androlib.Androlib.build(Androlib.java:176)
    at brut.apktool.Main.cmdBuild(Main.java:228)
    at brut.apktool.Main.main(Main.java:79)
Caused by: brut.directory.PathNotExist: apktool.yml
    at brut.directory.AbstractDirectory.getFileInput(AbstractDirectory.java:103)
    at brut.androlib.Androlib.readMetaFile(Androlib.java:160)
    ... 4 more


apktool 2.2.0 버전을 사용하였으며, apktool이 리패키징 시 apktool.yml의 위치를 찾지 못해서 생기는 에러입니다.


해당 에러는 apktool의 일종의 버그이며, 최신버전을 사용하면 해결이 됩니다.


apktool 2.3.1버전을 설치하여 재 실행하였을때는 에러없이 실행되었습니다.

'Mobile' 카테고리의 다른 글

Instant Run(Split apk)  (1) 2018.01.10
Frida를 이용한 앱 실행 중 로드하는 클래스 확인  (2) 2018.01.03
IOS SSL(HTTPS)통신하기  (0) 2018.01.02
Android Proxy Check 우회(Frida)  (0) 2017.12.28
Android Device Monitor 실행 에러  (0) 2017.12.28

IOS 앱 진단시 PROXY를 잡고 SSL통신을 해야하는 상황이 존재합니다.


Android의 경우 .cer파일을 push로 넣어서 설치하면 되지만 IOS의 경우 어떤 경로에 burp인증서파일을 넣어야 하는지 몰라서 찾다가 포스팅을 합니다.


 경로는 찾지 못했지만 결론은 프록시를 잡은 후, 웹에서와 같이 http://burp를 통해 인증서를 받아서 설치합니다.




검은박스의 CA Certificate를 클릭하여 인증서를 설치합니다.



동일하게 우측 상단의 설치를 터치하여 인증서를 설치합니다.



마지막으로 설치를 눌러주면 인증서 설치가 완료됩니다.



설치 후, naver.com에 접속하여 ssl통신을 확인합니다.

※ 혹시 인증서파일을 단말기에 직접 업로드하여 설치할 경우 어느 경로에 넣어주어야 하는지 아시는분은 댓글로 부탁드립니다.


http://taesun1114.tistory.com/entry/안드로이드-프록시-사용-유무-체크에서 포스팅했던 Proxy Check하는 App을 이용하여 Proxy Check를 우회해 보려고 합니다.


Frida 공식 홈페이지는 아래와 같으며, 홈페이지를 통해 여러 정보를 획득할 수 있습니다.

https://www.frida.re/docs/home/



Test App Souce)


package com.example.gnsan.myapplication;

import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.*;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textview = (TextView)findViewById(R.id.test);
if(System.getProperty("http.proxyHost")!=null) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setPositiveButton("확인", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
android.os.Process.killProcess(android.os.Process.myPid());
}
});
alert.setMessage("Denied Proxy");
alert.show();
textview.setText(System.getProperty("http.proxyHost"));
}
}
}

프록시 유무를 체크한 후, 프록시를 사용중이라면 알림을 띄운 후 앱을 종료하는 간단한 소스입니다.


          

<프록시 사용 x>                                <프록시 사용 o>





프록시를 우회하는 Frida Code는 다음과 같습니다.



import sys
import frida



def on_message(message,data):
 print "[RET Value] -> %s" % (message)



PACKAGE_NAME = "com.example.gnsan.myapplication"

jscode = """
 Java.perform(function(){
  var System = Java.use("java.lang.System");   //System.getProperty함수는 java.lang.System
  System.getProperty.overloads[0].implementation = function(prop){ 
   return ;  // 프록시를 사용하지 않을 때 getProperty함수는 null을 리턴함
  }
 });
"""


try:
     device = frida.get_usb_device(timeout=10)
     pid = device.spawn([PACKAGE_NAME])    //Packagename으로 앱을 찾음
     print("App is starting ... pid : {}".format(pid))
     process = device.attach(pid)        
     device.resume(pid)    //resume을 해주지 않으면 화면을 불러올 수 없음
     script = process.create_script(jscode)
     script.on('message',on_message)
     print('[*] Running Frida')
     script.load()
     sys.stdin.read()
except Exception as e:
     print(e)



출처: http://hyunmini.tistory.com/111?category=523090 [Hyunmini]


-----------------------------------------------------------------------------------

실패한 jscode


var isproxy = Java.use("java.lang.System");
 isproxy.getProperty.implementation=function(a){   

 

  //overloads를 해주지 않으면 error 

  //어느경우에 overload를 하는지 아시는분은 댓글로 부탁드립니다

  //overload는 다음을 통해 알게됨 : 출처: http://hyunmini.tistory.com/111?category=523090 [Hyunmini]


 console.log("getProperty's called!");
 this.getProperty();
 };



var test = Java.use("java.lang.System");
 Interceptor.attach(Module.findExportByName(null,'getProperty'),{

             //findExportByName으로 getProperty를 찾으려했으나 실패함
  onLeave: function(retVal){
   console.log("HI");
   var orig_rtn = retVal.toString();
   send("return vallue :"+orig_rtn);
   retVal.replace("null");
  }
 };


-----------------------------------------------------------------------------------

  .overload() Example
    .overload('java.lang.String')
    .overload('android.app.Activity')
    .overload('int')
    .overload('[B') // byte array
    .overload('float')
    .overload('android.content.Context')
    .overload('[C')
    .overload('android.content.Context', 'android.view.View')
    .overload('android.app.Activity', 'com.cherrypicks.hsbcpayme.model.object.PayMeNotification')
    .overload('android.content.Context', 'boolean')
    .overload('android.content.Context', 'int')
    .overload('android.content.Context', 'java.lang.String')
    .overload('android.app.Activity', 'int')
    .overload('java.lang.String', 'java.lang.String')
    .overload('android.content.Context', 'android.graphics.Bitmap')
    .overload('java.lang.String', 'java.io.File')
    .overload('android.content.Context', 'java.lang.String', 'java.util.List')
    .overload('java.lang.String', 'java.lang.String', 'java.lang.String')
    .overload('java.lang.String', '[B', '[B')
    .overload('java.lang.String', 'java.lang.String', 'android.content.Context')
    .overload('android.app.Activity', 'com.cherrypicks.hsbcpayme.model.object.PayMeNotification', 'int')
    .overload('[B', '[B', '[B')
    .overload('android.content.Context', 'java.lang.String', 'java.lang.String')
    .overload('android.app.Activity', 'int', 'int', 'int', 'boolean')

Device Monitor 실행 시, 에러와 함께 로그파일 확인하라는 알람이 나타남.



※하단 에러 로그 참조


!SESSION 2017-12-28 11:50:33.244 -----------------------------------------------
eclipse.buildId=unknown
java.version=9.0.1
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=ko_KR
Command-line arguments:  -os win32 -ws win32 -arch x86_64 -data @noDefault

!ENTRY org.eclipse.osgi 4 0 2017-12-28 11:50:33.666
!MESSAGE Application error
!STACK 1
java.lang.IllegalStateException: Unable to acquire application service. Ensure that the org.eclipse.core.runtime bundle is resolved and started (see config.ini).
 at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:74)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
 at java.base/java.lang.reflect.Method.invoke(Unknown Source)
 at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
 at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
 at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
 at org.eclipse.equinox.launcher.Main.main(Main.java:1414)



너무 높은 JDK 버전(현재 JDK 9 )에서 실행해서 나는 에러로 JDK 8을 설치하고 실행하니 제대로 실행되는 것을 확인함

Android에서 Proxy를 사용하는지 체크하는 경우 System.getProperty를 이용하는 방법이 존재한다.


System.getProperty(key) - 운영체제나 JVM에 의존적인 정보를 알아낼 때 사용하는 함수로써 시스템정보를 불러옴


Example)

package com.example.taehwan.proxy_integrity;

import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.net.Proxy;
import android.util.Log;
import android.widget.*;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textview = (TextView)findViewById(R.id.test);
// String proxy=Settings.Secure.getString(getBaseContext().getContentResolver(),Settings.Secure.HTTP_PROXY);
if(System.getProperty("http.proxyHost")!=null) {
textview.setText(System.getProperty("http.proxyHost"));
}
else
{
textview.setText("NULL!!");
}
}
}



위 방법 외에도 Settings.Secure를 이용한 방법도 존재하지만 조금더 찾아 봐야 할 것 같다..


혹시 Settings.Secure를 이용하여 Proxy Check하는 방법을 알고 계신 분은 댓글로 

예제 부탁드립니다.

====================================================================='17.12.28추가

Settings.Secure의 HTTP_PROXY옵션은 API 17 이상부터 보안취약점 때문에 사용하지 않는다고 합니다.




volatility


vol.py파일을 이용하여 리눅스에서 실행할 것이다.


imageinfo - 대부분의 경우 이 명령어는 운영시스템이나 서비스팩, 그리고 하드웨어 구조(32 또는 64 비트)를 식별하기 위해 쓰였지만 DTB 주소나 수집된 샘플의 시간과 같은 유용한 정보도 담고 있다. Imageinfo 출력값은 다른 플러그인을 사용할 때 --profile=PROFILE­­­­을 파라미터로 해야만 하는 제안된 프로파일을 알려 준다.



위와 같이 운영체제를 알 수 있으며, --profile=Win7SP1x86와 같이 사용하면 된다.


pslist - 시스템의 프로세스들을 열거하기 위해 pslist 명령어를 사용한다. 오프셋, 프로세스 이름, 프로세스 ID, 부모 프로세스 ID, 쓰레드의 수, 핸들의 수, 프로세스 시작 시간과 종료 시간을 보여 준다


pstree - 트리 형태로 프로세스를 목록화해서 보기위해 pstree 명령어를 사용한다. 이는 pslist 와 같은 방식을 사용하여 프로세스들을 열거하기에, pslist 와 마찬가지로 숨겨지거나 연결이 끊어진 프로세스들을 보여주지 않는다. 자식 프로세스들은 공백과 마침표를 이용하여 표기한다.



dlllist - 한 프로세스에서 로드된 DLL 들을 보기 위해 dlllist 명령어를 사용한다. 모든 프로세스들 대신에 특정 프로세스의 DLL 들을 보기 위해 아래와 같이 -p 또는 -pid 필터를 사용한다



printkey - 레지스트리 키값을 보여준다.

(S)하위 키값들이며 하위 키값을 살펴보기 위해서는 경로 끝에 원하는 키를 넣어주면 해당 키의 값이 나오게 된다.


사용자 계정 레지스트리 값

Microsoft\Windows NT\CurrentVersion\Profilelist\S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-1000


S-1-5-18 - 시스템 프로필(system profile)
S-1-5-19 - 로컬 서비스(Local Service)
S-1-5-20 - 네트워크 서비스(Network Service

'Forensics' 카테고리의 다른 글

Memory Forensics  (0) 2015.11.11

메모리 포렌식 도구 목록


Volatility - 메모리 포렌식에서 주로 사용되는 도구

Rekall - 구글에서 볼라틸리티를 개조한 메모리 포렌식 도구


Redline - Mandiant의 메모리 분석 도구로써 메모리뿐만 아니라 [Mandiant's IOC Editor]와 연계한 IOC 분석을 지원해주는 도구. 성능은 무난한데, 사용자 친화성이 많이 좋다



LogTracker - $MFT, $LogFile, $UsnJrnl:$J 이 삼형제를 파싱 해주는 도구.


PLASO - Log2Timeline이라는 도구의 뒤를 잇는 Timeline 분석 도구. 정확히는 Timeline 분석을 위한 도구 집합.


등등이 있다.
이제 Volatility를 사용해보도록 하겠다.
Volatility는 공식홈페이지에서 exe파일을 받아서 설치를 해도 되며, py파일 형태로 받아서 사용해도 무방하다.

https://code.google.com/p/volatility/downloads/list 위 URL에서 Volatility 다운이 가능하다.

아마도 분석을 하면서 알게 된 내용이나 낙서장 용도로 자주 사용할 예정이다.

'Forensics' 카테고리의 다른 글

Volatility  (0) 2015.11.11

vi 에서 hex editor 처럼 사용할 수 있는 모드가 있다.


1. 실행파일을 vi로 연후에 


:%!xxd 


입력.




:%!xxd




'System > Linux' 카테고리의 다른 글

CentOs 7.x 네트워크 설정  (0) 2018.10.31
Kali Wine32 Error  (0) 2018.04.23
리눅스 core file  (0) 2013.03.18
nohup  (0) 2013.03.18
리눅스 tee 명령어  (0) 2013.03.14

+ Recent posts