CTFshow:一句话木马变形详解

admin 2026-02-04 01:23:05 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细解析了CTF中PHP一句话木马的四种变形技巧,利用localeconv与scandir等函数组合绕过WAF关键词过滤。文章深入讲解了无参获取当前目录、扫描文件、读取源码及文件内容的实现原理,适用于渗透测试中的信息收集与代码混淆,为绕过安全检测提供了具体的技术参考。 综合评分: 88 文章分类: CTF,WEB安全,免杀,渗透测试,代码审计


cover_image

CTFshow: 一句话木马变形详解

原创

小话安全 小话安全

小话安全

2026年2月3日 18:31 山东

第二章一句话木马变形

1、print_r(scandir(pos(localeconv())));

完整解析

  1. localeconv()

作用:返回一个数组,包含本地化(locale)设置信息

返回值示例:

php

Array (

    [decimal_point] => “.”

    [thousands_sep] => “”

    [int_curr_symbol] => “”

    // … 其他本地化设置

)

关键点:第一个元素 decimal_point 通常是小数点字符 .

  1. pos()(即 current() 的别名)

作用:返回数组的当前元素(默认指向第一个元素)

pos(localeconv()) → 返回 .(小数点,表示当前目录)

  1. scandir(‘.’)

作用:扫描指定目录的内容

返回值:数组,包含目录中的所有文件和子目录

示例:

php

Array (

    [0] => “.”

    [1] => “..”

    [2] => “index.php”

    [3] => “config.ini”

    [4] => “uploads”

)

  1. print_r()

作用:以人类可读的格式打印变量信息

对于数组,会显示键名和值

整体流程

localeconv() 返回本地化设置数组

pos() 获取数组的第一个元素(小数点 .)

scandir(‘.’) 扫描当前目录,返回文件列表数组

print_r() 打印这个数组

等效的简化代码

php

// 最简写法

print_r(scandir(‘.’));

// 分步写法

$current_dir = ‘.’;

$file_list = scandir($current_dir);

print_r($file_list);

输出示例

php

Array

(

    [0] => .

    [1] => ..

    [2] => index.php

    [3] => config.php

    [4] => uploads

    [5] => .htaccess

    [6] => logs

)

在CTF中的使用场景

这种复杂写法主要用于:

绕过关键词过滤:避免直接出现 ‘.’ 或 ‘scandir’ 等被禁止的字符串

字符限制:在限制代码长度或特定字符的挑战中使用

混淆代码:使代码更难以理解和分析

展示PHP特性:利用PHP函数链式调用特性

2、print_r(array_reverse(scandir(current(localeconv()))));

  PHP代码解析:print_r(array_reverse(scandir(current(localeconv()))));

    一、代码分解与功能说明

    1. localeconv()函数

  • 功能:返回包含本地化数字和货币格式信息的数组

  • 返回值示例:

php

Array (

    [decimal_point] => “.”      // 小数点符号(通常是点号)

    [thousands_sep] => “”       // 千位分隔符

    [int_curr_symbol] => “”     // 国际货币符号

    [currency_symbol] => “$”    // 货币符号

    // … 其他本地化设置

)

  • 关键作用:获取本地化设置中的小数点字符.,用于表示当前目录

    2. current()函数

  • 功能:返回数组中的当前元素(默认指向第一个元素)

  • 等价函数:pos(),两者功能完全相同

  • 在此代码中的作用:从localeconv()返回的数组中提取第一个元素(小数点.)

    3. scandir(‘.’)函数

  • 功能:扫描指定目录,返回包含文件和子目录的数组

  • 返回值特点:

  – 按字母顺序排序

  – 始终包含.(当前目录)和..(上级目录)作为前两个元素

  • 返回示例:

php

Array (

    [0] => “.”

    [1] => “..”

    [2] => “config.php”

    [3] => “index.php”

    [4] => “uploads”

    [5] => “.htaccess”

)

    4. array_reverse()函数

  • 功能:反转数组的顺序

  • 处理效果:将数组元素从后到前重新排列

  • 示例转换:

  原始数组:[“.”, “..”, “config.php”, “index.php”]

  反转后数组:[“index.php”, “config.php”, “..”, “.”]

    5. print_r()函数

  • 功能:以人类可读的格式打印变量的结构和内容

  • 显示特点:对于数组,会显示键名和对应的值

   二、整体执行流程

