这个应该是我20年时遇到的题目,现在补发记录。
该源码是由werkzeug和flask共同搭建,入口文件为run.py,根据每一个@app.route去看路由就很好分析,自己搭环境运行访问首页如下图。
问题(一)、
路径./GKshop/taobao/.config.py内容如下:
这里是os.popen出的问题,从7行开始,创建了一个tcp套接字,并监听8080端口,将接收的消息带入os.popen执行,再将执行结果用connection传回客户端,那我们就创建一个sock去连接服务端并发送恶意请求,执行结果如下:
问题(二)、
同样在taobao/route.py中,上传部分代码如下图,在37行,绝对路径与f.filename拼接之前没有过滤,也没有修改文件名,所以可以控制文件名和文件路径,则直接传马或覆盖文件都可以。
问题(三)、
在朋友的提醒下,看了46行的load函数,发现在pyyaml版本为3.11,确实存在反序列化漏洞,当上传的文件后缀为yml,内容为!!python/object/new:os.system ["cat /flag.txt"]时(payload网上有很多其他的当时我就试了这一个),可以执行命令。
!!python/object/new:os.system为 PyYAML 中对 Python 对象的类型转化标签,在pyyaml包里的constructor.py可以看到,684行会调用construct_python_object_new函数,最终调用了581行的construct_python_object_apply函数
下图可以看到,打断点后payload里的os.system传给了suffix,args接受了cat /flag.txt
直接进到make_python_instance函数
再进入find_python_name,name为os.system,516行的module_name, object_name = name.rsplit('.', 1)以点做了分离,521行__import__(module_name)动态导入os,再找到os模块的路径,最后getattr返回os模块的system属性,此时cls为<built-in function system>内置函数system,此时556行的return cls(*args, **kwds)执行了代码。但是这里不会被flask返回前端,可以去反弹shell。
问题(四)、
同样在taobao/route.py最末尾地方,访问不存的页面时返回404页面如下,查找资料后发现类似这样render_template_string函数渲染的字符串包含request.url时存在模板注入漏洞(ssti),这个函数将字符串渲染成页面时遇到{{ }}和{% %}会将里面的内容当代码执行,所以request.url也就是我们的浏览器的url里携带{{ }}和{% %}时可以造成命令执行。但我这环境版本有问题,此处未测试功。