代码审计(1):CVE-2022-4957分析及复现
0x00漏洞描述:
ѕрееdtеѕt iѕ а vеrу liɡhtԝеiɡht nеtԝоrk ѕрееd tеѕtinɡ tооl imрlеmеntеd in Jаvаѕсriрt. Thеrе iѕ а Crоѕѕ-ѕitе Sсriрtinɡ vulnеrаbilitу in librеѕроndеd ѕрееdtеѕt 5.2.4 аnd еаrliеr vеrѕiоnѕ. Thе vulnеrаbilitу iѕ саuѕеd bу thе раrаmеtеr id оf thе filе rеѕultѕ/ѕtаtѕ.рhр thаt ԝill саuѕе Crоѕѕ-ѕitе Sсriрtinɡ.
0x01 分析:
先到Github把ѕрееdtеѕt的5.2.4版本的源代码下下来,然后直接看rеѕultѕ/ѕtаtѕ.рhр文件:
<?php
session_start();
error_reporting(0);require 'telemetry_settings.php';
require_once 'telemetry_db.php';header('Content-Type: text/html; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0, s-maxage=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
?>
<!DOCTYPE html>
<html><head><title>LibreSpeed - Stats</title><style type="text/css">html,body{margin:0;padding:0;border:none;width:100%; min-height:100%;}html{background-color: hsl(198,72%,35%);font-family: "Segoe UI","Roboto",sans-serif;}body{background-color:#FFFFFF;box-sizing:border-box;width:100%;max-width:70em;margin:4em auto;box-shadow:0 1em 6em #00000080;padding:1em 1em 4em 1em;border-radius:0.4em;}h1,h2,h3,h4,h5,h6{font-weight:300;margin-bottom: 0.1em;}h1{text-align:center;}table{margin:2em 0;width:100%;}table, tr, th, td {border: 1px solid #AAAAAA;}th {width: 6em;}td {word-break: break-all;}div {margin: 1em 0;}</style></head><body><h1>LibreSpeed - Stats</h1><?phpif (!isset($stats_password) || $stats_password === 'PASSWORD') {?>Please set $stats_password in telemetry_settings.php to enable access.<?php} elseif ($_SESSION['logged'] === true) {if ($_GET['op'] === 'logout') {$_SESSION['logged'] = false;?><script type="text/javascript">window.location=location.protocol+"//"+location.host+location.pathname;</script><?php} else {?><form action="stats.php" method="GET"><input type="hidden" name="op" value="logout" /><input type="submit" value="Logout" /></form><form action="stats.php" method="GET"><h3>Search test results</h3><input type="hidden" name="op" value="id" /><input type="text" name="id" id="id" placeholder="Test ID" value=""/><input type="submit" value="Find" /><input type="submit" onclick="document.getElementById('id').value=''" value="Show last 100 tests" /></form><?phpif ($_GET['op'] === 'id' && !empty($_GET['id'])) {$speedtest = getSpeedtestUserById($_GET['id']);$speedtests = [];if (false === $speedtest) {echo '<div>There was an error trying to fetch the speedtest result for ID "'.$_GET['id'].'".</div>';} elseif (null === $speedtest) {echo '<div>Could not find a speedtest result for ID "'.$_GET['id'].'".</div>';} else {$speedtests = [$speedtest];}} else {$speedtests = getLatestSpeedtestUsers();if (false === $speedtests) {echo '<div>There was an error trying to fetch latest speedtest results.</div>';} elseif (empty($speedtests)) {echo '<div>Could not find any speedtest results in database.</div>';}}foreach ($speedtests as $speedtest) {?><table><tr><th>Test ID</th><td><?= htmlspecialchars($speedtest['id_formatted'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Date and time</th><td><?= htmlspecialchars($speedtest['timestamp'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>IP and ISP Info</th><td><?= htmlspecialchars($speedtest['ip'], ENT_HTML5, 'UTF-8') ?><br/><?= htmlspecialchars($speedtest['ispinfo'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>User agent and locale</th><td><?= htmlspecialchars($speedtest['ua'], ENT_HTML5, 'UTF-8') ?><br/><?= htmlspecialchars($speedtest['lang'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Download speed</th><td><?= htmlspecialchars($speedtest['dl'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Upload speed</th><td><?= htmlspecialchars($speedtest['ul'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Ping</th><td><?= htmlspecialchars($speedtest['ping'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Jitter</th><td><?= htmlspecialchars($speedtest['jitter'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Log</th><td><?= htmlspecialchars($speedtest['log'], ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Extra info</th><td><?= htmlspecialchars($speedtest['extra'], ENT_HTML5, 'UTF-8') ?></td></tr></table><?php}}} elseif ($_GET['op'] === 'login' && $_POST['password'] === $stats_password) {$_SESSION['logged'] = true;?><script type="text/javascript">window.location=location.protocol+"//"+location.host+location.pathname;</script><?php} else {?><form action="stats.php?op=login" method="POST"><h3>Login</h3><input type="password" name="password" placeholder="Password" value=""/><input type="submit" value="Login" /></form><?php}?></body>
</html>
直接看第89行的漏洞点:
<?phpif ($_GET['op'] === 'id' && !empty($_GET['id'])) {$speedtest = getSpeedtestUserById($_GET['id']);$speedtests = [];if (false === $speedtest) {echo '<div>There was an error trying to fetch the speedtest result for ID "'.$_GET['id'].'".</div>';} elseif (null === $speedtest) {echo '<div>Could not find a speedtest result for ID "'.$_GET['id'].'".</div>';} else {$speedtests = [$speedtest];}} else {$speedtests = getLatestSpeedtestUsers();if (false === $speedtests) {echo '<div>There was an error trying to fetch latest speedtest results.</div>';} elseif (empty($speedtests)) {echo '<div>Could not find any speedtest results in database.</div>';}}foreach ($speedtests as $speedtest) {?>
当接收参数op=id,参数id=空或者flase时,直接将$_GET[‘id’]拼接到HTML代码中,导致了一个反射型的XSS。
0x02 复现
直接docker pull下来官方镜像,把里面的内容换成5.2.4版本的代码,然后点击登录:

这里由于stats.php的代码里有一句:
<?phpif (!isset($stats_password) || $stats_password === 'PASSWORD') {?>Please set $stats_password in telemetry_settings.php to enable access.<?php} elseif ($_SESSION['logged'] === true) {if ($_GET['op'] === 'logout') {$_SESSION['logged'] = false;?><script type="text/javascript">window.location=location.protocol+"//"+location.host+location.pathname;</script><?php
因此,还要到telemetry_settings.php里去把$stats_password改掉。
登录进去之后输入payload:

利用成功:

0x03利用条件
1.知道stats.php的登录密码
2.目标给results文件夹配置了php执行的权限(实际上很多目标都没有给results文件夹php文件的解析权限)
3.反射型XSS,必须要与目标有交互
4.版本有极大限制,仅限于5.2.3和5.2.4版本,如5.2.2版本就不存在这个问题:
<?php$q=null;if($_GET["op"]=="id"&&!empty($_GET["id"])){$id=$_GET["id"];if($enable_id_obfuscation) $id=deobfuscateId($id);if($db_type=="mysql"){$q=$conn->prepare("select id,timestamp,ip,ispinfo,ua,lang,dl,ul,ping,jitter,log,extra from speedtest_users where id=?");$q->bind_param("i",$id);$q->execute();$q->store_result();$q->bind_result($id,$timestamp,$ip,$ispinfo,$ua,$lang,$dl,$ul,$ping,$jitter,$log,$extra);} else if($db_type=="sqlite"||$db_type=="postgresql"){$q=$conn->prepare("select id,timestamp,ip,ispinfo,ua,lang,dl,ul,ping,jitter,log,extra from speedtest_users where id=?");$q->execute(array($id));} else die();}else{if($db_type=="mysql"){$q=$conn->prepare("select id,timestamp,ip,ispinfo,ua,lang,dl,ul,ping,jitter,log,extra from speedtest_users order by timestamp desc limit 0,100");$q->execute();$q->store_result();$q->bind_result($id,$timestamp,$ip,$ispinfo,$ua,$lang,$dl,$ul,$ping,$jitter,$log,$extra);} else if($db_type=="sqlite"||$db_type=="postgresql"){$q=$conn->prepare("select id,timestamp,ip,ispinfo,ua,lang,dl,ul,ping,jitter,log,extra from speedtest_users order by timestamp desc limit 100");$q->execute();}else die();}while(true){$id=null; $timestamp=null; $ip=null; $ispinfo=null; $ua=null; $lang=null; $dl=null; $ul=null; $ping=null; $jitter=null; $log=null; $extra=null;if($db_type=="mysql"){if(!$q->fetch()) break;} else if($db_type=="sqlite"||$db_type=="postgresql"){if(!($row=$q->fetch())) break;$id=$row["id"];$timestamp=$row["timestamp"];$ip=$row["ip"];$ispinfo=$row["ispinfo"];$ua=$row["ua"];$lang=$row["lang"];$dl=$row["dl"];$ul=$row["ul"];$ping=$row["ping"];$jitter=$row["jitter"];$log=$row["log"];$extra=$row["extra"];}else die();?><table><tr><th>Test ID</th><td><?=htmlspecialchars(($enable_id_obfuscation?(obfuscateId($id)." (deobfuscated: ".$id.")"):$id), ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Date and time</th><td><?=htmlspecialchars($timestamp, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>IP and ISP Info</th><td><?=$ip ?><br/><?=htmlspecialchars($ispinfo, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>User agent and locale</th><td><?=$ua ?><br/><?=htmlspecialchars($lang, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Download speed</th><td><?=htmlspecialchars($dl, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Upload speed</th><td><?=htmlspecialchars($ul, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Ping</th><td><?=htmlspecialchars($ping, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Jitter</th><td><?=htmlspecialchars($jitter, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Log</th><td><?=htmlspecialchars($log, ENT_HTML5, 'UTF-8') ?></td></tr><tr><th>Extra info</th><td><?=htmlspecialchars($extra, ENT_HTML5, 'UTF-8') ?></td></tr></table><?php}?>
综合评价:利用条件极其苛刻,鸡肋漏洞。这种洞居然也是CVE,我真是服了。
相关文章:
代码审计(1):CVE-2022-4957分析及复现
0x00漏洞描述: ѕрееdtеѕt iѕ а vеrу liɡhtԝеiɡht nеtԝоrk ѕрееd tеѕtinɡ tооl imрlеmеntеd in Jаvаѕсriрt. Thеrе iѕ а Crоѕѕ-ѕitе Sсriрtinɡ vulnеrаbilitу in librеѕроndеd ѕрееdtеѕt…...
问题:设备管理指标为完好率不低于( ),待修率不高于5%,事故率不高于1%。 #知识分享#经验分享#经验分享
问题:设备管理指标为完好率不低于( ),待修率不高于5%,事故率不高于1%。 A、100% B、95% C、90% D、80% 参考答案如图所示...
【Linux】(六)—— vim编辑器
vim文件编辑器 Vim(Vi Improved)是一个高度可配置的文本编辑器,最初基于UNIX下的Vi编辑器发展而来,广泛用于程序开发和系统管理中。vim编辑器可以只通过终端命令即可编写修改文件,不需要和gedit一样需要打开类似于记事…...
06016传感器原理与应用202207
06016传感器原理与应用202207 选择题(2*11) 1.基本的电子测量系统由四部分组成,即电源、信号调节、显示系统和B(P7) A.分档器 B.传感器 C.处理器 D.采集器 2.热电阻温度计的测量电路采用精度较高的是B&am…...
java web:springboot mysql开发的一套家政预约上门服务系统源码:家政上门服务系统的运行流程
java web:springboot mysql开发的一套家政预约上门服务系统源码:家政上门服务系统的运行流程 家政上门服务系统的优势 服务质量更稳定:由专业的家政人员提供服务,经过严格的培训和筛选。 价格更透明:采用套餐式收费&…...
二叉树的后序遍历-力扣
二叉树的后序遍历,指首先遍历二叉树的左节点,然后遍历二叉树的右节点,最后遍历中间节点。按照顺序进行递归遍历即可。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *rig…...
C++基础编程100题-008 OpenJudge-1.3-06 甲流疫情死亡率
更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0103/06/ 描述 甲流并不可怕,在中国,它的死亡率并不是很高。请根据截止2009年12月22日各省报告的甲流确诊数和死亡数,计算甲流在各省的死亡率。 输入 输入仅一行ÿ…...
计算机网络 ——网络层(IPv4地址)
计算机网络 ——网络层(IPv4地址) 什么是IPv4地址IP地址的分类特殊的IP地址 查看自己的IPv4地址 我们今天来看IPv4地址: 什么是IPv4地址 IPv4(Internet Protocol version 4)是第四版互联网协议,是第一个被…...
重写mybatisPlus自定义ID生成策略
1.项目中需要引入mybatisplus核心组件 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mp.version}</version></dependency> 2.新建一个类实现IdentifierGenera…...
华为坤灵路由器配置SSH
配置SSH服务器的管理网口IP地址。 <HUAWEI> system-view [HUAWEI] sysname SSH Server [SSH Server] interface meth 0/0/0 [SSH Server-MEth0/0/0] ip address 10.248.103.194 255.255.255.0 [SSH Server-MEth0/0/0] quit 在SSH服务器端生成本地密钥对。 [SSH Server…...
盘点一个Python网络爬虫的实战问题
点击上方“Python爬虫与数据挖掘”,进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 西宫南内多秋草,落叶满阶红不扫。 大家好,我是Python进阶者。 一、前言 前几天在Python最强王者交流群【🇿 &#x…...
100道面试必会算法-32-二叉树右视图用栈实现队列
100道面试必会算法-32-二叉树右视图&用栈实现队列 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,n…...
⽀付逻辑漏洞思路⼩集合
⼀.直接的价格修改 ⼆.修改⽀付状态 三.修改购买数量 四:⽀付附属值修改 ➀:修改优惠劵⾦额 ➁:修改优惠劵⾦额及业务逻辑问题 ➂:修改积分⾦额 ➃:满减修改 五:订单替代⽀付 六:⽀付接…...
嵌入式学习——Linux高级编程复习(线程)——day40
1. 线程 1.1 定义 线程是一个轻量级的进程 是一个任务被创建、调度、消亡的过程 1.2 线程和进程的区别与联系 1. 线程是CPU任务调度的最小单元 2. 进程是操作系统资源分配的最小单元 3. 线程(Thread)是操作系统能够进行运算调度的最小单位…...
kvm管理工具-virsh
virsh 查看全部虚拟机列表停止虚拟机列表启动虚拟机强制关闭虚拟机连接虚拟机控制台查看虚拟机的详细信息查看虚拟机接口信息查看虚拟机xml文件配置删除虚拟机 KVM(Kernel-based Virtual Machine)是一种基于 Linux 内核的虚拟化技术,允许在一…...
VisionPro的应用和入门教程
第1章 关于VisionPro 1.1 康耐视的核心技术 1. 先进的视觉系统 康耐视的视觉系统结合了高性能的图像传感器、复杂的算法和强大的计算能力,能够实时捕捉、分析和处理高分辨率图像。其视觉系统包括固定式和手持式两种,适用于各种工业环境。无论是精密电…...
整数规划问题算法例子
整数规划问题算法概述 整数规划(Integer Programming, IP)问题是优化问题的一种,其中决策变量必须取整数值。整数规划问题在许多实际应用中广泛存在,如资源分配、排班、路径优化等。 0-1背包问题旅行商问题利用线性规划库求解整数规划问题的方法 以下是两个常见的整数规划…...
C#启动一个cmd.exe多次随时输入命令并获取输出
想要实现的效果,程序通过Process类一次启动cmd,后台线程每隔一定时间,向其输入命令,获得并处理输出。 一、基本操作 首先,通常操作的例子一抓一大把: 1、通过Process启动cmd执行一条/多条(&am…...
持续总结中!2024年面试必问 20 道分布式、微服务面试题(五)
上一篇地址:持续总结中!2024年面试必问 20 道分布式、微服务面试题(四)-CSDN博客 九、请解释API网关在微服务架构中的作用。 API网关是微服务架构中的一个重要组件,它充当所有客户端请求的单一入口点,然后…...
Android输入法IME(三)之 管理端(IMMS)启动流程
2.2. IME管理端(IMMS)初始化流程 IMMS运行在system server进程中,属于系统服务的一部分,用于控制输入法的显示/隐藏、切换、绑定等操作。 涉及代码文件路径: IMMS运行在system server进程中,属于系统服务的…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
