关于 CTF 中 php 考点与绕过那些事的总结

关于 CTF 中常见 php 绕过的总结可以参考我之前的博客:

CTF之PHP特性与绕过

PHP特性之CTF中常见的PHP绕过-CSDN博客

其中主要介绍了 md5()、sha1()、strcmp、switch、intval、$_SERVER 函数、三元运算符、strpos() 、数组、非法参数名传参等相关的绕过。

在此基础上我们进行一些其他补充

目录

1、PHP 系统预定义变量(超全局变量)

2、 PHP 错误控制运算符

3、PHP 变量默认值

4、$_GET 和 $_POST

5、内置函数的松散性

(1)php 弱类型

(2)array_search 函数 与 in_array 函数

(3)switch 函数

(4)is_numeric 函数

(5)ereg 函数

(6)preg_match 函数

(7)extract 变量覆盖

(8)parse_str 函数变量覆盖缺陷

(9)$$ 变量覆盖

(10)unset 函数

(11)mt_rand() 伪随机数

(12)rand() 函数


1、PHP 系统预定义变量(超全局变量)

$_POST //获取post数据,是一个字典$_GET //获取get数据,是一个字典$_COOKIE //获取cookie数据$_SESSION //获取session数据$_FILES //获取上传的文件$_REQUEST //获取$_GET, $_POST, $_COOKIE中的数据$_SERVER //用户和服务器的基本信息数据库$_ENV //环境数据$GLOBALS //所有全局变量

2、 PHP 错误控制运算符

PHP 支持一个错误控制运算符:@

当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。

(阻止错误信息显示在用户的界面上,并继续执行代码)

测试代码:

由于文件不存在,file_get_contents() 函数将会产生一个警告

<?php// 启用错误报告
error_reporting(E_ALL);
ini_set('display_errors', 1);$file = 'nonexistentfile.txt';// 如果文件不存在,则会触发警告
$content = file_get_contents($file);if ($content !== false) {echo "文件内容:$content";
} else {echo "无法读取文件或文件不存在!";
}?>

运行结果: 

下面我们使用 @ 来抑制错误信息的显示

@ 符号直接加在可能导致错误的函数或表达式前面

运行结果:

3、PHP 变量默认值

在PHP中,各种类型的变量在被定义但未被赋值时,它们的默认值如下:

整数 (integer):默认值为0。


浮点数 (float):默认值为0.0。


字符串 (string):默认值为空字符串 ''。


布尔值 (boolean):默认值为false。


数组 (array):默认值为一个空数组 array()。


对象 (object):默认值为一个空对象。

4、$_GET 和 $_POST

如果 GET 参数中设置 name[]=a,那么 $_GET['name'] = [a],php 会把 []=a 当成数组传入, $_GET 会自动对参数调用 urldecode 函数进行 URL 解码。

$_POST 同样存在这样的漏洞,提交的表单数据,user[]=admin,$_POST['user'] 得到的是['admin'],是一个数组。

5、内置函数的松散性

关于 md5()、sha1()、strcmp、switch()、intval()、strpos() 等函数我们在前面的文章中已经进行过例题的演示和讲解,这里不再过多赘述,下面我们进行补充。

(1)php 弱类型

php 中有两种比较的符号: == 与 ===

=== 是严格相等运算符,在进行比较时,会先判断两种字符串的类型是否相等,再比较;

== 是相等运算符,在进行比较时,会先将字符串类型转化成相同,再比较,比如比较一个数字和字符串或者比较涉及到数字内容的字符串,字符串会被转换成数值并按照数值来进行比较

先来看一个测试:

<?phpvar_dump("myon" == 0);
var_dump("1myon" == 1);
var_dump("myon1" == 0);
var_dump("m1y2o3n4" == 0);
var_dump("0e12345" == "0e6789");?>

运行结果: 

从运行结果我们可以看到,所有比较均为 true 

"myon" == 0 比较时,会将 myon 转化成数值,强制转化成数值,由于 myon 是字符串,转化的结果是 0 ,自然和 0 是相等的;

第二个 "1myon" == 1 可推断出比较时将 1myon 转化成数值,结果为 1;