localeconv() → 返回包含本地化设置的数组

current() → 提取数组的第一个元素(小数点”.”)

scandir(‘.’) → 扫描当前目录,返回文件列表数组

array_reverse() → 反转数组元素的顺序

print_r() → 打印反转后的数组内容

   三、实际输出示例

     假设当前目录包含以下文件:

  • .(当前目录)

  • ..(上级目录)

  • index.php

  • config.php

  • uploads/(目录)

  • .htaccess

     执行后的输出结果:

php

Array

(

    [0] => .htaccess

    [1] => uploads

    [2] => config.php

    [3] => index.php

    [4] => ..

    [5] => .

)

   四、与其他变体的对比

 | 代码示例 | 功能描述 | 输出顺序 |

|———|———|———|

| print_r(scandir(pos(localeconv()))) | 列出当前目录内容 | 正常顺序(.、..、其他文件按字母顺序) |

| print_r(array_reverse(scandir(current(localeconv()))) | 列出当前目录内容 | 反转顺序(其他文件按字母倒序、..、.) |

| show_source(next(array_reverse(scandir(pos(localeconv()))))) | 读取倒数第二个文件的源代码 | 读取特定文件内容 |

   五、在CTF和安全测试中的用途

     1. 目录侦察

  • 获取目标系统的目录结构

  • 发现敏感文件和目录

    2. 绕过安全过滤

  • 避免直接使用scandir(‘.’)等可能被WAF检测的代码

  • 通过函数组合隐藏真实意图

     3. 代码混淆

  • 增加代码阅读和分析的难度

  • 展示PHP函数链式调用的技巧

   4. 权限验证

  • 测试PHP进程对目录的读取权限

  • 验证文件系统访问能力

   六、代码特点分析

    优点:

  1. 隐蔽性强:不使用直接的字符串表示当前目录

  2. 功能完整:能够完整展示目录结构

  3. 可读性好:输出格式清晰,便于分析

    注意事项:

  1. 权限要求:需要PHP进程具有目录读取权限

  2. 性能影响:对大型目录进行反转操作可能影响性能

  3. 隐藏文件:以点开头的隐藏文件会正常显示

   七、实际应用场景

    1. 渗透测试

  • 信息收集阶段,枚举Web目录结构

  • 查找备份文件、配置文件、上传目录等敏感位置

    2. 系统管理

  • 快速查看服务器目录内容

  • 监控文件系统的变化

    3. 调试与开发

  • 验证文件上传功能

  • 检查服务器环境配置

    4. CTF竞赛

  • 解决文件系统相关的挑战

  • 绕过代码执行限制

   八、等价简化代码

php

// 最简写法

print_r(array_reverse(scandir(‘.’)));

// 分步写法

$directory = ‘.’;

$files = scandir($directory);

$reversed_files = array_reverse($files);

print_r($reversed_files);

 九、安全建议

  1. 生产环境禁用:不应在生产环境的PHP代码中使用此类目录遍历功能

  2. 输入验证:任何涉及文件系统的操作都应进行严格的输入验证

  3. 权限最小化:PHP进程应以最低必要权限运行

  4. 错误处理:添加适当的错误处理机制,避免信息泄露

3、show_source(next(array_reverse(scandir(pos(localeconv())))));

函数分解(从内到外):

localeconv()

返回包含本地化数字格式信息的数组

数组的第一个元素通常是小数点字符(.)

pos()(即 current() 的别名)

返回数组的当前元素(第一个元素)

pos(localeconv()) → 返回小数点 .(表示当前目录)

scandir(‘.’)

扫描当前目录,返回文件和目录的数组

例如:[‘.’, ‘..’, ‘file1.php’, ‘flag.txt’, …]

array_reverse()

反转数组顺序

[‘.’, ‘..’, ‘file1.php’, ‘flag.txt’] → [‘flag.txt’, ‘file1.php’, ‘..’, ‘.’]

next()

将数组内部指针向后移动一位,并返回该元素

在反转后的数组中,从第一个元素移动到第二个元素

show_source()(即 highlight_file() 的别名)

语法高亮显示指定文件的源代码

整体功能:

显示当前目录中按字母顺序排列的倒数第二个文件的源代码

实际例子:

假设目录包含:

index.php

config.php

flag.php

test.php

执行流程:

scandir(‘.’) → [‘.’, ‘..’, ‘config.php’, ‘flag.php’, ‘index.php’, ‘test.php’]

array_reverse() → [‘test.php’, ‘index.php’, ‘flag.php’, ‘config.php’, ‘..’, ‘.’]

next() → 从 ‘test.php’ 移动到 ‘index.php’

show_source(‘index.php’) → 高亮显示 index.php 的源代码

4、print_r(readfile(next(array_reverse(scandir(current(localeconv()))))));

 PHP代码解析:

print_r(readfile(next(array_reverse(scandir(current(localeconv()))))));

  一、代码功能概述

读取当前目录中按字母顺序排列的倒数第二个文件的内容并显示文件大小

  二、函数链式执行解析

  函数执行顺序(从内到外):

  1. localeconv() → 返回本地化设置数组(包含小数点.)

  2. current() → 获取数组第一个元素(小数点.)

  3. scandir(‘.’) → 扫描当前目录,返回文件列表数组

  4. array_reverse() → 反转数组顺序

  5. next() → 取反转后数组的第二个元素(原数组倒数第二个文件)

  6. readfile() → 读取文件内容并输出,返回文件大小

  7. print_r() → 打印文件大小

 三、执行流程示意图

localeconv() → 获取本地化数组

current() → 提取小数点’.’

scandir(‘.’) → 扫描目录获取文件列表

array_reverse() → 反转列表顺序

next() → 获取倒数第二个文件名

readfile() → 输出文件内容并返回大小

print_r() → 显示文件大小

 四、示例场景

 目录文件结构(按字母排序):

  1. .

  2. ..

  3. config.php

  4. index.php

  5. readme.txt

  6. uploads/

  代码执行过程:

  1. scandir(‘.’)返回:[“.”, “..”, “config.php”, “index.php”, “readme.txt”, “uploads”]

  2. array_reverse()反转:[“uploads”, “readme.txt”, “index.php”, “config.php”, “..”, “.”]

  3. next()获取:”readme.txt”(反转数组的第二个元素)

  4. readfile(“readme.txt”)执行:

   – 将readme.txt内容输出到页面

   – 返回文件字节数(如1024)

  1. print_r(1024)输出:1024

 最终显示效果:

[readme.txt文件内容在此显示]

 五、关键特性

| 特性 | 说明 |

|——|——|

| 目标文件 | 总是获取按字母顺序排列的倒数第二个文件 |

| 双重输出 | 1. 文件原始内容 2. 文件大小字节数 |

| 目录限制 | 仅处理当前目录文件 |

| 依赖条件 | 目录中必须至少有两个实际文件(除.和..外) |

 六、潜在问题

  1. 文件类型问题:读取二进制文件(如图片)会导致页面显示乱码

  2. 目录为空:如果只有.和..,next()返回false,导致错误

  3. 权限不足:无读取权限的文件会导致读取失败

  4. 大文件风险:读取大文件可能导致内存问题或超时

 七、应用场景

  1. CTF挑战:绕过文件读取限制的技巧

  2. 系统调试:快速查看特定文件内容和大小

  3. 渗透测试:测试文件读取漏洞

  4. 代码审计:识别潜在的安全风险模式

 八、简化的等价代码

php

// 分步执行的等价代码

$files = scandir(‘.’);                 // 获取目录列表

$reversed = array_reverse($files);     // 反转顺序

$target_file = $reversed[1];           // 取第二个元素(索引1)

$file_size = readfile($target_file);   // 读取文件并获取大小

echo $file_size;                       // 显示文件大小


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:小话安全 小话安全 小话安全《CTFshow: 一句话木马变形详解》

评论:0   参与:  0