阅读:2977回复:0
论PHP常见的漏洞
◆0 前言
里面很多都是像laterain学习到的, 如果能考上cuit的话 自动献菊花了。 ◆1 安装的问题 首先拿到一份源码 肯定是先install上。 而在安装文件上又会经常出现问题。 一般的安装文件在安装完成后 基本上都不会自动删除这个安装的文件 我遇到过的会自动删除的好像也就qibocms了。 其他的基本都是通过生成一个lock文件 来判断程序是否安装过了 如果存在这个lock文件了 就会退出了。 这里首先 先来说一下安装文件经常出现的问题。 根本无验证。 这种的虽然不多 但是有时还是会遇到个。 在安装完成后 并不会自动删除文件 又不会生成lock来判断是否安装过了。 导致了可以直接重装过 例子: WooYun: PHPSHE B2C 重装。 安装file 因为install 一般都会有step 步骤啥的。。 Step 1 check 啥啥 step 2 是安装啥的。 而一些cms 默认step是1 而step又是GET 来的 而他check lock的时候就是在step1里面。 这时候如果我们直接用GET提交step 2 那么就直接进入下一步了 就没check lock了。 例如某cms中的安装文件 #!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 ' 你已经安装过该系统,如果想重新安装,请先删除install目录下的 installed.txt 文件,然后再安装。 '; 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') ? '[color=green][√]On[/color]' : '[color=red][×]Off[/color]'); $sp_allow_url_fopen = (in 变量覆盖导致重装 #!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!"); } foreach($$_request as $_k => $_v) ${$_k} = _runmagicquotes($_v); 这里是一个经常遇到的一个变量覆盖。 导致了我们可以覆盖掉$insLockfile 从而让file_exists 为false就不会退出了。导致再次重装。 这个变量覆盖不知道咋的 能在一些小cms的安装文件里看到。 之前看的xdcms 和 frcms 都存在这个变量覆盖。 例子: WooYun: frcms 重装系统 判断Lock后 无exit的。 这个从早期的phpdisk 的那个 header bypass 到现在的又遇到各种。 很久前的phpdisk的安装文件中。 判断是否存在lock文件 如果存在lock文件了 就会header到index.php 但是header 后 他并没有exit 所以并不会退出 导致了又是一个重装。 跟这种类似的还有javascript 弹个框 啥的 也没exit的。 例子: WooYun: 开源轻论坛StartBBS前台getshell 例子: WooYun: FengCMS 修复不当导致getshell 解析漏洞 这个也比较少, 就随便说句。 就是像dedecms很久以前的那样 在安装完成后会在install.php rename 为 Install.php.bak 但是由于apache的解析漏洞 如果无法识别最后的一个后缀的话 就会向上解析,那么就又成php了。 然后又结合dedecms安装时的变量覆盖 又成重装了。 满足一些条件不会退出的。 这种例子也不算太多, 自己好像也没遇到过太多。 首先以之前发过的sitestar举例下 #!php if(file_exists($lockfile) && ($_a=='template' || $_a=='setting' || $_a=='check')) { exit('please delete install.lock!'); } 这里我们来理解一下这个逻辑, 这里的file_exists($lockfile) 因为安装成功后 lockfile 肯定存在的 所以这里肯定会是true 然后再看一下 这里是一个 && true true 才会进入语句块。 那么如果$_a 不为 template 、 setting 、 check 的话 那么后面的就为false True and false => false就不会进入这个语句块 就不会exit 再配合后面的 #!php else if($_a=="create"){ $link = mysql_connect($db_host,$db_user,$db_pwd); 刚好有个其他的 如果$_a 为 create 那么就不会退出这个脚本 刚好这个create 能达到Getshell的效果 例子: WooYun: 建站之星Sitestar前台Getshell一枚 剩下的还有hdwiki之前也有一个基本差不多这样的例子 #!php if (file_exists(HDWIKI_ROOT.'/data/install.lock') && $step != '8') { echo "[color=red]{$lang['tipAlreadyInstall']}[/color]"; exit(); } 如果step为8的话 那么就不会执行exit了。 #!php case 8: require_once HDWIKI_ROOT.'/config.php'; require_once HDWIKI_ROOT.'/lib/hddb.class.php'; require_once HDWIKI_ROOT.'/lib/util.class.php'; require_once HDWIKI_ROOT.'/lib/string.class.php'; $db = new hddb(DB_HOST, DB_USER, DB_PW, DB_NAME, DB_CHARSET); //install $setting=$db->result_first('select `value` from '.DB_TABLEPRE.'setting WHERE `variable` = 'site_appkey''); if ($setting){ echo "[size=1]百科联盟开通成功.[/size]进入首页"; break; } //update info $data = $_GET['info']; $data = str_replace(' ', '+', $data); $info = base64_decode($data); if ($info){ $obj = unserialize($info); if(is_array($obj)){ $url2 = 'http://localhost/count2/in.php?action=update&sitedomain='.$_SERVER['SERVER_NAME'].'&info='.$data; $data = util::hfopen($url2); //if gbk then toutf8 if ($lang['commonCharset'] == 'GBK'){ $obj['sitenick'] = string::hiconv($obj['sitenick'], 'gbk', 'utf-8'); 刚好这里step 8 又能执行一些特殊的操作。。 现在就把case 8 注释掉了。 这里代码我就不复制过了 免得占篇幅。 这里差不多是我比较常遇到的一些安装文件经常遇到的问题了,突然想也想不到其他啥的了。 ◆2 包含漏洞 这里再来谈一下包含 其实包含也并没有什么好说的。 包含一般也就分为LFI RFI local file inclusion 和 remote嘛 对于LFI的话 因为很多都限制了包含的后缀结尾必须为.php Include ($a.'.php') 例如这种的 所以我们想包含我们的图片马儿的话 那么就需要截断后面的这.php 1: 00截断 需要gpc off && php |
|