前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[ffffffff0x] 浅谈web安全之前端加密

[ffffffff0x] 浅谈web安全之前端加密

原创
作者头像
r0fus0d
修改2020-12-25 17:49:45
1.4K0
修改2020-12-25 17:49:45
举报
文章被收录于专栏:ffffffff0xffffffff0x

简介

数学是现代加密的基础,而加密,是现代一切认证实现的基础。

在web中,很多场景登陆的账号密码请求都是经过 js 加密之后再发送,如图

通过burp抓包可以看到加密信息. 很明显可以看到 password 参数的值是经过前端加密之后再进行传输的,遇到这种情况,普通发包的爆破脚本就很难爆破成功。所以我们需要明白基础的加密概念,与常见的加密方式。

下面总结几种常见的加密,与真实案例中的加密对抗。


几种加密类型

ASCII 编码

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符。

JS代码示例

代码语言:txt
复制
document.write(escape("password") )
var code=unescape("112 97 115 115 119 111 114 100");
eval(code)  

PHP代码示例

代码语言:txt
复制
$urlencode =_GET[passwd]
// urlencode 加密
$urlencode = urlencode($str);
echo $urlencode . '</br>';
// urldecode 解密
$urldecode = urldecode($urlencode);
echo $urldecode; // 要加密的字符串

JAVA代码示例

代码语言:txt
复制
public String EnCode(String a,String s)
{
    s = CheckSelectItem(s);//分隔符获取
    StringBuilder ASCIIL = new StringBuilder();//结果保存
    StringBuilder ssvb = new StringBuilder();//输入值
    String[] ss = a.split("");
    for (String ik : ss) {
        ssvb.append(ik);
    }
    char[] chars = ssvb.toString().toCharArray();//输入值保存为char数组
    for (int i = 0; i < chars.length; i++) {
        if(i != chars.length - 1)
        {
            ASCIIL.append(Integer.valueOf(chars[i])).append(s);
        }
        else {
            ASCIIL.append(Integer.valueOf(chars[i]));
        }
    }//ASCII转换
    return ASCIIL.toString();
}

public String DeCode(String a,String s)
{
    s = CheckSelectItem(s);//分隔符获取
    String out;//输出
    if(s.equals(""))
    {
        out = "解密请选择空格分割或换行分割";
    }
    else
        {
    StringBuilder sbu = new StringBuilder();
    String[] chars = a.split(s);//输入值切片
    for (String aChar : chars) {
        sbu.append((char) Integer.parseInt(aChar));
    }//ASCII转换
    out = sbu.toString();
    }
    return out;
}

private String CheckSelectItem(String i)
{
    String delc;
    switch (i)
    {
        case "NULL": delc = "";break;
        case "    Space": delc = " ";break;
        case "\\n Newline": delc = "\n";break;
        default: delc = i;
    }
    return delc;
}//返回分隔符

Hash算法

Hash 算法是一个广义的算法,也可以认为是一种思想,使用Hash算法可以提高存储空间的利用率,可以提高数据的查询效率,也可以做数字签名 来保障数据传递的安全性。所以Hash算法被广泛地应用在互联网应用中。

MD5 和 SHA1 是曾经被广泛应用的Hash函数,而它们都是以 MD4 为基础设计的。

MD5(Message Digest Algorithm MD5),将输入以512位分组,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,函数的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

JS代码示例

代码语言:txt
复制
var b =$("#logPassword");$.md5(b.val());

PHP代码示例

代码语言:txt
复制
// md5 加密
$md5 = md5($str);
echo $md5 . '</br>';  

JAVA代码示例

代码语言:txt
复制
public String HashEncode(String message,String check)