但是第三个 "myon1" == 0 ,为什么比较时 myon1 会被转化成 0 呢?

查了 php 手册得知:

当一个字符串被当作一个数值来取值,其结果和类型如下:如果该字符串没有包含
'.','e','E'并且其数值值在整形的范围之内,该字符串被当作 int 来取值,其他所有情
况下都被作为 float 来取值,该字符串的开始部分决定了它的值,如果该字符串以合
法的数值开始,则使用该数值,否则其值为 0。

因此 "m1y2o3n4" == 0 中,m1y2o3n4 也被转化成了 0 ;

至于为什么 "0e12345" == "0e6789",在比较时,会将 0e 这类字符串识别为科学计数法的数字,0 的无论多少次方都是零,所以相等。

(2)array_search 函数 与 in_array 函数

array_search() 函数用于在数组中搜索指定的值,如果找到则返回其键,否则返回 false。

语法:array_search(value,array,strict)

参数描述
value必需。规定在数组中搜索的键值。
array必需。规定被搜索的数组。
strict可选。如果该参数被设置为 TRUE,则函数在数组中搜索数据类型和值都一致的元素。可能的值:
  • true
  • false - 默认
如果设置为 true,则在数组中检查给定值的类型,比如数字 5 和字符串 5 是不同的。

这样一看 array_search 函数其实就类似于 == (在第三个参数为 false 的情况下)

测试代码:

<?php$a = array(0,1);
var_dump(array_search("myon",$a));
var_dump(array_search("1myon",$a));?>

运行结果:

可以看到 myon 被转化成了 0 ;

1myon 则被转化成了 1 ;

与我们前面使用 == 测试的效果一样。

in_array() 函数用于搜索数组中是否存在指定的值,如果找到指定的值,则返回 true,否则返回 false。

语法:bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

参数描述
needle必需。规定要在数组搜索的值。
haystack必需。规定要搜索的数组。
strict可选。如果该参数设置为 TRUE,则 in_array() 函数检查搜索的数据与数组的值的类型是否相同。

基本功能是一样的,因此绕过方法也是一样的,同上。

(3)switch 函数

如果 switch 是数字类型的 case 的判断时, switch 会将其中的参数转换为 int 类型。

测试代码:

<?php$content = "2myon";switch ($content) {case 0:case 1:case 2:echo "content 小于3";break;case 3:echo "content 是3";break;default:echo "没有匹配";
}?>

运行结果:

输出的是content 小于3,是由于 switch() 函数将 $content 进行了类型转换,转换结果为 2。

如果 $content = "m2yon" ,则转换结果为 0。

(4)is_numeric 函数

PHP 提供了 is_numeric 函数,用于检测变量是否为数字或数字字符串。但是函数的范围比较广 泛,不仅仅是十进制的数字,它还可以识别其他进制的数字字符串,以及科学计数法表示的数字等。

测试代码:

<?phpvar_dump(is_numeric(123));
var_dump(is_numeric('123'));
var_dump(is_numeric(0x7e));
var_dump(is_numeric('0x7e'));
var_dump(is_numeric(0e123));
var_dump(is_numeric('0e123'));?>

运行结果:

原本我以为都会返回 true 

但是十六进制的字符型返回了 false

而科学计数法 0e 开头的数字则是都返回的 true

对于数字和字母组合的字符串,无论是否以数字开头,都是返回 false

因此我们可以将 payload 转换为其他进制传入,或者传入 0e 开头的参数来实现绕过。

(5)ereg 函数

ereg() 函数用于进行正则表达式的匹配,不过它已经在PHP 5.3.0中被废弃。

关于它的两个特性:

ereg() 只能处理字符串,遇到数组会返回null,null !== false;

当 ereg() 读到 %00 的时候,就截止了。

(6)preg_match 函数

preg_match 函数用于执行一个正则表达式匹配。

用法:preg_match(pattern, input, matches, flags, offset)

