代码审计(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>
        <?php
        if (!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>
                <?php
                if ($_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行的漏洞点:

 <?php
                if ($_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的代码里有一句:

<?php
        if (!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,我真是服了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/687261.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SD卡格式化怎么恢复?一键扫描,轻松找回丢失的数据

SD卡格式化怎么恢复数据&#xff1f;在日常生活中&#xff0c;我们常常会使用SD卡来存储各种数据&#xff0c;如照片、视频、文档等。然而&#xff0c;当SD卡意外格式化或者出现其他问题时&#xff0c;里面的数据就会面临丢失的风险。 此时&#xff0c;如何恢复格式化的SD卡就…

聚焦Cayman 环二核苷酸(CDNs)

环二核苷酸CDNs 环二核苷酸&#xff08;cyclic dinucleotides&#xff0c;CDNs&#xff09;是一类天然的环状RNA分子&#xff0c;细菌衍生的CDNs分子包括c-di-GMP、c-di-AMP和3,3-cGAMP&#xff0c;它们介导对恶性、病毒性和细菌性疾病的先天免疫的保护作用&#xff0c;并在自…

遇见桂林山水画廊,深层互联自动讲解耳机走进漓江

遇见山水&#xff0c;听懂山水。由深层互联独家打造&#xff0c;桂林漓江山水画廊导览工程&#xff0c;于不久前正式启动&#xff0c;声情并茂的真人语音引导着游客&#xff0c;走进有声有色的山水画卷中。 桂林山水甲天下&#xff0c;得天独厚的自然景观&#xff0c;奇幻瑰丽…

html5实现端午节网站源码

文章目录 1.设计来源1.1 端午首页页面1.2 端午由来页面1.3 端午图集页面1.4 端午活动页面1.5 给我留言页面 2.效果和源码2.1 动态效果2.2 目录结构 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/139524377 ht…

【Python入门与进阶】Anaconda环境配置

1.Conda换源 1.1.打开Anaconda Powershell Prompt 1.2.在界面中输入以下命名&#xff08;加入清华源并设置搜索优先级&#xff09;&#xff1a; conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.…

计算机毕业设计python+hadoop+spark猫眼电影票房预测 电影推荐系统 猫眼电影爬虫 电影数据可视化 电影用户画像系统 协同过滤算法 数据仓库

山东青年政治学院毕业论文&#xff08;设计&#xff09;开题报告 学生姓名 高宜凡 学 号 202010520237 所在学院 信息工程学院 专 业 信息管理与信息系统&#xff08;云计算与大数据技术&#xff09; 指导教师姓名 李海斌 黄虹 指导教师职称 工程师 副教授 指导教…

二十年编程人生,倾囊相授:自学Python所有方向好书精选,助你全方位攻略!

一、论看书的重要性 现在不像十几年前那样&#xff0c;现在的学习资源很多&#xff0c;出了校园工作了之后&#xff0c;很多人都不怎么喜欢看书&#xff0c;通过看书来学习的人越来越少了&#xff0c;但我一直保持着这个习惯&#xff0c;现在也是&#xff0c;每天早上都会起来…

Win11 ubuntu子系统安装WslRegisterDistribution failed with error: 0x800701bc

执行完这两部&#xff0c;然后再打开ubuntu即可。链接

【成品设计】基于红外线的目标跟踪无线测温系统设计

《基于红外线的目标跟踪无线测温系统设计》 整体功能&#xff1a; A端&#xff1a;无线跟踪端 主控&#xff1a;采用STM32F103C8T6单片机作为核心控制。360度编码模块数字脉冲输出红外解码编码模块OLED屏幕。 B端&#xff1a;无线待测端 主控&#xff1a;采用STM32F103C8T…

数字人的技术实现方案比较

数字人的实现方案通常包括以下几个关键技术领域&#xff0c;数字人的实现是一个跨学科的领域&#xff0c;涉及到计算机图形学、人工智能、机器学习、自然语言处理等多个技术领域&#xff0c;随着技术的不断进步&#xff0c;数字人的能力和应用范围将不断扩大。北京木奇移动技术…

亚马逊新品如何快速吸引流量?自养号测评助卖家一臂之力

在亚马逊平台上每天都会有大量的新品推出&#xff0c;而这些新品中有部分可能并没有什么流量和订单&#xff0c;有些可能上架后立马就能获得流量了&#xff0c;那么亚马逊上新品一般几天出单&#xff1f; 一、亚马逊上新品一般几天出单&#xff1f; 亚马逊上新品出单的时间因…

轻松实现Excel工作表按行拆分,提升办公效率新神器!

在快节奏的现代办公环境中&#xff0c;数据处理和文档编辑成为了我们日常工作中不可或缺的一部分。而Excel工作表作为数据存储和处理的利器&#xff0c;其重要性不言而喻。然而&#xff0c;当面对庞大且复杂的工作表时&#xff0c;如何高效地进行数据拆分和处理&#xff0c;成为…

day52 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 关键在于至多买卖两次&#xff0c;这意味着可以买卖一次&#xff0c;可以买卖两次&#xff0c;也可以不买卖。 动态规划五部曲 1.确定dp数组以及下标的含义 一天一共就有五个状态&#xff0c; 没有操作 &#xff08;其实我们也可以不设置这个状态&a…

QA | 关于智能座舱SusPIS-ATx系统常见问题答疑

前沿 在上一期《基于SusPIS-ATx的座舱仿真系统搭建与评估方法创意研讨会》中&#xff0c;我们围绕汽车智能座舱仿真测试相关评价规范和法规&#xff08;如C-ICAP&#xff09;&#xff0c;引入了智能座舱测试行业难点及次生问题&#xff0c;介绍了基于SusPIS-ATx的智能座舱全域…

Ollama 的 Web Desktop

Ollama 的 Web & Desktop Web & Desktop Ollama的Web & Desktop非常多&#xff0c;比较流行的是 Open WebUl; Open WebUl Github: https://github.com/open-webui/open-webui Open WebUl 官网:https://www.openwebui.com/ Open WebUl是一个可扩展、功能丰富、用户…

这几项合规没做好,50家APP被通报处罚,顶格处罚累计900w(文附APP合规方案)

APP合规 吉祥学安全知识星球&#x1f517;除了包含技术干货&#xff1a;Java代码审计、web安全、应急响应等&#xff0c;还包含了安全中常见的售前护网案例、售前方案、ppt等&#xff0c;同时也有面向学生的网络安全面试、护网面试等。 近期国家公布了2024年第3批APP不合规的企…

HackTheBox-Machines--Aragog

Aragog 测试过程 1 信息收集 NMAP 服务器开启了 21、22、80端口 21 端口测试 首先测试 21 端口&#xff0c;21端口开启了匿名登录 ftp服务器上存在 test.txt 文件&#xff0c;test.txt 文件是 xml 格式。 80 端口测试 echo "10.129.97.250 aragog.htb" | sudo tee…

<microros> 如何自定义uROS2数据类型

如何自定义数据类型 在microros中&#xff0c;我们可以看到&#xff0c;官方给我们提供了很多数据类型。 如果我们在实际使用的时候&#xff0c;这些类型无法满足我们的传输要求怎么办呢&#xff1f; 官方也提供了自定义数据类型的办法。 参考&#xff1a; https://github…

Allegro添加区域规则

阿里狗添加区域规则 前言 当芯片的引脚间距很小&#xff0c;比设置的规则线距小时&#xff0c;拉线就会报错&#xff0c;此时需要添加区域规则去避免这种报错 一、报错详情 规则设置的最小线距是6mil&#xff0c;但是芯片引脚间距是4.5mil&#xff0c;此时线拉出来的间距也…

GD32如何配置中断优先级分组以及中断优先级

使用GD32 MCU的过程中&#xff0c;大家可能会有以下疑问&#xff1a;中断优先级如何配置和使用&#xff1f; 本文将会为大家解析中断优先级分组以及中断优先级的配置使用&#xff1a; 中断优先级分组配置 一个GD32 MCU系统需要大家明确系统中使用的中断优先级分组&#xff0…