0x00 前言
日常刷题
给了一个蝉知cms
hint:后台密码五位
没扫 凭经验试了几个 后台 /admin.php
admin 12345
0x01 brain.md
一开始想的就是基础文件上传getshell
一些上传logo的地方都被ban了
在设计模块中可以自定义网站头部的php源代码
通过在服务器创建文件判断管理员身份
在组件素材库处可以上传txt文件
拦一下包看看
POST /chanzhi/www/admin.php?m=file&f=editsource&fileID=1 HTTP/1.1
Host: 192.168.2.26
Content-Length: 290
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.2.26
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNMMMY8BhfGvBoBai
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.2.26/chanzhi/www/admin.php?m=file&f=browsesource
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: adminsid=pvbj0olrrghhe6tmmgq7r8vspl; adminLang=zh-cn; adminDevice=desktop; theme=default; currentGroup=design
Connection: close
------WebKitFormBoundaryNMMMY8BhfGvBoBai
Content-Disposition: form-data; name="filename"
wipqq
------WebKitFormBoundaryNMMMY8BhfGvBoBai
Content-Disposition: form-data; name="upFile"; filename=""
Content-Type: application/octet-stream
------WebKitFormBoundaryNMMMY8BhfGvBoBai--
源码跟进到函数
D:\phpStudy\PHPTutorial\WWW\chanzhi\system\module\file\control.php
public function editSource($fileID)
{
$this->file->setSavePath('source');
$file = $this->file->getById($fileID);
if(!empty($_POST))
{
if(!$this->file->checkSavePath()) $this->send(array('result' => 'fail', 'message' => $this->lang->file->errorUnwritable));
if($this->post->filename == false or $this->post->filename == '') $this->send(array('result' => 'fail', 'message' => $this->lang->file->nameEmpty));
$filename = $this->post->filename;
if(!validater::checkFileName($filename)) $this->send(array('result' => 'fail', 'message' => $this->lang->file->evilChar));
if(!$this->post->continue)
{
$extension = $this->file->getExtension($_FILES['upFile']['name']);
$sameUpFile = $this->file->checkSameFile(str_replace('.' . $extension, '', $_FILES['upFile']['name']), $fileID);
$sameFilename = $this->file->checkSameFile($this->post->filename, $fileID);
if(!empty($sameUpFile) or !empty($sameFilename))$this->send(array('result' => 'fail', 'message' => $this->lang->file->sameName));
}
$result = $this->file->editSource($file, $filename);
if($result) $this->send(array('result' => 'success','message' => $this->lang->saveSuccess, 'locate' => $this->createLink('file', 'browseSource')));
$this->send(array('result' => 'fail', 'message' => dao::getError() ));
}
$this->view->title = $this->lang->file->edit;
$this->view->modalWidth = 500;
$this->view->file = $file;
$this->display();
}
跟进checkfilename
D:\phpStudy\PHPTutorial\WWW\chanzhi\system\lib\base\filter\filter.class.php
没有过滤 /
public static function checkFileName($var)
{
return !preg_match('/>+|:+|<+/', $var);
}
跟进$this->file->editSource
D:\phpStudy\PHPTutorial\WWW\chanzhi\system\module\file\model.php
public function editSource($file, $fileName)
{
$files = $this->getUpload('upFile', $file->objectType);
$uploadPath = $this->app->getDataRoot();
if(!empty($files))
{
/* Use post fileName as file title. */
$_FILES['upFile']['name'] = $fileName . '.' . $file->extension;
$replaceResult = $this->replaceFile($file->id, 'upFile');
if(!$replaceResult) return false;
}
if($fileName != $file->title)
{
$file = $this->getByID($file->id);
if(!file_exists($file->realPath)) return false;
$newPath = dirname($file->realPath) . DS . $fileName . '.' . $file->extension;
$result = copy($file->realPath, $newPath);
if(!$result) return false;
@unlink($file->realPath);
$newPathname = str_replace($uploadPath, '', $newPath);
$this->dao->update(TABLE_FILE)->set('title')->eq($fileName)->set('pathName')->eq($newPathname)->where('id')->eq($file->id)->exec();
}
return !dao::isError();
}
最后的newPath只是做了简易的拼接
存在目录穿越
web端的存储路径只是相对路径 所以还是得把源码包down下来仔细看一下
/var/www/html/www/data/source/default/blank/
目标目录
/var/www/html/system/tmp/
0x02 rethink
水平不济 看源码时可能纰漏很多