0x00 前言
设计缺陷和逻辑相关的漏洞是目前漏洞挖掘者比较关注的。
最近在国外漏洞披露平台hackerone
上就有位白帽子挖掘到了Uber
的一个修改任意账户密码的逻辑漏洞获得了$10000
的丰厚奖励。
所以如何在源码中找逻辑漏洞是安全和开发人员必须熟悉的技能,主要总结了安装问题、找回密码这两篇内容,本篇讲的是代码审计中的安装问题。
0x01 设计缺陷&&逻辑漏洞挖掘的脑图:
0x02 无任何验证 :
程序安装完成后不会自动删除安装文件,也不会生成lock
来判断是否安装过导致的重装漏洞,之前出现过的漏洞代码如下:
install/index.php
:
<?php
error_reporting(E_ALL ^ E_NOTICE);
date_default_timezone_set('PRC');
header('Content-Type: text/html; charset=utf-8');
//改写不安全的register_global和防sql注入处理
if (@ini_get('register_globals')) {
foreach($_REQUEST as $name => $value){unset($$name);}
}
$pe['host_root'] = 'http://'.str_ireplace(rtrim(str_replace('\\','/',$_SERVER['DOCUMENT_ROOT']), '/'), $_SERVER['HTTP_HOST'], str_replace('\\', '/', dirname(__FILE__))).'/../';
$pe['path_root'] = str_replace('\\','/',dirname(__FILE__)).'/../';
include("{$pe['path_root']}/include/class/cache.class.php");
include("{$pe['path_root']}/include/function/global.func.php");
if (get_magic_quotes_gpc()) {
!empty($_GET) && extract(pe_trim(pe_stripslashes($_GET)), EXTR_PREFIX_ALL, '_g');
!empty($_POST) && extract(pe_trim(pe_stripslashes($_POST)), EXTR_PREFIX_ALL, '_p');
}
else {
!empty($_GET) && extract(pe_trim($_GET),EXTR_PREFIX_ALL,'_g');
!empty($_POST) && extract(pe_trim($_POST),EXTR_PREFIX_ALL,'_p');
}
switch ($_g_step) {
//#####################@ 配置信息 @#####################//
case 'setting':
if (isset($_p_pesubmit)) {
install
的引导文件里没有判断lock
导致可以直接重装
0x03 代码的逻辑问题 :
1.Step1判断lock文件可直接Step2绕过
install/index.php
的缺陷代码和分析如下:
if (empty ($step))
{
$step = 1;//当用户没有提交step的时候 赋值为1
}
require_once ("includes/inc_install.php");
$gototime = 2000;
/*------------------------
显示协议文件
------------------------*/
if ($step == 1) //当1才检测lock
{
if (file_exists('installed.txt'))
{
echo '<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
你已经安装过该系统,如果想重新安装,请先删除install目录下的 installed.txt 文件,然后再安装。
</body>
</html>';
exit;
}
include_once ("./templates/s1.html");
exit ();
}
/*------------------------
测试环境要求
------------------------*/
else
if ($step == 2) // 我们直接提交step为2 就不check lock了
{
$phpv = @ phpversion();
$sp_os = $_ENV["OS"];
$sp_gd = @ gdversion();
$sp_server = $_SERVER["SERVER_SOFTWARE"];
$sp_host = (empty ($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_HOST"] : $_SERVER["SERVER_ADDR"]);
$sp_name = $_SERVER["SERVER_NAME"];
$sp_max_execution_time = ini_get('max_execution_time');
$sp_allow_reference = (ini_get('allow_call_time_pass_reference') ? '<font color=green>[√]On</font>' : '<font color=red>[×]Off</font>');
2.判断lock文件的代码有问题
还有一种是在判断lock
文件是否存在的代码上有问题了,我们看下缺陷代码:
<?php
$lockfile=ROOT.'/install.lock';
$pattern_db= '/[0-9a-zA-Z]*$/';
if (!preg_match($pattern_db,$db_name)||!preg_match($pattern_db,$db_user)) {
echo '1001';exit;
}
if(file_exists($lockfile) && ($_a=='template' || $_a=='setting' || $_a=='check')){
exit('please delete install.lock');
}
?>
可以看到这里判断了Lock
是否存在,但是
if(file_exists($lockfile) && ($_a=='template' || $_a=='setting' || $_a=='check')
这里除了判断lock
还判断了$_a
,并且使用&&
导致$_a
为空时就绕过了lock
的验证最终导致可继续重装。
0x04 变量覆盖:
在install/index.php
中
header("Content-Type: text/html; charset={$lang}");
foreach(Array('_GET','_POST','_COOKIE') as $_request){
foreach($$_request as $_k => $_v) ${$_k} = _runmagicquotes($_v);
}
function _runmagicquotes(&$svar){
if(!get_magic_quotes_gpc()){
if( is_array($svar) ){
foreach($svar as $_k => $_v) $svar[$_k] = _runmagicquotes($_v);
}else{
$svar = addslashes($svar);
}
}
return $svar;
}
if(file_exists($insLockfile)){
exit(" 程序已运行安装,如果你确定要重新安装,请先从FTP中删除 install/install_lock.txt!");
}
file_exists($insLockfile)
这里判断lock
文件是否存在并退出,但是这行代码
foreach($$_request as $_k => $_v) ${$_k} = _runmagicquotes($_v);
存在变量覆盖,所以可以直接将$insLockfile
变量覆盖为1
就使得file_exists($insLockfile)
的返回为0
,从而可以继续重装。
0x05 判断lock后无exit:
缺陷代码如下:
<?php
class Install extends Install_Controller
{
function __construct ()
{
parent::__construct();
$this->load->library('myclass');
$file=FCPATH.'install.lock';
if (file_exists($file)){
$this->myclass->notice('alert("系统已安装过");window.location.href="'.site_url().'";');
}
}
?>
检查是否存在install.lock
,然后用javascript
的方式告诉用户”系统已安装过”,然后跳转。问题在于这个脚本根本还没有使用exit
函数来结束,程序会继续运行,导致可继续重装。
赏
使用支付宝打赏
使用微信打赏
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章