목차
1. 함정 분석에 집중
1.okhttp 호출 프로세스
2. Frida가 분석 과정에서 밟은 함정(핵심은 댓글에 있습니다)
2. 사용자 만료를 초래하는 android_id 처리하기
3. 패킷 캡처 도구를 사용하여 패킷을 캡처하고 구덩이에서 빠져나옵니다
1. 프록시 설정은 괜찮은데 앱이 로그인할 수 없습니다
4. 종료
운영 및 유지보수 안전 Frida에서 APK 네트워크 패키지를 가져오는 방법

Frida에서 APK 네트워크 패키지를 가져오는 방법

May 16, 2023 pm 07:16 PM
apk frida

1. 함정 분석에 집중

패킷을 캡처하기보다는 시스템 관점에서 후크 포인트를 찾으세요.

1.okhttp 호출 프로세스

public static final MediaType JSON
= MediaType.get("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
로그인 후 복사

클라이언트의 중요한 코드는 client.newCall()에 있습니다. 위는 okhttp 공식 웹사이트의 예입니다. 여기에서 인터페이스 호출을 시작하면 결국 okhttp 프레임워크로 호출됩니다. okhttp는 원래 SDK이므로 나중에 AOSP가 시스템에 통합되므로 프레임워크 계층으로 분류할 수 있습니다.

프레임워크 레이어는 상세하지 않습니다. 주로 다음 Java 클래스입니다.

com.android.okhttp.internal.huc.HttpURLConnectionImpl
com.android.okhttp.internal.http.HttpEngine
com.android.okhttp.internal.http.RetryableSink
com.android.okhttp.internal.http.CacheStrategy$Factory
로그인 후 복사

사실 client.newCall은 결국 URL을 통해 연결을 얻습니다

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
로그인 후 복사

여기의 urlConnection은 실제로 HttpURLConnectionImpl의 인스턴스입니다. 이 클래스에는 getInputStream getOutputStream이 있습니다. 메서드 내부적으로 HttpEngine의 getBufferedRequestBody 및 getResponse가 각각 호출됩니다. 처음에는 이 두 인터페이스를 연결하려고 했습니다. 예를 들어 getResponse를 연결한 후 응답을 인쇄할 수 있습니다.

나중에 Request는 본문이 아닌 헤더만 출력할 수 있다는 것을 발견했습니다. 그래서 분석에 푹 빠져서 getBufferedRequestBody 함수를 사용하여 싱크를 얻을 수 있다는 것을 발견했습니다. 마지막으로 RetryableSink가 획기적인 지점으로 사용됩니다. 예를 들어 쓰기 함수를 연결하면 본문이 인쇄될 수 있습니다. 쓰기 함수는 앱 수준에서 urlConnection.getOutputStream().write에 해당합니다.

나중에 요청에 대해 getBufferedReuqestBody 함수가 두 번 이상 호출될 수 있으므로 데이터 중복 문제가 있을 수 있다는 것을 발견했습니다. 나중에 CacheStrategy$Factory.get 지점이 후크에 있음을 발견했습니다. 데이터 복제. 위의 모든 후크에는 단점이 있는 것으로 나타났습니다

  • 데이터 복제

  • non-okhttp 호출을 캡처할 수 없습니다

다음 호출 스택은 기본 레이어의 send, sendmsg, write, recv, read부터 시작됩니다. 인쇄되기도 했습니다. 결국 3일 동안 고생한 끝에 치료를 포기하고 대신 도구를 사용하기로 결정했습니다.

okhttp流程:sdk接口->okhttp框架->native(libc)
로그인 후 복사

2. Frida가 분석 과정에서 밟은 함정(핵심은 댓글에 있습니다)

  1. android.util.Log가 인쇄되지 않습니다

    var Logd = function Logd(tag, msg) {
    Java.use("android.util.Log").d(tag, msg);
    };
    
    
    Logd('http-body-', '11111111111111');//该log不打印
    Logd('http-body', '11111111111111');//该log打印
    로그인 후 복사
  2. 익명 내부 클래스는 멤버를 얻기 위해 반사가 필요합니다

    var printRequest = function(request) {
    var Buffer = Java.use("com.android.okhttp.okio.Buffer");
    var bodyField = request.getClass().getDeclaredField('body');
    bodyField.setAccessible(true);
    
    if (request == null) return;
    Logd('http', 'printRequest: request' + request);
    //var requestBody = request.body();//gadget直接报错
    var requestBody = bodyField.get(request);
    
    var requestBodyClass = requestBody.getClass();
    var ClassInstanceArray = Java.array('java.lang.Class', []);
    
    //var contentLengthMethod = requestBodyClass.getMethod("contentLength");//gadget直接报错
    var contentLengthMethod = requestBodyClass.getMethod("contentLength", ClassInstanceArray);
    
    contentLengthMethod.setAccessible(true);
    var ObjectInstanceArray = Java.array('java.lang.Object', []);
    var contentLength = requestBody ? contentLengthMethod.invoke(requestBody, ObjectInstanceArray) : 0;
    //if (contentLength == 0) contentLength = contentLen;
    Logd('http', 'printRequest contentLength: ' + contentLength);
    if (contentLength > 0) {
    var BufferObj = Buffer.$new();
    requestBody.writeTo(BufferObj);
    Logd(TAG, "\nrequest body :\n" + BufferObj.readString() + "\n");
    }
    };
    로그인 후 복사
  3. android.os.Bundle을 인쇄할 때 Bundle

    var printIntentAndExtras = function printIntentAndExtras(intentObj) {
    if (intentObj == null) return;
    var Intent = Java.use("android.content.Intent");
    var Bundle = Java.use("android.os.Bundle");
    var bundleObj = Intent.getExtras.call(intentObj);
    
    if (bundleObj != null) {
    Bundle.getSize.call(bundleObj, null);//调用getSize即可反序列化
    }
    
    Logd(TAG, ‘printIntentAndExtras ’ + bundleObj);
    };
    로그인 후 복사

을 풀어야 합니다. 사실, 위에서 언급한 함정은 처음에는 몇 가지 frida 네트워크 차단 솔루션을 시도했습니다. 또한 okhttp의 인터셉터 솔루션을 주의 깊게 연구한 결과 마침내 앱도 사용하고 있음을 발견했습니다. 인터셉터가 비활성화되어 충돌이 발생하여 솔루션을 사용할 수 없습니다.

앱의 스말리도 순수하게 분석해 콜 스택과 네트워크 요청을 찾아보았지만 결국 상대적으로 작은 이득이 몇 개밖에 없어 독자들에게는 유용하지 않을 수도 있지만, 참고할 수 있도록 기록해 두었습니다. 나중에 기억해 보세요.

  1. java.net.URL 가로채기

    var URLHook = function() {
    var URL = Java.use('java.net.URL');
    URL.openConnection.overload().implementation = function() {
    var retval = this.openConnection();
    Logd('URL', openConnection' + retval);
    return retval;
    };
    };//URL.openConnection调用概率比较大,但是不一定对网络进行请求
    로그인 후 복사
  2. 앱이 http 요청을 호출하기 전에 json이 사용되는 위치를 가로채는데, 이는 그 중 하나일 뿐입니다

    var jsonHook = function() {
    var xx = Java.use('e.h.a.a');//app smali
    var xxa_method = xx.a.overload('org.json.JSONObject', 'java.lang.String', 'java.lang.String');
    xxa_method.implementation = function(jsonObj, str1, str2) {
    Logd("json", jsonObj + " str1: " + str1 + " str2" + str2);
    xxa_method.call(this, jsonObj, str1, str2);
    }
    }
    로그인 후 복사
  3. trace http 관련 클래스

    var traceAllHttpClass = function() {
    Java.perform(function() {
    Java.enumerateLoadedClasses({
    onMatch: function(name, handle) {
    /*"e.h.a.a$a",起初也拦截过app的该混淆类*/
    if (name.indexOf("com.android.okhttp.Http") != -1 || name.indexOf("com.android.okhttp.Request") != -1
    || name.indexOf("com.android.okhttp.internal") != -1) {
    traceClass(name);//对这三个class进行trace
    }
    },
    onComplete: function() {
    }
    });
    });
    };
    로그인 후 복사
  4. Request $Builder 가로채기

    var BuilderClass = Java.use('com.android.okhttp.Request$Builder')
    
    BuilderClass.build.implementation = function () {
    //LOG('com.android.okhttp.HttpUrl$Builder.build overload', { c: Color.Light.Cyan });
    //printBacktrace();
    var retval = this.build();
    Logd(TAG, "retval:" + retval);
    printRequest(retval);
    return retval;
    }
    로그인 후 복사
  5. property_get 가로채기

    var nativePropertyGetAddr = Module.findExportByName(null, '__system_property_get');
    Interceptor.attach(nativePropertyGetAddr, {
    onEnter: function onEnter(args) {
    this._name = args[0].readCString();
    this._value = args[1];
    },
    onLeave: function onLeave(retval) {
    if (this._name.indexOf("ro.build.id") != -1) {
    var virtualDevice = getVirtualDevice();
    if (DEBUG_PROP) Logd(TAG, "__system_property_get fake " + this._name + "=>to " + virtualDevice.build_id);
    
    this._value.writeUtf8String(virtualDevice.build_id);
    }
    
    var strFilter = /^ro\./g;
    if (DEBUG_PROP && this._name.match(strFilter) != null) Logd(TAG, "__system_property_get " + this._name);
    }
    });
    로그인 후 복사

2. 사용자 만료를 초래하는 android_id 처리하기

var DEBUG_PROP = false;
var DEVICE_CONFIG = "/sdcard/.device";

function getVirtualDevice() {
var nativeOpen = new NativeFunction(Module.findExportByName(‘libc.so’, 'open'), 'int', ['pointer', 'int']);
var nativeRead = new NativeFunction(Module.findExportByName('libc.so', 'read'), 'int', ['int', 'pointer', 'int']);
var fd = nativeOpen(Memory.allocUtf8String(DEVICE_CONFIG), 0);
var mem = Memory.alloc(1024);
var readLen = nativeRead(fd, mem, 1024);
var json = JSON.parse(mem.readCString(readLen));
return json;
}

Secure.getString.implementation = function () {
var retval = this.getString(arguments[0], arguments[1]);
if (DEBUG_PROP) Logd(TAG, "Settings.Secure get " + arguments[1] + " val " + retval);

if (arguments[1].indexOf("android_id") != -1) {
var virtualDevice = getVirtualDevice();
return virtualDevice.android_id;
}

return retval;
};
로그인 후 복사

3. 패킷 캡처 도구를 사용하여 패킷을 캡처하고 구덩이에서 빠져나옵니다

1. 프록시 설정은 괜찮은데 앱이 로그인할 수 없습니다

Analytic adb 로그, 프로세스에 java.security.cert.CertPathValidatorException이 인쇄되어 있고 이전에 frida가 패킷을 가로채고 인증서를 우회하는 것에 대한 게시물을 본 적이 있습니다. 먼저 무차별 검색을 시도해보세요:

Java.perform(function(){
const groups = Java.enumerateMethods('*!verify/u');
var classes = null;
for(var i in groups){
var classes = groups[i]['classes'];

for(var i in classes){
Java.use(classes[i]['name'])
.verify
.overload('java.lang.String', 'javax.net.ssl.SSLSession')
.implementation = function() {
printBacktrace();
LOG("[+] invoke verify", { c: Color.Red });
return true;
}
}
}
});
로그인 후 복사

직접 강제로 true를 반환하도록 강제 검증하더라도 동일한 SSL 문제 오류가 발생하기 때문에 여전히 로그인할 수 없습니다. 바이두에서 검색해서 답을 찾았습니다. apktool의 압축을 푼 다음

res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<!--添加fiddle证书可信任
<certificates src="user" />
-->
</trust-anchors>
</base-config>
</network-security-config>
로그인 후 복사

를 수정하여 서명을 다시 패키지하고 실행합니다. Fiddle이 패키지를 포착하면 앱이 정상적으로 로그인할 수 있습니다. 이번에는 앱의 SSL 확인이 단방향 앱 확인만 가능합니다. 서버가 확인을 수행하지 않습니다.

4. 종료

화요일 오후부터 금요일까지 고생했습니다. 결국 시스템 수준에서 HttpEngine에서 Hook Point를 찾는 것은 좋은 방법이 아니며 단점은 이미 명확합니다. 그래서 일요일에는 Baidu에서 찾은 패킷 캡처 도구와 다양한 방법을 사용하여 발생한 문제를 점차적으로 해결했습니다.

여기에 잡힌 가방 두 개가 있습니다:

HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:34 GMT
Content-Type: application/json
Content-Length: 101
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding

{"result":{"errno":"OK","errmsg":"成功"},"data":{"version":"xxxxxxxx-351e-40cf-aaa9-3177d6df9b7f"}}
-----------------------------------
HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:34 GMT
Content-Type: application/json
Content-Length: 99
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding

{"result":{"errno":"OK","errmsg":"成功"},"data":{"nodeToken":"xxxxxxxc24d79f55c0b07beaf50cb566"}}
로그인 후 복사
POST https://tap-xxxxxxx.xxxxxx.com/api/v2/Android/analytics/basic HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cjbcjdsabcjvbXVCJ9.eyJ1aWQiOjE4ODMzMDEsInNlY3JldCI6IjAzNzE0M2Y3LTExMTUtNGY2Yi1iNzQxLWUyMjc5ZDM3MGY3MCIsImV4cCI6MTU5NzgxNjQ0MiwiaXNzIjoiZ3Vlc3QgbG9naW4ifQ.W3SiO0-afbhxPITjRinnhyWhZLy1bzZhYexm5VCWklI
X-Device-ID: 9xxxxxxx84d4542e
X-Loc: ["China","Shanghai","Shanghai","","ChinaUnicom","31.224349","121.4767528","Asia/Shanghai","UTC+8","310000","86","CN","AP","xxx.166.xxx.xxx"]
X-App-Version: 2.2.0
Content-Type: application/json; charset=utf-8
Content-Length: 208
Host: xx-xxxx.xxxxxx.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.7.2

{"deviceID":"9xxxxxxx84d4542e","model":"V1813BA","systemVersion":"9","version":"2.2.0","location":{"latitude":xx.x99x990990991,"longitude":xxx.26689769073256},"network":{"g2":0,"g3":0,"g4":4,"g5":0,"wifi":4}}

-----------------------------------
HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:35 GMT
Content-Type: application/json
Content-Length: 43
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding

{"result":{"errno":"OK","errmsg":"成功"}}
로그인 후 복사

위 내용은 Frida에서 APK 네트워크 패키지를 가져오는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

승인된 APK 침투 테스트를 수행하는 방법 승인된 APK 침투 테스트를 수행하는 방법 May 20, 2023 pm 12:29 PM

침투 테스트 초보자로서 이 기사의 목적은 나와 같은 초보자에게 몇 가지 테스트 아이디어를 제공하는 것입니다. 관련된 내용은 비교적 기본적일 수 있습니다. 사촌 여러분, 양해해 주시기 바랍니다. APK의 압축을 풀고 APK를 얻은 후 7-Zip을 사용하여 직접 압축을 풀면 여러 폴더, AndroidManifest.xml 파일 및 dex 파일을 얻을 수 있습니다. dex2jar https://sourceforge.net/projects/dex2jar/를 사용하여 이 dex 파일의 압축을 풀어 jar 파일을 생성한 다음 jd-gui를 사용하여 Java 소스 코드를 봅니다. 물론, 소스 코드에서 허점을 찾을 수 있지만 일반적으로 혼동이 있으므로 여기서는 깊이 논의하지 않습니다.

Google 앱 베타 APK 분해로 Gemini AI 비서에 추가되는 새로운 확장 기능 공개 Google 앱 베타 APK 분해로 Gemini AI 비서에 추가되는 새로운 확장 기능 공개 Jul 30, 2024 pm 01:06 PM

최신 업데이트(v15.29.34.29 베타)의 APK 분해를 고려하면 Google의 AI 비서인 Gemini가 더욱 강력해질 예정입니다. 거대 기술 기업의 새로운 AI 비서는 몇 가지 새로운 확장 기능을 얻을 수 있는 것으로 알려졌습니다. 이러한 확장 기능은

Windows 11에서 APK 파일을 여는 방법 Windows 11에서 APK 파일을 여는 방법 Apr 14, 2023 am 11:19 AM

APK라는 글자로 끝나는 파일을 다운로드해 본 적이 있나요? 이는 일반적으로 휴대폰에서 작동하고 컴퓨터에 로드되는 앱에서 발생합니다. 이러한 파일의 대부분은 문자 APK로 끝납니다. 이러한 파일을 열려고 했지만 비정상적인 확장명으로 인해 파일이 저장된 위치나 여는 방법을 알 수 없었을 수도 있습니다. Windows 11에서 이러한 파일을 여는 방법을 찾고 있고 Google에서 검색해 본 적이 있다면 걱정하지 마세요! 실제로는 그보다 훨씬 쉽습니다. 실제로 무료이며 아무것도 설치할 필요도 없습니다. 글쎄요, 운영 체제에 맞는 APK 파일 오프너를 다운로드해야 합니다. 하지만 아직 다운로드하지 않은 경우에만 해당됩니다.

APK 소프트웨어의 이름을 바꾸는 방법 APK 소프트웨어의 이름을 바꾸는 방법 Dec 08, 2023 am 10:23 AM

변경 단계: 1. 이름을 변경하려는 APK 파일이 컴퓨터에 저장되어 있는지 확인하세요. 2. APK 파일을 마우스 오른쪽 버튼으로 클릭하고 '이름 바꾸기' 옵션을 선택하세요. 3. 원본 파일 이름을 새 이름으로 바꾸세요. 원하는 이름. 파일 확장자 ".apk"가 아닌 파일 이름 부분만 변경해야 합니다. 4. Enter 키를 누르거나 창에서 "이름 바꾸기" 버튼을 클릭하여 변경 사항을 저장합니다.

Frida에서 APK 네트워크 패키지를 가져오는 방법 Frida에서 APK 네트워크 패키지를 가져오는 방법 May 16, 2023 pm 07:16 PM

1. 단지 패킷을 캡처하기 위해 캡처하는 것이 아니라 시스템 관점에서 함정을 분석하고 후크 포인트를 찾습니다. 1.okhttp 호출 프로세스 publicstaticfinalMediaTypeJSON=MediaType.get("application/json;charset=utf-8");OkHttpClientclient=newOkHttpClient();Stringpost(Stringurl,Stringjson)throwsIOException{RequestBodybody=RequestBody

Unity에서 출시한 Android APK를 암호화하는 방법 Unity에서 출시한 Android APK를 암호화하는 방법 May 13, 2023 am 11:10 AM

Unity3D 프로그램 코드의 보안 문제 보안 문제 Unity3D 프로그램의 핵심 어셈블리 파일 Assembly-CSharp.dll은 표준 .NET 파일 형식이며 메서드 이름, 클래스 이름, 유형 정의 등과 같은 풍부한 메타데이터 정보가 함께 제공됩니다. DnSpy와 같은 도구를 사용하면 쉽게 디컴파일 및 변조가 가능하며 코드 로직, 클래스 이름, 메소드 이름 등을 한눈에 볼 수 있습니다. 코드 로직이 디컴파일되면 다양한 유형의 플러그인이 번식하기 쉽고 게임의 밸런스가 파괴되기 쉽습니다. 코드 로직에 허점이 있으면 발견되어 악용되기 쉬우며 이로 인해 예측할 수 없는 손실이 발생할 수 있습니다. 개발자. 리소스 보안 문제: 컴파일 및 패키징 단계에서 Unity3D 프로그램은 Unity 편집기를 통해 리소스를 AssetBun으로 패키징합니다.

Win11 APK 설치 가이드 Win11 APK 설치 가이드 Jan 03, 2024 pm 10:24 PM

우리 모두 알고 있듯이 Microsoft는 win11에서 Android 애플리케이션을 실행하고 로컬 apk를 설치할 수 있다고 발표했습니다. 그러나 win11을 업데이트한 후 사용자는 로컬 apk를 설치하는 방법을 몰랐다는 사실을 발견했습니다. 아직 win11에서는 이 기능을 구현하지 않았습니다. 이 기능을 사용하려면 먼저 해당 기능이 설치될 때까지 기다려야 합니다. win11에서 로컬 apk를 설치하는 방법: 1. Microsoft에 따르면 win11이 이 기능을 설치한 후 다운로드한 apk 파일을 직접 두 번 클릭하여 직접 설치할 수 있습니다. 2. 설치가 완료된 후 사용자는 시스템에서 직접 실행할 수도 있습니다. 3. 현재는 win11의 공식 버전이지만 Microsoft에서는 아직 win11에 대해 이 기능을 구현하지 않았습니다. 4. 그래서 사용자가 win11을 사용하고 싶다면

APK 단순 코드 삽입을 수행하는 방법 APK 단순 코드 삽입을 수행하는 방법 May 14, 2023 am 11:43 AM

1. 서문 apk가 암호화되지 않은 경우, 이를 디컴파일하여 smail 파일을 얻습니다. 삽입해야 할 코드를 삽입하면 됩니다. 그런 다음 도장을 찍고 서명하세요! 2. apk 만들기 androidstudio를 사용하여 간단한 apk를 생성합니다. 그냥 기본 코드를 사용하세요. packagecom.example.myapplication1;importandroidx.appcompat.app.AppCompatActivity;importandroid.os.Bundle;publicclassMainActivityextendsAppCompatActivity{

See all articles