1.攻防世界easyphp

news/2025/2/3 3:56:13 标签: 网络, web安全, 安全, 网络安全, php, 代码复审

进入题目页面如下

是一段PHP代码进行代码审计

php"><?php
// 高亮显示PHP文件源代码
highlight_file(__FILE__);

// 初始化变量$key1和$key2为0
$key1 = 0;
$key2 = 0;

// 从GET请求中获取参数'a'的值,并赋值给变量$a
$a = $_GET['a'];
// 从GET请求中获取参数'b'的值,并赋值给变量$b
$b = $_GET['b'];
// 检查是否在GET请求中存在,并且将$a转换为整数后大于6000000,同时$a的字符串长度小于等于3
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
    // 检查变量$b是否被设置,并且$b的MD5哈希值的最后6位等于'8b184b'
    if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
        // 如果上述条件都满足,将$key1的值设置为1
        $key1 = 1;
    }else{
        // 如果$b不满足条件,输出提示信息并终止脚本执行
        die("Emmm...再想想");
    }
}else{
    // 如果$a不满足条件,输出提示信息并终止脚本执行
    die("Emmm...");
}

// 从GET请求中获取参数'c'的值,使用json_decode函数将其解码为数组,并将结果强制转换为数组类型,赋值给变量$c
$c=(array)json_decode(@$_GET['c']);

// 检查$c是否为数组,并且$c数组中的键'm'对应的值不是数字类型,同时该值大于2022
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
    // 检查$c数组中的键'n'对应的值是否为数组,并且该数组的元素个数为2,同时数组的第一个元素也是数组
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        // 在$c["n"]数组中搜索值为'DGGJ'的元素,并返回其键名,赋值给变量$d
        $d = array_search("DGGJ", $c["n"]);
        // 如果没有找到值为'DGGJ'的元素,输出提示信息并终止脚本执行
        $d === false?die("no..."):NULL;
        // 遍历$c["n"]数组,检查是否有元素的值直接等于'DGGJ'
        foreach($c["n"] as $key=>$val){
            // 如果有元素的值等于'DGGJ',输出提示信息并终止脚本执行
            $val==="DGGJ"?die("no......"):NULL;
        }
        // 如果上述条件都满足,将$key2的值设置为1
        $key2 = 1;
    }else{
        // 如果$c["n"]不满足条件,输出提示信息并终止脚本执行
        die("no hack");
    }
}else{
    // 如果$c不满足条件,输出提示信息并终止脚本执行
    die("no");
}

// 检查$key1和$key2的值是否都为1,如果都为1,则表示所有条件都满足
if($key1 && $key2){
    // 包含名为'Hgfks.php'的文件
    include "Hgfks.php";
    // 输出成功提示
    echo "You're right"."\n";
    // 输出$flag变量的值
    echo $flag;
}

?>

重点看以下几行代码

php">// 检查是否在GET请求中存在,并且将$a转换为整数后大于6000000,同时$a的字符串长度小于等于3
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
    // 检查变量$b是否被设置,并且$b的MD5哈希值的最后6位等于'8b184b'
    if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
        // 如果上述条件都满足,将$key1的值设置为1
        $key1 = 1;


