XSS——学习日志1

XSS

跨站脚本攻击(Cross Site Scripting),为了与重叠样式表CSS区分,换了另一个缩写XSS。
xss

概念阐述

XSS攻击的核心是将可执行的前端脚本代码(一般为JavaScript)植入到网页中。

反射型

在这里插入图片描述

1、攻击者将JS代码作为请求参数放置URL中,诱导用户点击 示例:

http://localhost:8080/test?name=<script>alert("you are under attack!")</script>

2、用户点击后,该JS作为请求参数传给Web服务器后端

3、后端服务器没有检查过滤,简单处理后放入网页正文中返回给浏览器

4、浏览器解析返回的网页,中招!

存储型

在这里插入图片描述

上述方式攻击脚本直接经服务器转手后返回浏览器触发执行,存储型与之的区别在于能够将攻击脚本入库存储,在后面进行查询时,再将攻击脚本渲染进网页,返回给浏览器触发执行。常见的套路举例如下:

1、攻击者网页回帖,帖子中包含JS脚本

2、回帖提交服务器后,存储至数据库

3、其他网友查看帖子,后台查询该帖子的回帖内容,构建完整网页,返回浏览器

4、该网友浏览器渲染返回的网页,中招!

DOM型

特点与反射型xss相同,区别在于脚本存在于hash值中,并未向后端传送。

形成原因

形成XSS漏洞的主要原因是程序中输入和输出的控制不够严格

测试流程

① 在目标上找输入点,比如查询接口、留言板

② 输入一组 “特殊字符(>,’,"等)+唯一识别字符” ,点击提交后,查看返回源码,看后端返回的数据是否有处理

③ 通过搜索定位到唯一字符,结合唯一字符前后语法确定是否可以构造执行js的条件(构造闭合)

④ 提交构造的脚本代码(以及各种绕过姿势),看是否可以成功执行,如果成功执行则说明存在XSS漏洞

DVWA实例

反射型

在这里插入图片描述

low

输入“<xss>”显示如下
在这里插入图片描述
可以看出是有反应的,尝试输入<script>alert(/xss/)</script>,得到如下结果
在这里插入图片描述
在这里插入图片描述
写入成功,这时候返回头再看源码

<?php

header ("X-XSS-Protection: 0");

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Feedback for end user
    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}

?>

嚯!果然是,没有什么防范措施。

medium

输入low一样的代码<script>alert(/xss/)</script>,获得结果
在这里插入图片描述
可以看出没什么作用
这个时候我们看一下源码


<?php

header ("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 user
    echo "<pre>Hello ${name}</pre>";
}

?>

发现其中加入了对<script>的限制,因为只有对此标签的限制,很好绕过。
方法一:换标签

<img src=a onerror=alert(/xss/)>

方法二:双写

<scr<script>ipt>alert(/xss/)</script>

方法三:大小写

<sCRIpT>alert(/xss/)</script>

写入成功
在这里插入图片描述
可见遇到限制有时候未必是全限制,可以多试几个标签,万一限制也有限,就撞出来了

high

输入<script>alert(/xss/)</script>
在这里插入图片描述
输入<scr<script>ipt>alert(/xss/)</script>结果一样
查看源码


<?php

header ("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 user
    echo "<pre>Hello ${name}</pre>";
}

?>

发现双写和大小写都给堵死了,<script>标签已经不能再用,只能改换标签
输入<img src=a onerror=alert(/xss/)>
在这里插入图片描述
写入成功

impossible

直接查看源码

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $name = htmlspecialchars( $_GET[ 'name' ] );

    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";
}

// Generate Anti-CSRF token
generateSessionToken();

?>

可以看到,代码使用htmlspecialchars函数把预定义的字符&、”、 ’、<、>转换为 HTML 实体

存储型

在这里插入图片描述

low

尝试可以发现,name输入框有字数限制,可以抓包写入,也可以直接在Message中写入<script>alert(/xss/)</script>
在这里插入图片描述
在这里插入图片描述
写入成功
而且这个时候,也可以看到写入的信息以及存储并输出在下方
在这里插入图片描述
存储型xss的特点就是“存储”,只要不清除下方的存储,每次刷新都会有弹窗显示,因为每次刷新都是进行一次新的查询,都会把数据库中的数据调到前端,而前端每执行一次都会引发一次xss

源码

<?php

if( 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();
}

?>
medium

源码

<?php

if( 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();
}

?>

从medium难度开始就对message输入框加上了htmlspecialchars函数进行编码,因此无法再通过message参数注入XSS代码,但是对于name参数,只是简单过滤了<script>字符串,仍然存在存储型的XSS,可以抓包修改输入来注入。
限制了<script>标签,但可以使用双写和大小写来绕过。

high

彻底限制了<script>标签,但仍可以用其他标签绕过,如<img>

DOM型

在这里插入图片描述
选择的结果会显示在url中,因此直接在url中注释即可

low

