安全矩阵

 找回密码
 立即注册
搜索
楼主: gclome

郝恬学习日记

[复制链接]

839

主题

889

帖子

3559

积分

论坛元老

Rank: 8Rank: 8

积分
3559
 楼主| 发表于 2020-12-5 20:43:26 | 显示全部楼层
本帖最后由 gclome 于 2020-12-5 22:46 编辑

5.1 序列化保护方式
5.1.1 序列号保护机制
软件验证序列号,其实就是验证用户名和序列号之间的数学映射关系

(1)将用户名等信息作为自信息,通过函数F变换之后得到注册码

公式为:序列号=F(用户名)

      由于这种方式的保护机制在用户机器上再现了生成注册码的过程(即在用户机器上执行了函数F),所以是以明文出现在内存中的。这是非常不安全的,因为无论F函数多么复杂,解密者只需要把函数F的实现代码从软件提取出来,就可编制一个通用的计算注册码程序了

(2)通过注册码验证用户名的正确性
       软件作者在给注册用户生成注册码的时候,使用的依然是下面这种变换

    序列号=F(用户名) 注:这里的F是一个可逆变换
       软件在检查注册码的时候,是利用F的逆变换对用户输入的注册码进行变换的。若变换的结果和用户名相同,这说明是正确的注册码,
                             (5-2)
       用来生成注册码的函数F未直接出现在软件代码中,而且正确注册码的明文也未出现在内存中
破解此类注册码检查方式的途径
1、修改比较指令
2、通过找出其逆变换,即函数F,从而得到一个正确的注册码或者写出注册机
3、给定一个用户名,利用穷举法找到一个满足式(5-2)的序列号。只适合穷举难度不大的函数
4、给定一个序列号,利用式(5-2)变换出一个用户名,从而得到一个正确的用户名/序列号对。

(3)通过对等函数来检查注册码



    此方法同样不会再内存中出现明文,F1、F2是两种完全不同的的算法,但用户名通过F1算法的计算出的特征字等于序列号通过F2算法计算出的特征字,这种算法在设计上比较简单,保密性相对以上两种算法也要好的多。如果能够把F1、F2算法设计成不可逆算法的话,保密性相当的好;可一旦解密者找到其中之一的反算法的话,这种算法就不安全了。一元算法的设计看来再如何努力也很难有太大的突破,那么二元呢?

(4)同时将用户名和注册码采用的自变量(即采用二元函数)

特定值 = F(用户名,序列号)

    这个算法看上去相当不错,用户名称与序列号之间的关系不再那么清晰了,但同时也失去了用户名于序列号的一一对应关系,软件开发者必须自己维护用户名称与序列号之间的唯一性,但这似乎不是难以办到的事,建个数据库就好了。当然你也可以根据这一思路把用户名称和序列号分为几个部分来构造多元的算法。

    
特定值 = F(用户名1,用户名2,...序列号1,序列号2...)


5.1.2 如何攻击序列号保护机制
1、数据约束性的秘诀

 这个概念是+ORC提出的,只限于用明文比较注册码的那种保护方式。在大多数序列号保护的程序中,那个真正的、正确的注册码或密码(Password)会于某个时刻出现在内存中,当然它出现的位置是不定的,但多数情况下它会在一个范围之内,即存放用户输入序列号的内存地址±0X90字节的地方。这是由于加密者所用工具内部的一个Windows数据传输的约束条件决定的。

2、hmemcpy函数

 函数Hmemcpy是Windows9x系统的内部函数,位于KERNEL32.DLL中,它的作用是将内存中的一块数据拷贝到另一个地方。由于Windows9x系统频繁使用该函数处理各种字串,因此用它作为断点很实用,它是Windows9x平台最常用的断点。在Windows NT/2K中没有这个断点,因为其内核和Windows9x完全不同。
3、利用消息断点
许多序列号保护软件都有一个按钮,当按下和释放鼠标时,将发送WM_LBUTTONDOWN(0201h)和VM_LBUTTONUP(0202h)消息,因此,用这个消息下断点很容易就能得到按钮的事件代码。

4、利用提示信息
  目前大多数软件在设计时采用了人机对话的方式。即软件在执行一段程序之后会显示一串提示信息,以反映该程序运行后的状态。
     例如:在traceme实例中输入假序列号,会显示“序列号错误,再来一次”。可以用ollydbg、ida、X64dbg等反汇编工具查找相应的字符串,定位到相关代码处

5.1.3 字符串比较形式









本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

839

主题

889

帖子

3559

积分

论坛元老

Rank: 8Rank: 8

积分
3559
 楼主| 发表于 2020-12-7 16:40:06 | 显示全部楼层
160个carckme ---1、 Acid burn

首先使用peid查壳,发现没有壳,是Delphi的程序。

接下来把它载入到ollydbg里面,并运行这个程序


我们可以先看一下这个运行的程序,这个cm给了我们两个进行破解的模式,一个是用户名+注册码,另一个是只有注册码

先来看第一种 有用户名+注册码的

当我们输入用户名和注册码,由于注册码错误,就会引发弹框报错。


接下来我们用最常用,也是最快的方式找到弹出这个对话框的位置,搜索字符串,回到ollydbg右键 查找----所有参考文本字串----查找文本(搜索Sorry):我们可以看到,根据关键词搜索,有两处一模一样的,如果此时去做分析,需要对两个都进行下判断,看那个是有效的。


先看第一处“Sorry , The serial is incorect !”
成功搜索到关键字符,我们双击到反汇编窗口,成功定位!可以看到错误提示的call,上面有个jge跳转可以跳过错误提示,我们下断点,再次check it,停下来了,这时发现跳转是实现的!但是我们判断一下,我们应该找到执行正确的地方,然后替换这里的jge,但是在这个代码的附近并没有,说明这个报错字符串很有可能是迷惑人的,真正做判断的应该不是这里。



在看到下一个搜索到的“Sorry , The serial is incorect !”
这里有正确的提示信息,但是在jnz处跳过了正确提示信息。
我们大概浏览下代码,最近部分有两个可疑跳转JNZ 和JMP, JNZ会通过它上面的call 004039FC 判断我们的伪码是否正确,判断的结果存在EAX中,如果EAX不等于就跳转到错误提示信息框那里。我们的目的是无论伪码是否正确都通过验证,所以最简单的办法就是将jnz这句
使用NOP填充,我们尝试一下:选择JNZ这句,用nop进行汇编,回到原始程序,再次点击Check it baby!

也可以修改成jmp无条件跳转,让他跳转到回显正确的地方!

对于另外一种只有注册码的,我们的分析也是和上面一样
可以看见报错框中显示:“Try Again!”
我们将Try Again!作为关键词进行搜索,通过筛选判断,定位到了这里

接下来可以直接使用nop代替jnz那一行


小结:对于做crackme,有以下几个步骤:
一、查壳,使用peid查看是否有壳(由于刚起步,自己练习的都是不加壳的)
二、进行破解:
1、先运行下程序,观察一下报错的一些关键字
2、通过搜索关键字,使用文本进行定位,此时可能会有多处,我们应该加以判断
3、利用填充nop可以使条件判断跳转je jnz等跳转取消
     同理可利用jmp无条件跳转使其必须跳转达到爆破的目的
   (破解的方法可能不止这些,不过目前只接触了这两个)






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2021-4-15 22:00 , Processed in 0.017009 second(s), 17 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表