VPN认证-登陆包协议分析
起因
这个玩意是业务需求, hw支撑, 去年2022年的项目, 分析一下这个SSLVPN软件的登陆包, 走协议去批量登录(?).
都一年了, 应该没啥用了.
经过
简单来说就是先找关键函数, 然后分析调用, 最后直接调用; 因为这个协议比较简单就完全模拟了
关键函数
先对软件的gwclient.exe
下了断点, 发现最终发包是在WSASend
交叉引用发现就一个东西
下断点打堆栈发现是用了InitializeSecurityContextA
发现是直接用BCryptDecrypt解密
这个明显是http 那么找这个的请求包 来源是BCryptHashData
同时有
/download/sign.package.conf
/client/custom_lang.json
发现前面就这几个请求
那么我们dump下他这个非http的返回值 frida-trace -i BCrypt*rypt
grep一下, 发现log中有敏感信息
敏感日志
仔细分析日志, 发现已经解析了相关的信息
其中SSLMSG_One发送了信息 ParseMsg_One函数进行了该配置的解析
找到了这里
这里直接新线程了
配置数据包解析
在上述分析的parser函数中, 结合抓的包进行分析
0x213e是端口
In [5]: hex(8510)
Out[5]: ‘0x213e’
这个包是待parse的包
推测结构体
1 | struct my_struct1 |
这个函数sub_44EF70是crc么
这里是上面那个函数的执行结果
其中分配的buf1为 此时结构体为长度 网址 空
此时v8的union为
后面函数执行完成后为
这边先剧透下 长度为0x04+0x17(+0x01)+0x4 分别是string(0x17)+long 见下图的sendlen
也就是在字符串之后 此时查看日志文件 发现buf后的即为地址
而这个函数就是搞字符串的
dump一下
上图中少了个ListCount
发现和type强相关
如果type为1 则自增0x4
如果type为2 则先读取长度 然后再获取信息 不能被4整除的情况暂时未考虑
对齐的话找了个非标准的 推测是0x4对齐
In [3]: hex(0xca+0x4270088+0x4)
Out[3]: ‘0x4270156’
反编译
发现vpninfo_count与ListCount应该一致 如果无的则不进行解析
一致
那么结构体2
1 | struct my_struct2 |
登陆包解析
这里是请求包
猜测 2000003为登录
那么就直接对SSLMSG_One交叉引用就好了
那么看上面怎么去push的
那么就是这个
那么加密后的buffer是
这是最终发的数据
仔细分析发现ioctl就在里面
1 | struct __declspec(align(4)) my_struct3 |
而且还加了长度!
包的返回应该也有0x8的结构体头
登录返回
1 | 00000000 82 00 00 03 00 00 00 04 02 00 04 05 67 e2 01 15 |............gâ..| |
对应的位置
构建脚本
根据上述, 把包的结构搞定了后 dump看看区别
对比抓包无误, 那么写脚本
结果
结果就是能登录了