2023年第四届 “赣网杯” 网络安全大赛 gwb-web3 Write UP【PHP 临时函数名特性 + 绕过trim函数】

本文主要是介绍2023年第四届 “赣网杯” 网络安全大赛 gwb-web3 Write UP【PHP 临时函数名特性 + 绕过trim函数】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、题目如下:

在这里插入图片描述


二、代码解读:

这段代码是一个简单的PHP脚本,它接受通过GET请求传递的两个参数:‘pass’和’func’:
$password = trim($_GET['pass'] ?? '');:从GET请求中获取名为’pass’的参数,然后使用trim函数去除首尾空格,并将结果赋给变量 $password。如果’pass’参数不存在,则使用空字符串。
$func = trim($_GET['func'] ?? 'hint');:从GET请求中获取名为’func’的参数,然后使用trim函数去除首尾空格,并将结果赋给变量$func。如果’func’参数不存在,则默认使用字符串’hint’。
function hint() {show_source(__FILE__);} :定义了一个名为hint的函数,它的作用是显示当前文件的源代码,使用了show_source函数。
if (md5(\$password)==='21c6008facc283f8839d3b9fed640c15') {:检查通过GET请求传递的’pass’参数的MD5哈希值是否等于指定的值。如果匹配,进入条件块。
function youwin() {echo file_get_contents("/flag");}:在条件成立时,定义了一个名为youwin的函数,它的作用是输出名为’/flag’的文件的内容,使用了file_get_contents函数。
$func();:调用根据’func’参数确定的函数。默认情况下,如果’func’参数不存在,将调用hint函数。


二、解题思路:

常规思路就是绕过 md5 效验。但是这里是强比较,显然无法绕过。尝试参数爆破,看有没有除pass、func 额外的请求参数, bp 跑参数字典:

在这里插入图片描述

果然发现了一个 file 请求参数,使用 readfile() 函数读取文件,尝试任意文件读取:

在这里插入图片描述尝试读取 flag, 发现存在拦截:

在这里插入图片描述

readfile() 可以直接读取 php 文件,且php代码不会被解析

读取当前文件源代码:

在这里插入图片描述尝试绕过 preg_match 正则,传递数组参数:

在这里插入图片描述成功绕过,但是 readfile() 不接受数组作为参数, 网上没找到 readfile() 相关漏洞的文献资料。故放弃…


想起上上周看到 p 牛10月份写的一篇文章,提到了 PHP 临时函数名特性 , 且给的题目案例跟这题很像。 ==> 2023年10月PHP函数小挑战

PHP在编译“函数定义”的时候,会使用 zend_compile_func_decl 函数。这个函数有个关键的参数叫 toplevel,这个参数表示当前的函数定义是否在顶层作用域。

顶层作用域: 顶层作用域通常是指在全局范围内声明的变量、函数或类,而不是在任何函数或控制结构内声明的。

<?php// 在顶层作用域定义的函数
function func1() {echo 'func1';
}if (true) {// 在if条件判断内部定义的函数,不是顶层作用域function func2() {echo 'func2';}
}

当toplevel为true的时候,就是直接将当前函数名 lcname 加入函数表;当 toplevel为false的时候,使用 zend_build_runtime_definition_key 函数生成一个 key,将 key 作为函数名加入函数表。也就是说,根据函数所在的位置的不同(是否是顶级作用域),PHP编译时生成的函数名也会不同。
在这里插入图片描述

key 是按照如下算法生成:

'\0' + name + filename + ':' + start_lineno + '$' + rtd_key_counter

除了第一个 \0 字符,后面四部分的含义如下:

  • name 函数名
  • filename PHP文件绝对路径
  • start_lineno 函数起始定义行号(以1为第一行)
  • rtd_key_counter 一个全局访问计数,每次执行会自增1,从0开始

最后保存在函数表中的函数名,就是上面这个以 \0 开头的字符串。


以上是看 p 牛的文章简要梳理一下核心知识点。但是我发现一个问题:

在这里插入图片描述图中说只要构造:'\0' + name + filename + ':' + start_lineno + '$' + rtd_key_counter 调用就可以了,但是后面图中 payload 又是:
'%00' + name + filename + ':' + start_lineno + '$' + rtd_key_counter 这种方式:

在这里插入图片描述在这里插入图片描述
为什么又变成了 %00 而不是 \0 呢?小小的探究一下:

前提:windows,php 7.4 (要限制7.4版本,稍后会说), vld.dll 内存监控插件 (要下载和php版本相对应的)

本地编写和比赛环境一样的代码,文件名为:965ee283f4c848ad99b0a7961ed89199.php,使用php7.4 配合vld插件解释运行:

 ./php -d vld.execute=0 -d vld.active=1  E:\phpstudy_pro\WWW\php-learn\965ee283f4c848ad99b0a7961ed89199.php

在这里插入图片描述在这里插入图片描述可以看到实际的临时函数名确实是以 %00 开头的。php 底层是由C语言编写的,在C语言中,\0和%00实际上有相似的作用,都表示空字符(null character)。\0是C语言中用于表示空字符的一种方式,通常用在字符串中作为字符串的结束标志。%00通常是在格式化输入输出函数中使用的格式说明符,表示空字符。 我们请求参数被php接收并解释运行,也是一个输入的过程,所以要使用 %00 为开头构建。(个人见解)


为什么要限制 php7.4 这个版本去复现呢?

我尝试使用 php7.3 版本配合vld插件去解释运行相同的代码,得到如下:

在这里插入图片描述在这里插入图片描述不同版本有差异性,7.4 版本结尾更加具有规律性,能爆破。


按照上面的思路,按照 zend_build_runtime_definition_key 的算法计算出 key 作为函数名:(rtd_key_counter 从 0 开始爆破)

%00youwin/var/www/html/965ee283f4c848ad99b0a7961ed89199.php:7$rtd_key_counter

比赛环境没了,本地搭了一个。

发现爆破不出flag:

在这里插入图片描述

trim 函数在接收参数的时候会去除掉字符串首尾的空白字符。可以加反斜杠绕过:\%00

故要改写成如下:

\%00youwin/var/www/html/965ee283f4c848ad99b0a7961ed89199.php:7$rtd_key_counter

bp 开始爆破 rtd_key_counter 得 flag:

在这里插入图片描述

这篇关于2023年第四届 “赣网杯” 网络安全大赛 gwb-web3 Write UP【PHP 临时函数名特性 + 绕过trim函数】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

从去中心化到智能化:Web3如何与AI共同塑造数字生态

在数字时代的演进中,Web3和人工智能(AI)正成为塑造未来互联网的两大核心力量。Web3的去中心化理念与AI的智能化技术,正相互交织,共同推动数字生态的变革。本文将探讨Web3与AI的融合如何改变数字世界,并展望这一新兴组合如何重塑我们的在线体验。 Web3的去中心化愿景 Web3代表了互联网的第三代发展,它基于去中心化的区块链技术,旨在创建一个开放、透明且用户主导的数字生态。不同于传统

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

如何做好网络安全

随着互联网技术的飞速发展,网站已成为企业对外展示、交流和服务的重要窗口。然而,随之而来的网站安全问题也日益凸显,给企业的业务发展和用户数据安全带来了巨大威胁。因此,高度重视网站安全已成为网络安全的首要任务。今天我们就来详细探讨网站安全的重要性、面临的挑战以及有什么应对方案。 一、网站安全的重要性 1. 数据安全与用户隐私 网站是企业存储和传输数据的关键平台,包括用户个人信息、

ActiveMQ—消息特性(延迟和定时消息投递)

ActiveMQ消息特性:延迟和定时消息投递(Delay and Schedule Message Delivery) 转自:http://blog.csdn.net/kimmking/article/details/8443872 有时候我们不希望消息马上被broker投递出去,而是想要消息60秒以后发给消费者,或者我们想让消息没隔一定时间投递一次,一共投递指定的次数。。。 类似

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据