前言:在渗透测试中,常见的密码等敏感信息会采用加密处理,其中作为安全测试人员必须要了解常见的加密方式,才能为后续的安全测试做好准备。

涉及知识

常见加密编码算法

MD5,SHA,ASC,进制,时间戳,URL,BASE64,Unescape,AES,DES等

1. MD5(不可逆)

密文特征

16位和32位,加密密文字符串由A-Z(或a-z,不区分大小写),0-9随机分配

实际应用

80%网站管理员或用户密码加采取MD5加密。(不可逆)

示例

解密

网上的MD5在线工具,解密过程采用枚举方法如:cmd5

2. SHA(不可逆)

密文特征

  • SHA-1、SHA-256、SHA-384、SHA-512;
  • 生成密文长度固定;
  • 由A-Z(或a-z,不区分大小写),0-9随机组合。(不可逆)

3. 进制加密

16进制加密

示例

4. 时间戳

实际应用

网站或者服务器脚本语言里经常会使用,会在数据库里记录用户注册、登录、注销时使用时间戳记录

示例

5. URL

密文特征

如果在网址中看到**%开始 + 两位a-z(或A-Z,不区分大小写),0-9组合**时,通常就是使用了URL编码

实际应用

通常在访问网站时的地址信息中使用URL编码加密

示例

图中加入空格访问时,空格被转化为%20

意义

浏览器一般只做一次加密,在渗透绕过的时候可能会使用二次,三次加密方式

6. BASE64编码

密文特征

  • 由A-Z、a-z(区分大小写)、0-9随机组合,即BASE64密文中可能既有大写又有小写字母
  • 在字符串后面经常出现一个或两个等号,当然有可能没等号
  • 明文越长,密文越长

实际应用

BASE64常见于Web应用中:

  • 代码编码
  • 密码编码
  • 参数编码

7. Unecode/unescape

密文特征

  • %u+4位数字;
  • 每两位明文对应一个%u+4位数字

实际应用

主要应用WEB应用上

示例

8. AES加密

密文特征

AES加密结果直接显示是乱码,一般还要使用BASE64编码输出,所以如果用BASE64解密出来是乱码,则有很大可能是AES加密。有时候会有斜杠/出现在BASE64编码后的密文里面。

AES是一种安全的加密方式,涉及到密码,偏移量,数据块,填充,在加密时候涉及到4种随机性。解密难度大。

解密

必须要知道有密码、偏移量,否则无法进行解密

实际应用

目前一些比较注重安全和大型网站已经从MD5加密转向AES加密,大部分网站仍然使用MD5或明文。安全比赛中也常见AES加密。

示例

9. DES

密文特征

类似于BASE64,有时候 + 会出现密文里

示例

常见加密形式

  • 直接加密
  • 带salt
  • 带密码
  • 带偏移
  • 带位数
  • 带模式
  • 带干扰
  • 自定义组合:根据已知加密算法自行改写实现的加密算法

常见解密方式(针对)

  • 枚举
  • 自定义逆向解密算法
  • 可逆向算法

常规加密算法的特性

  • 长度位数
  • 字符规律
  • 代码分析
  • 搜索获取等

涉及案例

某CTF比赛题目解析——脚本自定义算法组合逆向

https://ctf.bugku.com/challenges

题目所给代码如下,寻找flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
function encrypt($data,$key)
{
$key = md5('ISCC'); //md5加密
$x = 0;
$len = strlen($data); //取参数data长度
$klen = strlen($key); //取参数key长度
for ($i=0; $i < $len; $i++) {
if ($x == $klen)
{
$x = 0; //遍历当x==key长度时x归零
}
$char .= $key[$x];
$x+=1;
}

for ($i=0; $i < $len; $i++) {
$str .= chr((ord($data[$i]) + ord($char[$i])) % 128); //PHP的ord()函数即是ASCII码编码,chr() 函数从指定 ASCII 值返回字符。
}
return base64_encode($str);
}
?>

