PHP代码审计01

概述

    代码审计是对应用程序源代码进行系统性检查的工作,目的是为了找到并且修复应用程序在开发阶段存在的一些漏洞,或者程序逻辑错误。

    从代码级别上,也就是应用层次上考虑代码安全的话,程序安全问题就是函数和变量的问题。变量接收到不安全的输入后,没有做恰当的过滤,又用在不同的函数上,就可能造成不同的危害。

审计方法

  • 通篇阅读代码:根据代码整体逻辑进行漏洞挖掘
  • 查找危险函数:使用代码审计工具通过正则匹配危险函数,然后根据危险函数中的变量回溯到传入变量的方式
  • 根据功能点进行审计:定位敏感功能点,分析功能是否存在安全缺陷

工具介绍

SeayPHP

seayPHP是一款针对PHP代码安全审计的系统,基于C#语言开发,主要用于windows系统,主要使用正则来匹配危险函数,直接新建项目,把源代码拖进工具即可

工具下载地址:https://github.com/f1tz/cnseay

RIPS

RIPS是一款基于PHP编写的静态代码分析工具,可检测PHP应用程序中的漏洞,并进行结构化输出,RIPS还提供了一个集成的代码审核框架。

工具下载地址:https://sourceforge.net/projects/rips-scanner/files/

超全局变量

PHP中预定义了几个超级全局变量,这意味着他们在一个脚本的全部作用域中都可用,不需要进行特别说明,就可以在函数即类中使用。

  • $GLOBALS

  是PHP的一个超级全局变量组,在一个PHP脚本的全部作用域中都可以访问。包含了全部变量的全局组合数组。变量的名字就是数组的键。

  • $_SERVER

  包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。

  下面列出了所有 $_SERVER 变量中的重要元素:

 

  • $_REQUEST

  用于收集HTML表单提交的数据。

  • $_POST

  用于收集表单数据,在HTML form标签的指定该属性:"method="post"。

  • $_GET

  用于收集表单数据,在HTML form标签的指定该属性:"method="get"。

  • $_FILES

  通过 HTTP POST 方式上传到当前脚本的项目的数组

  • $_ENV

  通过环境方式传递给当前脚本的变量的数组。

  • $_COOKIE

  通过 HTTP Cookies 方式传递给当前脚本的变量的数组。

  • $_SESSION

  当前脚本可用 SESSION 变量的数组。

74cms v5.0.1前端sql注入

74cms源码下载地址:http://www.74cms.com/download/index.html

文件地址:

74cms_Home_Setup_v5.0.1/Application/Home/Controller/AjaxPersonalController.class.php

从代码中可以看出传入的$company_id参数未经过函数的过滤

public function company_focus($company_id) {

        if (!$company_id) {

            $this->ajaxReturn(0, '请选择企业!');

        }

        $r = D('PersonalFocusCompany')->add_focus($company_id, C('visitor.uid'));

        $this->ajaxReturn($r['state'], $r['msg'], $r['data']);

    }

注:

Public:表明该函数是对所有的用户开放的,所有用户可直接调用

Private:表示为私有的,除了class自己,任何人都不可以直接调用

Protected:受保护的类,对于它的继承类来说是公开的,没有任何限制,对其他外部的类,就会变为私有的,不可访问。

$this->ajaxReturn(0, '请选择企业!');

使用ThinkPHP的ajaxReturn方法返回数据,数据格式为

$this->ajaxReturn(返回数据,提示信息,操作状态);

data 返回数据 、info 提示信息 、status 操作状态 

返回数据data可以支持字符串、数字和数组、对象,返回客户端的时候根据不同的返回格式进行编码后传输。如果是JSON格式,会自动编码成JSON字符串,如果是XML方式,会自动编码成XML字符串,如果是EVAL方式的话,只会输出字符串data数据,并且忽略status和info信息。

->符号用户引用对象的成员(属性与方法)

 

=>符号可以自定义任意字符键名

 

然后跟踪add_focus函数,发现SQL语句参数可控,造成sql注入漏洞

文件路径:/Application/Common/Model/PersonalFocusCompanyModel.class.php

 

public function add_focus($company_id,$uid){

    $has = $this->check_focus($company_id,$uid);

    if($has){

        $this->where(array('company_id'=>$company_id,'uid'=>$uid))->delete();

        return array('state'=>1,'msg'=>'已取消关注!','data'=>array('html'=>’关注','op'=>2));

    }else{

        $this->add(array('company_id'=>$company_id,'uid'=>$uid,'addtime'=>time()));

        return array('state'=>1,'msg'=>'已关注','data'=>array('html'=>'取消关注','op'=>1));

    }

}

public function check_focus($company_id,$uid){

    return $this->where(array('company_id'=>$company_id,'uid'=>$uid))->find();

}

注:

Where:如需有条件的从表中选取数据,可将Where添加到SELECT语句

语法:SELECT 列名称 FROM 表名称 WHERE 列 运算符 值

74cms v4.2.3任意文件删除

文件位置: 74cms_v4.2.3/Application/Admin/Controller/DatabaseController.class.php

 

  public function del(){

        $name = I('request.name','','trim');

        !$name && $this->error('请选择要删除的备份文件');

        !is_array($name) && $name = array($name);

        foreach ($name as $key => $val) {

            rmdirs(DATABASE_BACKUP_PATH.$val,true);

        }

        $this->success('删除备份文件成功');

    }

变量$name未经任何过滤,直接使用请求包中的文件名,把传进来的文件名生成 $name数组,并用foreach() 进行遍历,然后传输到rmdirs方法进行删除

注:

foreach ($name as $key => $val)

foreach是一种遍历数组的简便方法,而且只能用于数组,当用于其他数据类型,或者一个未初始化的变量时会产生错误。fareach有两种语法

  • foreach($name as $val)

  遍历给定的 $name数组。每次循环中,当前单元的值被赋给 $val 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)

  • foreach($name as $key => $val)

  遍历给定的 $name数组。每次循环中,当前单元的值,键值被赋给 $val 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)

  • is_array($name),检测$name是否为一个数组

  语法:bool is_array ( mixed $var )

  $var:要检测的变量,如果检测的变量是数组,则返回 TRUE,否则返回 FALSE。

原文地址:https://www.cnblogs.com/Excellent-person/p/13343871.html