看到网站参数MDAwMDAwMDAwM开头的一串东西,刷了几个页面看到网站是thinkphp写的,翻了一下这个是think_encrypt加密出来的,带key。
但是这个加密算法不是一个散列的算法,里面用了md5仅仅是对key做了一次加密,后续没有用到。
那么在不知道秘钥的情况下可以很方便地对该算法进行攻击,暴力(因为算法的各种弱鸡,这个词有点严重了)拆解出key的md5值,毕竟算法中真正的key其实是这个md5值,知道这个md5值之后,就可以很方便地进行加密数据伪造。
以下步骤和数据仅供学习参考扩展,“单凭理论无法解决现实事情,需要理论与现实结合,才能更简单更快速地解决”
找出几个加密字符串,并确定这个是数字加密后的内容。$exapmleencodea = [
'MDAwMDAwMDAwMLR2uaE',
'MDAwMDAwMDAwMLR2vaE',
'MDAwMDAwMDAwMLR2x6E',
'MDAwMDAwMDAwMLR2y6E',
'MDAwMDAwMDAwMLOspZmIubtp',
'MDAwMDAwMDAwMLOcpdyGz7tq',
'MDAwMDAwMDAwMLOGx92G38mwhNtyoQ',
'MDAwMDAwMDAwMLOcpdyGz7tq',
'MDAwMDAwMDAwMLOGud2Gz9GxhriCmLHcdZ4',
'MDAwMDAwMDAwMLSctaE',
'MDAwMDAwMDAwMLScpaE',
'MDAwMDAwMDAwMLSGsaE',
];
对于base64不再进行解读,根据理论,对数字字符串加密后的base64进行统计(也就两行代码,不贴,我用的md写的文字),每一位的字符有一部分限制,所以收紧了暴力的范围
一千万以内的数字有以下规则0=>['M','N','O'],//第一位,只可能是这三个字符
1=>['Q','g','w','A','T','j','z','D'],
2=>['=','A','E','I','M','Q','U','Y','c','g','k'],
3=>['=','w','x','y','z','0','1','2','3','4','5'],
4=>['M','N','O'],
5=>['A','Q','g','w','D','T','j','z'],
6=>['=','A','E','I','M','Q','U','Y','c','g','k'],
7=>['=','w','x','y','z','0','1','2','3','4','5'],
8=>['M','N','O'],
9=>['A','Q','g','w'],
10=>['='],
11=>['='],
真正的key是md5之后的内容,每一位只可能是:16个字符,又收紧95%的暴力范围$keychara = ['0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f'];
然后把解密代码进行改造对key的每一位进行排除拆解for ($i = 0; $i < $data_len; $i++) {
$data_charint = ord(substr($data, $i, 1));
//$key_charint = ord(substr($eqlen_keystring, $i, 1));
foreach ($keychara as $kc) {
$key_charint = ord($kc);
if ($data_charint
$thisposchar = chr(($data_charint + 256) - $key_charint);
}else{
$thisposchar = chr($data_charint - $key_charint);
}
if(in_array($thisposchar, $numcode[$i]))
{
$maybe[$i][] = $kc;//符合规矩
}
}
}
得出key的每一位有以下可能:0=>['e','f'],
1=>['2','5'],
2=>['d'],
3=>['d'],
把可能性带入进行正式解密再排除$maybekey = ['e2dd','e5dd','f2dd','f5dd'];
foreach ($maybekey as $key) {
echo "\r\n\r\n$key :\r\n";
foreach ($exapmleencodea as $encode) {
$data = str_replace(array('-','_'),array('+','/'),$encode);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
$data = base64_decode($data);
$data = substr($data,10);
$x = 0;
$data_len = strlen($data);
$eqlen_keystring = $str = '';
$eqlen_keystring = $key;
$maybe = [];
for ($i = 0; $i < $data_len; $i++) {
$data_charint = ord(substr($data, $i, 1));
$key_charint = ord(substr($eqlen_keystring, $i, 1));
if ($data_charint
$thisposchar = chr(($data_charint + 256) - $key_charint);
}else{
$thisposchar = chr($data_charint - $key_charint);
}
$str .= $thisposchar;
//echo $str."\r\n\r\n";
}
echo base64_decode($str)."\r\n";
}
}
根据最后每一种可能的key decode出来的明文样子,得出前四位是f2dd,足够我自己用来数据伪造了
没精力写那么详细,要是有兴趣,对着think_decrypt一步一步看看,然后看我的思路即可。