ctfer

文件上传

2026-11-02 #dev

从这一期开始,至少不全是笔者agent的ai slop了,起码内容都是牢苏提问法问出来的()不过笔者仍然期待能有一阵可以重整一下这些笔记,顺便在到时候附上每个对应的例题wp(会贴在blog上头,不过想来是个挺大的工程量,A·A·O!)

.htaccess 速查笔记(苏格拉底 11 问版)

用途:复习 fu 文件上传题时用。题目细节看同目录 writeup.md,这里只记“为什么”和“怎么查/怎么验”。

0. 一句话

.htaccess 是 Apache 的目录级配置;上传题里它的价值 = 改“文件交给谁处理”(handler)+ 改“PHP 在这个目录的 ini”(php_value),配合 php://filter 就能在磁盘没有 < 的情况下执行代码。

1. 十一问速览

# 问题 答案要点
1 .htaccess 是普通文件吗? 不是。它是 Apache 读取的目录级配置;直接访问 .ht* 会被 403(默认保护)
2 Apache 无条件读它吗? 不。httpd.conf 的 <Directory> 里 AllowOverride 控制:None 不读、All 全读、或按类别放行
3 它和 httpd.conf 的区别? 作用范围(本目录+子目录 vs 全局/vhost)、读取时机(每请求 vs 启动/重载)、可写指令(子集 vs 全部)
4 AddType application/x-httpd-php .txt 在干什么? 后缀 → MIME 类型;该字符串恰好是 mod_php 注册的 handler 名,Apache 按类型匹配到同名 handler → 交给 mod_php
5 php_value 和 php_admin_value 差在哪? 上下文:ACCESS_CONF(.htaccess 可用)vs RSRC_CONF(只 server config,写了就 500)
6 内容不能有 <,怎么执行代码? 磁盘存 base64(无 <),读取时用 php://filter/convert.base64-decode 解码出 <?php
7 php://filter/convert.base64-decode/resource=z.txt 三段是什么? 打开 z.txt 拿字节流 → 过 base64 解码过滤器 → 结果交给 include/编译流程
8 谁去 include 这个流? PHP 自己的 ini 项 auto_prepend_file(不是后端代码的 include)
9 什么时候触发? 每个“交给 PHP 执行”的请求,在编译主脚本之前,且只对主脚本一次
10 关键词被 WAF 拦怎么办? 用 Apache 的行续接:行尾 \ + 换行会被删掉并与下一行直接拼接,WAF 看不到连续关键词
11 如果靶机是 FPM 呢? php_value 是 mod_php 指令,FPM 下 Apache 不认识 → 500;改用 .user.ini(PERDIR 项,300s 缓存)

2. 三层概念别混

层 东西 例子 能改吗
Apache 指令(设置器) php_value / php_flag / AddType / SetHandler php_value memory_limit 256M 看 AllowOverride
PHP ini 项(被设置的对象) auto_prepend_file、engine、display_errors 查 PHP 手册/php -i 看 ini 访问级别
值 路径、On/Off、256M php://filter/... —

3. 指令对照

3.1 后缀/处理器

指令 作用 本题/实战备注
AddType 类型 .后缀 后缀 → MIME 类型 依赖“类型名 = mod_php handler 名”的碰撞,application/x-httpd-php 必须拼对
AddHandler handler .后缀 后缀 → handler 跳过 MIME 环节,等价于“只对某后缀的 SetHandler”
SetHandler handler 位置 → handler(作用于该目录/段内全部文件) 最猛,也最容易把目录搞坏

3.2 PHP 配置

指令 值类型 上下文 备注
php_value 键 值 字符串 ACCESS_CONF 能设字符串/数字/路径;也能设布尔项(由 ini 自己解析)
php_flag 键 On|Off 布尔 ACCESS_CONF 值强制布尔;用于字符串项会变成 "1"
php_admin_value / php_admin_flag 同左 RSRC_CONF 只能 server config/vhost,.htaccess 写 → 500

3.3 ini 访问级别

级别 能否 .htaccess(mod_php) / .user.ini(FPM) 设置
PHP_INI_USER 脚本内 ini_set()
PHP_INI_PERDIR ✅ 可以(目录级)
PHP_INI_SYSTEM ❌ 只能 php.ini / server config
PHP_INI_ALL 以上都行

4. 可复制模板

4.1 mod_php(本题环境)

1
2
AddType application/x-httpd-php .txt
php_value auto_prepend_file "php://filter/convert.base64-decode/resource=z.txt"

若关键词被 WAF 拦(本题):

1
2
3
4
AddType application/x-httpd-php .txt
php_\
value auto_prep\
end_file php://filter/convert.base64-decode/resource=z.txt

4.2 FPM / CGI

1
2
; .user.ini
auto_prepend_file=php://filter/convert.base64-decode/resource=z.txt

handler 用 FPM 的方式(站点现成规则或 SetHandler "proxy:unix:/run/php/phpX.Y-fpm.sock|fcgi://localhost")。

4.3 已有 LFI 时

1
?file=php://filter/convert.base64-decode/resource=uploads/z.txt

4.4 防御模板(写进 httpd.conf 的 <Directory>)

1
2
AllowOverride None
php_admin_flag engine off

5. 验证探针

想确认什么 怎么做 看什么
.htaccess 是否生效 写 AddType application/x-httpd-php .txt,再访问某个 .txt 响应是否变成 PHP 输出(text/html; charset=UTF-8、无 ETag/Last-Modified)
php_value 是否生效 php_value default_charset ISO-8859-1 响应头 charset 是否变化
mod_php 是否存在 php_flag display_errors on 200 = 指令被识别(模块在);500 = 指令不存在
上下文是否受限 php_admin_value default_charset ... 预期 500(RSRC_CONF)
SAPI 是 mod_php 还是 FPM .user.ini 写一个可见项 是否生效;或看 php_value 是否 500
模块是否加载 httpd -M / apachectl -M 有无 php_module、rewrite_module、cgi_module、actions_module

6. 常见坑

  • 续行 \ 后不能有空格;拼接不插空格,断点可以落在词中间;
  • .htaccess 行内 # 不是注释(会变成参数值);
  • .user.ini 只对 CGI/FastCGI 生效,且 user_ini.cache_ttl 默认 300s;
  • auto_prepend_file 只对交给 PHP 的请求生效,纯静态请求不触发;
  • php://filter 的 resource= 相对路径以 PHP 进程 cwd 为基准,不确定就写绝对路径;
  • allow_url_include=Off 不拦 php://filter(拦的是 http/ftp/data 等 URL 包装器);
  • 写坏一条指令会让整个目录 500,测指令要能随时恢复;
  • .htaccess 只影响本目录及子目录,别指望影响上层目录的 index.php。

7. 参考

评论
也许会发生一些好事!
分享

评论