如何合理绕过域名开关类的安卓网络验证

小胖个人博客:www.seawind-gz.com.cn

交流群:348355266

今天有一个需求,逆向某违法APK,分析其的工作原理.由于样本不便提供,这里只提供部分代码.

private String mSerial = "123";


int id = view.getId();
if (id == R.id.adb_view) {
    RequestQueue newRequestQueue = Volley.newRequestQueue(getApplicationContext());
    newRequestQueue.add(new StringRequest(0, "https://la.xxxxx.com/lala/adb?serial=" + this.mSerial, new Response.Listener<String>() {
        /* 

        public void onResponse(String str) {
            if (str != null && str.contains("true") && str.contains(MainActivity.this.mSerial)) {
                MainActivity.this.mHandler.sendEmptyMessage(4);
            }
        }
    }, new Response.ErrorListener() {
        /* 

        @Override // com.android.volley.Response.ErrorListener
        public void onErrorResponse(VolleyError volleyError) {
        }
    }));
} else if (id == R.id.jinru) {
    ...
} else if (id != R.id.update_button && id == R.id.yingyongshangdian_button) {
    ...
}



private Handler mHandler = new Handler() {
        /* 

        public void handleMessage(Message message) {
            super.handleMessage(message);
            int i = message.what;
            if (i != 4) {
                switch (i) {
                    case 0:
                        MainActivity.this.showProgressbar2();
                        return;
                    case 1:
                        if (MainActivity.this.mProgressDialog != null && MainActivity.this.mProgressDialog.isShowing()) {
                            MainActivity.this.mProgressDialog.dismiss();
                            return;
                        }
                        return;
                    default:
                        return;
                }
            } else {
                Toast.makeText(MainActivity.this.getBaseContext(), "开发者打开成功", 0).show();
                SystemProperties.set(MainActivity.KEY_ADB, "true");
            }
        }
    };

1. 背景

这边的大概意思就是,如果接口https://la.xxxxx.com/lala/adb?serial=123接口返回的内容包含"123"和"true"的时候,则执行SystemProperties.set(MainActivity.KEY_ADB, "true");命令打开adb操作的接口.

Q:可能有的人问,为什么不打开开发者模式?

A:该APP为系统应用且系统魔改过,无法截图,adb等许多操作。修改apk文件也无法安装进去(有会的大佬教下如何安装)。所以就只能通过伪造接口的方式来实现了。

2. 修改Hosts文件

管理员模式打开文件C:\Windows\System32\drivers\etc\hosts

添加关系

192.168.x.xxxx la.xxxxxx.com

3. 使用Flask伪装接口

from html import escape
from utils import valid_login, log_the_user_in
from flask import Flask, render_template, request

app = Flask(__name__)


@app.route('/')
def hello():
    return '个人博客: http://www.seawind-gz.com.cn'


@app.route('/lala/adb',methods = ['POST','GET'])
def adb():
    return '123 true'

if __name__ == '__main__':
    app.run(host="xxx.xxx.xxx.xxx",port=443,ssl_context=(
        r"F:\nginx-1.21.0\https\name.crt",
        r"F:\nginx-1.21.0\https\name.key"
    ))

4. 生成Https证书

  1. 下载openssl http://slproweb.com/products/Win32OpenSSL.html
  2. 安装之后配置环境变量 OPENSSL_HOME ...bin Path变量末尾加;%OPENSSL_HOME%
  3. 创建私钥 openssl genrsa -des3 -out name.key 1024 需要记住输入的密码 name为自定义的名字
  4. 创建ssr证书 openssl req -new -key name.key -out name.csr 需要输入一些列信息,最重要的是Common Name表示要使用https访问的域名
  5. 去除密码 复制name.key重命名为name.copy.key
  6. .执行openssl rsa -in name.copy.key -out name.key
  7. 生成crt证书 openssl x509 -req -days 365 -in name.csr -signkey name.key -out name.crt

此时我们就有4个文件

name.copy.key  name.crt  name.csr  name.key

5. 配置Nginx


    server {
        listen       443 ssl;
        server_name  la.xxxxx.com;
        root   F:/nginx-1.21.0/https;
        ssl_certificate ../https/name.crt;
        ssl_certificate_key ../https/name.key;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

6.总结

至此,一个接口的伪造就完成了. 虽然比较麻烦,但这也是一种解决办法.