查看网页源代码可得
在这里插入图片描述
属于由document.write属性造成的DOM型xss漏洞
直接在url中写入<script>alert(/xss/)</script>即可
在这里插入图片描述
这个时候再试验一下<img src=a onerror=alert(/xss/)>,发现无法通过
在这里插入图片描述
再次查看网页源代码,发现输入的部分是在select和option标签内部,select标签内只允许内嵌option标签,而option标签中能内嵌script标签但不能内嵌img等标签,因此需要在注入时先闭合option和select标签,从而使注入的标签逃逸出来执行XSS
在这里插入图片描述
查看源码
在这里插入图片描述
未做任何防御机制

medium

先尝试<script>alert(/xss/)</script>,发现会重定向至English的页面
试验过后发现,双写和大小写也无法绕过
但可以用上述的<img>标签,前提是要闭合option和select标签
在这里插入图片描述
查看源码

调用stripos()函数获取“<script”字符串出现在参数的哪个位置(不区分大小写),因此重复内嵌和大小写等方式无法绕过该过滤机制

high

上述方法一一尝试后发现失败,查看源码


<?php

// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {

    # White list the allowable languages
    switch ($_GET['default']) {
        case "French":
        case "English":
        case "German":
        case "Spanish":
            # ok
            break;
        default:
            header ("location: ?default=English");
            exit;
    }
}

?>

发现使用了白名单过滤,已经限制死了
这时只能尝试应用#号,URL栏的#号之后的内容并不会发送至服务器端,JS应用该符号实现在页面创建加载过程中定向到指定的页面内容上。
在这里插入图片描述
输入后是没有反应的(按回车也是),需要手动点击浏览器的刷新按钮,才会弹出xss弹窗

漏洞利用

窃取cookie——createElement()
在这里插入图片描述
使用document.cookie来获取cookie字段。
下面顺便来看一下DVWA的CSRF的high难度
通过<iframe src="../csrf" onload=alert(frames[0].document.getElementsByName('user_token')[0].value)>可获取user token,直接在csrf的包中添加即可
在这里插入图片描述

pikachu实例

反射型xss(get)

在这里插入图片描述
输入内容后,输入的内容会经过后台并回显
在这里插入图片描述
在这里插入图片描述
并在url中显示
在这里插入图片描述
get和post的特征区别在于是否在url中显示,get方法就可以直接在url中修改message的值
在这里插入图片描述

获取cookie成功

反射型xss(post)

先是一个登录页面
在这里插入图片描述
提示中有账号密码,登录后遇到与get型一样的形式,不同在于无法在url中直接修改,只能更改页面源码或者抓包修改
在这里插入图片描述
获取cookie成功

存储型xss

在这里插入图片描述
同DVWA中的存储型xss,输入的内容会保存,而每一次进入页面,从数据库调取数据时都会产生xss
在这里插入图片描述
一直到删除相应的内容为止

DOM型xss

在这里插入图片描述
随意输入后查看页面源码
在这里插入图片描述
尝试用双引号闭合,发现失败,查看源代码发现提示用‘ >来闭合,尝试后发现<script>标签无反应,尝试换用' > <img src=a onerror=alert(document.cookie)>
在这里插入图片描述
获取成功

DOM型xss-x

在这里插入图片描述
当输入完成后会出现链接,点击链接后会出现第二条链接,此时出现的链接与上题一样,查看源码后根据限制写出条件即可
在这里插入图片描述
需要点击第一个链接才会触发,算是多了一重保障。

xss之盲打

在这里插入图片描述
在两个输入框输入不同的xss弹窗,进行试验
提交后进入后台
在这里插入图片描述
在这里插入图片描述
可见两个输入框都存在xss漏洞

xss之过滤

查看源码发现如DVWA的高级难度,对<script>标签进行了限制,便可使用其他标签进行xss注入
在这里插入图片描述

xss之htmlspecialchars

在这里插入图片描述
htmlspecialchars()函数把预定义字符转换成HT,L实体
预定义字符为:
1、& (和 )&amp(编码)
2、” (双引号)&qupt
3、’ (单引号)&#039
4、< (小于) &It
5、> (大于) &gt
可用引号类型:
ENT_COMPAT—默认,仅编码双引号
ENT_QUOTES—编码双引号和单引号(推荐)
ENT_NOQUOTES—不编码任何引号
我们发现特殊字符除了单引号都被进行了编码,因此我们可以我进输入单引号进行注释掉。输入:' onclick='alert(document.cookie)'
在这里插入图片描述
获取成功

xss之href输出

在这里插入图片描述
虽然有htmlspecialchars()函数,但由于输入的url拼接在 < a href=‘输入的内容’>属性中,所以可以使用javascript语法来构造使用伪协议payload:
javascript:alert(document.cookie)
在这里插入图片描述

xss之js输出

在这里插入图片描述
查看页面源码
在这里插入图片描述
输入的代码被生成再js中并赋值给$ms。既然我们的输入被带入到js中,可以闭合
</script><script>alert(document.cookie)</script>
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值