您的位置  > 互联网

关于php代码审计中相关的问题,你了解多少?

最近,我遇到了几个与PHP代码审计相关的问题。 之前没有做过系统的总结,这里补一下。

0x01 基础知识

这里主要讲传统PHP中的“服务器”。至于什么是服务器,什么是客户端,可以看看P神**客户端带来的安全问题

概念:在计算机中,特别是在网络应用中,称为“会话控制”。 该对象存储特定用户会话所需的属性和配置信息。 这样,当用户在应用程序中的网页之间跳转时,存储在对象中的变量不会丢失,而是会在整个用户会话期间持续存在。 当用户从应用程序请求网页时,如果用户还没有会话,则 Web 服务器会自动创建一个对象。 当会话过期或被放弃时,服务器将终止该会话。

机制:内容一般以文件的形式存储在服务器中,本地浏览器会在服务器中存储一个与该文件对应的值。 存储的是键值为“”的值。 当用户访问Web应用程序时,每次跳转发生http请求时,都会自动发送存储的值,因此Web应用程序的所有页面都可以获得该值。 也就是说,可以获取到服务器中存储的值。 当用户关闭浏览器时,存储的值将自动清除。 ,一般情况下服务器上存储的文件会在30分钟后自动清除。

例如在wamp环境下,index.php如下:

<?php	session_start();	phpinfo();?>

首先了解一下()

当会话自动启动或者通过()手动启动时,PHP内部会根据客户端的输入获取已有的相应会话数据(即文件)。 PHP会自动反序列化文件内容,并将其填充到$super全局变量中。 如果对应的会话数据不存在,则创建一个名为SID的文件(由客户端传递)。 如果客户端没有发送,则创建一个 32 个字母的并返回 set-。

可以在请求中看到对应的:

在服务器端,在/wamp/tmp下,我们可以找到生成的记录文件。 由于没有记录会话信息,因此该文件是一个空文件。

添加一些php相关配置的说明

php.ini中有很多配置。 在这里我们将解释几个重要的点。

描述如下:

session.save_path=""  --设置session的存储路径session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式),默认files以文件存储session.auto_start  boolen --指定会话模块是否在请求开始时启动一个会话,默认为0不启动session.serialize_handler  string --定义用来序列化/

常见的 php 存储位置

/var/lib/php5/

/var/lib/php7/

/var/lib/php/

/tmp/

/tmp//

0x02 可能的攻击面 0x03 序列化攻击

要了解序列化攻击,我们首先了解序列化在机制中是如何处理的。

php中有3个序列化处理引擎

.对应的存储格式

php

键名+竖线+()函数序列化的值

键名+键名+()函数序列化的值的长度对应的ASCII字符

(php >= 5.5.4)

通过 () 函数序列化数组

本地测试如下:

文件内容对应的结果为:

test|s:7:"CoCo1er";<0x04>tests:7:"CoCo1er";a:1:{s:4:"test";s:7:"CoCo1er";}

攻击与利用原理

其中数以千计,原则第一。

(这里补充一下,在PHP中实现是没有问题的,危害主要是程序员使用不当造成的,如下)

使用不同的引擎处理文件

如果 PHP 反序列化存储的 $ 数据所使用的引擎与序列化所使用的引擎不同,则数据将无法正确反序列化。 通过精心构造的数据包,可以绕过程序验证或执行某些系统方法。 例如:

在这种情况下:

如果我们在数据存储的时候使用引擎对数据进行序列化,我们就可以得到内容

$_SESSION[‘key’] = ‘Boby’;a:1:{s:3:”key”;s:4:”Boby”;}

这时候我们的分析使用了另外一个引擎:php

想想这个时候会发生什么? (在PHP引擎中,竖线用于分隔键和值)

如果我们像上面那样改的话,传入的内容和获取到的存储内容如下:

$_SESSION['key'] = '|O:4:"User":0:{}';a:1:{s:3:"key";s:16:"|O:4:"User":0:{}";}

