[某小说旗下漫画SFSecurity逆向记录]
某天心血来潮,弄了个书源,爬某平台的漫画既然这样,那么第一步肯定就是抓包了
先MT看看
APP有某数字加固,不慌,通过一些手段绕过SSL检查,开始抓包
我们看看请求
```
https://api.*****.com/search/comics/result/new?q=血姬与骑士&expand=comics,typeName,authorName,intro,latestchaptitle,latestchapintro,tags,sysTags&sort=hot&page=0&size=12&systagids=&isFinish=-1&updateDays=-1
```
这里没啥特殊的
我们再看看请求头
有一个Authorization头,但分析了好几次后,发现是固定的,所以我们也写死就行
还有一个叫SFSecurity头,里面包含了一个随机的uuid,时间戳和deviceToken
nonce=1DD2FC4E-15C0-4FA7-AD33-599B8483B9A9×tamp=1741955967576&devicetoken=5B1883D9-D7E9-BAD4-A60F-DF82A415E432&sign=6A92026619F3C78EAC36270E729C5EBB
那么我们的目标就很明确了,那便是拿下sign参数
32位HEX,盲猜MD5
经过一些奇奇怪怪的操作之后,我们成功把数字加固脱了下来
进dex分析
看到了一些奇怪的东西
上面的clinit里加载了二进制库libsfdata.so,所以算法大概率就在这里面
我这里没有电脑,所以是纯手机处理(其实我看过ida,一so有壳,二被混淆了,静态分析超级难)
我们先readelf一下
```
47: 0000000000021a4c 21584 FUNC GLOBAL DEFAULT 10 _ZN3MD59transformEPKh
49: 0000000000020bdc 900 FUNC GLOBAL DEFAULT 10 _ZN3MD5C2Ev
97: 0000000000028c44 92 FUNC GLOBAL DEFAULT 10 _Z3md5Ss
109: 00000000000283fc1632 FUNC GLOBAL DEFAULT 10 _ZNK3MD59hexdigestEv
113: 0000000000026e9c1584 FUNC WEAK DEFAULT 10 _ZN3MD52HHERjjjjjjj
444: 0000000000027aa42392 FUNC GLOBAL DEFAULT 10 _ZN3MD56updateEPKhj
后面省略
```
发现了大量的MD5相关,所以MD5无疑
因为APP有数字加固,所以我决定自己搓一个APP,模拟调用函数
写APP这一步省略
那么,上frida吧
编写Hook脚本
```js
Java.perform(function () {
console.log('hook start');
var checkInterval = 1000;
var maxAttempts = 20;
var attempt = 0;
// 因为我APP逻辑问题,so不是启动时加载,所以需要这一步
var interval = setInterval(function () {
attempt++;
var module = Module.findBaseAddress('lib**data.so');
if (module) {
clearInterval(interval);
console.log('lib**data.so loaded at: ' + module);
hookFunction();
} else if (attempt >= maxAttempts) {
clearInterval(interval);
console.log('Failed to load lib**data.so within the given attempts');
}
}, checkInterval);
function hookFunction() {
var funcAddress = Module.findExportByName('lib**data.so', '_ZN3MD56updateEPKhj');
if (!funcAddress) {
console.log('Function _ZN3MD56updateEPKhj not found'); // 这是MD5最关键的MD5Update函数
return;
}
console.log('Function address: ' + funcAddress);
Interceptor.attach(funcAddress, {
onEnter: function(args) {
// C++成员函数的第一个参数是this指针
// 后续参数为数据指针和数据长度
var thisPtr = args;
var dataPtr = args;
var dataLength = args.toInt32();
console.log('\nMD5::update called');
console.log('this:', thisPtr);
console.log('dataPtr:', dataPtr);
console.log('dataLength:', dataLength);
// 检查指针有效性
if (!dataPtr.isNull() && dataLength > 0) {
// 读取前N个字节(防止数据过长)
var readSize = Math.min(dataLength, 512);
var rawData = Memory.readByteArray(dataPtr, readSize);
console.log('Data:', rawData);
} else {
console.log('Invalid data pointer or length');
}
}
});
}
});
```
就酱紫,我们成功拿到了MD5哈希前的明文
```
1DD2FC4E-15C0-4FA7-AD33-599B8483B9A917419559675765B1883D9-D7E9-BAD4-A60F-DF82A415E432后面保密
```
一看,这不就是前面三个参数拼上一个固定的盐吗
最后经过测试,抓取的盐是正确的,那么我们的工作便顺利完成了
好厉害。谢谢澄子 橙子,牛批。 看不懂 但好厉害 夸夸{:5_192:} 看不懂,但是感觉很牛逼 绝绝子。厉害哒
大佬厉害 漫画的盐xw*******{:5_188:} 感谢分享 太厉害了,都是看不懂的代码