PHP的两个特性导致waf绕过注入(有趣的知识点)

2024-06-16 03:32

本文主要是介绍PHP的两个特性导致waf绕过注入(有趣的知识点),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、HPP HTTP参数污染
HTTP参数污染指的是,在URL中提交相同键值的两个参数时,服务器端一般会进行一些处理。比如Apache就要以最后一个参数为准,比如:
user.php?id=111&id=222
如果输出$_GET数组,则id的值只会取222,即URL上提交的多余值覆盖了前一个值。

2、一个CTF题目
http://drops.wooyun.org/tips/17248

关于注入的waf绕过,注入点为:

$sql="select * from user where id=".$_REQUEST["id"].";";
可以看到了REQUEST进行传递,并且存在如下的waf代码:

functionwaf($str) {if(stripos($str,"select")!==false)die("Be a good person!");if(stripos($str,"union")!==false)die("Be a good person!");......
}  functionwafArr($arr) {foreach($arras$k=> $v) {waf($k);waf($v);}
}  wafArr($_GET);
wafArr($_POST);
wafArr($_COOKIE);
wafArr($_SESSION); functionstripStr($str) {if(get_magic_quotes_gpc())$str= stripslashes($str);returnaddslashes(htmlspecialchars($str, ENT_QUOTES, 'UTF-8'));
}  $uri= explode("?",$_SERVER['REQUEST_URI']);
if(isset($uri[1])) {$parameter= explode("&",$uri[1]);foreach($parameteras$k=> $v) {$v1= explode("=",$v);if(isset($v1[1])) {$_REQUEST[$v1[0]] = stripStr($v1[1]);}}
}  functionstripArr($arr) {$new_arr= array();foreach($arras$k=> $v) {$new_arr[stripStr($k)] = stripStr($v);}return$new_arr;
}  $_GET=stripArr($_GET);
$_POST=stripArr($_POST);
$_COOKIE=stripArr($_COOKIE);
$_SESSION=stripArr($_SESSION);

这里使用了waf函数分别对GET POST SESSION COOKIE数据进行过滤,并且对这些全局数组进行转义。
值得注意的是,这里的$_REQUEST是代码中重新根据$_SERVER['REQUEST_URI']进行拼接,在拼接过程中将参数值进行转义操作。
(1)思路1  使用HPP特性
看似不太可能存在注入,但是使用HPP可以实现。
示例代码:
user.php?id=0 or 1&id%00=1
user.php?id=0 or 1&%20id=1
user.php?id=0 or 1?&id=1
测试代码:

<?php function stripArr($arr) {$new_arr = array();foreach ($arr as $k => $v) {$new_arr[stripStr($k)] = stripStr($v);}return $new_arr;
}function stripStr($str) {if (get_magic_quotes_gpc())$str = stripslashes($str);return addslashes(htmlspecialchars($str, ENT_QUOTES, 'UTF-8'));
}$uri = explode("?",$_SERVER['REQUEST_URI']);
if(isset($uri[1])) {$parameter = explode("&",$uri[1]);foreach ($parameter as $k => $v) {$v1 = explode("=",$v);if (isset($v1[1])) {$_REQUEST[$v1[0]] = stripStr($v1[1]);}}
}
var_dump($_GET) ;var_dump($_REQUEST) ;?>
输出结果:

可以看到,这里的GET数组取到了最后一个值,不会触发waf,而REQUEST数据中,id则为我们的注入语句,这样
利用这两者之间的差异,我们可以绕过waf函数的检测,并且利用之前的注入点来实现注入。

(2)思路2: 利用#特性($_SERVER['REQUEST_URI'])
在浏览器中,是不会将#号之后的hash内容发送给服务器的,这里利用burp发包,可以将hash的内容发送至服务器,比如发送:
/#?id=1
这里GET数组为空,REQUEST则输出为/#?id=1,这样,就可以绕过waf函数对GET数组的判断,
并且在REQUEST(这里主要因为REQUEST数组是使用了REQUEST_URI进行了重组)中携带注入的语句,绕过了waf检测。

3、总结
这种特性导致的漏洞场景比较特殊,首先,CTF中模拟的场景是waf函数只对GET,POST,SESSION,COOKIES全局数组进行的处理,注入点为REQUEST,在场景中,代码对REQUEST数组通过$_SERVER['REQUEST_URI'],使用&分割重新组装的,这种代码处理可能是由于程序员想对REQUEST数组进行转义或者一些净化处理才加进来的。
利用:
(1)HPP特性,提交重复参数内容,PHP处理参数时会覆盖,但是程序拼接时会出现差异,
比如提交:http:// 127.0.0.1/shell.php?id=0 or 1&id%00=1
GET为id=1,REQUEST为:
  'id' =>string'0%20or%201'(length=10)'id%00' =>string'1'(length=1)
可以看到,成功将注入内容引入到REQUEST数组中。
(2)利用#符号,#后面的内容不会带入至GET数组中,但是会出现在REQUEST_URI中,所以可以利用这个特性将注入语句带入到REQUEST对象中。
总之,这种特性导致的漏洞场景比较特殊,但是确实比较有趣。

这篇关于PHP的两个特性导致waf绕过注入(有趣的知识点)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1065361

相关文章

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Spring Boot3.0新特性全面解析与应用实战

《SpringBoot3.0新特性全面解析与应用实战》SpringBoot3.0作为Spring生态系统的一个重要里程碑,带来了众多令人兴奋的新特性和改进,本文将深入解析SpringBoot3.0的... 目录核心变化概览Java版本要求提升迁移至Jakarta EE重要新特性详解1. Native Ima

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

Maven 配置中的 <mirror>绕过 HTTP 阻断机制的方法

《Maven配置中的<mirror>绕过HTTP阻断机制的方法》:本文主要介绍Maven配置中的<mirror>绕过HTTP阻断机制的方法,本文给大家分享问题原因及解决方案,感兴趣的朋友一... 目录一、问题场景:升级 Maven 后构建失败二、解决方案:通过 <mirror> 配置覆盖默认行为1. 配置示

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

JDK9到JDK21中值得掌握的29个实用特性分享

《JDK9到JDK21中值得掌握的29个实用特性分享》Java的演进节奏从JDK9开始显著加快,每半年一个新版本的发布节奏为Java带来了大量的新特性,本文整理了29个JDK9到JDK21中值得掌握的... 目录JDK 9 模块化与API增强1. 集合工厂方法:一行代码创建不可变集合2. 私有接口方法:接口