【问题标题】:Why is my brute-force MD5 hack not working?为什么我的蛮力 MD5 破解不起作用?
【发布时间】:2015-03-23 13:44:39
【问题描述】:

在课堂上,我得到了一个通过 md5 哈希运行的密码。我被告知它最多只能包含 6 个字符,大写和数字。我要写一个蛮力算法来揭示原始密码。我已经能够获得自己的哈希值,通过我的程序运行它并对其进行解码,但它在我的老师给我们的那个上失败了。我从一个网站上采购了我的 md5,并与其他人检查了它的结果,所以我知道这不是问题所在。我的代码中是否有一些错误,比如我没有涵盖所有可能的组合,或者给我的哈希值很可能有错误?

#include <stdlib.h>
#include <string>
#include <iostream>
#include "md5.h"//File was sourced from http://www.zedwood.com/article/cpp-md5-function

using namespace std;

const int numPossibleChar = 36;
const string givenHash = "ad2ad129385e4b2ba3b477378bc1d9b6";
long count=0;//make sure I go through all combinations

const char * charOptions[numPossibleChar]={"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
                            "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
                            "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7",
                            "8", "9", "0"};



int main()
{   
    for( int i =0; i<numPossibleChar; i++)
    {
         string guess1 = charOptions[i];
        string guessHash = md5(guess1);
        if( md5(guess1)==givenHash)
        {
            cout <<"match, password is: "<< guess1<<endl;
            return 0;
        }
        cout<<guess1<<endl;
        count++;
        for (int j=0; j<numPossibleChar; j++)
        {
            string guess2=guess1+charOptions[j];
            if( md5(guess2)==givenHash)
            {
                cout <<"match, password is: "<< guess2<<endl;
                return 0;
            }
            count++;
            for(int k=0; k<numPossibleChar; k++)
            {
                string guess3=guess2+charOptions[k];
                if( md5(guess3)== givenHash)
                {
                    cout <<"match, password is: "<< guess3<<endl;
                    return 0;
                }
                count++;
                for(int l=0; l<numPossibleChar; l++)
                {
                    string guess4=guess3+charOptions[l];
                    if( md5(guess4)== givenHash)
                    {
                        cout <<"match, password is: "<< guess4<<endl;
                        return 0;
                    }
                    count++;
                    for(int m=0; m<numPossibleChar; m++)
                    {
                        string guess5=guess4+charOptions[m];
                        if( md5(guess4)==givenHash)
                        {
                            cout <<"match, password is: "<< guess5<<endl;
                            return 0;
                        }
                        count++;
                        for(int n=0; n<numPossibleChar; n++)
                        {
                            string guess6=guess5+charOptions[n];
                            if( md5(guess6)==givenHash)
                            {
                                cout <<"match, password is: "<< guess6<<endl;
                                return 0;
                            }
                            count++;
                        }
                    }
                }

            }
        }
    }

    cout << "Count "<<count<<endl;




    return 0;
}

不,我实际上不知道 count 的最终值是多少。我最初将它作为 int 而不是 long,所以在运行 9 小时后它溢出了。在我再次运行它并得到一个新号码之前,我想和你们核实一下。

【问题讨论】:

  • 源代码中的哈希是给你的吗?如果没有,你给了什么?
  • MD5 哈希值不是唯一的,因此您的第一个肯定可能不是原始密码。 (多个密码可以产生相同的 MD5 哈希)。
  • VTC 作为“需要问题陈述”的人需要他们的眼睛检查。
  • @Galik:是的,但是两个 6 字符的字符串几乎不可能具有相同的 md5sum。有超过 2^31 个可能的密码符合标准;有 2^128 个可能的 md5sum。我敢打赌它已经过测试;如果这样的短字符串发生 md5sum 冲突,那将是已知的。相关:crypto.stackexchange.com/questions/15873/…
  • @Galik:一个有趣的想法,但正如我所说,几乎可以肯定没有任何重复那么短。

标签: c++ md5 brute-force


【解决方案1】:

除了风格问题,

                string guess4=guess3+charOptions[l];
                if( md5(guess4)== givenHash)
                {
                    cout <<"match, password is: "<< guess4<<endl;
                    return 0;
                }
                count++;
                for(int m=0; m<numPossibleChar; m++)
                {
                    string guess5=guess4+charOptions[m];
                    if( md5(guess4)==givenHash)
                    {
                        cout <<"match, password is: "<< guess5<<endl;
                        return 0;
                    }

我冒昧地猜测您并不是要检查两次md5(guess4)

编辑,以扩展此和样式问题: 显然,如果不检查md5(guess5),六分之一的潜在密码就会丢失。

通过重构代码以获得更好的样式,可以轻松解决此类错误。特别值得注意的是,我建议您阅读Arrow Anti-pattern。您有很多代码重复(例如,使用不同的变量执行几乎/完全相同的操作),这意味着您可以轻松地重构为递归函数或堆叠(推送/弹出到堆样式)循环并实现更易于阅读(因此一般不容易出错)代码。

如果您的count 溢出需要 9 个小时,我建议您遇到了一些性能问题(假设您在相对较新的硬件上运行)。您可以进一步扩展,通过为每次检查重用现有字符串来减少字符串分配和释放的数量。例如,count 可以通过添加count=1+i+j+k+l+m+n 来严格推断,因此无需手动递增。

【讨论】:

  • 天哪,我想可能是这样。我当然希望如此!谢谢你。我会再次运行它,然后接受你的答案。
  • 那是问题所在吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 2020-02-16
  • 1970-01-01
相关资源
最近更新 更多