创建时间:2022年5月15日17:01:18
作者:在下小黄




存储区:URL
插入点:HTML


  1. XSS攻击需要具备两个条件:
  • 需要向web页面注入恶意代码;
  • 这些恶意代码能够被浏览器成功的执行
  1. XSS反射型漏洞:
  • 反射型XSS,顾名思义在于“反射”这个一来一回的过程。
  • 反射型XSS的触发有后端的参与,而之所以触发XSS是因为后端解析用户在前端输入的带有XSS性质的脚本或者脚本的data URI编码,后端解析用户输入处理后返回给前端,由浏览器解析这段XSS脚本,触发XSS漏洞。
  • 因此如果要避免反射性XSS,则必须需要后端的协调,在后端解析前端的数据时首先做相关的字串检测和转义处理;同时前端同样也许针对用户的数据做excape转义,保证数据源的可靠性
  1. 基本原理:就是通过给别人发送带有恶意脚本代码参数的URL,当URL地址被打开时,特定的代码参数会被HTML解析,执行,如此就可以获取用户的COOIKE,进而盗号登陆。
  2. 特点是:非持久化 必须用户点击带有特定参数的链接才能引起。
  3. XSS反射型攻击,恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。

一、Reflected Low 级别:

  1. 我们拿到靶场之后,先检查代码。
<?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>';
}

?>
------------------------------------------------------------------------------------
array_key_exists() 函数检查某个数组中是否存在指定的键名,如果键名存在则返回 true,如果键名不存在则返回 false。
echo() 函数输出一个或多个字符串。

简单来说:简单来说就是,输入请求不为空的时候,直接原样输出!!
  • 前端负责输入,后端接收到​​name​​参数后没有防范措施,直接打印在屏幕上。(echo)
  • ​<script>alert('xss')</script> ​

二、详解 DVWA_Reflected反射型XSS_web安全

  1. PHP 输出已经变成了,​​'<pre>Hello <script>alert('xss')</script></pre>' ​​​然后输出到页面时,直接运行​​<script>alert(1)</script> ​​这就是 XSS,原本这个地方应该是输入数据的,但是却变成运行代码了。

二、Reflected Medium 级别:

  1. 还是像之前一样,拿到之后我们先审计一下代码
<?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>";
}

?>
-----------------------------------------------------------------------------------
str_replace() 函数以其他字符替换字符串中的一些字符(区分大小写),这里是过滤请求中的<script>
  • 输入​​<scri<script>pt>alert('xss')</script>​

二、详解 DVWA_Reflected反射型XSS_html_02

  • 另一种方法,大小写混淆绕过:
  • 输入:​​<SCriPt>alert(/xss/)</ScRipt>​

二、详解 DVWA_Reflected反射型XSS_系统安全_03

  • 输入其他标签,如​​<IMG src=1 onerror=alert(document.cookie)>​

二、详解 DVWA_Reflected反射型XSS_web安全_04


三、Reflected High 级别:

  • 输入​​<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 = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );

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

?>
--------------------------------------------------------------------------------------
preg_replace():函数执行一个正则表达式的搜索和替换
(.*) 表示从头到尾匹配字符,表示贪婪匹配,(.*)s 从头到尾匹配s
/i 表示不区分大小写
'/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i' 表示过滤了<script>

虽然<script>标签不管用了,但是可以使用其他标签绕过
输入<IMG src=1 onerror=alert(document.cookie)>
  • ​<script>​​被过滤了
  • 构造出​​<scri<script>pt>alalertert('xss')</scr</script>ipt>​
  • 发现无法提交 猜测对提交的数据长度做了限制

二、详解 DVWA_Reflected反射型XSS_web安全_05

  • 源码对任何形式的​​script​​做了过滤
  • 所以可以采用不使用​​script​​的方式。
  • 比如利用​​img ​​​的​​ onerror​​​ 函数 ,意思是说,如果图片的地址是错误的,就执行​​alert(1)​
  • 函数使用正则表达式的搜索和替换,这样使得双写绕过和大小写混淆不可行。
  • 我们可以考虑通过​​img、body​​​等标签的事件或者​​iframe​​​等标签的​​src​​注入恶意的js代码。
  • 输入:​​<img src=1 onerror=alert(/xss/)>​

二、详解 DVWA_Reflected反射型XSS_前端_06

四、Reflected 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 实体。
预定义的字符是:
& (和号)成为 &
" (双引号)成为 "
' (单引号)成为 '
< (小于)成为 <
> (大于)成为 >

虽然利用了htmlspecialchars()函数将用户的输入进行过滤,但是在特定情况下需要用户输入一些被过滤,会丢失原始数据。且htmlspecialchars本质也是黑名单过滤,没有绝对安全

简单来说:就是直接输出
  1. 那么什么是HTML实体?
  • 在 HTML 中,某些字符是预留的。
  • 在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签,当然在HTML中还有其他实体。
  • 如果希望正确地显示预留字符,我们必须在HTML源代码中使用字符实体(character entities)。
  • 如需显示小于号,我们必须这样写:< 或 <使用实体名而不是数字的好处是,名称易于记忆。不过坏处是,浏览器也许并不支持所有实体名称(对实体数字的支持却很好)。
    于号(>),这是因为浏览器会误认为它们是标签,当然在HTML中还有其他实体。
  • 如果希望正确地显示预留字符,我们必须在HTML源代码中使用字符实体(character entities)。
  • 如需显示小于号,我们必须这样写:< 或 <使用实体名而不是数字的好处是,名称易于记忆。不过坏处是,浏览器也许并不支持所有实体名称(对实体数字的支持却很好)。