第29天:安全开发-JS应用&DOM树&加密编码库&断点调试&逆向分析&元素属性操作

发布于:2024-11-28 ⋅ 阅读:(8) ⋅ 点赞:(0)

时间轴:

42b58c6ce84e4d06908c599bab2a072a.jpeg

112a67c73bc8453e8b590f12f11c63ae.jpeg

演示案例:

JS 原生开发-DOM 树-用户交互

DOM:文档操作对象
浏览器提供的一套专门用来操作网页代码内容的功能,实现自主或用户交互动作反馈
 
安全问题:本身的前端代码通过 DOM 技术实现代码的更新修改,但是更新修改如果修改
的数据可以由用户来指定,就会造成 DOM-XSS 攻击!
 
1、获取对象
标签:直接写
Class:加上符号.
id:加上符号#
<h1 id="myHeader" οnclick="getValue()">这是标题</h1>
document.querySelector('h1')
document.querySelector('.id')
document.querySelector('#myHeader')
 
2、获取对象属性
<h1 id="myHeader" οnclick="getValue()">这是标题</h1>
const h1=document.querySelector('h1')
const id=h1.id
console.log(id)
 
2、操作元素数据
innerHTML 解析后续代码
innerText 不解析后续代码
 
3、操作元素属性
className src id 等
<img src="iphone.jpg" width="300" height="300"></img>
const src=document.querySelector('img')
src.src='huawei.png'
 

案例1:

1.使用visual studio打开文件夹打开28天的demo01。
f037ede5ddc744ba9cddb6cb6c6e4039.png
2.
使用此进行调试
2068b8a1d84a49a58c365b22c7c0b997.png

3.dom.html:

操作元素:
innerHTML 解析后续代码
innerText  不解析后续代码
<h1 id="myHeader" onclick="update1()">这是标题</h1>

<img src="huawei.png" width="300" height="300"><br>

<button onclick="update()">刷新</button>

<script>
    function update(){
        const s=document.querySelector('img')
        console.log(s.src)
    }
    
    function update1(){
        const s=document.querySelector('h1')
        //s.innerText="这是小迪<br>"  //innerText 不解析后续代码

        s.innerHTML='这是小迪<hr>'   //innerHTML 解析后续代码
        //<hr>下划线
        console.log(str)
    }


</script>
其中:
点击"这是标题"会转换为"这是小迪",点击刷新会得到src中的img图片
效果展示:
 
e214b188d4824530ab574ec4a2254a0f.png
触发图:
 
4bd8949b62bf4f2cba0337d2d0ae928b.png
 
使用innerText会显示"这是小迪<br>"
使用innerHTML会显示"这是小迪"
 

4.图片切换

将s.src=huawei.png转为iphone.jpg。

<script>
    function update(){
        const s=document.querySelector('img')
        s.src="iphone.jpg"
        console.log(s.src)
    }
    
    function update1(){
        const s=document.querySelector('h1')
        //s.innerText="这是小迪<br>"
        s.innerHTML='这是小迪<hr>'
        console.log(str)
    }


</script>

ed847c9442dc43378edafa3a1741fa23.png

 

5.DOM XSS漏洞:

const s=document.querySelector('img')
        s.src="iphone.jpg"
        console.log(s.src)
如果这里iphone.jpg为一个变量由用户传递决定,那么就会造成DOM XSS(改为用户传递)
 
s.src="JaVaScRiPt:alert('XSS')"
XSS payload参考文章:
 
 
 
有时候不弹窗的原因:
1.不支持(高版)
 
2.浏览器安排策略问题
 
使用<img src='#' onerror = "alert(1)"><br>在上面可以绕过弹窗alert(1)。
 

真实案例1:

有道翻译(已经被修复)

在输入whoami后会在下方出现值

794807f6cb384231a9bac39873a72df4.png

使用dnslog.cn进行带外处理:
 
1fc29566e00e44b99283f15afb321955.png
在network中看到访问成功:
 
