样本名称及版本:QUJDX0FuZHJvaWRfVjEwLjAuMA==
菜鸡发帖,大佬些不要喷我
菜鸡发帖,大佬些不要喷我
菜鸡发帖,大佬些不要喷我
重要的事说三遍
首先拿到apk,用mt管理器查看,发现是绑企业版,使用fart脱壳能够成功脱下来
抓包
样本有vpn检测,需要过掉
抓到的包结果如下:

可以发现请求体和响应体都进行了加密,应该是同一套加解密算法
复制curl到postman里面,发现请求没有响应,同时发现请求头里面有个sign,应该也会有检测,所以大概就有两个需要搞的加密:headers里的sign,请求体的加密以及响应的解析(猜测应该是对应的)
Sign
通过frida hook定位可以找到加密函数是com.alipay.mobile.common.transport.utils.RpcSignUtil类下的
public static SignData signature(Context context, String externalAppKey, boolean isReq2Online, String content, boolean pUseSignAtlas, int signType) {
int rpcGlobalSignType;
try {
SignRequest signRequest = new SignRequest();
signRequest.appkey = MpaasPropertiesUtil.getAppkey(externalAppKey, isReq2Online, context);
signRequest.content = content;
if (signType == 0 && (rpcGlobalSignType = TransportStrategy.getGlobalRpcSignType()) != 0) {
signType = rpcGlobalSignType;
}
if (signType != 0) {
signRequest.signType = a(signType);
} else if (a(context, pUseSignAtlas)) {
signRequest.signType = SignRequest.SIGN_TYPE_ATLAS;
}
LogCatUtil.info("RpcSignUtil", "[signature] signType ".concat(String.valueOf(signType)));
return SignData.createSignDataBySignResult(SecurityUtil.signature(signRequest));
} catch (Throwable e) {
LoggerFactory.getTraceLogger().warn("RpcSignUtil", e);
return SignData.newEmptySignData();
}
}继续往上寻找,可以发现加密函数在接口SecurityManager里面,寻找接口实现,再往上寻找可以找到接口com.alibaba.wireless.security.open.securesignature.ISecureSignatureComponent
@InterfacePluginInfo(pluginName = "main")
/
public interface ISecureSignatureComponent extends IComponent {
String getSafeCookie(String str, String str2, String str3) throws SecException;
String signRequest(SecurityGuardParamContext securityGuardParamContext, String str) throws SecException;
}注意这个pluginName,看起来有点熟悉,没错,这个加密参数是用的淘系的加密,将一部分代码做成插件的形式,寻找app lib目录下的libmain.so文件,果然是个压缩包,里面有一段dex和加密用到的so文件
最后定位到so层的加密函数是
public class JNICLibrary {
public static native Object doCommandNative(int i, Object... objArr);
}使用肉丝的r0tracer hook 入参出参

可以确定是正确的位置,于是hook so层的注册地址
这里还会报错,查看最后一个hook到的so层函数名字是 stopjni啥的,猜测应该是啥禁止hook函数注册地址的方式,在hook代码里添加
class_name.indexOf('com.xxxx') == 0这样只hook特定的函数就不会报错,然后直接上unidbg
补完环境发现报错,才想起来这种函数应该是需要执行初始化才能调用
可以看到初始化调用了两次,一次是10101,第二次是10102

unidbg里先初始化然后在调用docommandNative函数成功生成加密参数,和hook到的对比发现一样

这样sign参数就算解决了
请求体加密以及响应解密
hook定位到加密函数是
public byte[] encrypt(byte[] data) {
try {
byte[] seed = MiscUtils.generateRandomStr(16).getBytes();
byte[][] encodeResult = this.d.encode(seed, GzipUtils.toGzip(data), this.c);
this.e = encodeResult[0];
byte[] encryptedBody = encodeResult[1];
byte[] encryptedKey = encodeResult[2];
return a(encryptedKey, encryptedBody);
} catch (Exception ex) {
LogCatUtil.error("ClientRpcPack", "encrypt ex: " + ex.toString() + " ,error: " + this.d.error());
throw ex;
}
}so层加密函数是com.alipay.mobile.common.mpaas_crypto.Client下的encode
同上hook入参出参

然后hook so层注册地址,hook了半天没hook到才想到可能是静态注册的

同样上unidbg,一来直接报错

一开始我还以为是啥自带的方法没有,找了半天后面看ida代码才意识到,这不就是取Java层类的一个属性吗(我是废物呜呜呜
)
注意这个函数也需要初始化
将环境补齐之后能成功加密请求体

经测试,解密响应也可以
于是在idea中测试是否能获取到数据(本来是想在python中调用的,但是在python中gzip压缩的结果和Java的压缩结果始终不一样,不知道是不是我哪里没设置正确
)
最终测试能够成功请求并返回响应

ps:成都有没有大佬找小弟的 
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
最后于 2025-2-21 15:49
被727编辑
,原因: