简体   繁体   English

如何保护Android应用程序免受网络流量捕获

[英]How to secure android app from network traffic capturing

My app is making some http requests and I don't want others to see the content of those requests.我的应用程序正在发出一些 http 请求,我不希望其他人看到这些请求的内容。 At the moment I can easily check what my app is doing by using Fiddler.目前,我可以使用 Fiddler 轻松检查我的应用程序在做什么。 Now in order to track network traffic on my phone I had to change my Wi-Fi settings and connect to the Internet using proxy server.现在为了跟踪我手机上的网络流量,我不得不更改我的 Wi-Fi 设置并使用代理服务器连接到 Internet。 ie my computer.即我的电脑。 Is it possible to programatically check whether phone is using proxy?是否可以以编程方式检查手机是否使用代理? If knew that phone is using proxy I would forbid user using the app by showing some error dialog.如果知道手机正在使用代理,我会通过显示一些错误对话框来禁止用户使用该应用程序。 Are there any ways of solving this problem?有没有办法解决这个问题? I've seen apps that work on normal Wi-Fi settings but does not when using proxy therefore I assume there is a solution.我见过可以在普通 Wi-Fi 设置下运行但在使用代理时不运行的应用程序,因此我认为有解决方案。 By the way I'm using retrofit library for making requests.顺便说一下,我正在使用改造库来提出请求。

Moving your traffic to use HTTPS will help protect it against network snoops like Fiddler.移动您的流量以使用 HTTPS 将有助于保护它免受像 Fiddler 这样的网络窥探。

However, Fiddler can decrypt HTTPS traffic with the user's help, which means that you can't only use HTTPS, you also need to implement Certificate Pinning, whereby the client code verifies that the server presented one specific certificate (not the interception certificate Fiddler generates).但是,Fiddler 可以在用户的​​帮助下解密 HTTPS 流量,这意味着您不能只使用 HTTPS,还需要实现 Certificate Pinning,即客户端代码验证服务器是否提供了一个特定的证书(而不是 Fiddler 生成的拦截证书) )。

However, even that doesn't really solve the problem, as the user can simply jailbreak their device and disable your certificate pinning code.然而,即使这样也不能真正解决问题,因为用户可以简单地越狱他们的设备并禁用您的证书固定代码。

You should probably step back and reconsider what threats specifically you're trying to protect against and then update your question appropriately.您可能应该退后一步,重新考虑您要防范的具体威胁,然后适当地更新您的问题。

Programmatically check for a Proxy以编程方式检查代理

Is it possible to programmatically check whether phone is using proxy?是否可以以编程方式检查手机是否使用代理?

Yes.是的。 Check the replies to this Stackoverflow anser.检查对此Stackoverflow anser 的回复。

If knew that phone is using proxy I would forbid user using the app by showing some error dialog.如果知道手机正在使用代理,我会通过显示一些错误对话框来禁止用户使用该应用程序。

Any code running on the client side can be manipulated at runtime by the attacker on a device he controls by using an instrumentation framework, for example Frida :任何在客户端运行的代码都可以在运行时由攻击者在他控制的设备上通过使用检测框架(例如Frida)进行操作

Inject your own scripts into black box processes.将您自己的脚本注入黑盒进程。 Hook any function, spy on crypto APIs or trace private application code, no source code needed.挂钩任何函数,监视加密 API 或跟踪私有应用程序代码,无需源代码。 Edit, hit save, and instantly see the results.编辑,点击保存,并立即查看结果。 All without compilation steps or program restarts.无需编译步骤或程序重新启动。

Possible Solutions可能的解决方案

My app is making some http requests and I don't want others to see the content of those requests.我的应用程序正在发出一些 http 请求,我不希望其他人看到这些请求的内容。

You've got yourself a difficult challenge here.你在这里遇到了一个艰难的挑战。 Let's see some of your options...让我们看看你的一些选择......

Certificate Pinning证书固定

Several techniques exist to implement certificate pinning, but since Android API 24 it's supported natively via the network security config file.存在几种实现证书锁定的技术,但自 Android API 24 以来,它通过网络安全配置文件得到本地支持。 I have wrote the article Securing HTTPS with Certificate Pinning to show how it can be done:我已经写了文章使用证书锁定保护 HTTPS来展示它是如何完成的:

In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.为了演示如何使用证书锁定来保护您的移动应用程序和 API 服务器之间的 https 流量,我们将使用我在上一篇文章中使用的相同 货币转换器演示移动应用程序。

In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.在本文中,我们将了解什么是证书锁定、何时使用它、如何在 Android 应用程序中实现它,以及它如何防止中间人攻击。

Bypassing Certificate Pinning绕过证书锁定

Several methods exist, like with an instrumentation framework or by repacking the mobile app.存在多种方法,例如使用检测框架或重新打包移动应用程序。

Bear in mind that just because certificate pinning can be bypassed it doesn't mean you shouldn't be using it in your mobile app, by the contrary it's strongly recommended that you do so.请记住,仅仅因为可以绕过证书锁定并不意味着您不应该在您的移动应用程序中使用它,相反,强烈建议您这样做。

Using an Instrumentation Framework使用检测框架

Unfortunately, Frida can also be used to bypass certificate pinning and I wrote the article How to Bypass Certificate Pinning with Frida on an Android App to show you how to do it:不幸的是,Frida 也可用于绕过证书固定,我写了文章如何在 Android 应用程序上使用 Frida 绕过证书固定来向您展示如何做到这一点:

Today I will show how to use the Frida instrumentation framework to hook into the mobile app at runtime and instrument the code in order to perform a successful MitM attack even when the mobile app has implemented certificate pinning.今天,我将展示如何使用 Frida 检测框架在运行时连接到移动应用程序并检测代码,以便即使在移动应用程序已实现证书锁定的情况下也能成功执行 MitM 攻击。

Bypassing certificate pinning is not too hard, just a little laborious, and allows an attacker to understand in detail how a mobile app communicates with its API, and then use that same knowledge to automate attacks or build other services around it.绕过证书锁定并不太难,只是有点费力,并且允许攻击者详细了解移动应用程序如何与其 API 通信,然后使用相同的知识来自动化攻击或围绕它构建其他服务。

Using the a Repackaged Mobile App使用重新包装的移动应用程序

Another techinque widely used is to repackage the mobile app without the code for certificate pinning or with it disabled.另一种广泛使用的技术是在没有证书固定代码或禁用证书的情况下重新打包移动应用程序。 I wrote the article Bypassing Certificate Pinning that shows how to remove the network security config file and repackage the mobile app:我写了绕过证书锁定的文章,展示了如何删除网络安全配置文件并重新打包移动应用程序:

In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates.在本文中,您将学习如何重新打包移动应用程序以使其信任自定义 ssl 证书。 This will allow us to bypass certificate pinning.这将允许我们绕过证书锁定。

A Possible Better Solution一个可能的更好的解决方案

Are there any ways of solving this problem?有没有办法解决这个问题?

So, you already saw that certificate pinning is the way to go, but once it can be bypassed you need a way to detect this bypass in order to prevent this type of attack.因此,您已经看到证书锁定是可行的方法,但是一旦可以绕过它,您需要一种方法来检测此绕过以防止此类攻击。

I recommend you to read this answer I gave to the question How to secure an API REST for mobile app?我建议您阅读我对如何为移动应用程序保护 API REST的问题给出的答案 , especially the sections Hardening and Shielding the Mobile App , Securing the API Server and A Possible Better Solution . ,尤其是加强和屏蔽移动应用程序保护 API 服务器一个可能的更好的解决方案部分

Do You Want To Go The Extra Mile?你想走得更远吗?

In any response to a security question I always like to reference the excellent work from the OWASP foundation.在对安全问题的任何回答中,我总是喜欢参考 OWASP 基金会的出色工作。

For Mobile Apps对于移动应用程序

OWASP Mobile Security Project - Top 10 risks OWASP 移动安全项目 - 十大风险

The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. OWASP 移动安全项目是一个集中资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。 Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性。

OWASP - Mobile Security Testing Guide : OWASP - 移动安全测试指南

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.移动安全测试指南 (MSTG) 是移动应用安全开发、测试和逆向工程的综合手册。

 public static boolean isNetworkConnected(final Context context) {
        boolean cks = false;
        final Activity activity = (Activity) context;
        ConnectivityManager connMgr = (ConnectivityManager) 
             context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isvpnConn = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            for (Network network : connMgr.getAllNetworks()) {
                NetworkInfo networkInfo = connMgr.getNetworkInfo(network);
                if (networkInfo.getType() == ConnectivityManager.TYPE_VPN) {
                    isvpnConn |= networkInfo.isConnected();
                           AlertDialog.Builder alert = new 
                             AlertDialog.Builder(getActivity());
                                  alert.setMessage("Sonthing want wrong!! Please 
                        disconnect VPN and try again.")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                          dialog.dismiss();
                            activity.finish();
                            activity.finishAffinity();
                    }
                }).setNegativeButton("Cancel", null);

        AlertDialog alert1 = alert.create();
        alert1.show();
                    cks = false;
                } else {
                    cks = true;
                }
            }
        }
        return connMgr.getActiveNetworkInfo() != null && connMgr.getActiveNetworkInfo().isConnected();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM