• 关于前端加密登陆绕过的渗透思路


    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 » 关于前端加密登陆绕过的渗透思路

  • 相关阅读:
    sql server 检测是否更新并输出更新的数据
    SQL Cross Join
    使用editplus删除 telepro的标记
    201671010104 初学Java的感想以及认知
    201671010104学习Java心得
    201671010104学习Java程序设计进度条
    从 URL 调用 WebService
    初识 Adobe AIR
    Adobe AIR 初体验:第一个Adobe AIR 的项目
    Float元素父容器在Firefox中自动撑大的方法
  • 原文地址:https://www.cnblogs.com/cn-gov/p/15171945.html
Copyright © 2020-2023  润新知