原理
如果session可控,我们可以写入我们想要执行的命令,主要在测试里面讲解
储存位置
在phpinfo中。我们可以在session.save_path里面看见文件位置

以下是一些常见的位置:
默认路径/var/lib/php/sess_PHPSESSID/var/lib/php/sessions/sess_PHPSESSID/tmp/sess_PHPSESSID/tmp/sessions/sess_PHPSESSID
命名格式
session 的文件名格式为 sess_[phpsessid]。而phpsessid 在发送请求的cookie字段中可以看到。
会话处理
在了解用户会话的存储下来就需要了解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 session_start(); $username = $_POST['username']; $_SESSION["username"] = $username; ?> |

从图中可以看出默认 session.serialize_header = php 模式只对用户名的内容进行了序列化存储,没有对变量名进行序列化,可以看对服务器对用户会话信息的版序列化存储过程。
session.serialize_header = php-serialize
php 5.5 之后启用这种模式,它使用serialize 反序列化格式进行存储用户的会话信息。一样的通过一个简单的用户会话过程了解 session.serialize_header = php-serialize 是如何工作的。这种模式可以在 php.ini 或者代码中设置。
session.php
1 | <?php ini_set('session.serialize_handler', 'php_serialize'); session_start(); $username = $_POST['username']; $_SESSION["username"] = $username;?> |

从图中可以看出 session.serialize_handler=php_serialize 处理模式,对整个session 信息包括文件名、文件内容都进行了序列化处理,可以看作是服务器对用户会话信息得完全序列化存储过程。
对比上面得 session.serialize_handler=php_serialize 的两种处理方式,可以看到他们在 session 上处理的差异,既然有差异我们就要合理的去利用这两种模式,假如编写代码不规范的时候处理 session 同时使用了两种模式,那么在攻击者可以利用的情况下,很可能会造成 session 反序列化漏洞。
测试
这里用到了如下的测试代码:

这里的session是可控的,那么这里我们就可以进行session文件包含:
传入我们的命令

拿sessionid:

因为我是第一次测试就直接拿命令去找的:find / -name “sess_39o4hf99oo2t2rjcr8800a90i2” 2>/dev/null
找到之后我们利用文件包含:
http://127.0.0.1/session_using/include.php?file=/private/var/tmp/sess_39o4hf99oo2t2rjcr8800a90i2