008074d27caa4d3e934dac6db06080af.png
进行关键字搜索:(ctrl+shift+f)    (搜索出第三个js/textTranslate.729eda88js)
 
6622423cd183419da4dcda1d6e6752b1.png
根据表单值发现id="js_fanyi_input"
 
a19dfff9e34e49e4adfa0060661b4762.png
在文本中查找id="js_fanyi_input":
 
9f9284fc4b4249c2959fbfcc95c03bf3.png
 
归纳下来就是换数据的关系:
接着修改数据
f2268fccbf5242aca56d37b077a8f676.png
 
发现点击左边过滤掉<img src =http:"127.0.0.1">   点击右边不过滤
单击左边:
 
3ad4b594b3934795baec12c76fc301cd.png
 
 
被进行了实体化技术:
497d0e6f01a045e081576b968e014679.png
 
 
单机右边:(成功进入)
faf7f68332e14070aaed0b8796cdd557.png
 
用自己的案例进行尝试:   alert(1)
24199f79d0aa4228b6b6a4f85e0f944d.png
 function update1(){
        const s=document.querySelector('h1')
        //s.innerText="这是小迪<br>"
        s.innerHTML='<img src=# onerror="alert(1)">'  //注入代码
        console.log(s)
    }
 

JS 导入库开发-编码加密-逆向调试

//MD5
<script src="js/md5.js"></script>
<script>
    var str1 = 'xiaodisec'
    var str_encode = md5(str1);
    console.log(str_encode)
</script>

//SHA1
<script src="js/crypto-js.js"></script>
<script>
    var str1 = 'xiaodisec';
    var str_encode = CryptoJS.SHA1(str1).toString(); // 注意:1是数字1
    console.log(str_encode)  
</script>

//HMAC
<script src="js/crypto-js.js"></script>
<script>
    var key = 'key';
    var str1 = 'xiaodisec';
    var hash = CryptoJS.HmacSHA256(key, str1);
    var str_encode = CryptoJS.enc.Hex.stringify(hash);
    console.log(str_encode)  // '11a7960cd583ee2c3f1ed910dbc3b6c3991207cbc527d122f69e84d13cc5ce5c'
</script>


//AES
<script src="js/crypto-js.js"></script>
    <script type="text/javascript">
          var aseKey = "12345678"     // 定制秘钥,长度必须为:8/16/32位, 长度不一致也没问题
          var message = "xiaodisec";  // 需要加密的内容
          // 加密 DES/AES切换只需要修改 CryptoJS.AES <=> CryptoJS.DES
          var encrypt = CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(aseKey),  // 参数1=密钥, 参数2=加密内容
              {
                mode: CryptoJS.mode.ECB, // 为DES的工作方式
                padding: CryptoJS.pad.Pkcs7  // 当加密后密文长度达不到指定整数倍(8个字节、16个字节)则填充对应字符
             }
          ).toString(); // toString=转字符串类型

          console.log(encrypt);//在弹窗中打印字符串2vcsEDJv9vAZZLgFLjkZ9A==


//解密
          var decrypt = CryptoJS.AES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(aseKey), // 参数1=密钥, 参数2=解密内容
              {
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
              }
          ).toString(CryptoJS.enc.Utf8); // toString=转字符串类型,并指定编码
          console.log(decrypt); // "xiaodisec"
    </script>


//DES
<script src="js/crypto-js.js"></script>
    <script type="text/javascript">
          var aseKey = "12345678"     // 定制秘钥,长度必须为:8/16/32位, 长度不一致也没问题
 var message = "xiaodisec";  // 需要加密的内容
          // 加密 DES/AES切换只需要修改 CryptoJS.AES <=> CryptoJS.DES
          var encrypt = CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(aseKey),  // 参数1=密钥, 参数2=加密内容
              {
                mode: CryptoJS.mode.ECB, // 为DES的工作方式
                padding: CryptoJS.pad.Pkcs7  // 当加密后密文长度达不到指定整数倍(8个字节、16个字节)则填充对应字符
             }
          ).toString(); // toString=转字符串类型

          console.log(encrypt);//  控制台打印 CDVNwmEwDRM

