安全开发-web应用-JS-dom_xss-断点调试
上期我们简单的学习了关于js的文件上传和登录验证,相信大家对那部分的漏洞已经有所了解了,这期我们来看看关于js的外的一些知识
DOM树操作以及安全隐患
加密编码和数据安全测试
这两个因为关系不大,就新开一期讲了,不然就写在上期了,因为这两个关于安全还是有点作用的,这里就拉出来讲
首先说到DOM能想到的肯定是DOM型的xss漏洞咯,数据加密更不用说了,后期我们说关于js的漏洞的时候一些调试都会涉及到他。
这期我们就首先来学习一下关于DOM树-用户交互的小技术~
DOM是什么呢,中文翻译过来就是文档对象模型
DOM(Document Object Model)文档对象模型 是浏览器用来表示网页结构的一种方式。
当我们打开一个网页时,浏览器会把 HTML 代码 解析成一个“树状结构”,这就是 DOM 树。
简单来说就是,浏览器提供的专门操作网页代码的接口,实现自主或者用户交互的动作反馈,就是你点啥他就触发啥
元素节点:HTML 标签(如
<div>
、<p>
)文本节点:标签中的文字内容(如
"Hello"
)属性节点:元素的属性(如
<img src="a.jpg">
中的src
)
多的不说,直接上案例,依旧js文件夹
我们首先来看看到底有啥用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <img src="images/ew.jpg" width="300" height="300"><br> <button onclick="">刷新</button> </body> </html>
首先我们想一下,如果你想通过这个刷新按钮刷新这张图片,就跟你点击验证码他刷新一样,以php来说是不是通过传入刷新参数然后让后面接收到通过某种办法替换图片呢,反正就是叽里咕噜的,让人觉得很麻烦,有没有办法简单的实现效果呢
有的兄弟,有的
获取元素:
document.getElementById("myDiv")
修改内容:
element.innerText = "新内容"
改变样式:
element.style.color = "red"
首先你想获取对象,有三种不同的写法
标签:直接写(‘h1’)
class:加上符号(‘#class’)
id:加上符号(“.id”)
然后我们来看看他是怎么写的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <img src="images/ew.jpg" width="300" height="300"><br> <button onclick="update()">刷新</button> <script> function update(){ const src = document.querySelector('img') console.log(src) } </script> </body> </html>
可以看到这是一个简单的调试测试,当点击按钮的时候就会触发下面的函数,来看看到底有啥用
可以看到,当你点击刷新的时候,首先就会查询到这个标签的信息,然后我们想要的是src的地址位置,所以我们再修改一点点代码
console.log(src.src)
可以看到他直接就输出了这张图片的完整路径,继续来看看别的效果
<h1 class="biaoti" onclick="duqu()">我去你的</h1> <script> function duqu(){ const biaoti = document.querySelector('.biaoti') console.log(biaoti.innerHTML) } </script>
和上面一样,点击触发时间后来显示标签里的文本内容
可以看到也是能正常的获取到对象
还可以整个好玩的
function duqu(){ const biaoti = document.querySelector('h1') biaoti.innerText = '你去我的 <br>' console.log(biaoti.innerText) }
我们上面默认的值是这个我去你的,但是当我们点击触发按钮事件后,代码里可以看到会重新赋值,会怎么样呢
可以看到直接是变了我们重新赋值的你去我的,哈哈哈,可以知道我们这里对获取的是h1标签的值,然后利用innerTEXT来检测里面的文本,如果你在里面添加数据,他也只是当成文本来输出,比如我们随便输出一个标签
可以看到直接被当成文本输出了,这时候我们要是用html来表示他呢
function duqu(){ const biaoti = document.querySelector('h1') biaoti.innerHTML = '你去我的 <hr>' console.log(biaoti.innerHTML) }
可以看到我用的hr标签他也能成功的被html表示,并且下面也能正常的输出标签
所以这个有什么用呢
这就是第二个小芝士
操作元素数据
innerHTML :解析后续代码
innerTEXT :不解析后续代码
上面的实验已经很清楚的演示了作用哈
那我们现在就知道了,如何去更新图片,只要在js里重新给他赋值即可,我们来试试
function update(){ const src = document.querySelector('img') src.src = 'imates/小猫.jpg' console.log(src.src) }
可以看到也是能正常刷新的哈
所以叽里咕噜搞了半天想表达什么呢,其实这个东西的功能就是利用JS通过用户的操作来动态的改变当前的网页内容
我们知道了他有什么用了,那他有什么安全问题呢
前面我们更改图片的时候知道,当点击按钮的时候会读取到图片的src地址然后更改,但是现在用户觉得不够,他想自己选择图片,然后网站还真给他提供这个功能了,这时候变量由户传递,会发生甚么事呢
首先我们知道,通过刷新图片,会导致网页代码直接被更改
当你点击按钮就会直接在浏览器中更改代码,这一切都直接在前端js里完成,没有经过服务器,这时候就会导致一个问题,别人要是丢一个恶意代码过来呢,我们来看看
为了方便我创建了一个新的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>DOM-xss</title> </head> <body> <img id="myImg" src="images/ew.jpg" width="300" height="300"><br> <button onclick="update()">刷新</button><br> <script> function update() { const img = document.getElementById("myImg"); // 从 URL 中获取 src 参数并赋值给图片(不安全操作) const params = new URLSearchParams(location.search); const src = params.get("src"); if (src) { img.src = src; console.log("更新后的 src:", img.src); } } </script> </body> </html>
可以看到我们最后在传参的时候没有做任何校验,也就是说最后图片地址那里我们不管输入什么他都能被执行,
可以看到我们上面注入了小猫,然后只要我们点击刷新就会触发语句
如果输入一个js脚本呢
?src=javascript:alert('XSS')
这里由于浏览器问题无法成功哈,但是原理是这样的,这就是DOM xss 攻击,让用户自行输入参数,但没有过滤,导致可以执行js语句
这里就不再过多赘述了,我们继续来看
现在我们来看看关于js加密和调试
这部分相信大家就不陌生了,比如登录的时候服务器通过调用加密的js文件来个你输入的密码加密,然后因为数据库中存储的也是加密的数据,然后通过对比来判断是否正确,你抓包的时候就会看见自己输入的密码被加密了,至于什么加密就看调用了什么文件加密了,我们现在来试试
首先我这里准备了三个加密用的文件
如何实现呢,我们首先创建一个jiami.html文件
<script src="js/md5.js"></script> <script> var str1 = '123456'; var str_encode = md5(str1); document.write(str_encode); </script>
也就是对123456进行md5加密
可以看到他被加密了,然后我们解密看看
没有问题
加密有很多种,这里就不演示太多了,直接看案例
就拿我网站后台登录来说
当你想日一个网站的时候,你访问可以看看他有没有什么关于加密的文件,这里一看就知道加载了一个md5加密文件,那说明有可能他用上了md5加密
这里我有一个平民卡特的用户,我现在输入了一个密码,可以看到他被加密了,这一看就是md5加密哈,前面根据文件判断没有问题
观察一下源代码,可以发现他和我们前面学习的ajax写法是不是一样的呢,这不就是用到了那个技术吗,要是之前没有学的时候是不是代码审计的时候就一头雾水了呢,可以看到他用这个strPassWord来接受我们前面表单提交的密码,我们再来追踪一下
到这里这个登录逻辑已经非常明白了,他这里添加另一个md5参数,不就是和我刚刚写的一模一样吗,现在只要你能破解出来这个md5值,你不就能登进我的后台了吗(不准!!!!)
当然哈,由于md5的特性呢,最好使用一些高强度密码数字加大小写加字符组合,这样的高强度密码就不容易被破解,说真的嘞,我看哪个学网安的还搁那用弱口令,打你的狗头哈
这时候我们再提一个,你没有看到这个md5文件,代码中他也没有明显的告诉你,现在该怎么知道他如何加密的呢
这时候我们就要用到我们非常重要的技术了
调试
这里是简单的调试哈,后面更多的以后再讲
刚刚我们看到了他的代码逻辑,我们知道有个参数来接受我们传入的数据然后加密,那我们直接对变量进行修改呢
可以看到他能正常的输出我们传入的数据
现在我们来看个更吊的,我们去看看申通快递的登录
当我们登录的时候,可以看到他传输了三个加密的值,用户名,中间这个mobile和密码信息
但是这叽里咕噜谁知道是什么加密的啊,所以我们现在就来找找看
随便找找没有发现什么关于加密的
然后我们来追踪一下源代码
首先找到他传输参数的变量名
通过搜索我们找到了他登录时的使用的js命令,可以看到是同名的变量名来判断的登录行为
但是这里还是没有什么有用的信息,这里下面只是对输入值的判断对错,我们继续看看
在仔细搜索之下,我们看到了他加密使用的参数
为什么我们一定要知道他的加密方法呢,你在构造payload的时候首先都是使用明文构造,然后尝试去注入,但是服务器他不接受明文啊,你传输明文他以为这是个加密密文然后尝试解密,结果发现没有结果他就直接丢弃了,你这个攻击就没有造成任何效果,在我之前的做墨者的sql注入那个文章中,你就可以很好的理解到为什么我们要知道加密方法
可以去看一眼哈,现在我们了解了为什么要知道他的加密方法之后,我们就来尝试把他逆向的破解出来
首先我们来尝试前面第一种直接赋值的方法
由于他可能是引用了某些别的文件,他无法直接使用,所以这时候我们就要使用传说中的断点调试了
我们再输入一次记录当前的账号密码
点击前面的行数,就会给他添加一个断点标记
这时候再点登陆
页面就会在这里暂停
在旁边就可以看到你当前输入的明文,这时候他还没有进入加密方法里面,然后我们再回去调用那个加密参数
可以看到他成功的被调用了,然后我们就可以直接传入攻击语句
就可以让他帮我们构造攻击语句的加密,当然,这里只是简单的断点调试然后调用这个参数帮我们加密数据,一般这种加密都是随机性的,你可以看到就算输入一样的他的值还是会改变,但是我们已经简单的会使用断点调试了捏
高端的用法我们以后接着学习捏
这一期就到这里了,简单的学习了一下关于dom型xss的漏洞和断点调试的使用,这下学会的漏洞日日日又多了起来了捏
舒服了捏
未完待续~~