参数描述
pattern必需。包含一个正则表达式,指示要搜索的内容
input必需。将在其中执行搜索的字符串
matches可选。此参数中使用的变量将填充一个包含所有找到的匹配项的数组
flags可选。一组改变匹配数组结构的选项:
  • PREG_OFFSET_CAPTURE - 启用此选项后,每个匹配项将不是一个字符串,而是一个数组,其中第一个元素是包含匹配项的子字符串,而 第二个元素是输入中子字符串的第一个字符的位置。
  • PREG_UNMATCHED_AS_NULL - 启用此选项后,不匹配的子模式将返回为 NULL 而不是空字符串。
offset可选。默认为 0。指示开始搜索到字符串的深度。 preg_match() 函数不会找到出现在此参数中给定位置之前的匹配项

关于这个函数的一些特性与绕过:

preg_match 只能处理字符串,当传入数组时会返回 false;

测试代码:

我们匹配字符 world,原本是能匹配到的,但是由于我们传入的是数组,则会直接匹配失败。

<?php$pattern = '/world/';
$string = array('hello', 'world');
$result = preg_match($pattern, $string);
var_dump($result); 

运行结果:

回溯绕过:pcre.backtrack_limit 给 pcre 设定了一个回溯次数上限,默认为1000000,如果回溯次数超过这个数字,preg_match 就会返回 false,即匹配失败,从而绕过正则匹配。

%0a 换行绕过:.不会匹配换行符,并且在非多行模式下,当出现换行符 %0a 的时候,会被当做两行处理,而此时只可以匹配第一行,后面的行就会被忽略。(原因其实是正则书写不当)

(7)extract 变量覆盖

extract() 函数从数组中把变量导入到当前的符号表中。对于数组中的每个元素, 键名用于变量名,键值用于变量值。

例子:

<?php$flag='flag.php';
extract($_GET);  
if(isset($ceshi))
{$content=trim(file_get_contents($flag));
if($ceshi==$content)
{echo'flag{xxxxxxx}';
}
else
{echo'Oh.no';
}
}?>

大致分析是要求我们GET传参进去值会经过extract()函数,下来会有两个if,第一个 if 判断 ceshi 这个变量是否存在,存在则继续执行 if 里面的,使用 file_get_contents() 读取 flag 变量里面的文件传递给 content 变量 之后,再进行判断传进来 ceshi 变量的值等不等于 $content,如果等于则打印出 flag 。

因为通过extract()函数我们传进的值会变成一个变量,例如我们GET传入 ceshi=1 ,则会存在$ceshi=1 ,所以我们构造 GET 传参 pyaload:

$ceshi=&$flag=  

这样就会有两个为空的变量,而 $flag=空 则覆盖了上面的 $flag 中的值,进行判断都是空,所以为真,则可以得到 flag 。

(8)parse_str 函数变量覆盖缺陷

parse_str() 的作用是解析字符串,并注册成变量。在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉已有变量。与 parse_str() 类似的函数还有 mb_parse_str(),parse_str 会将字符串解析成多个变量,如果参数 str 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域。

这里我们也来看一个例子:

$a = "test123";
$b = $_GET['b'];
@parse_str($b);
if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO')) {echo $flag;

虽然 a 的值看似已经固定,但是我们可以利用变量覆盖对 a 进行重新赋值

构造 payload:

(这里还利用了 md5 的缺陷,它会把每个以0E开头的哈希值都解释为0

?b=a[0]=s878926199a

(9)$$ 变量覆盖

如果把变量本身的 key 也当变量,也就是使用了 $$,就可能存在问题。

(10)unset 函数

unset($bar) 用来销毁指定的变量,如果变量 $bar 包含在请求参数中,可能出 现销毁一些变量而实现程序逻辑绕过。

(11)mt_rand() 伪随机数

mt_rand() 函数是一个伪随机发生器,即如果知道随机数种子是可以预测的。

linux 64 位系统中,rand() 和 mt_rand() 产生的最大随机数都是 2147483647,正好是 2^31-1,也就是说随机播种的种子也是在这个范围中的, 0 – 2147483647 的这个范围是可以爆破的。 但是用 php 爆破比较慢,有一个 C 的版本,可以根据随机数,爆破出种子 php_mt_seed。

在 php > 4.2.0 的版本中,不再需要用 srand() 或 mt_srand() 函数给随机数 发生器播种,现已由 PHP 自动完成。php 中产生一系列的随机数时,只进行了一 次播种,而不是每次调用 mt_rand() 都进行播种。

(12)rand() 函数

在使用 rand() 函数生成随机数时,如果没有先调用 srand() 函数来设置随机数种子,生成的随机数会遵循伪随机数生成算法,其生成的随机数序列就会有规律可循。

此外,关于 PHP 代码相关的漏洞还有文件包含、RCE、反序列化等,关于这些漏洞的利用方法与绕过技巧,可以参考我之前 web 专栏的博客。

创作不易,期待大家的关注与支持!

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

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

相关文章

Linux系统使用宝塔面板安装MySQL服务并实现公网远程访问本地数据库【内网穿透】

文章目录 前言1.Mysql服务安装2.创建数据库3.安装cpolar3.2 创建HTTP隧道 4.远程连接5.固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 宝塔面板的简易操作性,使得运维难度降低,简化了Linux命令行进行繁琐的配置,下面简单几步,通过宝塔面板cp…

在Java中处理JSON数据:Jackson与Gson库比较

引言 JSON&#xff0c;作为一种轻量级的数据交换格式&#xff0c;因其易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;而被广泛应用于网络通信和配置文件中。在Java中&#xff0c;有两个强大的工具帮助咱们处理JSON数据——Jackson和Gson。这两个库各有千秋…

从零开始写 Docker(四)---使用 pivotRoot 切换 rootfs 实现文件系统隔离

本文为从零开始写 Docker 系列第四篇&#xff0c;在mydocker run 基础上使用 pivotRoot 系统调用切换 rootfs 实现容器和宿主机之间的文件系统隔离。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&…

javascript作用域编译浅析

作用域思维导图 1&#xff1a;编译原理 分词/词法分析 如果词法单元生成器在判断a是一个独立的词法单元还是其他词法单元的一部分时&#xff0c;调用的是有状态的解析规则&#xff0c;那么这个过程就被称为词法分析。 解析/语法分析 由词法单元流转换成一个由元素逐级嵌套所组…

期货开户交易软件如何下单?

一、手机和电脑使用的交易软件 目前期货市场常用的软件有文华、博弈、快期、易盛、同花顺等&#xff0c;这5款电脑软件对应的手机端是文华随身行、博弈手机版、快期小Q、易盛易星、同花顺期货通&#xff0c;这些常用软件大部分期货公司都是支持的。 二、交易软件如何下单 软…

C打印内存16进制

下面是一段C代码打印16进制 void print_hex(const char *msg, void *addr, int len) {uint8_t *p (uint8_t *)addr;printf("%s ,stat:%0x8, len:%d\n", msg, addr, len);for (int i 0; i < len / 16; i) {printf("0x%08x: ", p i * 16);for (int j …

【音视频开发好书推荐】《RTC程序设计:实时音视频权威指南》

1、WebRTC概述 WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个由Google发起的实时音视频通讯C开源库&#xff0c;其提供了音视频采集、编码、网络传输&#xff0c;解码显示等一整套音视频解决方案&#xff0c;我们可以通过该开源库快速地构建出一个音视频通…

【小黑嵌入式系统第十七课】结课总结(一)——硬件部分(系统总线处理器外设通信)

上一课&#xff1a; 【小黑嵌入式系统第十六课】PSoC 5LP第三个实验——μC/OS-III 综合实验 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能 文章目录 一、基础知识…

2024新版SonarQube+JenKins+Github联动代码扫描(1)-JenKins安装与配置

文章目录 前言一、官网下载二、访问ip:port三、安装推荐插件-自动下载四、创建用户名密码五、安装SonarQube插件六、配置全局工具总结 前言 Sonar是一个半开源的静态代码扫描工具&#xff0c;试用过一次觉得功能还算可以&#xff0c;所以记录一下SonarQube扫描的用法以及在中大…

IO接口 2月5日学习笔记

1.fgetc 用于从文件中读取一个字符&#xff0c;fgetc 函数每次调用将会返回当前文件指针所指向的字符&#xff0c;并将文件指针指向下一个字符。 int fgetc(FILE *stream); 功能: 从流中读取下一个字符 参数: stream:文件流指针 返回值: …

5分钟速成渐变色css

色彩的分支——渐变色定义&#xff1a;按照一定规律做阶段性变化的色彩&#xff08;抽象&#xff01;&#xff01;&#xff01;&#xff09; 我们可以将图片分为两块 以中心线为参考&#xff0c;再来看渐变色的定义&#xff1a;按照一定规律做阶段性变化的色彩 既然是按一定的…

使用Android Native Hook技术解决VLC播放器闪退的问题

文章目录 1.概述2.问题描述3.问题分析4.问题解决5.总结 1.概述 在做公司的一个TOB的需求时&#xff0c;发现调起Unity提供的3D播放器播放网络在线视频时闪退了&#xff0c;然后就拉着相关部门的人一起分析问题&#xff0c;最后定位到是VLC里面用到的系统日志打印函数在部分的系…

动态代理IP的并发处理技巧

目录 前言 一、什么是动态代理IP&#xff1f; 二、动态代理IP的并发处理技巧 1. 获取代理IP 2. 动态生成代理对象 3. 并发处理 总结 前言 在进行网络爬虫开发时&#xff0c;经常会遇到限制IP访问频率的情况。为了突破这个限制&#xff0c;我们可以通过使用代理IP来实现…

华为配置基于VLAN限速示例

华为配置基于VLAN限速示例 组网图形 图1 流量监管配置组网图 表1 Switch为上行流量提供的QoS保障 流量类型 CIR(kbps) PIR(kbps) DSCP优先级 语音 2000 10000 46 视频 4000 10000 30 数据 4000 10000 14 ^^^ 流分类简介配置注意事项组网需求配置思路操作步…

C#与欧姆龙PLC实现CIP通讯

参考文档&#xff1a; 欧姆龙PLC使用-CSDN博客 CIP通讯介绍&#xff08;欧姆龙PLC&#xff09;-CSDN博客 使用NuGet添加引用&#xff1a;CIPCompolet 基础参考我的CIP协议介绍&#xff0c;默认TCP端口为&#xff1a;44818 类NXCompolet 类的功能可以在安装PLC开发软件后帮…

vue svelte solid 虚拟滚动性能对比

前言 由于svelte solid 两大无虚拟DOM框架&#xff0c;由于其性能好&#xff0c;在前端越来越有影响力。 因此本次想要验证&#xff0c;这三个框架关于实现表格虚拟滚动的性能。 比较版本 vue3.4.21svelte4.2.12solid-js1.8.15 比较代码 这里使用了我的 stk-table-vue(np…

web坦克大战小游戏

H5小游戏源码、JS开发网页小游戏开源源码大合集。无需运行环境,解压后浏览器直接打开。有需要的订阅后,私信本人,发源码,含60+小游戏源码。如五子棋、象棋、植物大战僵尸、贪吃蛇、飞机大战、坦克大战、开心消消乐、扑鱼达人、扫雷、打地鼠、斗地主等等。 <!DOCTYPE htm…

【图论】Dijkstra 算法求最短路 - 构建邻接矩阵(带权无向图)

文章目录 例题&#xff1a;到达目的地的方案数题目描述代码与解题思路构建带权无向图的邻接矩阵 例题&#xff1a;到达目的地的方案数 题目链接&#xff1a;1976. 到达目的地的方案数 题目描述 代码与解题思路 func countPaths(n int, roads [][]int) int {g : make([][]int…

数据库和缓存如何保持一致性

目录 前言 更新数据库更新缓存&#xff1a; 1.在更新缓存前先加一个分布式锁 2.在更新完缓存时&#xff0c;给缓存加上较短的过期时间 Cache Aside策略 1.先删除缓存&#xff0c;再更新数据库 延迟双删 2.先更新数据库&#xff0c;再删除缓存 保证两个操作都能执行成功…

【译】WordPress Bricks主题安全漏洞曝光,25,000个安装受影响

WordPress的Bricks主题存在一个严重的安全漏洞,恶意威胁行为者正在积极利用该漏洞在易受攻击的安装上运行任意PHP代码。 该漏洞被跟踪为CVE-2024-25600(CVSS评分:9.8),使未经身份验证的攻击者能够实现远程代码执行。它影响Bricks的所有版本,包括1.9.6版本及更早版本。 该…