基于python的自动化代码审计

 2018-02-11  10,539
 

本文通过介绍在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官方公众号,谢谢!

本文作者:逢魔安全实验室

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/68344.html

python 自动化审计的更多相关文章

  1. flow.ci + Github + Slack 一步步搭建 Python 自动化持续集成

    理想的程序员必须懒惰,永远追随自动化法则.Automating shapes smarter future. 在一个 Python 项目的开发过程中可能会做的事情:编译.手动或自动化测试.部署环境配置 ...

  2. Selenium2+python自动化23-富文本(自动发帖)

    前言 富文本编辑框是做web自动化最常见的场景,有很多小伙伴遇到了不知道无从下手,本篇以博客园的编辑器为例,解决如何定位富文本,输入文本内容 一.加载配置 1.打开博客园写随笔,首先需要登录,这里为了 ...

  3. Selenium2+python自动化24-js处理富文本(带iframe)

    前言 上一篇Selenium2+python自动化23-富文本(自动发帖)解决了富文本上iframe问题,其实没什么特别之处,主要是iframe的切换,本篇讲解通过js的方法处理富文本上iframe的 ...

  4. Selenium2+python自动化7-xpath定位

    前言 在上一篇简单的介绍了用工具查看目标元素的xpath地址,工具查看比较死板,不够灵活,有时候直接复制粘贴会定位不到.这个时候就需要自己手动的去写xpath了,这一篇详细讲解xpath的一些语法. ...

  5. Selenium2+python自动化13-Alert

    不是所有的弹出框都叫alert,在使用alert方法前,先要识别出它到底是不是alert.先认清楚alert长什么样子,下次碰到了,就可以用对应方法解决.alert\confirm\prompt弹出框 ...

  6. 【python自动化第十一篇】

    [python自动化第十一篇:] 课程简介 gevent协程 select/poll/epoll/异步IO/事件驱动 RabbitMQ队列 上节课回顾 进程: 进程的诞生时为了处理多任务,资源的隔离, ...

  7. Day1 老男孩python自动化运维课程学习笔记

    2017年1月7日老男孩python自动化运维课程正式开课 第一天学习内容: 上午 1.python语言的基本介绍 python语言是一门解释型的语言,与1989年的圣诞节期间,吉多·范罗苏姆为了在阿 ...

  8. Selenium2+python自动化28-table定位

    前言 在web页面中经常会遇到table表格,特别是后台操作页面比较常见.本篇详细讲解table表格如何定位. 一.认识table 1.首先看下table长什么样,如下图,这种网状表格的都是table ...

  9. python自动化运维学习第一天--day1

    学习python自动化运维第一天自己总结的作业 所使用到知识:json模块,用于数据转化sys.exit 用于中断循环退出程序字符串格式化.format字典.文件打开读写with open(file, ...

随机推荐

  1. Spring Boot 老启动失败,这次再也不怕了!

    Spring Boot 项目是不是经常失败,显示一大堆的错误信息,如端口重复绑定时会打印以下异常: *************************** APPLICATION FAILED TO ...

  2. 【机制】js中的this指向

    1.this的使用场景 我们先把this的使用场景分为两大类:函数外和函数内: 函数外的this 就是在全局代码里,直接使用this: "use strict"; let name ...

  3. JavaScript初级学习

    1. JavaScript的介绍 前身是LiveScript+JavaScript JavaScript(js)是一个脚本语言 基于浏览器的脚本语言 基于对象,面向对象的一个编程语言 2. EcmaS ...

  4. SpringMVC-03 RestFul和控制器

    SpringMVC-03 RestFul和控制器 控制器Controller 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现. 控制器负责解析用户的请求并将其转换为一个模型. ...

  5. strick-footer 粘边布局

    当网页缩小, 缩放到一定高度时(这个高度就是页面内容高度)footer的页尾自动消失,这个就叫做粘边布局 strick-footer 粘边布局基本思路: 主体{ height:100%; } 内容体{ ...

  6. ASP.NET Core扩展库之日志

        上一篇我们对Xfrogcn.AspNetCore.Extensions扩展库功能进行了简单的介绍,从这一篇文章开始,我将逐步介绍扩展库中的核心功能.     日志作为非业务的通用领域基础功能, ...

  7. Tornado 简明教程

    1.TornadoTornado:python编写的web服务器兼web应用框架1.1.Tornado的优势轻量级web框架异步非阻塞IO处理方式出色的抗负载能力优异的处理性能,不依赖多进程/多线程, ...

  8. android 调用js,js调用android

    Java调用JavaScript   1.main.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?xml v ...

  9. P1048_采药(JAVA语言)

    思路:动态规划的背包问题.把时间看作重量,转换为01背包问题求解. 题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出 ...

  10. windows 以管理员身份运行 代码

    1 // 以管理员身份运行本进程 2 // 1 获取本进程的文件路径. 3 TCHAR path[MAX_PATH] = { 0 }; // 需要初始化 4 DWORD dwPathSize = MA ...