1、JS技术-DOM树操作及安全隐患
2、JS技术-加密编码及数据安全调试
➢JS原生开发-DOM树-用户交互
➢JS导入库开发-编码加密-逆向调试
➢两则案例分析-解析安全&登录调试
浏览器提供的一套专门用来操作网页代码内容的功能,实现自主或用户交互动作反馈
- 在Web开发中,浏览器将HTML文档解析为DOM树的结构。DOM树由节点(Nodes)组成,节点可以是元素节点、文本节点、注释节点等。每个节点都有与之相关联的属性、方法和事件。
- 通过使用DOM,您可以通过JavaScript或其他支持DOM的编程语言来访问和操作HTML文档的内容、结构和样式。您可以使用DOM提供的方法和属性来选择元素、修改元素的属性和内容、添加或删除元素,以及响应用户交互等。
标签:直接写
Class:加上符号.
id:加上符号#r
具体来说,document
是代表整个文档的对象,而 querySelector()
是在文档中查找与指定选择器匹配的第一个元素的方法。
<h1 id="myHeader" onclick="getValue()">这是标题h1>
document.querySelector('h1')
document.querySelector('.id')
document.querySelector('#myHeader')
**console.log():**
是一个用于在控制台输出信息的方法。它是由浏览器或其他 JavaScript 运行环境提供的调试工具。通过调用 console.log(),您可以在控制台中输出消息、变量的值、调试信息等,以便在开发过程中进行调试和测试。
例如:
console.log("Hello, world!");
这行代码将在控制台输出字符串 "Hello, world!"。
**const:**
是 JavaScript 中的一个关键字,用于声明一个只读的常量变量。使用 const 声明的变量不能被重新赋值。一旦被赋值后,它的值就不能再改变。
例如:
const PI = 3.14159;
这行代码声明了一个常量 PI,其值为 3.14159。由于是常量,PI 的值不能再被修改。
总结:console.log() 是一个用于输出信息到控制台的方法,而 const 是一个关键字,用于声明只读的常量变量。它们在功能和用途上是完全不同的。
<h1 id="myHeader" onclick="getValue()">这是标题h1>
<script>
// 选择第一个 h1 元素
const h1 = document.querySelector('h1');
**// 获取 h1 元素的 id 属性
const id = h1.id;
// 输出 id 到控制台
console.log(id);**
script>
innerHTML 解析后续代码
var element = document.getElementById("myElement");
var htmlContent = element.innerHTML; // 获取元素的内容(包括 HTML 标记)
**element.innerHTML = "New Content"; // 设置元素的内容,并解析 HTML 标记**
innerText 不解析后续代码
var element = document.getElementById("myElement");
var textContent = element.innerText; // 获取元素的纯文本内容
**element.innerText = "New Text Content"; // 设置元素的纯文本内容**
innerHTML 解析后续代码
<h1 id="myHeader" onclick="update1()">这是标题</h1>
<script>
function update1(){
const h1=document.querySelector('h1')
**h1.innerHTML="这是小迪
"**
console.log(str)
}
</script>
innerText 不解析后续代码
<h1 id="myHeader" onclick="update1()">这是标题</h1>
<script>
function update1(){
const h1=document.querySelector('h1')
**h1.innerText="这是小迪
"**
console.log(str)
}
</script>
可以实现强制转换图片
<img src="iphone.jpg" width="300" height="300"><br>
<script>
function update(){
**const s=document.querySelector('img')
s.src='huawei.png'
console.log(s.src)
//如果这里huawei.png为一个变量由用户传递决定,那么就会造成DOM XSS**
}
</script>
本身的前端代码通过DOM技术实现代码的更新修改,但是更新修改如果修改的数据可以由用户来指定,就会造成DOM-XSS攻击!
update1
函数通过 innerHTML
插入带有 onerror
事件的 img
元素,这可能导致 XSS(跨站脚本攻击)漏洞。在实际应用中,需要谨慎处理用户提供的内容,以防止安全漏洞。<h1 id="myHeader" onclick="update1()">这是标题</h1>
<script>
function update1(){
const h1=document.querySelector('h1')
**h1.innerHTML=''**
console.log(str)
}
</script>
//Base64
<script src="js/md5.js">script>
<script>
// 定义字符串变量
var str1 = 'xiaodi jichu No1';
// 使用 md5.js 中的 md5 函数对字符串进行加密
var str_encode = md5(str1);
// 输出加密后的字符串到控制台
console.log(str_encode);
script>
输出:afe5119ec0ab46b55432fc5e24f1dc62
<script src="js/crypto-js.js">script>
<script>
// 定义字符串变量
var str1 = 'xiaodisec';
// 使用 CryptoJS.SHA1 函数对字符串进行 SHA-1 加密,并将结果转为字符串
var str_encode = CryptoJS.SHA1(str1).toString();
// 输出加密后的字符串到控制台
console.log(str_encode);
script>
输出:ce22eaa1c5ebd3dfb3f4474b66f6d3612d4cb3ee
<script src="js/crypto-js.js">script>
<script>
// 定义密钥和字符串变量
var key = 'key';
var str1 = 'xiaodisec';
// 使用 CryptoJS.HmacSHA256 函数生成 HMAC-SHA256 散列
var hash = CryptoJS.HmacSHA256(key, str1);
// 将散列结果转为十六进制字符串
var str_encode = CryptoJS.enc.Hex.stringify(hash);
// 输出加密后的字符串到控制台
console.log(str_encode);
// 输出示例:'11a7960cd583ee2c3f1ed910dbc3b6c3991207cbc527d122f69e84d13cc5ce5c'
script>
输出:08ac6dc8773bd34dcadeffb2b90a8b8f5be9453a9dce7cf09d4da2fcb363d9e7
<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>
输出:g4ohopaiYA34XXLsV92Udw== xiaodisec
<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.DES.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.DES.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 xiaozhou ?"
script>
输出:WVSwdlodMcV2n1FH72uXgw== xiaodisec
<script src="js/jsencrypt.js">script>
<script type="text/javascript">
// 公钥 私匙是通过公匙计算生成的,不能盲目设置
var PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyBJ6kZ/VFJYTV3vOC07jqWIqgyvHulv6us/8wzlSBqQ2+eOTX7s5zKfXY40yZWDoCaIGk+tP/sc0D6dQzjaxECAwEAAQ==-----END PUBLIC KEY-----';
//私钥
var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvIEnqRn9UUlhNXe84LTuOpYiqDK8e6W/q6z/zDOVIGpDb545NfuznMp9djjTJlYOgJogaT60/+xzQPp1DONrEQIDAQABAkEAu7DFsqQEDDnKJpiwYfUE9ySiIWNTNLJWZDN/Bu2dYIV4DO2A5aHZfMe48rga5BkoWq2LALlY3tqsOFTe3M6yoQIhAOSfSAU3H6jIOnlEiZabUrVGqiFLCb5Ut3Jz9NN+5p59AiEA0xQDMrxWBBJ9BYq6RRY4pXwa/MthX/8Hy+3GnvNw/yUCIG/3Ee578KVYakq5pih8KSVeVjO37C2qj60d3Ok3XPqBAiEAqGPvxTsAuBDz0kcBIPqASGzArumljkrLsoHHkakOfU0CIDuhxKQwHlXFDO79ppYAPcVO3bph672qGD84YUaHF+pQ-----END PRIVATE KEY-----';
//使用公钥加密
var encrypt = new JSEncrypt();//实例化加密对象
encrypt.setPublicKey(PUBLIC_KEY);//设置公钥
var message = 'xiaodisec' // 需要加密的数据
var encrypted = encrypt.encrypt(message);//对指定数据进行加密
console.log(encrypted) // 'JQ83h8tmJpsSZcb4BJ3eQvuqIAs3ejepcUUnoFhQEvum8fA8bf1Y/fG+DO1bSIVNJF6EOZKe4wa0njv6aOar9w=='
//使用私钥解密
var decrypt = new JSEncrypt(); // 创建解密对象
decrypt.setPrivateKey(PRIVATE_KEY); //设置私钥
var uncrypted = decrypt.decrypt(encrypted); //解密 'xiaodisec'
console.log(uncrypted);
script>
输出:Fw1H5KoC6zZnwAzLee8z5ubmQYSqaVqu711VI+NBavYT9bkWpzxUtZHmbSUvLbuCblPO96NdfoQHtPe9TURo6A== xiaodisec
首先,让我们逐步解析这个语句的含义。在MySQL中,’admin’表示一个字符串常量,OR关键字表示逻辑或运算符,而1=1是一个恒定为真的条件。最后的’– ‘表示注释,使得引号后的内容成为注释而不被解析。
换句话说,这个语句在条件中使用了1=1,这个条件总是为真,因此结果总是返回真。这就可以绕过许多条件验证,让用户以admin的身份执行相关操作。
举个例子,假设SQL语句如下:
SELECT * FROM users WHERE username = 'admin' OR 1=1 -- ' AND password = '123456'
这个语句的意图是从users表中选择username为’admin’且password为’123456’的记录。然而,由于’admin’ OR 1=1 — ‘这个条件恒为真,实际上会选择所有的记录,而不仅仅是admin账户。
小迪渗透吧-提供最专业的渗透测试培训,web安全培训,网络安全培训,代码审计培训,安全服务培训,CTF比赛培训,SRC平台挖掘培训,红蓝对抗培训!-登录 (xiaodi8.com)
打开页面,选择密码右击鼠标打开检查
找到相关id值edtPassWord,并进行搜索$("#btnPost").click(function()
加#后证明是想取id值中的edtPassWord
<input type="text" **id="edtUserName"** name="edtUserName" size="20" value="" tabindex="1">
找到密码的加密方式$("#password").val(**MD5**(strPassWord));
为MD5
尝试传递数据,发现提交的表达数据中密码确实加密的btnPost=%E7%99%BB%E5%BD%95&username=admin&password=e10adc3949ba59abbe56e057f20f883e&savedate=1
分析代码过程:发出疑问如果加密格式不显示出来,怎样判断加密的方式是什么
可以借助检查的控制台,尝试输入获取加密后的密码值,再和提交表单的加密值进行比对,若一致则证明识别出。(一般安全防护比较强的,不会把运行的所以东西全加载到浏览器上)
**MD5('xiaodi')
'bb1be44c4f8e615aeba54e9d233c23b6'**
申通快递会员中心-登录 (sto.cn)
打开页面,选择密码右击鼠标打开检查找到相关id值**numPassword
** 并进行搜索
找到密码的加密格式,但是没有明文展现出来
logindata.UserName = encodeURI(encrypt.encrypt(numMobile));
logindata.Mobile = encodeURI(encrypt.encrypt(numMobile));;
//加密密码
logindata.Password = encodeURI(encrypt.encrypt(numPassword));
采用之前的方式在控制台中输入相应的代码encodeURI(encrypt.encrypt(numPassword))报错encrypt is not defined,有一些文件只在服务器本地执行,不会加载到浏览器中
必须采用调试断点的方式来,通过服务器获取其执行文件,然后修改对应的返回密文即可
对应地方打上断点,点击登录,进入断点调试,发现右侧出现输入的账号密码内容
点击最右侧按钮,进入调试,再次打开控制台,并输入encodeURI(encrypt.encrypt(numPassword))
发现成功回显加密后的密码
encodeURI(encrypt.encrypt(numPassword))
'YvnVBFSz/w0kv1st6gqlzu5bqnTJ/0L8aDnQIr2Vgy5QRfwYJ9a7/eUWdFTZ/+N0ppU7SYYcdwYH8Iu8Kpr32mXVHZh/2HgoAcnrukiTUfeJthrkczLn++mE9y9CW2d9jq4BRdfbh8uLzX1k5JxHrGI8IKyZTGQTXCZhVouI/qw='
将其修改为SQL注入的语句,也成功返回加密内容