John the Ripper使用指南,第6部分:如何破解非标准的哈希值(下)

2021-04-26 9,959

在本文中,我们将继续为读者详细介绍了如何破解非标准的哈希值。

(接上文)

分组。所有的表达式必须是一个单一的“外部”表达式,但在一个外部表达式中,可以有很多分组的数据。函数必须以一个函数名开始,并使用(和)来分组哈希值中的数据。所以像md5($p)或md5(md5($s.$p))或md5(md5($p).$s.md5($s.$p))都是正确的,因为从最外层来看,它们都是单个的括号()表达式,同时提供了所有必要的符号,因此语法正确。

除此之外,哈希函数还有另外几种“风格”,并且作用也略有不同。比如:

  • md5(EXPRESSION)

  • MD5(EXPRESSION)

  • md5_raw(EXPRESSION)

  • md5_64(EXPRESSION)

  • md5_64c(EXPRESSION)

小写的变体(如md5(…))将以小写的base16数字的形式返回结果。也就是说,md5("password")将返回5f4dcc3b5aa765d61d8327deb882cf99。

大写变体将返回以大写字母书写的16进制数字的结果。也就是说,MD5("password")将返回5F4DCC3B5AA765D61D8327DEB882CF99。附加了_raw的哈希函数则只返回一个原始二进制对象。也就是说,md5_raw("password")将返回16个字节,其中第一个字节是“x5f”,后面是其他15个字节。

而md5_64("password")将返回经过mime base-64类型的结果,即X03MO1qnZdYdgyfeuILPmQ(这些是base64编码的原始哈希值字节)。

而md5_64c("password")将返回crypt alphabet base64类型的字符串,对于我们的例子来说,该字符串为LorACpebNRMRUmTSi69DaE。

通常来说,64和64c用于外部函数,表明哈希值是base64编码的。这和大写字母的情况一样。如果外部函数是大写的,那么只有长度正确的大写十六进制字符串才有效。

哈希函数(每个都有一个小写、大写版本,后面是raw、64和_64c等后缀):

  • md2

  • md4

  • md5

  • sha1

  • sha224

  • sha256

  • sha384

  • sha512

  • tiger

  • sha3_224

  • sha3_256

  • sha3_384

  • sha3_512

  • keccak_256

  • keccak_512

  • ripemd128

  • ripemd160

  • ripemd256

  • ripemd320

  • whirlpool

  • gost

  • skein224

  • skein256

  • skein384

  • skein512

  • panama

  • haval_128_3

  • haval_128_4

  • haval_128_5

  • haval_160_3

  • haval_160_4

  • haval_160_5

  • haval_192_3

  • haval_192_4

  • haval_192_5

  • haval_256_3

  • haval_256_4

  • haval_256_5

