前言:学习软件逆向分析技术,使软件开发者能够更好的弥补软件缺陷1的补码,修复软件漏洞,提升软件安全,将损失降为最低。(这才是我们学习逆向的初衷)1的补码,本篇文章内容仅限于学习交流--同时也是给网络验证作者展示了一个漏洞亦或者说是一个有待加强的地方!其实作者已经写的很强了!!
0x1:前期分析工作
知己知彼百战不殆-我们想要弄一个东西的时候肯定是要弄清楚它的流程是什么样的,直接贴上坤坤云客户端最核心的地方 今天我们不讲封包-我们来讲讲补码
以上三张图大概就是坤坤云的客户端源码 核心子程序了,第一张图是登陆部分第二张图试用功能第三张图 是公告部分
判断开始 (取数组成员数 (分割取回的数据) = 5 且 分割取回的数据 [1] = “登录成功”)
写配置项 (取运行目录 () + “/配置.ini”, “配置”, “km”, 编辑框帐号.内容)
登录成功 = 真
全局_封包返回时间 = 分割取回的数据 [2]
全局_远程数据 = 分割取回的数据 [3]
全局_用户到期时间或者点数积分 = 分割取回的数据 [4]
全局_用户token = 分割取回的数据 [5]
全局_北京时间 = 时间_取北京时间 ()
上述文本代码可以看见 明显是登陆的组包数据 一共5个数组 也就是5条返回值根据 数组赋值的信息 大概组包如下:
“登录成功” + “|||” + 时间到文本 (取现行时间 (), ) + “|||” + “我是远程数据你知道吗?” + “|||” + “500” + “|||” + “”
为什么组包里面第二个 数据是时间到文本 (取现行时间 (), )呢?因为是这条 全局_封包返回时间 = 分割取回的数据 [2] 最后封包返回时间会跟北京时间(联网)做一个对比的 那么第三条就是远程数据 没啥好说的第四条坤坤云有两个返回参数 要么是用户点数 要么是用户到期时间 (我就默认写了500点 ) 很明显我没有正版卡 自然不知道它时间的格式 只能凭借着经验拼接了一下第五条也就是全局_用户token我也不知道他的长度和数据类型 比如全数字还是全英文 具体多长 我也不知道 反正我只知道不能让他是空的就可以了啊哈哈!!
第二张图的组包我就不列举了,直接看看第三张图的公告吧!因为也是从公告开始入手的!
.判断 (取数组成员数 (分割取回的数据) = 5 且 分割取回的数据 [1] = “公告”)
透明标签公告.标题 = 分割取回的数据 [2]
服务器版本 = 分割取回的数据 [3]
更新方式 = 分割取回的数据 [4]
更新地址 = 分割取回的数据 [5]
.如果真 (软件版本 ≠ 服务器版本)
时钟自动更新.时钟周期 = 1
大概组包如下:“公告” + “|||” + “我是公共内容我已经拦截补码啦你知道吗?” + “|||” + “2.2” + “|||” + “强制更新” + “|||” + “” 也是5条参数 分隔符为“|||”
知道了组包的方式和数据,那么我们就刻意关注一下客户端中这个子程序 (验证类处理数据)的内部写法了如下图:
通过反汇编坤坤云的模块我们得知了 验证处理数据的内部写法 只需要关注两个子程序即可! 文本_解密一共两个处理过程,大致流程就是 服务器组好数据包,进行特殊处理之后返回给客户端---客户端收到数据--先通过()处理一下数据 然后才进行最后一个步骤 文本_解密 最终得出明文数据 返回给客户端源码进行数据分割。
巧合的是 (验证类处理数据) 带有VMP标识了 然后 文本_解密 这两个最为关键的解密call(子程序)居然不带VMP标识。如下图所示
我个人想法猜测 这个 如果带VMP标识的话 第一是软件处理数据的效率变慢亦或者 直接处理数据错误文本_解密 这个也是一样 具体没有进行实测过。坤坤云作者不可能会漏下这个最主要的东西 很大程度上应该是为了软件处理数据的效率
既然你处理那么我只能通过你留下的缺陷进行补码了!
0x2 :开始实战
根据我们前期分析的缺陷-我们一共有两个方案 第一是直接定位 第二 是直接定位 文本_解密 无论那个方案其实都是可以的,下面我来演示一下
为了方便数据的输出,我对坤坤云客户端源码进行了一个小改动! 我添加了一个信息框输出我们补码之后返回的数据方便我们查看是否补码成功! 如下图
软件编译出来暂且是无壳状态,我们暂时不要加壳-因为我们要通过字符串来提取 没有被VM的那两个解密CALL的特征码 有了特征码之后我们就可以随意加壳了 不需要字符串去定位那两个解密call在什么位置了。用到的字符串是这个:断开||| “yz”, “”两个字符串都可以!
在OD中看到我们熟悉的字眼
就说明我们已经来到了坤坤云模块里面的这个位置
双击字符串进去就看见了我们熟悉的字眼啦!如下图 红色箭头指向的CALL就是我们亲爱的 解密子程序了直接F2下一个断点再说 然后跑起来 断下F7进去
我们进来之后你就成功了一半了!!进来的界面如下图-注意看我框起来的部分 这个复制出二进制 AD AB AD AB 68 08 00 00 00 记好特征码 下次直接搜索即可 任由它VM到死 这个特征码都不会定位不到!
然后我们进行第一种补码方式 直接在这里进行补码 由于我们补码的数据没有地方放 我索性就在它程序下面 填写上我们组好包的公告数据看如下图!
这个弄好补码数据之后我们就开始操作了 记住补码数据的地址
然后我们直接在头部 这样操作 mov eax, retn 意思是我们直接补明码不用它解密处理数据了 直接给他明文返回 紧接着按F8走出去还需要进行最后一个处理
F8走出来目前是这个位置看如下2张图 我们此时此刻补码的是明文 所以不能让它继续往下走了 再走就去 文本解密 这个子程序了 所以我们直接平衡堆栈 leave rent 让它返回出去即可
直接leave rent 让他返回到客户端源码的这个位置它返回会带着我们给的明文出去的
最终按F9大胆的跑起来!!!你就会发现!!软件崩溃了啊哈哈
别忘了我改造了源码让他信息框输出了
(这个方法好像是我平衡堆栈导致数据清空了 数据肯定是返回了公告没有成功分割 先不管了)( 我继续第二个方法 直接找文本解密 子程序的特征码 往下翻翻就看见了 )
我框起来就是特征码 DB 45 E8 DD 5D E8 DD 45 E8 DC 25 D1 DE 4F 00 DD 5D E0 DD 45 E0 同样也是没有被VM到 任它外壳怎么样VM都不会影响特征码的定位
如果打算在文本解密CALL这里用的话 只需要在头部赋值我们补码的地址+一个rent就可以 因为文本解密是最后一道call了所以不需要再走出去leave rent了看如下图
F9跑起来
此时此刻你会发现已经成功了!
既然已知第二种方法是最快的不需要处理堆栈平衡 那么我们就直接定位 文本解密然后接下来干登陆!!!
登录数据包:登录成功|||2023年2月18日23时17分59秒|||我是远程数据你知道吗?|||500|||”
由于登录数据包服务器时间我们要实时变动的 所以我写了一个小辅助源码来帮我实现每一次补丁都是实时时间--------
看如下图:登录的数据比较麻烦 它要进行一个时间对比---时间还是联网和本地对比的
我写了一个临时补丁如图!补丁数据 中的第三个参数我实时获取时间 用一个时钟疯狂写入!以免触发时间异常导致我凉凉
由于我提前准备好了一个空白的地址 一直存放实时时间 以便我补码时 时间永远对的上!!我直接在文本解密call头部补码了
然后大胆的按下F9 你会发现你被拉黑了哈哈
开玩笑!!!!
大概就是这样啦!!!
个人觉得作者是不是要VM虚拟化一下关键的解密call呢?
限时特惠:本站持续每日更新海量各大内部创业课程,一年会员仅需要98元,全站资源免费下载
点击查看详情
站长微信:Jiucxh