[CISCN2019 华东南赛区]Web4

Posted keelongz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CISCN2019 华东南赛区]Web4相关的知识,希望对你有一定的参考价值。

伪随机数专场了……

题目一览

技术图片

简单的前端,点击后会跳转,没有啥信息。

技术图片

P1 任意文件读取

说一下自己的fuzz过程。

首先这个url参数是可控的,看传的是http协议的url,尝试传个file://看一下:

技术图片

被ban了,那么试一下伪协议,没执行:

技术图片

注意他的url构造:read?url=https://baidu.com,感觉不像是php站点。

继续fuzz,发现可以任意文件读取:

技术图片

技术图片

赵师傅的默认目录为/app,所以感觉这可能是个flask架构,/read是其中一个路由:

读一下app.py,成功:

技术图片

P2 Flask session 伪造

来看下源码:


# encoding:utf-8
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"
    )

分析一下关键点:

@app.route(‘/flag‘)
def flag():
    if session and session[‘username‘] == ‘fuck‘:
        return open(‘/flag.txt‘).read()
    else:
        return ‘Access denied‘

路由/flag可以读取flag.txt,但是要求有session且有具体要求。这个session是怎么来的呢?

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>‘

复习一下Flask中SECRET_KEY的重要性:

技术图片

类似于php的secert_key,如果知道了这个值,就可以控制session。

而这道题的SECRET_KEY采用的是random()函数生成,其结果是伪随机数

而且还给了伪随机数的种子:

random.seed(uuid.getnode())

uuid.getnode()返回的是什么呢?——MAC地址

技术图片

技术图片

我们来看看怎么读取linux的默认网卡eth0的MAC地址:

技术图片

这也有文件……一切皆文件不是说着玩的。

读一下,获得了mac地址:

技术图片

这里的MAC地址是16进制形式,uuid.getnode()返回的是十进制的MAC地址:

技术图片

那么需要处理一下,然后就可以写个脚本生成SECRET_KEY了:

import random

ma="02:42:ae:01:d3:41"
mac=mac.replace(":", "")
random.seed(int(mac,16))
key = str(random.random() * 233)
print(key)

OK,密钥到手:

技术图片

下面来伪造session,这里介绍一款工具:flask-session-cookie-manager

用法如下:

技术图片

这里直接encode构造payload会打不通,我们先decode一下看看默认的session:

decode -s SECRET_KEY值 -c Cookie内容

Cookie内容直接访问/抓包查看:

技术图片

跑一下脚本:

技术图片

ok,看到结构了:

那我们构造一下,把username的值改为f*ck

encode -s SECRET_KEY值 -t 要构造的Cookie

技术图片

接下来访问/flag,把Cookie改成我们构造的session:

技术图片

成功获得了flag。

以上是关于[CISCN2019 华东南赛区]Web4的主要内容,如果未能解决你的问题,请参考以下文章

[CISCN2019 华东南赛区]Web11

BUUCTF:[CISCN2019 华东南赛区]Web11

BUUCTF:[CISCN2019 华东南赛区]Web11

BUUCTF:[CISCN2019 华东南赛区]Web11

第六十三题——[CISCN2019 华东南赛区]Web11

[CISCN2019 总决赛 Day1 Web4]Laravel1