代码审计

1. 定义

  • 根据应用程序源代码,从结构、脆弱性以及缺陷等方面进行审查,最终输出代码审计报告,完善应用程序,提高自身安全水平

2. 工具

(1). 辅助工具

  1. Notepad++编辑器
  2. Seay源码审计系统

(2). 其他工具

a. UltraEdit
  • 轻量级代码编辑器,支持十六进制查看及编辑,可****直接修改exe等文件,支持打开大文件,可直接执行代码
b. ZendStudio
  • 内置一个强大的****php代码调试工具,代码提示功能强大,支持6种以上语言。
c. RIPS(代码审计工具)
d. Burpsuite
e. 浏览器扩展
f. 编码转换及加解密
  • seay代码审计系统****自带编码,burp的Decoder功能
g. 正则调试功能
  • seay、灵者正则调试

3. 流程

  1. 获得源码
  2. 安装环境
  3. 查看网站结构
    • 了解该程序的大致目录
  4. 查找程序入口
    • 了解程序的业务逻辑
  5. 寻找配置文件
    • 类似于config.php的文件,保存数据库相关信息,查看****数据库编码方式(宽字节注入)以及变量引用方式(双引号执行)
  6. 过滤功能
    • 通过****公共函数文件和安全过滤等文件,了解过滤位置、绕过方式、过滤方式(GPC、正则、替换、addslasher)

4. 方法

  1. 通读源码
    • 应用文件结构 => 关键文件代码 => 配置文件 => 首页文件 => 入口文件 => 功能审计
  2. 定向功能分析法
    • 分析程序有哪些功能,****根据功能进行漏洞检测与测试
  3. 敏感函数参数回溯

5. 配置项和危险函数

(1). 配置项

  • php.ini配置项规定了各种环境的条件
模式 设定范围
PHP_INI_USER 用户脚本(例如ini_set())、注册表(5.3起)、.user.ini
PHP_INI_PERDIR php.ini、.htaccess、httpd.conf
PHP_INI_SYSTEM php.ini、httpd.conf
PHP_INI_ALL 可在任何地方设定

(2). 常见配置

a. register_global
  1. 作用
    • **设定全局变量的自动注册,**默认关闭
  2. 版本特性
    • 自5.3.0废弃,5.4.0移除,5.2.0中默认开启
  3. 配置影响
    • 变量覆盖漏洞,既可以成为下文绕过身份认证的方法,也可以突破其他已保护的变量产生新漏洞,如sql注入
  4. 不安全实例
    <?php
    	$username=$_GET['username'];
    	$password=$_GET['password'];
    	if(($username==='admin')&&($password==='123456')){
          $authorized=true;//可以通过[URL]?authorized=1,直接传入authorized变量的值进行覆盖从而任意用户登录
        }
    ?>
    
b. safe_mode
  • 相似配置还有:safe_mode_exec_dir、disable_classes=、disable_functions=fopen、unlink
  1. 作用
    • **禁用了php的一些危险的内置函数,如system、exec等,**默认关闭
  2. 版本特性
    • 自5.3.0废弃,5.4.0移除
  3. 配置影响
    • 在找到****可执行命令时,可以先检测环境的配置
  4. 不安全实例
    <?php
    	$commend=$_GET['commend'];
    	system("{$commend}");
    ?>
    
c. display_error
  1. 作用
    • **将显示php产生的错误,**默认开启
  2. 版本特性
    • 在php中默认开启,但是真实的站点发布后一般是关闭的
  3. 配置影响| 报错设置项 | 含义 |
    | --------------------------------- | ---------------------------------------------------- |
    | error_reporting=E_ALL | 将错误级别显示为最高 |
    | error_log= [path] | 自定义错误日志的位置,必须对web用户可写入 |
    | log_errors=on | 将错误日志输出到文件,而不是直接输出到前端 |
  4. 不安全实例
    站点关闭后未关闭display_error,呢么就会暴露服务器的目录信息,增加sql注入的风险
    

6. 危险函数

危险函数

7. 类型

(1). 安装漏洞审计

a. 概述
  • 一般php程序都有一个初始安装的功能,可能有以下漏洞
    1. 无验证功能,任意重装覆盖
    2. $_GET['step']跳过限制步骤
    3. 变量覆盖导致重装
    4. 判断lock后跳转无exit
    5. 解析install.php.bak漏洞
    6. 其他特定功能绕过漏洞
      安装漏洞
b. 审计思路
  1. 定向功能分析法,直接从安装问题找漏洞
  2. 判断Lock后面有没有exit(),如果没有,看代码重装部分有什么漏洞
    安装漏洞审计思路

(2). 命令注入漏洞

a. 分类
  1. 可以直接传入命令执行并返回结果
    • system()、exec()、shell_exec()、passthru()、反引号
  2. 可以传入命令执行,但无结果返回
    • popen()、proc_open()
  3. 需要开启pcntl扩展
    • pcntl_exec()
b. 函数作用

RCE函数作用

c. 多命令执行语法
①windows
命令格式 含义
command1**&**command2 先后执行,无论command1是否成功
command1**&&**command2 先后执行,command1成功,才执行command2
command1**
command1** **command2
②Linux
命令格式 含义
command1**;**command2 先后执行,无论command1是否成功
command1**&&**command2 先后执行,command1成功,才执行command2
command1**&**command2 先执行command1并放置后台,在执行command2
command1**
command1** **command2
d. 审计思路
  • **搜索目标函数 => 分析过滤 => 构造恶意字符串 => 执行 => 根据返回值判断 **

(3). XSS漏洞审计

a. 相关函数
  • echo、printf、print、print_r、sprintf、die、var_dump、var_export等
b. 审计思路
①反射型、存储型
  • 需要跟踪****输入输出位置是否有过滤
  • 搜索输出函数 => 寻找是否有js代码 => 是否过滤,绕过 => 重复
    1. 反射型:
    <?php
        $content = $_GET['content'];
        //没有做任何过滤
        echo $content;	//输出函数
    ?>
    
    2. 存储型:
        <?php
        $xss=$_POST['xss'];//没有做任何过滤
        if($xss!==null){
            $sql="insert into temp(id,payload) value('1','$xss')";
            $result=mysql_query($sql);
            echo $result;//输出函数
        }
    ?>
    
② DOM型
  • 要对js做审计,查看是否是直接输出的js代码
c. 漏洞修复
①简单修复
  • **使用****htmlspecialchars()**函数,将内容转化为HTMl实体
  • $sql = "INSERT INTO 'test'('name') VALUES('".htmlspecialchars($name)"')";
    $result=mysql_query($sql);
    echo $result; 
    
②严格限制输入
  • 以输入ip地址为例
    if(is_numeric($octet[0]))&&(is_numeric($octet[1]))&&(is_numeric($octet[2]))&&(is_numeric($octet[3]))&&(sizeor($octet)== 4)){
    $target=$octet[0].'.'.$octet[1].'.'.$octet[2].'.'.$octet[3];
    }
    

(4). SQL注入漏洞

a. 相关类型
  • 数字型注入、字符型注入、宽字节注入、编码注入、二次注入等
b. 审计思路
  • 是否存在****过滤函数 => addslashes(字符型无法注入) => set **character_set_client=gbk**(宽字节)
    SQL注入审计思路
①普通注入
  1. 观察sql语句的拼接,是否****对用户的输入进行处理

  2. 寻找数据库关键字 select frommysql_connect

    • 搜索$query => 查看输入函数是否有过滤 => 查找数据库关键词 => 重复
    $id = $_REQUEST['id'];
    $query = "SELECT * FROM users WHERE id = $id";
    echo $query;
    

(5). 文件包含漏洞

a. 产生原因
  • 服务器对要包含的来源文件没有进行审查,导致攻击者进行了任意文件的读取等危害
b. 原理
  • 服务器开启了allow_url_include选项
  • 利用php的某些特性函数,利用URL动态包含文件
c. 相关函数
  • include、include_once、require、require_once
    文件包含漏洞介绍
d. 审计思路
  1. 跟踪程序运行流程,查看模块加载时包含的文件****是否可控
  2. 直接****搜索相关函数回溯查看变量是否可控
e. 漏洞修复
  1. **尽量不要使用动态变量调用文件,**直接写要包含的文件
  2. 进行****白名单匹配,但大型web维护起来很复杂

(6). 二次注入漏洞