// 检查$key1和$key2的值是否都为1,如果都为1,则表示所有条件都满足
if($key1 && $key2){
    // 包含名为'Hgfks.php'的文件
    include "Hgfks.php";
    // 输出成功提示
    echo "You're right"."\n";
    // 输出$flag变量的值
    echo $flag;

可以知道当$key1和$key2值都为真时,输出flag

先构造$key1,通过GET传参a、b的值

$a需满足字符串长度小于等于3且值要大于6000000

常规的十进制数字表示中,要同时满足字符串长度小于等于 3 且值大于 6000000 是不可能的。但在 PHP 中,存在特殊的类型转换规则,我们可以借助科学计数法来绕过这个限制

在 PHP 里,当使用 intval() 函数转换字符串时,科学计数法表示的字符串会被正确转换为对应的整数。比如,字符串 "6e6" 代表 ,也就是 6000000。

需要大于6000000,则可以令$a的值为“7e6”、“8e6”、“9e6”等

$b的MD5哈希值的最后6位等于'8b184b'

用python写一个脚本爆破出$b的值,脚本如下

import hashlib
# 目标 MD5 哈希值的最后 6 位
target_suffix = '8b184b'
# 从一个简单的字符集开始生成字符串进行尝试
charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
length = 1
while True:
    from itertools import product
    # 生成所有可能的长度为 length 的字符串组合
    for combination in product(charset, repeat=length):
        s = ''.join(combination)
        # 计算字符串的 MD5 哈希值
        md5_hash = hashlib.md5(s.encode()).hexdigest()
        # 检查哈希值的最后 6 位是否等于目标后缀
        if md5_hash[-6:] == target_suffix:
            print(f"找到符合条件的字符串: {s}")
            print(f"其 MD5 哈希值为: {md5_hash}")
            break
    else:
        # 如果当前长度的所有组合都没有找到符合条件的字符串,增加长度继续尝试
        length += 1
        continue
    break

可以用pycharm来执行,结果如下

得到$b的值为bDIOS

将a、b的值通过get传参,并查看输出

构造的payload为

?a=9e6&&b=bDIOS

看到输出的结果改变,$key1以及构造成功,下面构造$key2

重点看以下几行代码

php">// 从GET请求中获取参数'c'的值,使用json_decode函数将其解码为数组,并将结果强制转换为数组类型,赋值给变量$c
$c=(array)json_decode(@$_GET['c']);

// 检查$c是否为数组,并且$c数组中的键'm'对应的值不是数字类型,同时该值大于2022
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
    // 检查$c数组中的键'n'对应的值是否为数组,并且该数组的元素个数为2,同时数组的第一个元素也是数组
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        // 在$c["n"]数组中搜索值为'DGGJ'的元素,并返回其键名,赋值给变量$d
        $d = array_search("DGGJ", $c["n"]);
        // 如果没有找到值为'DGGJ'的元素,输出提示信息并终止脚本执行
        $d === false?die("no..."):NULL;
        // 遍历$c["n"]数组,检查是否有元素的值直接等于'DGGJ'
        foreach($c["n"] as $key=>$val){
            // 如果有元素的值等于'DGGJ',输出提示信息并终止脚本执行
            $val==="DGGJ"?die("no......"):NULL;
        }
        // 如果上述条件都满足,将$key2的值设置为1
        $key2 = 1;

需要通过上传json形式的c来实现

外层条件
php">if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022)
  • is_array($c):$c必须是一个数组。通过 json_decode 解析 $_GET['c'] 得到的结果要能被强制转换为数组

  • !is_numeric(@$c["m"]):$c 数组中的键 "m" 对应的值不能是一个数字。这里使用 @ 符号来抑制可能出现的未定义索引警告

  • $c["m"] > 2022:虽然 $c["m"] 不是数字,但在进行比较时,PHP 会尝试将其转换为数字进行比较。可以利用 PHP 的类型转换规则,使用以数字开头的字符串来满足这个条件。

 由于is_numberic会将数字和数字字符串判定为真,但前导数字字符串不会以及>是弱类型比较,且是将c['m']的值与数字进行比较,我们可以直接用前导字符串来作为比较数字与2022进行比较。所以令c['m']='2025a'

键n值要满足:有且仅有两个元素的数组,第一个值为数组,第二个值要满足array_search("DGGJ", $c["n"])返回为真,同时c["n"]中又不能出现"DGGJ"。

可以利用array_search函数在比较两者是否相等时是使用的弱类型比较。由于"DGGJ"是既非数字字符串又非先导数字字符串的字符串,其在与数字进行比较时会转化为数字0。从而令c['n']的第二个值为0。(一点思考:此处若不是'DGGJ'而是其他字符串时,我们应该视情况而定,选择合适的数字)所以令c['n']=(array(1,2),0)

内层条件

if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0]))
  • is_array(@$c["n"])$c 数组中的键 "n" 对应的值必须是一个数组

  • count($c["n"]) == 2:这个数组的元素个数必须为 2

  • is_array($c["n"][0]):数组 $c["n"] 的第一个元素也必须是一个数组

