前两篇关于禅道826分享了两篇 getshell 的方法,这篇只算是一个小技巧,这个技巧只在 Windows 系统下有效。
在Windows系统下,PHP中大部分文件操作都是调用 WinAPI 中的函数 FindFirstFile() ,这个函数有 如下几个特性 。
1、文件名中的字符 > 相当于 ? (一个占位符)
2、文件名中的字符 < 相当于 * (N个占位符)
3、文件名中的字符 " 相当于 . (就是正常字符点)
一、文件删除
// D:\wamp\www\zentao826\module\editor\control.php public function delete($filePath = '', $confirm = 'no') { if($confirm == 'no') { die(js::confirm($this->lang->editor->deleteConfirm, inlink('delete', "filePath=$filePath&confirm=yes"))); } $filePath = helper::safe64Decode($filePath); if(file_exists($filePath) and unlink($filePath)) die(js::reload('parent')); die(js::alert($this->lang->editor->notDelete)); } |
没有什么难度,传递进来的文件路径先进行 base64 编码一次即可。
二、利用 Windows 的特性进行文件名爆破
// D:\wamp\www\zentao826\module\editor\control.php public function edit($filePath = '', $action = '', $isExtends = '') { $this->view->safeFilePath = $filePath; $fileContent = ''; if($filePath) { $filePath = helper::safe64Decode($filePath); if($action == 'extendOther' and file_exists($filePath)) { $this->view->showContent = htmlspecialchars(file_get_contents($filePath)); } if($action == 'edit' or $action == 'override') { if(file_exists($filePath)) { $fileContent = file_get_contents($filePath); if($action == 'override') { $fileContent = str_replace('../../', '../../../', $fileContent); $fileContent = str_replace(array('\'./', '"./'), array('\'../../view/', '"../../view'), $fileContent); } } else { $filePath = ''; } } elseif($action == 'extendModel') { $fileContent = $this->editor->extendModel($filePath); } elseif($action == 'extendControl') { $okUrl = $this->editor->getExtendLink($filePath, 'extendControl', 'yes'); $cancelUrl = $this->editor->getExtendLink($filePath, 'extendControl', 'no'); if(!$isExtends) die(js::confirm($this->lang->editor->extendConfirm, $okUrl, $cancelUrl)); $fileContent = $this->editor->extendControl($filePath, $isExtends); } elseif($action == 'newPage') { $fileContent = $this->editor->newControl($filePath); } elseif(strrpos(basename($filePath), '.php') !== false and empty($fileContent)) { $fileContent = "<?php\n"; } } $this->view->fileContent = $fileContent; $this->view->filePath = $filePath; $this->view->action = $action; $this->display(); } |
上面核心的东西其实就是获取文件路径,然后 file_get_contents() 获取文件内容,最后输出。
文件上传之后文件名到底有没有规律呢,下面是生成文件名的函数:
// D:\wamp\www\zentao826\module\file\model.php public function setPathName($fileID, $extension) { $sessionID = session_id(); $randString = substr($sessionID, mt_rand(0, strlen($sessionID) - 5), 3); return date('Ym/dHis', $this->now) . $fileID . mt_rand(0, 10000) . $randString . '.' . $extension; } |
文件名前一部分是基本上可以确定的,即使不确定到秒,但是分钟也是可以的