网络安全学习-15

60 阅读4分钟

sql注入漏洞中,常见的防护方案有哪些?

使用预处理语句

  • 原理:SQL结构和数据分离,即使传入恶意字符串(比如, ' or 1=1;),数据库也会把他当作纯数据处理,不会执行。

输入验证和白名单

  • 原理:在输入sql之前,严格校验其格式、类型或者取值范围。zzzzz
  • 输入验证:严格检查类型
  • 使用白名单匹配

特殊字符转义

  • 对特殊字符进行转义(比如, ‘ “ \)使其失去语法意义。

最小权限原则

  • 给数据库分配最小必要权限

类型转换

  • 将输⼊强制转换为整数/浮点 ⽤于整数/浮点类型的输⼊参数处理 可防⽌SQL注⼊

针对常见的防护方案,哪些是可以绕过的?哪些又没法绕过?

特殊字符转义

  • 使用addshalshes()函数对特殊字符转义
    • 单引号 ''
    • 双引号 ""
    • 反斜杠 `` → \
    • NULL字符 \0\0
  • 绕过姿势
    • 宽字节注入,使用%df可以绕过。
原始输入: %df'
addslashes: %df'  (0xdf 0x5c 0x27)
GBK解码:   運'     (0xdf5c=運, 0x27=单引号)
    • 二次注入
      • 原理:数据进入数据库之前被转义,从数据库取出后没有再次过滤直接拼接到sql语句中。
    • 数字型注入
      • 只转义引号,不影响数字
  • 编解码绕过
    • 注⼊语句进⾏两次编码,⾸先通过addslashes()过滤,然后urlencode解码
  • 弱类型
    • 在判断数据类型时,php有类型函数对其判断,php是⼀种弱类型,会⾃动转换类型。 如果只是判断并没有赋值。可能会造成漏洞。
  • http头信息注入
    • 通过 getenv()函数或者$_SERVER获取。

pikachu靶场,审计并利用宽字节注入漏洞

if(isset($_POST['submit']) && $_POST['name']!=null){

    $name = escape($link,$_POST['name']);	//对输入的数据进行转义
    $query="select id,email from member where username='$name'";
    $set = "set character_set_client=gbk";	//设置字符集为gbk
    execute($link,$set);

    
    $result=mysqli_query($link, $query);
    if(mysqli_num_rows($result) >= 1){
        while ($data=mysqli_fetch_assoc($result)){
            $id=$data['id'];
            $email=$data['email'];
            $html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";
        }
    }else{
        $html.="<p class='notice'>您输入的username不存在,请重新输入!</p>";
    }

上述代码漏洞逻辑:

  1. 首先对输入的数据进行转义
  2. 设置字符集为gbk
  3. 导致宽字节注入漏洞

绕过方法:

// 使用 %df让转义符失效
$_POST['name'] = '%df' OR 1=1#";

// escape函数处理后
$name = '%df' OR 1=1#";  

// 经过GBK编码解析:
// %df + \  → %df%5c合并成一个汉字 "運" (0xdf5c)
// 原本的转义符 \ 被"吃掉"了

// 最终SQL语句变为
$query = "select id,email from member where username='運' OR 1=1#'";		//单引号逃逸成功
                                                     

验证:

命令注入漏洞常见的函数有哪些?

system()

  • 自动输出命令执行结果
  • 返回命令执行的最后一行

exec()

  • 不会自动输出结果,需要使用echo才能显示
  • 结果存储在数组中

shell_exec()

  • 返回完整输出,以字符串的方式返回

passthru()

  • 直接输出原始数据,有回显
  • 适合传输二进制数据
  • 不对数据做处理

pcntl_exec()

  • Linux下面的扩展
  • 在当前进程空间执⾏指定程序
  • 版本要求:PHP>4.2.0

popen()

  • 打开⼀个指向进程的管道,该进程由派⽣给定的 command 命令执⾏⽽产⽣

proc_open()

  • 执⾏⼀个命令,并且打开⽤来输⼊/输出的⽂件指针

反引号(`)

  • 执⾏运算符,PHP 将尝试将反引号中的内容作为 shell 命令来执⾏,并将其输出信息返回,使⽤反引号运算符的效果与函数 shell_exec() 相同

ob_start()

  • 打开输出缓冲

代码执行漏洞常见的函数有哪些?

eval()

  • 直接把字符串当作php代码执行。

assert()

  • 判断一个表达式是否成立,返回ture or false,会执行该表达式。
  • 把字符串当作php代码执行,该行为在php 8.0.0中移除

create_function()

  • 创建匿名函数
  • php版本8.0.0中移除

call_user_func()

  • 把第⼀个参数作为回调函数调⽤

call_user_func_array()

  • 调用回调参数

a(a(b)

  • PHP 的函数⽀持直接由拼接的⽅式调⽤。

简述结合伪协议通过文件包含漏洞读取文件的原理?

  1. 当 PHP 的 include()require() 函数加载一个文件时,如果文件中包含 PHP 标签(如 <?php ... ?>),PHP 解析器会强制执行其中的代码。
  2. 如果想获取到代码信息,使用include()require()无法读取到config等信息。
  3. 使用伪协议可以不运行php文件,实现php文件读取。
  4. php伪协议:
  • php://
    • 条件:
      • allow_url_include=on,php://input php://stdin php://memory php://temp需要开启
      • allow_url_fopen=on/off
    • 作用:
      • 访问请求的原始数据中的只读数据。
  • zip://&zlib://&bzip2://
    • 条件:
      • allow_url_include=on/off
      • allow_url_fopen=on/off
    • 作用:
      • 属于压缩流,可以访问压缩⽂件中的⼦⽂件。
  • file://
    • 条件:
      • allow_url_include=on/off
      • allow_url_fopen=on/off
    • 作用:
      • 用于访问本地文件系统(读取文件内容等)
      • 是php默认流封装协议
      • 不受allow_url_include和allow_url_fopen限制
    • 语法:
file://[文件的绝对路径]

file:///etc/passwd
file://C:/Windows/win.ini
  • data://
    • 条件:
      • allow_url_include=on
      • allow_url_fopen=on
    • 作用:
      • 传递相应格式的数据。
      • 可以用来执行php代码
  • http://&https://
    • 条件:
      • allow_url_include=on
      • allow_url_fopen=on
    • 作用:
      • 通过http1.0的GET方法,只读取访问文件资源。
  • phar://
    • 作用:
      • 用来读取和操作这个压缩包内部文件的接口。