{
MessageDigest mc = null;//实例化MessageDigest方法用来作MD5转换
String checking;
checking = check;
try {
mc = MessageDigest.getInstance(checking);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

assert mc != null;
mc.update(message.getBytes());//hash摘要
System.out.println(java.util.Base64.getEncoder().encodeToString(mc.digest()));
}
public static void main(String[] args) {
Hash hash = new Hash();
hash.HashEncode("加密前文本","MD5");
}

Base64

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。

编码规则: 是将3个8位字节(3×8=24位)编码成4个6位的字节(4×6=24位),之后在每个6位字节前面,补充两个0,形成4个8位字节的形式,那么取值范围就变成了0~63。又因为2的6次方等于64,所以每6个位组成一个单元。

base64既可以加密也可以解密,导入base64.js然后在js脚本中

JS代码示例

代码语言:txt
复制
var b =$("#logPassword");var code = $.encode64(b.val());$.unencode64(code); //加密和解密

PHP代码示例

代码语言:txt
复制
<?php
$cany = $_GET[password];#定义要加密的字符串
echo base64_encode($cany); #输出加密后的字符串
echo base64_decode($cany); #输出解密后的字符串
?>

JAVA代码示例

代码语言:txt
复制
package All_Tool_List.Coding;

import java.nio.charset.StandardCharsets;

public class Base64 {
public String Base64Decode(String in)
{
byte[] bs64 = java.util.Base64.getDecoder().decode(in);//获取用户输入字符通过base64加密,输出byte数组型值
return new String(bs64, StandardCharsets.UTF_8);//将byte数组转换成String输出
}

public String Base64Encode(String in)
{
byte[] bytes = in.getBytes(StandardCharsets.UTF_8);//将用户输入字符转换成byte(utf-8编码)
return java.util.Base64.getEncoder().encodeToString(bytes);//输出值
}
}

下面配合实战案例来看一看


实战案例

前端加密示例

在一次实战中,登录页面输入admin admin,抓包如下

乍一看,不知道它使用了什么加密方式。

代码语言:txt
复制
admin  admin
["=96=98=106=101=105","=96=98=106=101=105","0"]

仔细分析,尝试修改密码字段为abcde,12345,继续抓包

代码语言:txt
复制
admin abcde
["=96=98=106=101=105","=96=96=96=96=96","0"]
admin 12345
["=96=98=106=101=105","=48=48=48=48=48","0"]

这个时候,对编码比较熟悉的人已经发现了,其实就是简单的ASCII码减去其所在位数,即第一位字符 a 的 ascii 减一为96,第二位字符 d 的 ascii 减二为98,以此类推,最后以 = 分隔每个字符即可。知道了加密规则后,代码就容易写出了。

JAVA代码示例

只需将密码本放在C盘下命名为pass.txt,程序会自动生成加密后的结果在控制台输出。

代码语言:txt
复制
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ASCIIM1EC {
    public static void main(String[] args) {
        FileReader("C:\pass.txt");
    }
    public static String ASCIIEnCode(String a)
    {
        String s = "=";
        String out;
        StringBuilder ASCIIL = new StringBuilder("=");
        StringBuilder ssvb = new StringBuilder();
        String[] ss = a.split(s);
        for (String ik : ss) {
            ssvb.append(ik);
        }
        String ika = ssvb.toString();
        char[] chars = ika.toCharArray();
        int k =1;
        for (int i = 0; i < chars.length; i++) {
            if(i != chars.length - 1)
            {
                ASCIIL.append(((int)chars[i])-k).append(s);
            }
            else {
                ASCIIL.append(((int)chars[i])-k);
            }
            k++;
        }
        k =1;
        out = ASCIIL.toString();
        return out;
    }
    public static int[] FileReader(String file) {
        Charset charset = Charset.forName("US-ASCII");
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(file), charset)) {
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                System.out.println(ASCIIEnCode(line));
            }
        } catch (IOException x) {
            System.err.format("IOException: %s%n", x);
        }
        return null;
    }
}

示例密码表

输出结果

代码语言:txt
复制
=48=48=48=48=48=48
=96=98=106=101=105
=111=95=112=111=114=105=107=92
=111=95=112=111
=48=48=48=48
=48=48=48=48=48=48=48=48=48
=106=95=112=108=106
=110=98=102=111=105=108=96
=48=48=48=48=117=114=92=107=91

可见,加密后的值和与案例中的基本吻合,剩下的就是配合代码与burp交互进行爆破

同时,我们以一个后端的反推案例为例

后端加密示例

在一次对 BlogEngine.NET 的站点进行渗透时,发现其存在CVE-2019-10718 XML实体注入漏洞。查找相应的exp,成功转储其存储用户信息的 users.xml

得到一串加密后的字符串: 91wzdr6ew+0xclxg1xsauvog6qeijwznsp1g/7ifm+u=

在看到这串字符时第一眼也依旧看不出是什么加密,查找其托管在github上的后端源码后发现使用的是 SHA-256 BASE64 Hash加密。

后端源码链接:https://github.com/rxtur/BlogEngine.NET/blob/master/BlogEngine/

分析后尝试本地实现这个加密方法,java代码示例如下。

JAVA代码示例

代码语言:txt
复制
public String HashEncode(String message,String check)
{
MessageDigest mc = null;//实例化MessageDigest方法用来作MD5转换
String checking;
checking = check;
try {
mc = MessageDigest.getInstance(checking);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
assert mc != null;
mc.update(message.getBytes());//hash摘要
System.out.println(java.util.Base64.getEncoder().encodeToString(mc.digest()));
}
public static void main(String[] args) {
Hash hash = new Hash();
hash.HashEncode("Password1","SHA-256");
}

输出结果

代码语言:txt
复制
Password1 //明文
GVE/3J2k+3KkoF62aRdUjTyQ/5TVQZ4fI2PuqJ3+4d0= //密文

接下来就看你的明文字典够不够强大了。


总结

本文从几种常见的加密方式切入,对目前web前端加密的几种情况进行了概括。并结合真实案例给出了两种加密的对抗方法。对于web安全来说,前端的加密是事倍功半,应该真正把重心着眼于后端,当然前后端同时加固必然是最优解。由于篇幅有限,本文无法展开描述,后续会慢慢补充关于web加密的这部分内容。


本文作者 r0fus0d、RyuZU、the-fog

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 几种加密类型
    • ASCII 编码
      • Hash算法
        • Base64
        • 实战案例
          • 前端加密示例
            • JAVA代码示例
          • 后端加密示例
            • JAVA代码示例
        • 总结
        相关产品与服务
        网站渗透测试
        网站渗透测试(Website Penetration Test,WPT)是完全模拟黑客可能使用的攻击技术和漏洞发现技术,对目标系统的安全做深入的探测,发现系统最脆弱的环节。渗透测试和黑客入侵最大区别在于渗透测试是经过客户授权,采用可控制、非破坏性质的方法和手段发现目标和网络设备中存在弱点,帮助管理者知道自己网络所面临的问题,同时提供安全加固意见帮助客户提升系统的安全性。腾讯云网站渗透测试由腾讯安全实验室安全专家进行,我们提供黑盒、白盒、灰盒多种测试方案,更全面更深入的发现客户的潜在风险。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档