a. 原理
  • 利用Mysql数据库出库值****反转义功能,多次与数据库交互造成的注入问题
b. 相关函数
  1. 在数据库****第一次进入数据库时进行了转义后再存储,后续使用时未再次过滤或转义而直接使用
  2. 开发者对语言中的****函数理解不充分导致,例如is_numeric
c. 审计思路
  1. 有数据****insert/update到数据库
  2. 从数据库****select数据,没有再次转义,再将数据拼接到新的语句中
d. 防御和修复
  1. 正则过滤输入
    if(!preg_match("/^[a-zA-Z0-9]+$/",$clean_name))
    
  2. 出库时数据过滤

(7). 任意文件读取

a. 原理
  1. 都具有****读取文件的函数
  2. 读取文件的****路径用户可控,且没有校验或者校验不严格
  3. 都会****输出文件内容
b. 相关函数
  • file_get_contents()、fgetss()、fgets()、file()、fopen()、fread()、parse_ini_file()、readfile()、show_source()、highlight_file()
    <?php 
    	$filename=$_GET['file'];
    	echo file_get_contents($filename);
    ?>
    
c. 审计思路
  1. 先查看****功能点对应的文件,再去进行代码审计,分析原理
  2. 搜索文件读取的相关函数,用****变量溯源的方法,查看是否可以直接或间接控制变量
d. 防御与修复
  1. 尽量将****url写死
  2. 正则判断用户输入的参数格式,匹配输入的格式是否合格
  3. **少使用敏感函数,**控制敏感函数传参
  4. 对****变量进行过滤,将单引号或者其他敏感字符转化为斜杠

(8). 任意文件操作

a. 原理
  • 文件操作相关****关键参数用户可控,导致的恶意操作
b. 分类
①文件/目录删除** **
  1. 相关函数

    1. unlink(路径):删除文件
    2. rmdir(路径):删除目录
  2. 相关手法

    1. 删除lock****文件锁,导致重复安装漏洞
    2. 删除网站****关键文件,导致数据丢失或网站拒绝服务
②文件写入/上传
  1. 相关函数
    1. file_put_contents(dir,content):直接将字符串写入文件
    2. $fp=fopen(dir,"w"):以写入模式打开一个文件
    3. fwrite($fp,content):向文件写入数据
    4. fclose($fp):关闭文件
    5. move_uploaded_file(tmp_dir,des_dir):移动临时上传的文件
③文件解压
  1. 审计思路

    • ZipArchive扩展在windows平台php>5.6默认安装
    1. 查看是否有文件解压类,例如 $zip = new \ZipArchive
    2. 查看是否有相关操作函数,例如 $zip->open()$zip->addFile()$zip->addEmptyDir()$zip->addFromString()$zip->extractTo()$zip->close()
    3. **判断解压目录 **
    4. 是否在web目录下
      1. 是否检查压缩包内的文件类型
      2. 是否不在web目录下也可以使用
c. 常见函数及用法

任意文件操作漏洞

任意文件操作函数2

(9). 越权漏洞

a. 常出现地方
  1. 根据订单号查订单
  2. 根据用户ID查看账户信息
  3. 修改/找回密码
b. 思维导图

越权漏洞思维导图

c. 审计思路
  1. 先查看****前端的页面源码,查看一些操作的表单提交的值
  2. 查看****配置文件和一些过滤器,是否对URL有相关的筛选操作
  3. 最后查看****后台处理逻辑,是否存在身份验证机制,逻辑是否异常
  4. 查看服务器端是否进行****身份校验
d. 修复和防御
  1. 查看用户信息操作需要****额外的身份验证信息
  2. 从****加密的Cookie中获取当前用户id
  3. 在每个页面****加载前进行权限认证
  4. 进行敏感操作时****再次验证身份信息

(10). 暴力破解

a. 原理
  • 穷举法
b. 审计思路
  • 分别审计登录页面、验证码页面、二维码页面,判断二维码是否可以绕过
c. 防御与修复
  1. **每次进行身份校验时,**调用二维码的文件,从而刷新验证码
  2. 添加一个****判断session不为null的条件
  3. 前端验证码****加密,或使用高级验证码
  4. 后台对用户输入密码****次数进行限制,或封禁失败次数过多的IP
  5. 禁止用户使用弱口令密码