该php脚本自定义了一个加密算法,其中涉及已知的md5加密、ASCII编码、base64编码等加密算法,因此写解密算法时就要逆向处理,从加密算法的末端反推解密算法。

参考以下解密代码。此处只说明解题思路,不要求书写出代码:

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
<?php
function decrypt( $str ) {
$mkey = "729623334f0aa2784a1599fd374c120d" ;
$klen = strlen ( $mkey );
$tmp = $str ;
$tmp = base64_decode ( $tmp ); // 对 base64 后的字符串 decode
$md_len = strlen ( $tmp ); //获取字符串长度
for ( $i =0; $i < $md_len ; $i ++) { // 取二次加密用 key;
if ( $x == $klen ) // 数据长度是否超过 key 长度检测
$x = 0;
$char .= $mkey [ $x ]; // 从 key 中取二次加密用 key
$x +=1;
}
$md_data = array ();
for ( $i =0; $i < $md_len ; $i ++) { // 取偏移后密文数据
array_push ( $md_data , ord( $tmp [ $i ]));
}
$md_data_source = array ();
$data1 = "" ;
$data2 = "" ;
foreach ( $md_data as $key => $value ) { // 对偏移后的密文数据进行还原
$i = $key ;
if ( $i >= strlen ( $mkey )) { $i = $i - strlen ( $mkey );}
$dd = $value ;
$od = ord( $mkey [ $i ]);
array_push ( $md_data_source , $dd );
$data1 .= chr (( $dd +128)- $od ); // 第一种可能, 余数+128-key 为回归数
$data2 .= chr ( $dd - $od ); // 第二种可能, 余数直接-key 为回归数
}
print "data1 => " . $data1 . "<br>\n" ;
print "data2 => " . $data2 . "<br>\n" ;
}

$str = "fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=" ; //题目所给的密文
decrypt( $str );
?>

某CMS密码加密解密——Discuz论坛用户密码的加密解密

加密方式

MD5+salt(salt即平台自行给用户密码拼接的字符串,也即干扰字符)

部分CMS密码加密形式相似如WordPress、Discuz 等

演示

Discuz版本:x3.4;在本地依托phpstudy环境进行搭建

在Discuz的数据库中有一张名为_ucenter_members的数据表保存了用户的账号和密码信息

从图中可以看到密文的值,而且常规只经过一次md5解密无法解出,此程序使用的是md5+salt加密的形式。若只知道密文不知道salt值进行解密是基本解不出来的,因此解密时要在md5解密平台输入密文:salt值进行解密

而且解密平台告诉我们加密的类型是md5(md5($pass.$salt)),可见加密方式是比较复杂的。因此对于此类加密方式的解密,除了要知道密文,还需要知道salt的值。

某URL加密地址的漏洞测试——参数加密的SQL注入漏洞

https://www.mozhe.cn/bug/detail/SjRRVFpOQWlLWDBJd3hzNGY5cFBiQT09bW96aGUmozhe

背景介绍

此WEB业务环境对参数进行了AES加密,为了防止参数产生SQL注入,也是防止SQL注入产生的一种方法,但是这种方式就安全了么?

实训目标

  1. 掌握信息泄露的方式;
  2. 了解AES加解密;
  3. 了解PHP的基本语法;
  4. 掌握手工SQL注入;
  5. 了解MySQL数据库的结构;

解题方向

通过SQL注入方式,获取WEB业务系统的账号密码进行登录。

解题过程

找到SQL注入点

根据提示的AES加密,而AES加密就必须知道密码和偏移量才能解密,又此题目涉及到信息泄露,因此想到题目会通过一些文件给我们这些信息,所以先对目标主机进行扫描:

扫描到一个地址,打开查看并下载该zip文件

