时间轴:
演示案例:
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。
2.
使用此进行调试
3.dom.html:
操作元素:
innerHTML 解析后续代码
innerText 不解析后续代码
html
<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图片
效果展示:
触发图:
使用innerText会显示"这是小迪<br>"
使用innerHTML会显示"这是小迪"
4.图片切换
将s.src=huawei.png转为iphone.jpg。
html
<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>
5.DOM XSS漏洞:
php
const s=document.querySelector('img')
s.src="iphone.jpg"
console.log(s.src)
如果这里iphone.jpg为一个变量由用户传递决定,那么就会造成DOM XSS(改为用户传递)
php
s.src="JaVaScRiPt:alert('XSS')"
XSS payload参考文章:
XSS攻击绕过过滤方法大全(转)_xss绕过-CSDN博客
有时候不弹窗的原因:
1.不支持(高版)
2.浏览器安排策略问题
使用<img src='#' onerror = "alert(1)"><br>在上面可以绕过弹窗alert(1)。
真实案例1:
有道翻译(已经被修复)
在输入whoami后会在下方出现值
使用dnslog.cn进行带外处理:
在network中看到访问成功:
进行关键字搜索:(ctrl+shift+f) (搜索出第三个js/textTranslate.729eda88js)
根据表单值发现id="js_fanyi_input"
在文本中查找id="js_fanyi_input":
归纳下来就是换数据的关系:
接着修改数据
发现点击左边过滤掉<img src =http:"127.0.0.1"> 点击右边不过滤
单击左边:
被进行了实体化技术:
单机右边:(成功进入)
用自己的案例进行尝试: alert(1)
php
function update1(){
const s=document.querySelector('h1')
//s.innerText="这是小迪<br>"
s.innerHTML='<img src=# onerror="alert(1)">' //注入代码
console.log(s)
}
JS 导入库开发-编码加密-逆向调试
html
//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文件夹中:
创建encry.html:
php
//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
效果展示:
两则案例分析-解析安全&登录调试
小迪8案例一:小迪8
1.根据传参值知道是edpassword
2.使用全局搜索edpassword:
3.发现传参变量edtPassWord
4.其中的$("#btnPost").click(function()
与我们所学习的ajax技术相对应:
html
<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
为什么#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
7.传输至这里
8.若不知道是md5加密可以用上面的方法进行溯源,之后在console中进行调试:
逻辑梳理:
进行调试对比:(发现相同)
案例二:
抓到包后看到看到LoginResult的username,Mobile,Password通过密文加密了
为了解密明文找到加密方式可以从表单入手:
全局搜索此值找到以下内容:
思考:
如果我们现在要测试注入一样
注入payload :admin ' 1=1
明文:admin '1=1
密文:xxxxxxxxxx
如果不知道加密算法 你发送明文?有效吗?
没有效 因为对方可能会解密
有效 以同样的加密方式去发送payload
以相同方法找到密码。
之后在控制台尝试使用平台加密方式进行加密,发现会进行报错(是在本地环境,不是在平台环境)。
只能使用断点调试:
点击此处进行断点调试:
会在右下角显示明文密码:
其中:
左边是调试跟踪代码执行流程(放走了)
右边是继续往下调
当往下调后数据将会发生改变:
现在在控制台调试会得到攻击语句和工具算法了
总结:
如果我们现在要测试注入一样
注入payload :admin ' 1=1
明文:admin '1=1
密文:xxxxxxxxxx
如果不知道加密算法 你发送明文?有效吗?
没有效 因为对方可能会解密
有效 以同样的加密方式去发送payload
为什么进行断点操作:
因为有些encrypt没有定义,浏览器没有显示断点。
此文章由李豆豆喵和番薯小羊卷~共同完成。