如何合理绕过域名开关类的安卓网络验证
小胖个人博客:www.zhuoyue360.com
原文链接:http://www.zhuoyue360.com/index.php/archives/21/
今天有一个需求,逆向某违法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.zhuoyue360.com'
@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证书
- 下载openssl http://slproweb.com/products/Win32OpenSSL.html
- 安装之后配置环境变量 OPENSSL_HOME ...\bin Path变量末尾加;%OPENSSL_HOME%
- 创建私钥 openssl genrsa -des3 -out name.key 1024 需要记住输入的密码 name为自定义的名字
- 创建ssr证书 openssl req -new -key name.key -out name.csr 需要输入一些列信息,最重要的是Common Name表示要使用https访问的域名
- 去除密码 复制name.key重命名为name.copy.key
- .执行openssl rsa -in name.copy.key -out name.key
- 生成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.总结
至此,一个接口的伪造就完成了. 虽然比较麻烦,但这也是一种解决办法.