网页布局设计技术廊坊优化网站排名
知识点:session 反序列化,代码审计
代码分析
flag.php 中有个 is_admin 函数的判断。

在 lib.php 中有 is_admin 函数,需要 session['admin'] 为 true,或者通过文件读取的方式。

在 index.php 中的 include 并不能使用伪协议读取 flag.php,那么要怎么使得 session['admin'] 为 true 呢?是不是可以通过 session 反序列化来绕过,我们可以全局搜一下有没有 session_start。

存在 sesson_start 那么也许真的存在 session 反序列化。

在 init.php 中我们可以看到 session 保存的目录,在 /var/www/tmp 下,那这个目录有什么特殊的呢?


session 保存的目录竟然和 node 的保存目录一样,那么怎么控制保存的文件名,怎么使得我们上传的内容 session 反序列化后能通过 is_admin 呢?

我们先看一下它的上传代码,在 add.php 中利用 add_note 函数来处理上传的信息。

而 add_note 函数功能就是把接收的 title 和 body 以及 hash 的 id,存入 $_SESSION['notes'] 列表里。

然后当我们访问 export.php 的时候,选择 tar 它就把 $_SESSION[‘notes’] 里的信息转换为 json 数据写入 TEMP_DIR / get_user() . '-' . bin2hex(random_bytes(8)) . '.' . 'tar'; 文档里最后输出出来。


我们上传个测试一下,这边用户名是 test,内容如下。

可以看到确实如讲的一样,那么我们是不是令用户名为 sess_ 也就是 session 文件保存的格式,这样就变成了 sess_-xxxxxx.tar,这个 tar 怎么处理?

我们只需要令 type 为 .,这样就会因为 str_replace 把 .. 替换为空,自然就消除了,文件名的问题解决了,那内容呢?内容就很简单了,因为 php 默认的 session 反序列化模式是 php 也就是以 | 符号为分界线,前面的是键名后面的是键值.
构造如下 title ,把前面多余的值设为空,设置 admin 为 bool(true)
|N;admin|b:1;

操作步骤
以 sess_ 为用户名登录。

写入反序列化值

把反序列化值,写入 session 格式的文件里。

获取我们伪造的 session 文件名。

修改 PHPSESSID 访问 flag,成功。