此时a:1:{s:3:"key";s:16:"被视为密钥。

后面的 O:4:"User":0:{}";} 被当做 value 来反序列化,这里可能有人会问,为什么要反序列化呢?

看一下官方文档

这里可能还会有人问? 该字符串值不符合反序列化字符串的“正常”规则。 不用担心这个。 这里提到的特点之一是以前做题的时候遇到过的。 执行过程中,如果字符串符合可反序列化的规则,则后续的不规则字符将被忽略。

如果不容易理解,为什么不直接看一下网上的测试用例:

综上所述,当PHP由引擎生成并被PHP引擎解析时,我们可能会通过传入$['name'] = | 这样的形式来触发反序列化漏洞。 序列化内容。 当然,这只是提到了反序列化可以被利用的点。 反序列化漏洞是否能够真正被触发,取决于当前的环境以及某些神奇功能是否存在可利用点。 这就涉及到利用PHP反序列化漏洞的知识了,这里不再赘述。 关于反序列化攻击的复杂利用,请参考 的问题。

没有 $ 赋值

从上面的情况我们可以发现我们的赋值是可控的。 那么如果代码中没有给$变量赋值怎么用呢? 我们再看下一点。

PHP还有一种机制,可以在$中自动创建键值对,而值中恰好有用户可控的部分。

写法主要是使用PHP来设置。 具体来说,上传文件时,如果 POST 一个名为 name 的变量,则可以为其赋值。

//上传表单

由于该字段可写,因此满足可控条件。 后续使用情况与上述场景一致。 两个不同的引擎先后起作用,导致恶意序列化字符串被解析。

0x04 文件包含

这也是一个比较老的知识点了。 事实上,这不仅仅是文件包含。 仔细想一想,理论上只要能在文件中写入php代码然后就可以实现了是吧? 只不过我们这里的可控点是文件。 如果我们可以将PHP代码写入其中,我们也可以利用文件包含漏洞。

此处未显示文件中包含的应用程序。 有关这方面的基本信息已经可以在线获取。

值得一提的是,现在的CTF题目往往并不局限于文件中包含的点,而是使用+lfi等形式输入题目来获取源代码。 并且可能会添加它来限制路径。 这时候就需要熟悉机制并使用更改保存路径的功能。 这个想法是 XCTF Final 中出现的一个问题的测试点。 有兴趣的同学可以找一个复现的环境。

0x05 假用户登录

前几天,3CTF正好为此发布了一个测试点。 这里我就借用这个话题来解释一下如何使用它。 (由于没有提供重现环境,所以这只能限于“纸上谈兵”,希望大家能明白利用原理。)

** 使用前提: ** 可控; 知道存储格式。

这里的测试问题是多个攻击面的组合。 在问题中,index.php 提示您以管理员身份登录。

0x06 逻辑漏洞

不幸的是,没有环境可以重现这一点。 (官方买断……)这是最近两周出现在unctf的一个网络问题。 这个逻辑缺陷出现在密码重置区域。 流程大致如下。

密码重置过程分为三个步骤。

这里的逻辑漏洞就在于首页的用户名。 猜测是后台有设定。 相似的:

$['名称'] = $_POST['名称'];

用途:重置管理员密码。

这里逻辑漏洞的原因是,填写验证码后,没有记录相关的用户绑定,在最后一步重置密码时,没有检查可靠性,直接执行了该功能。 而且我们都知道它是存储在服务器端的,所以我们可以通过打开另一个页面(保证在同一个文件夹下)来完成单个文件内容的修改。

0x07 摘要

这只是我学习PHP机制相关的一个记录。 提到的点都是我最近在CTF题中接触到的点,但是怎么可能只有这几个利用点呢? 当您遇到它时,让我们进一步了解。 由于篇幅限制,我们不讨论扩展利用,但说白了,扩展利用就是多个复杂知识点的综合。 我认为只有弄清楚原理问题才能理解复杂的组合攻击。 另外,文中如有理解或表述有误的地方,还望各位大师指正。

不要忘记贡献

大家都有不错的技术原创文章

欢迎将您的文章提交至:

和田将根据文章的时效性、新颖性、行文风格、实用性等方面,奖励200元至800元不等的稿费。

如果你有才华,请来贡献吧!

了解更多投稿详情请点击——