所以最后构造的$c的payload为:c={"m":"2025a","n":[[1,2],0]}

最后传参a、b、c构造payload

?a=8e6&&b=bDIOS&&c={"m":"2025a","n":[[1,2],0]}

最终得到flag


http://www.niftyadmin.cn/n/5840469.html

相关文章

Cesium+Vue3教程(011):打造数字城市

文章目录 Cesium打造数字城市创建项目加载地球设置底图设置摄像头查看具体位置和方向添加纽约建筑模型并设置样式添加纽约建筑模型设置样式划分城市区域并着色地图标记显示与实现实现飞机巡城完整项目下载Cesium打造数字城市 创建项目 使用vite创建vue3项目: pnpm create v…

MySQL(InnoDB表空间工具innodb_ruby)

后面也会持续更新&#xff0c;学到新东西会在其中补充。 建议按顺序食用&#xff0c;欢迎批评或者交流&#xff01; 缺什么东西欢迎评论&#xff01;我都会及时修改的&#xff01; Jeremy Cole的博客&#xff1a;blog.jcole.us/innodb/ ruby安装后 -bash: gem: command not fou…

当卷积神经网络遇上AI编译器:TVM自动调优深度解析

从铜线到指令&#xff1a;硬件如何"消化"卷积 在深度学习的世界里&#xff0c;卷积层就像人体中的毛细血管——数量庞大且至关重要。但鲜有人知&#xff0c;一个简单的3x3卷积在CPU上的执行路径&#xff0c;堪比北京地铁线路图般复杂。 卷积的数学本质 对于输入张…

Qt u盘自动升级软件

Qt u盘自动升级软件 Chapter1 Qt u盘自动升级软件u盘自动升级软件思路&#xff1a;step1. 获取U盘 判断U盘名字是否正确&#xff0c; 升级文件是否存在。step2. 升级step3. 升级界面 Chapter2 Qt 嵌入式设备应用程序&#xff0c;通过U盘升级的一种思路Chapter3 在开发板上运行的…

【ts + java】古玩系统开发总结

src别名的配置 开发中文件和文件的关系会比较复杂&#xff0c;我们需要给src文件夹一个别名吧 vite.config.js import { defineConfig } from vite import vue from vitejs/plugin-vue import path from path// https://vitejs.dev/config/ export default defineConfig({pl…

EWM 高架仓库管理(内含扫描枪集成)

目录 1 简介 2 解题思路 2.1 活动区域 & Bin 层数(高度) 2.2 仓库任务创建规则(WOCR) 2.3 拣选策略 2.4 扫描枪集成 3 测试 3.1 人工拣选 3.2 叉车拣选 1 简介 大部分仓库启用 EWM 功能,不仅因为它是 SAP 最新集成的仓库模块,它也能满足复杂多样的仓库流…

vue面试题|[2025-2-1]

1.封装一个可复用的组件&#xff0c;需要满足什么条件&#xff1f; 1.低耦合&#xff0c;组件之间的依赖越小越好 2.最好从父级传入信息&#xff0c;不要在公共组件中请求数据 3.传入的数据要进行校验 4.处理事件的方法写在父组件中 2.vue的过滤器怎么使用&#xff1f; vue的特…

微服务配置中心 Apollo解析——Portal 关联 Namespace

17: roleInitializationService.initNamespaceRoles(appId, namespaceName, operator); 18: // 循环 models &#xff0c;创建 Namespace 对象 19: for (NamespaceCreationModel model : models) { 20: NamespaceDTO namespace model.getNamespace(); 21: // 校验相关参数…