//解密
          var decrypt = CryptoJS.AES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(aseKey), // 参数1=密钥, 参数2=解密内容
              {
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
              }
          ).toString(CryptoJS.enc.Utf8); // toString=转字符串类型,并指定编码
          console.log(decrypt); // 控制台打印"i am xiaochou  ?"
</script>

//RSA
<script src="js/crypto-js.js"></script>
    <script type="text/javascript">
      // 公钥 私钥是通过公钥计算生产的,不能盲目设置
        var PUBLIC KEY='-----BEGIN PUBLICKEY-----MFWWDQYJKOZIhVCNAQEBBQADSWAWSAJBALyBJ6KZ/VFJYTV3vOC07jqWIqgyvHulv6us/8wz1sBqQ2+e0TX7s5zKfXY40yZWDoCaIGk+tP/sc0D6dQzjaxECAWEAAQ==-----END PUBLIC KEY-----';
//私钥
        var PRIVATE KEY='-----BEGIN PRIVATEKEY-----MIIBVQIBADANBgkqhkiG9WOBAQEFAASCAT8WggE7AgEAAkEAvIEnqRn9UU1hNXe84LTuOpYiqDK8e6W/q6z/zDOVIGpDb545NfuznMp9djjTJlYOgJogaT60/+x2QPP1DONrEQIDAQABAKEAu7DFSqQEDDnKJpiWYfUE9ySiIWNTNLJWZDN/Bu2dYIV4DO2A5aHZfMe48rga5BkoWq2LAL1Y3tqsOFTe3M6yoQIhAOSfSAU3H6jI0nlEiZaburVGqiFLCb5Ut3Jz9NN+5p59AiEA0xQDMrxWBBJ9BYq6RRY4pXwa/MthX/8Hy+3GnvNw/yUCIG/3Ee578KVYakq5pih8KsVeVj037c2gj60d30k3XPqBAiEAGGPVxTsAuBDz0kcBIPqASGzArumljkrLsoHHkakofU0cIDuhxKQwH1XFD079ppYAPcV03bph672qGD84YUaHF+pQ-----END PRIVATE KEY-----';

使用js进行加密:

将三个js放入js文件夹中:
b7fc3901159b42668290b2212f42a37e.png
 
创建encry.html:
//md5
<script src="js/md5.js"></script>
<script>
    var str1 = 'xiaodi jichu No1'
    var str_encode = md5(str1);
    console.log(str_encode) 
</script>

//SHA1
<script src="js/crypto-js.js"></script>
<script>
    var str1 = 'xiaodisec';
    var str_encode = CryptoJS.SHA1(str1).toString(); // 注意:1是数字1
    console.log(str_encode)  
</script>

//HMAC
<script src="js/crypto-js.js"></script>
<script>
    var key = 'key';
    var str1 = 'xiaodisec';
    var hash = CryptoJS.HmacSHA256(key, str1);
    var str_encode = CryptoJS.enc.Hex.stringify(hash);
    console.log(str_encode)  // '11a7960cd583ee2c3f1ed910dbc3b6c3991207cbc527d122f69e84d13cc5ce5c'
</script>


//AES
<script src="js/crypto-js.js"></script>
    <script type="text/javascript">
          var aseKey = "12345678"     // 定制秘钥,长度必须为:8/16/32位, 长度不一致也没问题
          var message = "xiaodisec";  // 需要加密的内容
          // 加密 DES/AES切换只需要修改 CryptoJS.AES <=> CryptoJS.DES
          var encrypt = CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(aseKey),  // 参数1=密钥, 参数2=加密内容
              {
                mode: CryptoJS.mode.ECB, // 为DES的工作方式
                padding: CryptoJS.pad.Pkcs7  // 当加密后密文长度达不到指定整数倍(8个字节、16个字节)则填充对应字符
             }
          ).toString(); // toString=转字符串类型

          console.log(encrypt);
          var decrypt = CryptoJS.AES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(aseKey), // 参数1=密钥, 参数2=解密内容
              {
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
              }
          ).toString(CryptoJS.enc.Utf8); // toString=转字符串类型,并指定编码
          console.log(decrypt); // "xiaodisec"
    </script>