这些函数几乎可以随意混合使用。因此,从语法的角度来看,sha512(md5(panama($p).$s.ripmd128($s.$p))是完全正确的。

使用自定义动态格式的例子

  1. 使用MD5计算密码的哈希值。

md5($p)
  1. 利用MD5计算密码的哈希值,然后再次用MD5对所得字符串继续进行哈希处理。

md5(md5($p))
  1. 利用md5计算密码的哈希值,然后对所得字符串进行Base64,之后,再次用md5对其进行哈希处理。

md5(md5_64($p))
  1. 将盐添加到密码中,然后计算串联在一起的字符串的MD5哈希值:

md5($p.$s)
  1. 使用sha1算法计算密码的哈希值:

sha1($p)
  1. 用MD5算法计算密码的哈希值,然后用sha1算法对得到的字符串再次进行处理:

sha1(md5($p))
  1. 将密码与盐进行组合,用sha512算法对得到的字符串进行哈希处理,然后用盐、生成的哈希值和密码组合成一个字符串,并再次用sha512算法对其进行哈希处理:

sha512($s.sha512($p.$s).$p)

常量与盐

上面提到了常量——它们的功能与盐的功能相似,那么它们到底是干什么的呢?本质上讲,常量就是盐,但它是以不同的方式传递给John the Ripper程序的。盐是和哈希值一起指定的,而常量是在公式中指定的(与-form选项搭配使用,或存储在配置文件中)。

下面是一个使用常量的例子:

md5($c1.$p),c1=hackware

也就是说,应该用静态的、不变的数据作为常量。而盐对每个密码都是单独的。

如何在命令行中指定动态格式的自定义哈希值

实际上,利用-form=dynamic='EXPRESSION'选项,便可以指定一个自定义的动态格式,比如:

-form=dynamic='sha1(md5(sha512($p.$s).$p).$s)'

请注意,引号是必需的,并且必须使用单引号!

您可以自己进行以下尝试——将表达式放在双引号中,并将其回显到终端,例如:

echo "sha1(md5(sha512($p.$s).$p).$s)"

该表达式的剩余部分如下所示:

sha1(md5(sha512(.).).)

就是说,程序会以这种形式看到它。

1.png

如何正确地为John the Ripper编写带有盐和用户名的哈希值

为动态编写哈希值的一般公式如下所示:

userID:$dynamic_#$base_16_hash[$salt]

其中:

  • userID是一个用户名(如果需要计算哈希值的话)

  • $dynamic_# (内置动态格式的数量,对此将在下面详细介绍)

  • $base_16_hash是哈希值本身

  • $salt是盐

除了这个哈希值外,大多数哈希算法都不需要其他数据。

下面展示一个加盐哈希值的例子(盐与哈希值之间用$字符分隔):

699fce08bf085fb80f5ae1f240cbbe720aa62278$jxV9tvClmWz0

下面的哈希值示例带有用户名:

user:1c3470194afdc84b90a0781c5e4462fc

内置的动态格式

要查看内置格式的列表,请输入下面的命令:  

john --list=subformats

输出如下所示:

Format = dynamic_0 type = dynamic_0: md5($p) (raw-md5)

Format = dynamic_1 type = dynamic_1: md5($p.$s) (joomla)

Format = dynamic_2 type = dynamic_2: md5(md5($p)) (e107)

Format = dynamic_3 type = dynamic_3: md5(md5(md5($p)))

Format = dynamic_4 type = dynamic_4: md5($s.$p) (OSC)

Format = dynamic_5 type = dynamic_5: md5($s.$p.$s)

Format = dynamic_6 type = dynamic_6: md5(md5($p).$s)

Format = dynamic_8 type = dynamic_8: md5(md5($s).$p)

其中,形如dynamic_*的字符串是格式名称,在选择一种格式或另一种格式时非常有用。此外,我们还可以看到每种格式的计算公式。对于某些格式,还提供了一个简短的注释。

您可能会注意到,其中两行的开头部分是与众不同的:

  • "Format = …"
    "UserFormat = …"

它们的不同之处在于,Format是John the Ripper的内置格式,而UserFormat,基本上也属于内置格式,但来自社区。在dynamic.conf文件中(位于/usr/share/john/dynamic.conf),可以看到UserFormat,同时,您也可以在此添加自己的UserFormat。

对于格式来说,通常采用像dynamic_#这样的名字,其中#是一个数字。John the Ripper为“内置”格式保留了数字dynamic_0到dynamic_999。不过,并非所有的格式都已被定义。

此外,UserFormat也可以使用像dynamic_#这样的名字,其中#是一个从1001到9999的数字。同样,不是所有这些格式都已经被定义了。

动态格式的运行和普通的哈希值格式一样,也就是说,它们是用--format选项指定的,我们需要指定dynamic_#作为名称,并用所需格式的编号来替换#,例如:  

john --test --format=dynamic_1030

如何在配置文件中存储自定义的动态哈希值格式

我们可以在john.conf(john.ini)、dynamic.conf(包含在john.conf中)或john.local.conf文件中编写自己的动态格式。

当然,仅仅写一个公式是不够的——实际上,该软件已经开发了一种原始语言,编写动态格式已经相当接近于编程。

感兴趣的可以参阅下面给出的文件:

  ./doc/DYNAMIC   
  ./doc/DYNAMIC_SCRIPTING

如何使用特殊字符表示盐

盐可以包含“问题”字符,比如:: \r \n \ NULL 等。

其中,冒号(:)在该软件中被用作字段分隔符。如果它存在于盐中,那么它将把盐分成多个字段(当然,这是错误的)。

回车或换行符会换行,这会导致该软件无法正确地读取它。

NULL字节在任何使用普通“字符串”函数的C程序中都会导致问题。

字符\用来转义动态格式内的字符,这也会引起问题。

此外,我们发现的另一个问题是:如果盐的结尾是空白符,例如“ ”或“\t”(空格或制表符),那么它们会在准备和清除行的过程中会被删除(程序不承认尾部的空格或制表符是字符串的一部分)。

由于所有这些问题,导致动态格式引入了对十六进制形式的盐的支持:  

$dynamic_#$HASH$HEX$HEX_BYTES_OF_SALT

在这种格式中,如果盐是1234,那么等价的十六进制值就是$HEX$31323334。

这样的话,在使用盐或对盐进行编码的时候,可以采用如下方式:  

$\x0:\r\nBadSalt

连这种盐都能用,编码后看起来是这样的:  

$HEX$003a0a0d42616453616c74

您可以使用前面提到的程序raw2dyna对字符进行编码并对盐的表示形式进行相应的转换。借助该软件,我们就能方便地对哈希值进行各种修改,具体方法请参考其帮助信息。

其实,最简单的用法就是转换单个字符,具体如下所示:  

raw2dyna -2h='STRING'

相关文章:

  • Advanced wordlist generating techniques (89.1%)

  • Comprehensive Guide to John the Ripper. Part 5: Rule-based attack (79.2%)

  • Comprehensive Guide to John the Ripper. Part 3: How to start cracking passwords in John the Ripper (how to specify masks, dictionaries, hashes, formats, modes) (76.9%)

  • Comprehensive Guide to John the Ripper. Part 4: Practical examples of John the Ripper usage (76.9%)

  • How to create dictionaries that comply with specific password strength policies (using Rule-based attack) (73.6%)

  • Hashcat manual: how to use the program for cracking passwords (RANDOM - 53.3%)


本文作者:mssp299

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/158018.html

Tags:
评论  (0)
快来写下你的想法吧!

mssp299

文章数:51 积分: 662

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号