【JTR&hashcat】JTR和hashcat中具体算法部分实现的信息获取
一. JTR
1. JTR中算法部分的各大函数
get_salt():从密文输出中还原计算时用的salt,比较多的密文输出时候都是对真实的密文值,还有salt值进行16进制化输出;
get_binary():从密文输出中还原计算出的真实密文结果;
set_key():对明文进行的,参与计算之前的转化操作,有转化成UTF16编码,大小写转换等操作;
set_salt():跟set_key()同理;
cry_all():算法实现的的主要流程,其中的#ifdef _OPENMP,#ifdef _SIMD_xxx等是优化相关的宏。
看串行原理的时候,可以先全部去掉;
get_key():set_key()的逆向操作,一般不用管。
2. 想在JTR源码中printf()算法中间结果,如何去改写的问题
这时候必须去掉openmp和simd这些优化项,直接在优化代码中插入printf()语句,输出会各种奇怪,总之就不是想要的结果。
但是光在具体算法文件undef或者去掉这些宏,可能会出问题的。
其中的主要原因就是,有些算法会关联其他实现文件,而这些宏在其他文件中,会影响到函数的定义。光在目标中去掉这些宏,而在依赖文件中不去掉,会出现函数未定义的错误。
解决方法非常简单,根据错误提示,找到所有的文件,把相关宏全部去掉就OK。
例子就是itunes_fmt_plug.c,
在依赖的其他文件中,这些宏影响到底是定义pbkdf2_sha1_sse(),还是定义pbkdf2_sha1()。
二. hashcat
1. interface.c中的算法描述结构
hashcat的这个文件,会有一大段类似这样的结构体,其中有挺多信息的。
(以很简单的131号算法,sql server2000的加密算法为例)
case 131: hashconfig->hash_type = HASH_TYPE_SHA1; hashconfig->salt_type = SALT_TYPE_EMBEDDED; hashconfig->attack_exec = ATTACK_EXEC_INSIDE_KERNEL; hashconfig->opts_type = OPTS_TYPE_PT_GENERATE_BE | OPTS_TYPE_PT_UTF16LE | OPTS_TYPE_PT_UPPER | OPTS_TYPE_ST_ADD80 | OPTS_TYPE_ST_ADDBITS15 | OPTS_TYPE_ST_HEX; hashconfig->kern_type = KERN_TYPE_SHA1_PWUSLT; hashconfig->dgst_size = DGST_SIZE_4_5; hashconfig->parse_func = mssql2000_parse_hash; hashconfig->opti_type = OPTI_TYPE_ZERO_BYTE | OPTI_TYPE_PRECOMPUTE_INIT | OPTI_TYPE_PRECOMPUTE_MERKLE | OPTI_TYPE_EARLY_SKIP | OPTI_TYPE_NOT_ITERATED | OPTI_TYPE_APPENDED_SALT | OPTI_TYPE_RAW_HASH; hashconfig->dgst_pos0 = 3; hashconfig->dgst_pos1 = 4; hashconfig->dgst_pos2 = 2; hashconfig->dgst_pos3 = 1; hashconfig->st_hash = ST_HASH_00131; hashconfig->st_pass = ST_PASS_HASHCAT_PLAIN; break;
A. hashconfig->opts_type
注意到hashconfig->opts_type这个项,这个参数里描述的是在计算之前,对于pwd和salt值的处理。
对,主要就是JTR的set_key和set_salt的信息,不过会包含get_salt的一部分信息,毕竟破解嘛,要从密文输出中提取并还原原来的salt值。
另外,可能有时处理会不全?记忆有点模糊了。
其类型分为OPTS_TYPE_PT和OPTS_TYPE_ST,这个PT和ST分别代表 pwd还有salt。
OPTS_TYPE_PT_GENERATE_BE,可能还有OPTS_TYPE_ST_GENERATE_BE?这个是不用管的,对于我们的目标来说,没有信息。
OPTS_TYPE_ST_ADD80和OPTS_TYPE_ST_ADDBITS15也没有关于pwd和salt转换处理的信息。
OPTS_TYPE_PT_UPPER表示pwd进行计算前,要先全部转换为大写。
OPTS_TYPE_PT_UTF16LE表示pwd进行计算前,要先进行小端模式的UTF16编码转换。
OPTS_TYPE_ST_HEX是get_salt()的信息,意思就是salt在转换为输出之前要进行16进制化转换,所以提取得到salt自然要进行逆转换;
B. hashconfig->parse_func
其实这个也没太多信息吧,就是跟你说用哪个函数对于密文输出进行parse,就是如何从密文输出中提取salt相关字段,密文相关字段,还有去掉标志字段等
hashconfig->parse_func = mssql2000_parse_hash;
就是说,sql server2000要用这个函数进行parse;
C. hashconfig->kern_type
有时候会出现这样的情况,有些算法号hashcat wiki上有,但在opencl(hashcat算法实现都放这)文件夹找不到相关的文件。
其实是因为有些算法的过程,和其他某个算法是相同的,而这个hashconfig->kern_type就是描述实际调用的算法的。
这里的值是KERN_TYPE_SHA1_PWUSLT,搜索一下可以发现130~133实际算法过程是相同的。
D. mssql2000_parse_hash()
密文输出字段提取函数,简要介绍一下。
主要看
token.len[0] = 6; token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; token.len[1] = 8; token.attr[1] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.len[2] = 40; token.attr[2] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.len[3] = 40; token.attr[3] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_HEX;
这里是token.len和token.attr的数组,就表明有几个字段,每个字段的长度等等。
但是哪些字段是密文,哪些字段是盐还需要获取其他的信息才可以判断。
2. OpenCL文件夹
各个算法实现文件会有这样的后缀_a0-pure,_a1-optimized,这里的ax表示攻击模式,想看原理的话,应该选择a0字典模式的实现文件,干扰最少。
pure和optxxx应该选择pure,optxxx优化版本的自然难以看懂。
A. 简单算法
以winphone8,13800号算法为例。
文件中出现
__kernel void m13800_mxx
__kernel void m13800_sxx
两大段东西,但是内容基本一样的,暂时不知道有什么用,但是据个人经验不用管的,随便看其中一段就能获取我们需要的算法过程信息。
for (u32 il_pos = 0; il_pos < il_cnt; il_pos++)循环里就是算法的具体过程,il是与规则攻击模式有关的,在这里不用管。
COMPARE_M_SCALAR (r0, r1, r2, r3); 应该是结果比较的,毕竟是破解软件,需要这一步,在这里也不用管。
B. 复杂算法
以pbkdf2-hmac-md5 11900号算法为例。
hmac_md5_run_V()是向量形式的hmac_md5()算法,其实原理上来说就是hmac_md5所以这个并不用管,hmac_md5是基础算法,在openssl中可以直接调用。
__kernel void m11900_init(),__kernel void m11900_loop()这两个函数合起来就是操作的全过程。
__kernel void m11900_init()中,w0[0] = j << 24;表示拼凑这样一个后缀“\x0\x0\x0\xloop”
由于for (u32 i = 0, j = 1; i < 4; i += 4, j += 1)看出,只循环一次,所以这里loop恒为1,
也就是这个“\x0\x0\x0\x1”。
由md5_hmac_update_global(), md5_hmac_update_64(),md5_hmac_final()可以看出,这个后缀的意义就是加个salt值后面,形成新的salt值。
我们要获取的信息,只看md5_hmac_update字样就可以,后面的global、64不需要管,在final前的连续update代表字符串的拼接。
__kernel void m11900_loop()中, for (u32 i = 0; i < 4; i += 4)循环中就是流程的另一部分。
out[0]~out[3]是并行的设置,理解原理而言将其当作out就可以,其他也同理,这里的过程还是比较直白的,不赘言了。