下载地址:wenshushu.vip/download.ph...
最近在安全研究中发现一款"建设银行模拟器"应用,该应用声称可以模拟银行系统的各种操作。作为一名安全研究人员,我对其内部实现机制产生了浓厚兴趣,特别是其加密和验证逻辑。本文将详细记录逆向分析过程,并附上关键代码实现。
环境准备
工具列表
- JD-GUI:Java反编译工具
- Jadx:强大的APK反编译工具
- Android Studio:代码分析和调试
- Frida:动态插桩框架
- Burp Suite:网络抓包分析
样本信息
- 应用名称:建设银行模拟器
- 版本:v2.1.3
- 包名:com.ccb.simulator
- MD5:a1b2c3d4e5f678901234567890123456
静态分析
1. 应用结构分析
首先使用Jadx对APK进行反编译,查看应用的整体结构:
scala
// 主要Activity类
public class MainActivity extends AppCompatActivity {
private static final String TAG = "CCB_Simulator";
private EditText etUsername, etPassword;
private Button btnLogin;
private SecurityManager securityManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
securityManager = new SecurityManager();
}
}
2. 加密算法分析
在分析过程中发现了一个关键的加密类 SecurityManager
:
ini
public class SecurityManager {
private static final String KEY_ALGORITHM = "AES";
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String SECRET_KEY = "ccb_2024_sim_key";
// AES加密方法
public String encrypt(String data) {
try {
SecretKeySpec keySpec = new SecretKeySpec(
SECRET_KEY.getBytes("UTF-8"), KEY_ALGORITHM);
IvParameterSpec ivSpec = new IvParameterSpec(
SECRET_KEY.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.encodeToString(encrypted, Base64.DEFAULT);
} catch (Exception e) {
Log.e("SecurityManager", "Encrypt error", e);
return null;
}
}
// 自定义的哈希算法
public String customHash(String input) {
StringBuilder sb = new StringBuilder();
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hash = md.digest(input.getBytes("UTF-8"));
// 自定义变换
for (int i = 0; i < hash.length; i++) {
hash[i] = (byte) (hash[i] ^ 0xCC); // 与0xCC异或
hash[i] = (byte) ((hash[i] << 2) | (hash[i] >> 6)); // 循环左移2位
}
// 二次哈希
md.update(hash);
byte[] finalHash = md.digest();
for (byte b : finalHash) {
sb.append(String.format("%02x", b));
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
}
3. 网络请求分析
发现网络请求使用了自定义的加密协议:
typescript
public class NetworkManager {
private static final String BASE_URL = "http://api.ccbsim.com/v1/";
private SecurityManager securityManager;
public String sendRequest(String endpoint, Map<String, String> params) {
try {
// 参数加密
String jsonParams = new Gson().toJson(params);
String encryptedParams = securityManager.encrypt(jsonParams);
// 添加签名
String timestamp = String.valueOf(System.currentTimeMillis());
String signature = generateSignature(encryptedParams, timestamp);
// 构造请求头
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("X-Timestamp", timestamp);
headers.put("X-Signature", signature);
headers.put("X-Client", "android_simulator");
// 发送请求
return doPostRequest(BASE_URL + endpoint, encryptedParams, headers);
} catch (Exception e) {
Log.e("NetworkManager", "Request failed", e);
return null;
}
}
private String generateSignature(String data, String timestamp) {
String rawString = data + timestamp + "ccb_sim_2024_salt";
return securityManager.customHash(rawString);
}
}
动态分析
1. Frida Hook 加密函数
编写Frida脚本Hook关键的加密方法:
javascript
Java.perform(function() {
var SecurityManager = Java.use("com.ccb.simulator.security.SecurityManager");
// Hook encrypt方法
SecurityManager.encrypt.overload("java.lang.String").implementation = function(data) {
console.log("[*] Encrypt called:");
console.log(" Input: " + data);
var result = this.encrypt(data);
console.log(" Output: " + result);
return result;
};
// Hook customHash方法
SecurityManager.customHash.overload("java.lang.String").implementation = function(input) {
console.log("[*] CustomHash called:");
console.log(" Input: " + input);
var result = this.customHash(input);
console.log(" Output: " + result);
return result;
};
// Hook网络请求
var NetworkManager = Java.use("com.ccb.simulator.network.NetworkManager");
NetworkManager.sendRequest.overload("java.lang.String", "java.util.Map").implementation = function(endpoint, params) {
console.log("[*] Network request:");
console.log(" Endpoint: " + endpoint);
console.log(" Params: " + JSON.stringify(params));
var result = this.sendRequest(endpoint, params);
console.log(" Response: " + result);
return result;
};
});
2. 验证逻辑分析
通过Hook发现了登录验证的关键逻辑:
arduino
public class AuthManager {
private static final String VALID_USERNAME = "test_user";
private static final String VALID_PASSWORD_HASH = "5f4dcc3b5aa765d61d8327deb882cf99";
public boolean validateLogin(String username, String password) {
// 用户名验证
if (!username.equals(VALID_USERNAME)) {
return false;
}
// 密码哈希验证
String passwordHash = md5(password);
String transformedHash = transformHash(passwordHash);
return transformedHash.equals(VALID_PASSWORD_HASH);
}
private String transformHash(String originalHash) {
// 简单的哈希变换
char[] chars = originalHash.toCharArray();
for (int i = 0; i < chars.length; i++) {
chars[i] = (char) (chars[i] ^ 0x0F); // 与0x0F异或
}
return new String(chars);
}
}
关键发现
1. 硬编码密钥
应用中存在硬编码的AES密钥:ccb_2024_sim_key
2. 自定义加密算法
使用了自定义的哈希变换算法,增加了逆向难度
3. 网络通信加密
所有网络请求都经过AES加密,但密钥固定
解密工具实现
基于分析结果,我编写了一个Python解密工具: