zoukankan      html  css  js  c++  java
  • 关于前端加密登陆绕过的渗透思路

    0x00 前端加密

    好久不发博客了,今天主要讲一下前端加密绕过。前端加密,判断加密类型,根据加密类型,找到对应解密形式,同时如果存在简单前端校验时,比如js绕过,base64编码,这样的话就会简单很多,但对于AES加密时,我们就首先要熟悉AES的加密规则。

    0x01 关于AES加密规则

    https://www.cnblogs.com/starwolf/p/3365834.html

    附上链接,AES五种加密模式(CBC、ECB、CTR、OCF、CFB)

    c++源码:

    /**
    *@param 实现AES五种加密模式的测试
    */
    #include <iostream>
    using namespace std;
    
    //加密编码过程函数,16位1和0
    int dataLen = 16;   //需要加密数据的长度
    int encLen = 4;     //加密分段的长度
    int encTable[4] = {1,0,1,0};  //置换表
    int data[16] = {1,0,0,1,0,0,0,1,1,1,1,1,0,0,0,0}; //明文
    int ciphertext[16]; //密文
    
    //切片加密函数
    void encode(int arr[])
    {
        for(int i=0;i<encLen;i++)
        {
            arr[i] = arr[i] ^ encTable[i];
        }
    }
    
    //电码本模式加密,4位分段
    void ECB(int arr[])
    {
        //数据明文切片
        int a[4][4];
        int dataCount = 0;  //位置变量
        for(int k=0;k<4;k++)
        {
            for(int t=0;t<4;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;//重置位置变量
        for(int i=0;i<dataLen;i=i+encLen)
        {
            int r = i/encLen;//行
            int l = 0;//列
            int encQue[4]; //编码片段
            for(int j=0;j<encLen;j++)
            {
                encQue[j] = a[r][l];
                l++;
            }
            encode(encQue); //切片加密
            //添加到密文表中
            for(int p=0;p<encLen;p++)
            {
                ciphertext[dataCount] = encQue[p];
                dataCount++;
            }
        }
        cout<<"ECB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
    
    //CBC
    //密码分组链接模式,4位分段
    void CCB(int arr[])
    {
        //数据明文切片
        int a[4][4];
        int dataCount = 0;  //位置变量
        for(int k=0;k<4;k++)
        {
            for(int t=0;t<4;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;//重置位置变量
    
        int init[4] = {1,1,0,0};  //初始异或运算输入
        //初始异或运算
        for(int i=0;i<dataLen;i=i+encLen)
        {
            int r = i/encLen;//行
            int l = 0;//列
            int encQue[4]; //编码片段
            //初始化异或运算
            for(int k=0;k<encLen;k++)
            {
                a[r][k] = a[r][k] ^ init[k];
            }
             //与Key加密的单切片
            for(int j=0;j<encLen;j++)
            {
                encQue[j] = a[r][j];
            }
            encode(encQue); //切片加密
            //添加到密文表中
            for(int p=0;p<encLen;p++)
            {
                ciphertext[dataCount] = encQue[p];
                dataCount++;
            }
            //变换初始输入
            for(int t=0;t<encLen;t++)
            {
                init[t] = encQue[t];
            }
        }
    
    
        cout<<"CCB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
    
    //CTR
    //计算器模式,4位分段
    void CTR(int arr[])
    {
        //数据明文切片
        int a[4][4];
        int dataCount = 0;  //位置变量
        for(int k=0;k<4;k++)
        {
            for(int t=0;t<4;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;//重置位置变量
    
        int init[4][4] = {{1,0,0,0},{0,0,0,1},{0,0,1,0},{0,1,0,0}};  //算子表
        int l = 0; //明文切片表列
        //初始异或运算
        for(int i=0;i<dataLen;i=i+encLen)
        {
            int r = i/encLen;//行
            int encQue[4]; //编码片段
            //将算子切片
            for(int t=0;t<encLen;t++)
            {
                encQue[t] = init[r][t];
            }
            encode(encQue); //算子与key加密
            //最后的异或运算
            for(int k=0;k<encLen;k++)
            {
                encQue[k] = encQue[k] ^ a[l][k];
            }
            l++;
    
            //添加到密文表中
            for(int p=0;p<encLen;p++)
            {
                ciphertext[dataCount] = encQue[p];
                dataCount++;
            }
        }
    
    
        cout<<"CTR加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
    
    //CFB
    //密码反馈模式,4位分段
    void CFB(int arr[])
    {
        //数据明文切片,切成2 * 8 片
        int a[8][2];
        int dataCount = 0;  //位置变量
        for(int k=0;k<8;k++)
        {
            for(int t=0;t<2;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;  //恢复初始化设置
        int lv[4] = {1,0,1,1};  //初始设置的位移变量
        int encQue[2]; //K的高两位
        int k[4]; //K
    
        for(int i=0;i<2 * encLen;i++) //外层加密循环
        {
            //产生K
            for(int vk=0;vk<encLen;vk++)
            {
                k[vk] = lv[vk];
            }
            encode(k);
            for(int k2=0;k2<2;k2++)
            {
                encQue[k2] = k[k2];
            }
            //K与数据明文异或产生密文
            for(int j=0;j<2;j++)
            {
                ciphertext[dataCount] = a[dataCount/2][j] ^ encQue[j];
                dataCount++;
            }
            //lv左移变换
            lv[0] = lv[2];
            lv[1] = lv[3];
            lv[2] = ciphertext[dataCount-2];
            lv[3] = ciphertext[dataCount-1];
        }
    
        cout<<"CFB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
    
    //OFB
    //输出反馈模式,4位分段
    void OFB(int arr[])
    {
        //数据明文切片,切成2 * 8 片
        int a[8][2];
        int dataCount = 0;  //位置变量
        for(int k=0;k<8;k++)
        {
            for(int t=0;t<2;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;  //恢复初始化设置
        int lv[4] = {1,0,1,1};  //初始设置的位移变量
        int encQue[2]; //K的高两位
        int k[4]; //K
    
        for(int i=0;i<2 * encLen;i++) //外层加密循环
        {
            //产生K
            for(int vk=0;vk<encLen;vk++)
            {
                k[vk] = lv[vk];
            }
            encode(k);
            for(int k2=0;k2<2;k2++)
            {
                encQue[k2] = k[k2];
            }
            //K与数据明文异或产生密文
            for(int j=0;j<2;j++)
            {
                ciphertext[dataCount] = a[dataCount/2][j] ^ encQue[j];
                dataCount++;
            }
            //lv左移变换
            lv[0] = lv[2];
            lv[1] = lv[3];
            lv[2] = encQue[0];
            lv[3] = encQue[1];
        }
    
        cout<<"CFB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
    
    
    void printData()
    {
        cout<<"以下示范AES五种加密模式的测试结果:"<<endl;
        cout<<"---------------------------------------------"<<endl;
        cout<<"明文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<data[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
    int main()
    {
        printData();
        ECB(data);
        CCB(data);
        CTR(data);
        CFB(data);
        OFB(data);
        return 0;
    }

    0x02 前端加密登录绕过

    提供思路,由于实战渗透环境敏感性,不方便截图,这边主要是通过以下思路进行绕过前端加密:

    1、全局搜索关键字,定位加密形式,例如敏感函数(encrypt),当然我们可以使用全局变量搜索,或者按下开发者模式F12来进行全局搜索定位。

    2、通过定位加密形式,进行有效的绕过,例如为AES加密,我们面对AES加密,首先要确认的就是加密过程中使用的密钥key和密钥偏移量iv,这边我一般常使用的方法就是,爆破JS文件,burp也有插件,可以根据正则去匹配敏感函数文件,另一个方式就是通过右键查看源文件来进行查看前端检验,同时可以模拟输入数据时,当进行提交时,出发前端加密文件,进行捕捉查看,这是我所总结的,如果以上办法还没有找到的话,就尝试查看敏感加密函数变量名是否被修改过,基本就是这样。

    3、当我们拿到敏感js前端加密文件时,我的思路是,使用浏览器调试的形式,进行调试,一般通过打断点进行开发者模式的调试,然后进行获取密钥key,通过console(控制台),输入密钥key的变量名,进行调试输出。

    4、通过获取到的密匙变量值,我们要对进行绕过的登陆点针对性的内容进行绕过,通过界面常规的AES进行界面,然后相对应的进行绕过,这里我百度大佬的解密站点,放在下面:

    https://gchq.github.io/CyberChef/

    载入我们之前获得的iv和密钥key进行界面,通过在线站点进行界面,获得正确我们需要的类型的字符串。

    5、通过burp进行抓包拦截,进行获取相当的位置进行替换,进而绕过,进而成功绕过。

    0x03 总结

    在进行前端加密绕过之前,建议先去看一下加密类型的规则,这样才能更好的去绕过加密登录,尤其在实战过程中,每次加密的key都会根据你的发包来变更key值,所以在掌握实际的偏移量和加密密钥时,才能准确的去进行解密。在我之前绕过的shiro框架登录时,后面和甲方开发者聊天,它采用后端负载均衡去调用shiro key,加上负载均衡服务器,这样会更安全,确实学到了不少。以上内容,如有侵权,或者不对的地方,还请各位师傅多多指点。

    转载请注明:Adminxe's Blog » 关于前端加密登陆绕过的渗透思路

  • 相关阅读:
    Linux之文件处理命令
    Linux基础命令
    rip实验
    Linux基础之磁盘分区
    mysql安装
    centos Apache、php、mysql默认安装路径
    You probably tried to upload too large file. Please refer to documentation for ways to workaround this limit.
    Wrong permissions on configuration file, should not be world writable!
    机器会学习么 学习总结
    实验 5 Spark SQL 编程初级实践
  • 原文地址:https://www.cnblogs.com/cn-gov/p/15171945.html
Copyright © 2011-2022 走看看