今晚有空 之后随缘写博客了 好好沉淀php
web1当天作出的队伍不多 其实不难 折腾到最后就差一步 惋惜 css
截图没留了 只留了代码部分。html
有个页面 有上传和下载功能前端
起初觉得是上传漏洞 发现上传后都会在后面加.jpgjquery
且phpsessionid为文件名和目录web
上传绕了好久 再看的时候是看下载功能 发现有文件读取。session
能够进行目录穿越读取 经过文件中的包含信息顺腾摸瓜把文件类读取出来:app
func.php:函数
而后根据这里auto_class读取其余类文件。post
逻辑顺序来读一遍。分析利用的点
先是定义类的index:
<?php defined('DS') or define('DS', DIRECTORY_SEPARATOR); define('APP_DIR', realpath('./')); define('Cache_DIR',APP_DIR.DS.'user'); define('View_DIR',APP_DIR.DS.'app'.DS.'view'); define('Core_DIR',APP_DIR.DS.'core'); define('Image_DIR',APP_DIR.DS.'upload'); include(Core_DIR.DS.'core.php');
而后是核心core文件:
<?php if(!defined('Core_DIR')){ exit(); } include(Core_DIR.DS.'config.php'); include(Core_DIR.DS.'func.php'); _if_debug($config['debug']); spl_autoload_register('autoload_class'); config($config['ini']); // 'session.name' => 'PHPSESSID', // 'session.serialize_handler' => 'php' session_start(); define('Upload_DIR',Image_DIR.DS.session_id()); init(); $app = new IndexController(); if(method_exists($app, $app->data['method'])){ $app->{$app->data['method']}($app->data['param']); }else{ $app->index(); } #$this->method($_POST)
先是包含了两个文件func和inc
而后spl_autoload_register('autoload_class');加载类文件 接着开启session 定义上传文件的路径 下面就是new 了一个 IndexController();对象
看看这个对象的IndexController类文件:
(比赛的时候本身作了点注释)
不难看出 在post方法中会实体一个FILEs类 这是题目本身定义的文件类 接着进行Cache类的实体化
FILE类:
Cache类:
File类对上传的文件进行控制处理,目录写死了的 $data虽然在IndexController类可控 意义不大 重点看Cache类:
<?php class Cache{ public $data; public $sj; public $path; public $html; function __construct($data){ $this->data['name']=isset($data['post']['name'])?$data['post']['name']:''; $this->data['message']=isset($data['post']['message'])?$data['post']['message']:''; $this->data['image']=!empty($data['image'])?$data['image']:'/static/images/pic04.jpg'; $this->path=Cache_DIR.DS.session_id().'.php'; } function __destruct(){ $this->html=sprintf('<!DOCTYPE HTML><html><head><title>LOL</title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /><link rel="stylesheet" href="/static/css/main.css" /><noscript><link rel="stylesheet" href="/static/css/noscript.css" /></noscript> </head> <body class="is-preload"><div id="wrapper"><header id="header"> <div class="logo"><span class="icon fa-diamond"></span> </div> <div class="content"><div class="inner"> <h1>Hero of you</h1></div> </div> <nav><ul> <li><a href="#you">YOU</a></li></ul> </nav></header><div id="main"><article id="you"> <h2 class="major" ng-app>%s</h2> <span class="image main"><img src="%s" alt="" /></span> <p>%s</p><button type="button" onclick=location.href="/download/%s">下载</button></article></div><footer id="footer"></footer></div><script src="/static/js/jquery.min.js"></script><script src="/static/js/browser.min.js"></script><script src="/static/js/breakpoints.min.js"></script><script src="/static/js/util.js"></script><script src="/static/js/main.js"></script><script src="/static/js/angular.js"></script> </body></html>', substr($this->data['name'],0,62),$this->data['image'],$this->data['message'],session_id().'.jpg'); if(file_put_contents($this->path,$this->html)){ include($this->path); } } }
发现此类的析构函数中对前端输出同时 用一些变量写入了文件 而且在后面进行写文件和包含
这里就考察了php反序列化的内容 一个经典的引擎解析不一样致使反序列化 + session.upload_progress进行文件包含
upload_progress这个之前没遇到过~ 卑微
关于解析引擎不一样的反序列化这里只简单提一下 看不懂本身网上去学
反序列化参数:
session.save_handler session保存形式。默认为files session.save_path session保存路径。 session.serialize_handler session序列化存储所用处理器。默认为php。 session.upload_progress.cleanup 一旦读取了全部POST数据,当即清除进度信息。默认开启 session.upload_progress.enabled 将上传文件的进度信息存在session中。默认开启。
当 session.serialize_handler=php 时,session文件内容为: name|s:7:"mochazz";
当 session.serialize_handler=php_serialize 时,session文件为: a:1:{s:4:"name";s:7:"mochazz";}
因此解析引擎不一样致使反序列化 原本是字符串的 | 被当成php中的分隔符
关于session.upload_progress.enabled
当 session.upload_progress.enabled INI 选项开启时,PHP 可以在每个文件上传时监测上传进度。 若是session.upload_progress.cleanup = off的话 会话信息会写到文件中。
这里对文件名直接反序列化并文件名被写在包含文件中
直接构造上传表单便可:
<form action="index.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="1111" /> <input type="file" name="file" /> <input type="submit"/> </form>
filename为咱们的反序列cache类的 paylaod 内容进行一句话的替换