php代码审计案例之easy_serialize_php

admin 2022年4月15日08:40:11评论157 views字数 2539阅读8分27秒阅读模式

所谓代码审计是一种以发现程序错误,安全漏洞和违反程序规范为目标的源代码分析。在安全领域,为了发现安全问题,常通过黑盒测试、白盒测试方法来尽可能的发现业务程序中的安全问题,代码审计就是白盒测试的常用方法,相较于黑盒测试,由于白盒测试能接触到源代码,可以更加详细的理解业务程序逻辑,也能更全面的发现安全风险。接下来本系列文章将以php代码审计为切入点,过程中结合常见源代码扫描工具和动态调试方法,来讲解php代码审计的常见漏洞点和分析方法。本章节以安洵杯Web题目easy_serialize_php为审计对象,相关源代码网上也都有公开。

代码审计过程
源代码扫描效果查看

php代码审计案例之easy_serialize_php

php代码审计案例之easy_serialize_php
php代码审计案例之easy_serialize_php
php代码审计案例之easy_serialize_php

可以看到seay发现了任意文件读取和变量覆盖问题,rips发现了变量覆盖问题,而fortify基本上是一些信息泄漏、配置问题及变量覆盖问题,并把变量覆盖问题划分为中危等级。

接下来看下源代码

php代码审计案例之easy_serialize_php

大致的逻辑是根据请求的function值,如果function是show_image,则会读取该文件内容,并打印出内容。CTF的题目最终是要获取flag的内容,所以猜测这里的问题应该是出在读取的问题上。

现在来看一下靶机的网页

php代码审计案例之easy_serialize_php

点进去就能看到源码

php代码审计案例之easy_serialize_php

默认f的参数就是highlight_file,对应源码里的代码逻辑就是

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

这里输入phpinfo查看是否有敏感信息

一般主要查看fopen、disable_、root类似字符,找到有文件名为d0g3_f1ag.php

php代码审计案例之easy_serialize_php

到这里2个判断逻辑都走过了,初步判断这里需要通过show_image逻辑,读取d0g3_f1ag.php文件。根据file_get_contents()函数的逻辑,从后往前看,主要逻辑如下。

$serialize_info = filter(serialize($_SESSION));$userinfo = unserialize($serialize_info);echo file_get_contents(base64_decode($userinfo['img']));

如果想要读取d0g3_f1ag.php文件,就需要保证base64_decode($userinfo['img'])= d0g3_f1ag.php。

然后继续跟踪,需要

$userinfo['img'] = ZDBnM19mMWFnLnBocA==,即d0g3_f1ag.php的64位编码。

而$userinfo是反序列化得到,因此这里必定要存在

{s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="}


所以就要重点关注$serialize_info的生成过程。

filter(serialize($_SESSION));

filter是一个过滤函数,用于将php/flag/php5/php4/fl1g这几个字符,替换成空。而serialize($_SESSION)是将该变量进行序列化成字符串。然后再看$_SESSION的生成过程,我们发现存在extract()函数,这个函数可以将数组转化成变量,因此理论上来讲我们可以控制$_SESSION变量。

 

如果没有经过filter函数过滤,那么payload就需要是

{s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==" }

 

因此这里我们可以构建恶意的输入

$_SESSION[aflagflagc]= "";s:1:"2";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}"

该数据通过序列化后得到

s:10:"aflagflagc";s:49:"";s:1:"2";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}"

而在经过filter函数处理后,flagflag都被被置空,得到序列化后的数据为

s:10:"ac";s:49:"";s:1:"2";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}"

这里我们来看一下反序列的过程

首先是s:10,表示这个变量有10位。

s:10:"ac";s:49:"";s:1:"2";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}"

如上标红的地方就成为新的key,标红地方的最后一个双引号是我们输入的,其后跟的分号表示变量的分隔符,如果将这些反序列后,其结果就是

$_SESSION[ac";s:49:"]=2

$_SESSION

= ZDBnM19mMWFnLnBocA==

由于最右边的花括号已经把序列化数据都分隔了,后面的数据就不会再引入。

我们请求看一下,成功读取d0g3_f1ag.ph文件

php代码审计案例之easy_serialize_php

如果想要读取/d0g3_fllllllag文件,只需要编码后替换并修改s:20的长度为替换后长度即可。这里因为编码后为L2QwZzNfZmxsbGxsbGFn,长度仍为20,无须修改

php代码审计案例之easy_serialize_php

最终获取flag{9194ad31-3fba-4d13-b93d-6788c3ba8c0e}

网上还有一种payload是

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

原理是一样的,phpflag去空后,多了7位,因此它这里通过;使前面强制闭合,而用flagflag就有8位,通过多一个引号,形成偶数对双引号。

总结

这道题的关键函数有extract;file_get_contents;serialize三个,利用到变量覆盖、反序列化漏洞、文件读取三个点,从代码审计工具的效果来看,seay发现了2个点,这跟它是利用函数名为关键词进行正则匹配有关,在做CTF题可以快速挖掘关键点,但要是审计含有大量代码的系统,最终呈现的就是一堆没有关联的可能存在恶意攻击点的函数。而Rips发现了1个点和fortify相同,但fortify提供了其他一堆漏洞,存在有误报率问题。

php代码审计案例之easy_serialize_php


php代码审计案例之easy_serialize_php

原文始发于微信公众号(第59号):php代码审计案例之easy_serialize_php

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月15日08:40:11
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   php代码审计案例之easy_serialize_phphttp://cn-sec.com/archives/913294.html

发表评论

匿名网友 填写信息