3

一位朋友给了我一个挑战:他使用 PHP 的 crypt 函数 (CRYPT_STD_DES)(来自 PHP4)加密了一个字符串。我知道用于加密的盐,并且由于 crypt 是一种单向算法,我必须使用蛮力方法,而且我知道密码仅由小写字母组成。

现在,我有 16 核(2x Xeon)和大量 RAM 的机器。什么是实现这种强制攻击的最有效方法(我假设我必须使用 PHP,这不太好,但如果你们有任何想法......)

[编辑]

我忘了说,加密的表示是 13 个字符长度,字符串少于 8 个字母,就像一个简单的密码加密 :)

4

3 回答 3

2

来自 PHP 手册:

crypt()将使用基于标准 Unix DES 的算法或系统上可能可用的替代算法返回一个散列字符串。

一些操作系统支持不止一种类型的哈希。事实上,有时标准的基于 DES 的算法会被基于 MD5 的算法所取代。哈希类型由 salt 参数触发。在 5.3 之前,PHP 会在安装时根据系统的 crypt() 确定可用的算法。如果没有提供盐,PHP 将根据 MD5 的可用性自动生成标准的两字符 (DES) 盐或十二字符 (MD5)

换句话说,crypt()函数只是从 C 库中调用操作系统的 crypt() 函数。这意味着两件事。

首先,加密的类型是标准化的。你不需要使用 PHP 来蛮力运行,你只需要知道使用的算法。许多程序,如 Cane 和 Abel 或 Jack the Ripper 都能够通过暴力破解、字典或彩虹表攻击来破解多种算法。

其次,加密类型取决于加密的操作系统。这意味着您可能必须尝试几种不同的加密方法,除非有明显的线索表明使用了哪种加密方法(加密字符串的模式可能会提示您某些东西)。

我绝对不建议尝试使用 PHP 来暴力破解它,因为解释语言的运行速度比编译语言慢得多。

于 2010-09-29T00:28:38.450 回答
2

这是Ubuntu 10.04.1 上C 代码(用 编译gcc -O2 -lcrypt)的快速尝试

  #define _XOPEN_SOURCE
  #include <unistd.h>
  #include <stdio.h>
  #include <stdlib.h>

  void inc(char *p)
  {
     int i;
     for (i=0 ; i<8 && p[i]=='z' ; i++);
     if (i >= 8) exit(printf("Not found :-(\n"));
     if (!p[i]) p[i]='a';
     else p[i]++;
     while (--i >= 0) p[i]='a';
  }

  int main ()
  {
    char *salt = "XY";
    char *buzz = "XYaAbBcCZ0123";

    char pass[] = { 'a',0,0,0,0,0,0,0,0 };

    while(1)
      if ( ! strcmp(crypt(pass, salt), buzz))
        exit(printf("Found %s :-)\n", pass));
      else
        inc(pass);
  }

该代码应该在一两天内(2.10^11 组合)在现在的PC 上运行,您可以在多台机器上运行它,一个从“a”到“gzzzzzzz”,另一个从“haaaaaaa”到“nzzzzzzz”等。 .. 例如。

于 2010-09-29T08:19:00.737 回答
1

最有效(尽管可能是最不具挑战性)的方法可能是找到已经实现它的人(例如使用开膛手约翰)。

于 2010-09-29T00:33:36.610 回答