18-PHP常见漏洞之代码审计

news/2025/2/24 17:54:00/文章来源:https://www.cnblogs.com/bokexiLu/p/18717780

1、sql注入漏洞中,常见的防护方案有哪些?请简述原理和用法

  • 类型转换(数字型)

    原理:将输入内容强制转换为整数或浮点来防止SQL注入

    常用函数:

    • intval($input)

    • floatval()

    • floor()

    • (int)$input

    • $input + 0

      以intval函数为例,用法如下:

      <?php
      /*强制类型转换*/
      $id=intval($_GET['id']); 	//因查询ID为整数 所以可以强制转换为整数
      $id=$pdo->quote($_GET['name']);
      /*预处理语句*/
      $stmt =$pdo->prepare("SELECT id, name FROM users WHERE id=?;");
      $stmt->execute([$_GET['id']]);
      ?>
      
  • 特殊字符转义(字符型)

    原理:在单引号'、双引号"、反斜线\与 NULL前加上反斜线可用于防止SQL注入。

    • addslashes函数以及magic_quotes_gpc选项具有该功能
      其中,当magic_quotes_gpc=On时,如果post、get、cookie过来的数据有单引号、双引号、反斜线与 NULL等字符,PHP解析器就会自动增加转义字符\,如果这个选项为off,那么我们就必须调用addslashes函数来为字符串增加转义。

      • 开启gpc,打开php.ini 找到 magic_quotes_gpc = Off 设置成On 重启服务,即可开启

        <?php
        var_dump(get_magic_quotes_gpc()); //查询gpc的值 1 是开启 0是关闭
        

    用法:在程序中通常是检测 gpc是否开启 如果没有开启则使用 addslashes 对传过来的字符进行过滤

    <?php
    function check_put($str){if(!get_magic_quotes_gpc()){ 		//判断gpc是否开启return addslashes($str); 			//没有开启 使⽤ addslashes 进⾏过滤}return $str;
    }
    echo check_put($_GET['id']);
    

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

  • 以下场景可以实现绕过

    • SQL语句中传参无单引号闭合:如数字型时,攻击者的SQL注入语句不需要单引号闭合,即addslashes函数不起作用,可以绕过。

    • 宽字节注入(传入的参数会使用GBK编码,如:iconv()和 mb_convert_encodeing()函数等)

      如:SQL语句为id=1%df'时,addslashes()函数会在单引号(%27)前面加⼀个反斜杠(%5c),在GBK编码中,%df%5c为汉字,这就导致后面的单引号逃逸,实现绕过。

    • 编解码绕过(urldecode、base64_decode、json_decode 编码注入)

      以urldecode编码注入为例:对注入语句进行两次编码,首先前端会进行一次解码,然后将依旧是url编码的注入语句传递给后端,使得addslashes()过滤失效,最后urlencode函数进行解码还原注入语句

      $id= $_GET['id'];
      $id = addslashes($id);
      $id = urldecode($id);
      echo "select * from news where id='$id'";
      
    • 弱类型绕过

      php是⼀种弱类型,会自动转换类型。如果只是判断并没有赋值。可能会造成漏洞。如

      <?php
      $id = isset($_GET['id'])?$_GET['id']:1;
      //如果使⽤intval
      if(intval($id)<99){		//仅判断并没有赋值,id=1' or 1=1即可绕过die("不符合条件");
      }
      $sql= "select * from news where id=$id";
      echo $sql;
      
    • 二次注入绕过

      二次注入的原理:在第一次数据库插入数据的时候,仅仅使用了 addslashes或magic_quotes_gpc 对特殊字符进行转义,虽然会添加 \ 进行转义,但是\并不会插入到数据库中,在写数据库的时候还是保留了原来的数据。

    • http头信息注入绕过

      通常程序员会设置全局过滤防止SQL注入,开启之后 GET、POST、Cookie这些传入过来的值都会进行过滤。而http头信息是直接获取,不会对其进行过滤。通过http头信息注入,来实现绕过

  • 没法绕过的场景

    • 强制类型转换(如intval函数处理数字型参数)
    • 参数化查询(预处理语句):SQL代码与数据分离,使得攻击者无法改变SQL命令的结构。
    • 严格的输入白名单验证:非白名单字符(如'"#)会被直接拒绝。
    • 数据库权限最小化

3、请参考pikachu靶场,审计并利用宽字节注入漏洞

  • 查询pikachu源码中set character_set_client=gbk语句,找到宽字节注入漏洞模块

    image-20250215181815971

    漏洞实现:构造kobe%df' or 1=1 #后,SQL语句变化%df\'or 1=1 #%df%5c%27 or 1=1 # ==> 運' or 1=1 # 实现单引号逃逸

    image-20250215180221780

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

system( ):能够将字符串作为OS命令执行,自带输出功能。

exec( ):能够将字符串作为OS命令执行,需要输出执行结果。返回结果是有限的。

shell_exec( ):通过 shell 执行命令并将完整的输出以字符串的方式返回。

passthru( ):执行外部程序并且显示原始输出。

pcntl_exec( ):pcntl是linux下的⼀个扩展,可以支持php的多线程操作。pcntl_exec函数的作用是在当前进程空间执行。

popen( ):打开⼀个指向进程的管道,该进程由派生给定的 command 命令执行产生。

proc_open( ):执行⼀个命令,并且打开用来输入/输出的文件指针。

反单引号``:在php中称之为执行运算符,PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返。

ob_start( ): 是 PHP 中用于开启输出缓冲的函数

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

eval( ):函数把字符串按照 PHP 代码来计算。该字符串必须是合法的 PHP 代码,且必须以分号结尾。

assert( ):功能是判断⼀个表达式是否成立,返回true or false,重点是函数会执行此表达式。

preg_replace( ):执行⼀个正则表达式的搜索和替换。

call_user_func( ): 把第一个参数作为回调函数调用。

call_user_func_array( ):调用回调函数,并把⼀个数组参数作为回调函数的参数。

create_function( ):PHP中的内置函数,用于在PHP中创建匿名(lambda-style)函数。

6、如何结合伪协议通过文件包含漏洞读取文件?请简述原理

伪协议: data://php://input (使用前提:allow_url_include=on) 、php://filter(无限制)

  • 以php://filter伪协议为例:

    • php://filter 伪协议允许对文件进行编码或解码,可以用于读取源码文件(绕过 include() 的 PHP 解析)对目标文件进行编码转换,绕过文件包含限制,获取文件原始内容。利用方式如下

      使用php://filter/read=convert.base64-encode/resource=/etc/passwd来读取并以Base64编码形式输出/etc/passwd文件的内容,最后进行Base64解码获取源码。

7、复习php常见漏洞

SQL注入漏洞

概述:未过滤的用户输入直接拼接 SQL 语句,导致恶意 SQL 语句执行。

修复方案:使用预编译语句和参数化查询,对所有用户输入进行严格的验证和过滤。

命令注入

概述:应用程序在执行系统命令时,未对用户输入进行适当的过滤或验证,导致攻击者能够注入恶意命令并在服务器上执行。

修复方案:使用过滤函数内置函数 escapeshellcmd(), escapeshellarg(),过滤和转义输入中的特殊字符,使用白名单限制输入,禁用危险函数。

代码执行

概述:在WEB中,PHP代码执行是指应用程序过滤不严,用户通过http请求将代码注入到应用中执行。

修复方案:严格对用户的输入进行验证与过滤、避免使用动态执行函数如eval()、create_function()、assert()、preg_replace()等、禁用危险函数,在php.ini中禁用不安全的函数,比如eval()、exec()、system()、passthru()等。

文件包含

概述:直接包含用户可控的文件路径,导致本地/远程代码执行。

修复方案:用户输入不能作为 include()的目标、限制 allow_url_include = Off(防止 RFI)、使用白名单验证文件路径。

文件上传

概述:未对上传文件的类型、内容、后缀名等进行严格校验,导致恶意代码上传并执行。

修复方案:严格限制上传文件类型、文件名处理、限制文件上传目录。

变量覆盖漏洞

概述:攻击者通过用户输入覆盖 PHP 代码中的全局变量进而影响程序的正常逻辑,甚至执行恶意操作。

修复方案:避免 extract()parse_str()覆盖全局变量、明确变量来源不依赖全局变量。

XSS漏洞

概述:未对用户输入的数据进行输出时的 HTML 实体编码,导致攻击者可以注入恶意 JavaScript。

修复方案:对所有输出到浏览器的内容进行适当的HTML实体编码。

SSRF漏洞

概述:是由于服务端提供了从其他服务器获取数据,但没有对地址或协议等进⾏过滤或限制造成的漏洞。

修复方案:校验用户输入的url,限制协议类型、使用白名单机制。

CSRF

概述:攻击者诱导用户在已认证的状态下向应用发送伪造请求。

修复方案:添加token/Referrer校验,拒绝空Referrer。

XXE

概述:攻击者通过自定义实体访问系统文件或远程资源。

修复方案:禁用XML解析器中的外部实体解析、使用安全的XML库(默认不支持外部实体)、验证和清理输入的XML内容,避免恶意内容被解析。

反序列化

概述:反序列化不可信数据导致代码执行或逻辑绕过。

修复方案:避免反序列化用户输入、使用 JSON 等安全格式替代

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/884581.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Chat2DB,AI驱动的数据库管理工具和分析平台

Chat2DB 是一款专为现代数据驱动型企业打造的数据库管理、数据开发及数据分析工具。作为一款 AI 原生的产品,Chat2DB 将人工智能技术与传统数据库管理功能深度融合,旨在提供更为智能、便捷的工作体验,助力用户高效地管理数据库、开展数据开发和分析工作。Chat2DB 是一款 AI …

C++ 数组02 - 数组初始化

C++数组在创建的时候,可以给一些默认的值——数组初始化。 数组初始化是数组的必会知识点哦!

读当我点击时,算法在想什么?02算法在监视我们(中)

主成分分析法用于人格分类,斯坦福教授Michael Kosinski通过社交媒体数据利用此法分类人群。脸书等社交媒体利用此法分析用户,用于配对、招聘等,但可能操纵用户。回归模型用于数据转化,但存在局限。1. 主成分分析方法 1.1. 在过去的 50年里,社会学家和心理学家一直利用主成…

win10下测试恶意代码追踪

目录源文件执行流程分析获取源脚本释义获取源脚本实践分析获取到的源脚本疑问 源文件 powershell -Command "$update=TradingView; $InstallPackage=AI_beta; $mode=devmode; $protocol=https; $InternalBuild=v1.9.32; $api=$protocol+://+$mode+beta.+dev; $Response=I…

1月的上海之行

1月去了趟上海抵达上海虹桥 我是自西向东路线出发。首先抵达交大徐汇饮水思源学校还是非常精致的,位于市中心。貌似徐汇只有经济管理与法学和一些理科专业的接着去了一大会址*新天地 下地铁还要走好一段才到会址里面有个纪念馆。旁边还有个纪念馆 外边都是商圈。新天地还是Lov…

容器

容器 mapfirst:代表键 second:代表值 遍历也可以使用迭代器来访问插入删除(erase)===> 返回删除元素的数量查找功能findupper_bound(返回的迭代器是指向键值大于所给定值的第一个元素) 找到所有价格小于等于 6.8 的商品lower_bound(返回的迭代器是指向键值不小于所给…

【Atcoder训练记录】AtCoder Beginner Contest 393

训练情况忙着处理训练数据,赛后打的,没有排名 赛后反思 这场太典了,感觉我能力范围内都是一眼题,剩下的真不会了 A题 显然有问题的就是 sick或fine补集,对应的交集,如果交集为空答案就是 4,我们直接大力分类讨论,fine fine是 4,sick fine是 2,fine sick是 3,sick si…

C#的GC垃圾回收

空间分配 在讨论垃圾回收之前,需要明白一个重要的事情,空间是怎么被分配出去的。在进程初始化时,CLR会保留一块连续的地址空间(托管堆),托管堆中维护着一个指针,称之为NextObjPtr,它指向下一个对象在堆中的分配位置。当我们在C#中调用new关键字的时候,编译器会自动生成…

ConcurrentHashMap(JDK1.8)put分析

一、ConcurrentHashMap整体结构 ConcurrentHashMap的数据结构与HashMap差不多,都是Node数组+红黑树+链表;ConcurrentHashMap中table的节点类型有 3 类:Node节点,是链表类型的节点;这类节点hash 大于 0 ;在扩容时ConcurrentHashMap会有一个特殊的标志对象:ForwardingNode…

如何接入sbus航模遥控器?

买了航模遥控器不会用sbus?快来快来我来教你呀(滑稽如何接入sbus航模遥控器? 最近队内大疆的遥控器短缺,故自行购买一款便宜好用的遥控器来替代,但是协议与dbus不同,研究了一阵子,所以诞生了这一篇文章来帮助大家少走弯路。 遥控器构成 一般都有发射端和接收端:发射端为…

2/15图论浅讲(知识点)

2/15图论浅讲(知识点) (后期会转移博客,所以排版不太好) 前置知识-vector 动态数组 操作1:创建一个动态数组 vector<数据类型> 数组名字操作2:插入元素 O(logn) 方式1:q.push_back(数据);在数组最后面塞数据 方式2:q.insert(q.begin()+i,a);i为下标,将a数据插入…