基于python的自动化代码审计

新年马上到了,FormSec现在这里给大家拜年,祝大家狗年旺财!

当然新年礼物已经给大家备好了:《基于python的自动化代码审计》

本文通过介绍在python开发中经常出现的常规web漏洞,然后通过静态和动态两种方式对python代码进行自动化审计挖掘漏洞,并且展示自动化系统在自动化审计python应用代码的成果,本文比较长,请耐心阅读

从python常规漏洞来看都有一个共同点,那就是危险函数中使用了可控参数,

  1. 如system函数中使用到的(‘mv %s’% filename),
  2. 如execute函数中使用到的username参数,
  3. 如HttpResponse中使用到的nickname参数,

这些参数直接从第一层入口函数中传进来,或者经过简单的编码,截断等处理直接进入危险函数,导致了以上危险行为。

静态分析的核心是什么?

注入判断的核心就在于找到危险函数,并且判断其参数是可控的,找到危险函数这个只需要维护一个危险函数列表即可。

当在语法树中发现了函数调用并且其名称在危险列表中就可以标记出该行代码,接下来的难点就在于跟踪该函数的参数,默认认为该危险函数的外层函数的参数是可控的,那就只需要分析这个外层函数参数的传递过程即可

在python中,参数的处理过程大概总结如下这些情况:

直接赋值:GET参数直接赋值 属性赋值:request.POST.get(‘name’)赋值,排除META中的内容 字符串拼接:字符串拼接 列表解析式: 元组、列表、字典数据处理:元素相加,赋值value等 Subscript分片取值:通过下标索引取值 函数调用后赋值:字符串操作的系统函数str,strip,split,encode等,未过滤的自定义函数,危险函数 With操作: For循环: If判断: 排除特殊情况: 判断是否合法:os.path.exitst,isdir等 锁定范围:Type in [xxx,xxx]

如果存在此文件中导入了其他非系统模块,继续递归解析此模块文件

如果存在此文件中导入了其他非系统模块,继续递归解析此模块文件

如果存在类的话,继续递归类里面方法的内容

Body的内容是嵌套的,一个body里面可能还有很多个body

循环body体中的元素,然后取出body中的body,orelse,test,handlers元素,继续递归查找可控参数

以行为单位解析出来的结构和内容

Name为被赋值的变量名

然后value里面就是具体的内容

从右往左一次嵌套,所以request在最里层的value

以Python文件为入口,解析成语法树,格式化为json格式

取出语法树中的函数体内容

然后遍历函数体中的代码行:

如果有危险函数调用,并且有可控参数进入此危险函数,则报出漏洞

所以这里的核心就是:

1、递归全部代码查找可控参数,生成可控参数列表 2、维护危险函数列表

最早的版本已经开源,大家可以借鉴,可以阅读代码了解python的语法树

静态分析的缺陷:

漏报误报高 可控参数分析覆盖不够全 外部导入函数对可控参数判断的影响

python 是一种动态类型语言,python 中一切皆对象

所以换句话说每个对象可以在程序里任何地方改变它

这就意味着我们可以劫持我们认为危险的函数

拦截进入函数的参数,判断是否有恶意参数进入,从而判断是否存在漏洞

Python的广泛使用,很大部分是因为开发效率高,模块使用方便

所以就劫持就针对:

1、模块的直接方法

2、模块的类,已经类方法进行了

举例:

模块的方法可以直接被劫持

首先通过imp导入os模块,然后在覆盖到其中的system方法

在调用system方法时,就是这里的__call__方法了

判断进入system方法的参数是否有恶意内容,从而可以判断是否真正触发了漏洞

元类:

元类就是用来创建类的类,函数type实际上是一个元类

元类的主要目的就是为了当创建类时能够自动地改变类。

__metaclass__: 你可以在写一个类的时候为其添加__metaclass__属性, Python就会用它来创建类 __metaclass__可以接受任何可调用的对象,你可以在__metaclass__中放置可以创建一个类的东西 __new__:是用来创建类并返回这个类的实例 __call__:任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用,用callable来判断是否可被调用 __getattribute__:定义了你的属性被访问时的行为

你首先写下class Foo(object),但是类对象Foo还没有在内存中创建。

Python会在类的定义中寻找__metaclass__属性,如果找到了,Python就会用它来创建类Foo,如果没有找到,就会用内建的type来创建这个类

定义test类,使用metaclass来创建tesk类

这时在metaclass中就可以动态修改这个类

