奇怪的cpp文件中出现了如下代码:
int check(unsigned char *data)
{
MD5_CTX ctx;
unsigned char md[16];
char buf[33]={'\0'};
char tmp[3]={'\0'};
int i;
MD5_Init(&ctx);
MD5_Update(&ctx, data, strlen((const char*)data));
MD5_Final(md, &ctx);
for( i=0; i<16; i++ ){
sprintf(tmp, "%02X", md[i]);
strcat(buf, tmp);
}
//printf("%s\n", buf);
if(strcmp(buf, "0AA5177C7EEC92A7EDB93B34561F7793") == 0)
return 1;
return 0;
}
想要进一步运行程序就要解出什么密码对应的
strcmp(buf,"0AA5177C7EEC92A7EDB93B34561F7793") == 0
strcmp是C中比较字符串的函数,使其值为0,则前后两字符串相同。
观察上述代码,应该是普通的MD5摘要。
重点来了:
for( i=0; i<16; i++ ){
sprintf(tmp, "%02X", md[i]);
strcat(buf, tmp);
}
起初一点也不理解这段语句什么意思(555~),查阅资料得知MD5摘要产生出一个128位(16字节)的散列值,sprintf是将md[i]以"%02X"(X表示16进制,X输出大写,x输出小写,不足两位按两位(前补0),超过两位全表示(也要注意字符串长度)),strcat是将前后两个字符串连接起来。
char a[100];
sprintf(a, "%02X", 6);//a=06
sprintf(a, "%02X", 321);//a=321
sprintf(a, "%02X", 0xab);//a=AB
sprintf(a, "%02x", 0xab);//a=ab
char b[3];
sprintf(b, "%02X", 321);//b=21
综合上述内容,MD5_Final(md, &ctx)是一个字节类型的数组,for循环将得到的数组内各个字节连接起来以十六进制类型格式输出。
如果已经知道密码格式,现在就可以开始做爆破了。
以下使用Python编程(已知密码格式为TC-2022-0A-2A-BBAB,其中A为数字,B为英文字母)
import hashlib
english='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
abstract='0AA5177C7EEC92A7EDB93B34561F7793'.lower()
for a in range(10):
for b in range(10):
for c in range(10):
for d in english:
for e in english:
for f in english:
MD5=hashlib.md5()
data='TC22'+str(a)+'-2'+str(b)+'-'+d+str(c)+e+f
data=data.encode()
MD5.update(data)
if MD5.hexdigest()==abstract:
print(data.decode())
print(a,b,d,c,e,f)
exit(0)
用时10分钟左右,爆破得到密码
又一个重点:
可以看到python里的MD5与C中很类似。其中的update函数有连接作用,会把上一次的摘要引入第二次的摘要(划重点!)。所以在循环嵌套时一定要每次都初始化md5!!!(否则浪费时间概不负责)
import hashlib
english='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
abstract='0AA5177C7EEC92A7EDB93B34561F7793'.lower()#替换字符串成相应爆破内容
for a in range(10):
for b in range(10):
for c in range(10):
for d in english:
for e in english:
for f in english:
MD5=hashlib.md5()
data='TC22-2022-0'+str(a)+'-2'+str(b)+'-'+d+str(c)+e+f
data=data.encode()
MD5.update(data)
if MD5.hexdigest()==abstract:
print(data.decode())
print(a,b,d,c,e,f)
exit(0)#找到答案则直接结束进程
成功爆破得到答案:
update函数实例:
import hashlib
MD5_1=hashlib.md5()
data1='Satifer!'.encode()
MD5_1.update(data1)
print(MD5_1.hexdigest())#400c38b2700328a13641540ec8bc725a
data2='Long time no see!'.encode()
MD5_1.update(data2)
print(MD5_1.hexdigest())#b8dac9ca6ae33826741345cfc0a6e60d
MD5_2=hashlib.md5()
data3='Satifer!Long time no see!'.encode()
MD5_2.update(data3)
print(MD5_2.hexdigest())#b8dac9ca6ae33826741345cfc0a6e60d
步骤总结:
1.得先知道密码格式才能开始爆破
2. 不同的算法注意各个函数的原理
3.根据原理写出嵌套进行爆破,尤其注意初始化
4.等等党大胜利!