赋值变量的三个方式:
let var const
 
效果展示:
90a78f97f4ef47aab5c80064d0157a8c.png

 

两则案例分析-解析安全&登录调试

小迪8案例一:小迪8

1.根据传参值知道是edpassword

9cafa4bc8ac740e3872463733ea315e4.png

2.使用全局搜索edpassword:

3.发现传参变量edtPassWord

1f5e8da5c22f46dc81b90f0db1afb336.png

4.其中的$("#btnPost").click(function()

与我们所学习的ajax技术相对应:

<script src="js/jquery-1.12.4.js"></script>
<script>
    $("button").click(function (){
        $.ajax({
            type: 'POST',
            url: 'shop.php',
            data: {
                num:$('.number').val(),
            },
            success: function (res){
                console.log(res);
                if(res['infoCode']==1){
                    alert('购买成功');
                    //购买成功的流程
                }else{
                    alert('购买失败');
                }
            },
            dataType: 'json',
        });

    });
</script>

5.在表单值中也是btnpost

b16e9c7e655a437bb73a4cdecfac76b7.png

为什么#btnPost前有#号?

答: 标签:直接写
        Class:加上符号.
        id:加上符号#
        <h1 id="myHeader" οnclick="getValue()">这是标题</h1>
        document.querySelector('h1')
        document.querySelector('.id')
        document.querySelector('#myHeader')
 
6.进行md5传参后action提交给cmd.php?act=verify
fd10f4117b6c4fe4ac82cada7753a7ec.png
 
7.传输至这里
bfc0acafaf2943e69934a49c42b19c73.png
 
8.若不知道是md5加密可以用上面的方法进行溯源,之后在console中进行调试:
逻辑梳理:
234b366f57de4d12b50e778487796c54.png
 
进行调试对比:(发现相同)
 
ce37e377d9664a8082ea048c4efb3f9e.png

案例二:
申通快递


抓到包后看到看到LoginResult的username,Mobile,Password通过密文加密了

354b36f2025f4e3f9ecebdc779dafa19.png

为了解密明文找到加密方式可以从表单入手:

95e9db59530a4282b33d030535980eaa.png

全局搜索此值找到以下内容:
17fc0e2d9f0248328b75e9a9eb9068de.png
思考:

如果我们现在要测试注入一样


注入payload :admin ’ 1=1

明文:admin ‘1=1
密文:xxxxxxxxxx
如果不知道加密算法 你发送明文?有效吗?

没有效 因为对方可能会解密
有效 以同样的加密方式去发送payload

以相同方法找到密码。

之后在控制台尝试使用平台加密方式进行加密,发现会进行报错(是在本地环境,不是在平台环境)。

7aa8b264f0604522aa87ad94ea22a3cd.png

只能使用断点调试:

点击此处进行断点调试:

2eca656a72454477ad71f0c469e47a35.png

会在右下角显示明文密码:

940aced7b47f4491a43471aff9e05644.png

其中:

cbaf5555c38547aeadbd1d2089a7343b.png

左边是调试跟踪代码执行流程(放走了)

右边是继续往下调

当往下调后数据将会发生改变:

现在在控制台调试会得到攻击语句和工具算法了

b8d3e80cf99d4521992b7871149d9529.png

总结:
 

如果我们现在要测试注入一样


注入payload :admin ’ 1=1

明文:admin ‘1=1
密文:xxxxxxxxxx
如果不知道加密算法 你发送明文?有效吗?

没有效 因为对方可能会解密
有效 以同样的加密方式去发送payload

为什么进行断点操作:

因为有些encrypt没有定义,浏览器没有显示断点。

此文章由李豆豆喵和番薯小羊卷~共同完成。