其中有一个list.php文件

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
<?php
header('content-type:text/html;charset=utf-8');
require_once '../config.php';
//解密过程
function decode($data){
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');//mcrypt_module_open()该功能打开算法模块和要使用的模式:CBC模式AES-128加密,通常它会返回一个加密描述符
mcrypt_generic_init($td,'ydhaqPQnexoaDuW3','2018201920202021'); //该函数初始化加密所需的所有缓冲区,需要在每次调用 mcrypt_generic()或 mdecrypt_generic()之前调用此函数
$data = mdecrypt_generic($td,base64_decode(base64_decode($data)));//加密过程:将密文使用两层base64解码之后的值再由mdecrypt_generic()函数进行解密,返回的明文赋值给$data
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
if(substr(trim($data),-6)!=='_mozhe'){ //若得到的明文后6位字符不是'_mozhe',就不再向后台传递解密后的值
echo '<script>window.location.href="/index.php";</script>'; //window.location.href当前页面打开URL页面
}else{//若得到的明文后6位字符为就是'_mozhe'
return substr(trim($data),0,strlen(trim($data))-6);
//substr — 返回字符串的子串 || trim — 去除字符串首尾处的空白字符(或者其他字符)
//这句代码意思是:若得到的明文后6位字符为就是'_mozhe',返回去除后6位字符之后的$data值,返回值传出函数
}
}
$id=decode($_GET['id']); //将GET提交的id使用decode()函数进行解密后传给sql语句
$sql="select id,title,content,time from notice where id=$id";
$info=$link->query($sql);
$arr=$info->fetch_assoc();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>X公司HR系统V1.0</title>
<style>.body{width:600px;height:500px;margin:0 auto}.title{color:red;height:60px;line-height:60px;font-size:30px;font-weight:700;margin-top:75pt;border-bottom:2px solid red;text-align:center}.content,.title{margin:0 auto;width:600px;display:block}.content{height:30px;line-height:30px;font-size:18px;margin-top:40px;text-align:left;color:#828282}</style>
</head>
<body>
<div class="body">
<div class="title"><?php echo $arr['title']?></div>
<div class="content"><?php echo $arr['content']?></div>
</body>
</html>

这个php文件其实就是url中出现的list.php

list.php提供了一个解密过程,它的作用是将url中id=后面的密文进行解密还原之后传到后台(如数据库)中进行处理(加密过程另有其他文件完成)。

参照注释回看解密函数的过程为

  • 对密文第一层base64解密
  • 第二层base64解密 + AES解密得到明文(一般AES加密时要自带一次base64)
  • 只有当上述明文的后6位字符是‘_mozhe’时,才截掉后6位字符后输出最终明文

则易知加密过程是

  • 明文后+_mozhe字符串
  • AES加密+第一层base64(一般AES加密时要自带一次base64)
  • 第二层base64

由于url中传递的id是加密之后的id,因此在进行SQL注入时也应该将提交的语句使用上述的加密方式进行加密,这样在后台解密时才能实现SQL注入的效果。

先对当前url中id的密文进行解密:

一次base64解密

将输出的内容直接拿去AES解密平台进行解密,AES解密平台会自行再进行一次base64并进行AES解密。并且注意填写好加密模式、加密秘钥、偏移量

可以看到解密之后的结果为1_mozhe,decode()函数后续还会过滤掉_mozhe,所以实际上传递给SQL语句的参数只有’1’,因此我们在书写SQL注入语句时也应该注意添加_mozhe以及加密。

此处略去SQL注入过程,后续到SQL注入学习中再进行。

某实际应用URL地址参数加密——搜索特定关键字加密字符串

某些url中传递参数时使用了某些加密方式对参数进行加密,因此在攻击如SQL注入时就需要使用同样的加密方式加密之后提交参数而不能简单地用id = 1 and 1 = 1这种明文语句传参,这就是学习加密解密对于渗透测试的意义。

涉及资源

站内搜索

没有找到内容!