1. 相关学习资料
http://en.wikipedia.org/wiki/Brute-force_attack http://en.wikipedia.org/wiki/Dictionary_attack http://en.wikipedia.org/wiki/Rainbow_tables http://lasecwww.epfl.ch/pub/lasec/doc/Oech03.pdf http://www.91ri.org/7593.html http://www.ha97.com/4009.html
2. 密码破解的分类
0x1:Brute-Force-Attack
也就是常说的"暴力破解",这是一种"时间消耗型"的password reverse方式,确定了密文的加密方式的前提下,使用相同的加密算法,计算 M = H(P) P为所有的明文空间 H为加密算法 M为密文 然后将计算得到的M和待破解的密文进行比较,如果匹配成功,则对应的明文P即为待破解密文的明文。值得注意的是,这个枚举P和比较M的过程往往是在内存中进行的,
也即在计算的过程中一边产生,一边比较,这次破解结束后,下一次破解又要重新开始从头枚举,效率不太高
典型的Brute-Force-Attack如图
0x2:Directory-Based-Attack
字典破解本质上还是"暴力破解"的一种,我觉得它是"Brute-Force-Attack"的另一个极端,"Brute-Force-Attack"是一种纯的"时间消耗型"的攻击方式,它所有的开销都是时间,
而"Directory-Based-Attack"是一种纯的"空间消耗型"的攻击方式。 在"Directory-Based-Attack"中,攻击者是对所有的明文(M)进行预计算(PreConputation),将所有的明文的HASH都事先计算好,并保存起来。典型的MD5字典如下: .... password 5f4dcc3b5aa765d61d8327deb882cf99 admin 21232f297a57a5a743894a0e4a801fc3 cnblog efbc3548e65e7225dcf43d3918d94e6f .... 在进行破解的时候,破解程序将字典映射Mapping到内存中,然后将HASH和待破解的密文进行逐条比较(这点和Brute-Force是一样的),直到找到某条HASH和待破解的密文相同为止。
值得注意的是,基于字典的暴力破解时间上比单纯的内存计算型暴力破解更有效率,只要一次的"字典生成"花费一定的时间,后续的多次破解都可以重复使用这个字典。
注意,这里说的"字典"指的对应某个算法的字典: MD5 Directory、SHA1 Directory、NTLM Directory等等。 总的来说,字典攻击是对单纯的内存型暴力破解的一个改进,它引入了PreComputation的思想,但缺点也很明显,需要占用及其庞大的磁盘空间,以至于对于长度16以上的密码字典,
完整存储根本不可能
典型的"Directory-Based-Attack"如图
0x3:Rainbow-Table-Attack
这是对"Brute-Force"和"Directory-Base"的一种折中的破解技术,在2003年瑞典的Philippe Oechslin 在Making a Faster Cryptanalytic Time-Memory Trade-Off一文
(文章开头有给出链接)中首次被提出,它有效的利用了PreComputation的优点,同时又克服了Diecretory-Based消耗太空磁盘空间的缺点,在这两者中找到了一个平衡点。 不过,它也有缺点,即: 1) password+salt: 加盐 2) key stretching: 密码扩展,包括轮数扩展和长度扩展 接下来,我们的文章会重点分析这个彩虹表破解的技术原理
3. 密码破解方式的应用场景
在开始研究Rainbow Table-Attack的技术之前,我们有必要先明白一个问题,虽然说彩虹表破解技术比"Brute-Force-Attack"、"Directory-Based-Attack"都要好,但并不是所有场景下都能使用彩虹表进行破解的。密码破解有两种场景:
1) 远程破解场景 攻击者面对的是一个远程的服务器,并且目标服务器存储密码的生成算法也不知道,此时,我们只能使用Hydra等工具进行穷举破解(Brute-Force)、
或者字典破解(Diretory-Attack)
2) 本地破解场景 攻击者知道远程服务器的密码生成算法(常常发生在一些常见的CMS系统后中)、通过hashdump抓到了内存中的HASH密码(LM、NTLM)、或者已经拿到了密码的HASH值(脱库中常见),
攻击者可以在本地自己的计算机上进行本地计算,这个时候,相比暴力破解(Brute-Force-Attack)、字典破解(Directory-Attacj)来说,彩虹表破解就是一个更好的选择了。
4. Rainbow Table彩虹表破解技术原理
Rainbow Table相比Directory做的第一个改进就是将庞大的明文密文对"分成"了"明-密文对链chain",链条的长度越长,空间的缩减效果就越大。为了使用彩虹表技术,需要事先确定两个
函数: H(HASH函数): 密码的加密方式,不同的彩虹表对应于不同的加密方式(这点和Directory-Based的道理是一样的) 常见的H函数有: MD4、MD5、SHA1、
R(Reverse Hash函数): 逆HASH函数,并不是真的对HASH函数求逆(我们都知道HASH函数是不可逆的),这里所谓的R函数,只是一个映射Mapping函数,将H()得到的密文再次映射回一个对应
的明文,不一定是原来的明文,只要是明文就行
0x1:彩虹表生成
要注意,彩虹表的核心思想还是PreComputation的字典思想,所以生成彩虹表就是在生成一个字典,只是这个生成过程不再是单一的H计算,并保存明-密文对那么简单了。
我们分别看每一条链:
H(wikiedia)=ao4kd -> R1(ao4kd)=secret -> H(secret)=9kpmw -> R2(9kpmw)=jimbo -> H(jimbo)=v0d$x -> R3(v0d$x)=rootroot H(abcdefgh)=1vn6s-> R1(1vn6s)=bernie-> H(bernie)=kolscx-> R2(kolscx)=zurich-> H(zurich)=8ntpy -> R3(8ntpy)=myname .... H(passwd)=dlcm4-> R1(dlcm4)=culture-> H(culture)=re3xes-> R2(re3xes)=crypto-> H(crypto)=1tik0-> R3(1tik0)=linux23
有几个重点要关注:
1) 在这个例子中,彩虹表的chain length是3,也就是说一条链包含3个节点,也即这种情况可以以原本 1/3 的磁盘空间保存同等规模的字典
2) wikiedia称为"头结点",rootroot称为"尾节点"。我们最后需要保存的也就是这个头-尾节点对,而中间的中间值全都不用保存,这也是彩虹表省空间的原因
3) R1、R2、R3....Rk(K代表每条链的长度,在这个例子中是3),是K个不同的Reverse Hash函数,它存在的目的是为了避免出现不同的chain中出现重复的节点,我们可以思考一下,如果这个R在一条链中的每个节点都是一样的,那如果假如在两条链中的某两个节点在进行R()之后,得到了相同的结果,则在这之后,H计算也会得到相同的结果,紧接着R计算又是相同的结果,则造成了重复存储,浪费了存储空间,也减低了这套破解系统的明文空间覆盖度,从而间接影响了破解效果。
假如R是不变的: H(startpoint1)=median1 -> R(median1)=median12 ...... -> R(median1x)=same -> H(same)=same1 -> .... same_end H(startpoint2)=median2 -> R(median1)=same -> H(same)=same1 -> .... same_end ... 注意这个重合一定是发生在不同链上的不同位置的节点,因为H的"非碰撞性"保证了这点(思考),这个重合导致的是两条链中的某一段发生了"重合"
会出现这个现象的原因是因为我们选择的R函数很难保证"非碰撞性",即无法保证不同的输入在进行R计算不会得到不同的输出,为了解决这个问题,将一条链上的不同节点的每次计算都使用不同的R函数,这样,即使在不同链上的不同位置因为Rk是不一样的,就不会发生重合了。
回到主题上来,这个链式的表生成好之后,我们之保存每条链的头和尾的两个明文节点,中间的点都是"可计算的",故丢弃,把全部的链的头尾节点保存起来,就成了所谓的彩虹表
0x2:使用彩虹表进行HASH密码破解
再次回顾这张图
假如我们要破解的HASH密文为re3xes 1) 对密文re3xes进行Rk(k代表最后一个R函数,这里是R3)运算,得到一个临时结果 I,将这个临时结果I和每条链的尾节点进行比较,检测是否是某一条链的尾节点 1.1) 如果匹配成功,则破解成功,我们知道了这个待破解的密文属于某一条链,就可以利用这条链的头尾节点重现(再次计算)出这条链上的每个明密文对,自然也包括了待破解密文的明文 1.2) 如果匹配失败,在所有链的尾节点上都没有这个临时结果 I,则继续进行(2) 2) 对密文re3xes进行Rk-1(k-1代表倒数第二个R函数,这里是R2),这里又得到一个临时结果: crypto,再对临时结果crypto进行H计算,得到: 1tik0,再对1tik0进行Rk
(k代表最后一个R函数,这里是R3)得到一个临时结果: linux23。将这个临时结果和每条链的尾节点进行比较,检测是否是某一条链的尾节点 1.1) 如果匹配成功,则破解成功,在这个例子中我们知道匹配成功,就可以利用这条链的头节点: passwd重现(再次计算)出这条链上的每个明密文对,自然也包括了待破解密文的
明文: culture 2.1) 如果匹配失败,则继续调用Rk-2进行搜索,步骤都是类似的 ... 直到完成了R1的搜索,如果还没有找到匹配的,则宣布本次破解失败,需要增大彩虹表文件大小、重组字典
0x3:彩虹表的缺点
我们知道,彩虹表的核心思想是"PreComputation预计算",而预计算的一个最大大问题就是"当加密的形式发生变化,这个预生成的字典从某种程度上就无用了"。这么说有些不太准确,我想表达的意思是预计算对算法的变化非常敏感,这也是对抗彩虹表技术的一个思考方式。
因为彩虹表需要针对算法变化的每一种形式都预生成一个对应的字典,如果这个变化空间很大,就会使彩虹表的生成成本变得很大,这样,彩虹表原本解决的空间成本问题又再次暴露出来。
而要达到"算法变化"的方式非常多,常见的有以下两种方法
1) 加盐 saltedhash(password) = hash(password+salt) Or saltedhash(password) = hash(hash(password)+salt) 需要对付这种加密方式,彩虹表就需要针对salt的每一种可能的取值都生成一套字典,当salt的长度很长时,彩虹表的生成成本和破解效率都会大幅下降 2) 密码增强 key stretching 是加密方式变化除了"加盐",加密轮数也是一个可变化的点,MD5-Crypt and in bcryp中都使用了Crypt Loop技术,即使用同一个算法,或不同的算法组合对一个明文进行迭代的
多次(1000以上)加密,这样,加密的轮数和加密方式的组合本身也构成了一个"变化空间" 需要对付这种加密方式,彩虹表就需要针对每一个加密轮数+加密方式的组合都生成一套字典,同样,彩虹表的生成成本和破解效率都会大幅下降
5. 密码破解工具
http://files.cnblogs.com/LittleHann/MD5%E7%A0%B4%E8%A7%A3%E5%B7%A5%E5%85%B7.rar MD5解密器个人加强版 LC5 http://ishare.iask.sina.com.cn/f/8862330.html Ophcrack http://www.objectif-securite.ch/ophcrack.php SAMInside http://www.insidepro.com/eng/saminside.shtml Rainbowcrack http://www.project-rainbowcrack.com/ 彩虹表免费下载 https://www.freerainbowtables.com/en/tables/
6. 新技术
研究一下目前密码破解的新技术,主要有以下几个方面
1. 当前密码破解的方法 目前大规模高速密码破解技术主要有: 1) CPU破解 通过大规模、高覆盖率、社工库类型的明文密码库作为输入字典,对密文进行破解,这里的关键就在于字典库的高高覆盖率,可以达到很高的破解率 2) GPU破解 关于GPU的告诉运算原理,可以参考这两篇文章,我目前对硬件的研究并不多,也会也许会考虑写一些关于GPU硬件方面的研究文章 http://blog.chinaunix.net/uid-9620812-id-3061237.html http://wenku.baidu.com/link?url=j90kB6Vk8KuEA8lITgZNJ4GbHeXgiArFcS3xwXRaEv83LxtqUFaWJLDyxqN6ue1iB-q3zwNTfPL55k2qneDHD3nHc2cqzBW2tktrfMRboDi GPU破解所带来的变化是计算速度的成倍提升,相当于原本的CPU破解,理论上GPU破解也可以采用字典的方法,但是,因为GPU的超高速性,所以针对GPU破解,我们就可以更多地采用一些时
间消耗型的计算,减少CPU破解中的磁盘IO的瓶颈问题。 也就是说,基于GPU的破解架构,我们采用"暴力穷举"就成了更好的选择,但是,单纯的使用暴力穷举也不是很好的办法,例如: LittleaHann2014china这种类型的密码,长度极长,但是
却含有一定的规律性,如果采用纯粹的暴力穷举,破解的效率不会很好。 所以,针对GPU破解,目前采用的"基础字典"+"词根衍变"的破解技术,这可以理解为在高速GPU的架构下对时间消耗和磁盘IO消耗的一个折中的优化方案,这个方案中有3个要素 1) 一定规模的明文字典 2) GPU高速运算 3) 某种词根衍变算法,能根据词根衍变算法,对基础的字典进行词根重组,组合出新的密码,例如组合出LittleaHann2014china http://hashcat.net/oclhashcat/ hashcat是一款使用GPU加速破解的软件,具有很好的效果。 2. 分布式的破解技术 1) 利用分布式系统做大规模批量破解 2) 对明文字典进行有效切分 举例来说,一个明文的MD5值是一个32位的密文,则我们可以根据这个32位密文的每一位的值将原本的一个大的字典切分成不同的部分,并放在不同的子目录中。 例如: ... 02f521d18b7100ce07cd17c94fe5a89f 03f521d18b7100ce07cd17c94fe5a89f 12f521d18b7100ce07cd17c94fe5a89f 13f521d18b7100ce07cd17c94fe5a89f ... 是一堆MD5值,我们先根据MD5值的第一位进行分类,将第一位为0的MD5对应的明文都放到一个路径下,将第一位为1的MD5对应的明文放到另一个路径下。 然后在刚才第一位为0的目录下,我们继续进行切分,将第二位为2的放到一个目录下,将第二位为3的放到另一个目录下 同时在刚才第一位为1的目录下,我们继续进行切分,将第二位为2的放到一个目录下,将第二位为3的放到另一个目录下 这个过程会不断地递归下去,直到分到单个明文字典文件的大小在可接受的范围内,即磁盘IO的压力能够取得平衡的时候。 这样做的好处在于,当你拿到一个待破解的密文,可以根据这个密文的头部每一位数值,进行对应的路径定位,这样,路径定位的过程从"某种程度上来说"就已经是在进行破解了,而且更重
要的是,这种技术可以有效利用分布式的架构,缓解因为读写文件导致的IO瓶颈,是一种非常好的技术
目前密码破解存在的问题
在密码破解攻防领域中,加盐salt依然是一种简单、而十分有效的方法,对于加盐的密码,黑客们要破解存在以下几个问题 1. 加盐salt的长度很短,只有几位的盐 1) 直接生成字典、彩虹表(在投入-产出比可接受的情况下) 2) 用GPU直接在内存中进行暴力枚举,因为如果盐的长度很短,在高速GPU的架构下投入-产出比完全可以接受 2. 加盐的长度很长,到达12位以上 1) 生成字典(不可行) 2) GPU破解(耗时太大)
我们可以看到,密码破解的本质是"资源",这个资源包括字典的资源、计算能力的资源,当然加上词根衍算法,就能将拥有的资源的效果翻倍
接下来待研究的知识点
1. 词根衍变算法 2. 分布式的、根据指定位的值对文件切分的多级目录存储明文词典 3. GPU破解(需要购买相应的显卡)