这里使用upperattr,在创建test类时,将属性名称全部大写

在test类实例化的时候就会执行上述操作,达到动态修改类的效果

举例:

模块的类的劫持

在当前pythonpath路径下创建socket.py文件

然后劫持_fileobject类,使用_installclshook动态修改此类

变量_fileobject的属性方法时,返回_hook_writelin 和 _hook_readline

写好的劫持脚本,放到当前的工作根目录下即可

然后正常启动项目,劫持脚本就会自动生效,劫持特定的方法

但是内建函数方法,built-in method无法直接覆盖劫持

这时也可以通过monkey path来实现:

Monkey patch就是在运行时修改代码,实现hot patch的一种手段

将patch脚本import到应用里面,在功能函数入口通过装饰器的方式应用patch即可

动态审计的优点:

准确性高 可以平台化 但是使用和扩展需要了解具体模块的结构,pyhton的魔术方法等基础知识 因为需要部署到目标系统代码中,所以动态修改后的类和方法会对系统造成未知的影响,(不过目前测试来看还没出现)

这里这个开源的项目是使用动态hook来制作python后门的例子,可以参考

动态检测和静态检测相结合,相辅相成,相互补助,才能达到更好的效果,最后才能自动化检测

对于,git和svn这种版本控制的,可以不用每次都扫描全部代码,可以根据版本号扫描范围之间的代码,节省资源,速度快

下载agent安装包后,根据右边的部署说明,部署agent到需要检测的服务器上即可

成功部署agent后,会在平台上显示主机是否在线

并且agent会自动hook功能代码入口:

比如django开发的系统,根据url整理views中的方法,然后自动劫持这些方法即可,不用全部劫持,尽量减少对系统代码的改动

用户设置代理,正常访问系统

代理替换参数内容为payload,到系统后,漏洞检测系统自动检测漏洞然后显示信息到控制台

原文发布于微信公众号 - 逢魔安全实验室(FormSec)

原文发表时间:2018-02-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏老马说编程

(67) 线程的基本协作机制 (上) / 计算机程序的思维逻辑

上节介绍了多线程之间竞争访问同一个资源的问题及解决方案synchronized,我们提到,多线程之间除了竞争,还经常需要相互协作,本节就来介绍Java中多线程协...

22060
来自专栏菜鸟计划

angularjs 服务详解

一、服务 服务提供了一种能在应用的整改生命周期内保持数据的方法,它能够在控制器之间进行通信,并保持数据的一致性。 1.服务是一个单例对象,在每个应用中只会被实例...

36160
来自专栏好好学java的技术栈

java基础提升篇:深入浅出Java多线程

13720
来自专栏大内老A

WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[下篇]

WCF客户端和服务端的框架体系相互协作,使得开发人员可以按照我们熟悉的方式进行异常的处理:在服务操作执行过程中抛出异常(FaultException),在调用服...

21590
来自专栏崔庆才的专栏

你还在用 os.path?快来感受一下 pathlib 给你带来的便捷吧!

pathlib 是Python内置库,Python 文档给它的定义是 Object-oriented filesystem paths(面向对象的文件系统路径)...

19240
来自专栏java一日一条

有了 GC 还会不会发生内存泄漏?

这个问题是我在写C++时考虑到的,C++需要手动管理内存,虽然现在标准库中提供了一些智能指针,可以实现基于引用计数的自动内存管理,但现实环境是很复杂的,我们仍要...

8630
来自专栏顶级程序员

死磕 Java 并发 :Java 内存模型之 happens-before

来源:chenssy, cmsblogs.com/?p=2102 那么我们正确使用同步、锁的情况下,线程A修改了变量a何时对线程B可见? 我们无法就所有场景...

40450
来自专栏Python中文社区

一种Python全局配置规范以及其修改

專 欄 ❈丁果,Python中文社区作者。对django、pyqt、opencv、tornado感兴趣。 GitHub:https://github.com/...

33690
来自专栏JMCui

MongoDB系列二(介绍).

一、特点     学习一个东西,至少首先得知道它能做什么?适合做什么?有什么优缺点吧?     传统关系型数据库,遵循三大范式。即原子性、唯一性、每列与主键直接...

30380
来自专栏安恒网络空间安全讲武堂

堆学习入门

借助hitcon training的题目对三种堆的利用方法进行了一个系统的学习,刚入坑的堆小白们可以一起学习一下。题目链接:https://github.com...

17720

扫码关注云+社区

领取腾讯云代金券