文件上传 .htaccess文件篇
文件上传 .htaccess文件篇¶
一. .htaccess文件是什么¶
.htaccess 是 Apache web 服务器的一种分布式配置文件。它允许在不修改主配置文件的情况下,对特定目录及其子目录的Apache行为进行配置。
//小芝士:
.ht表示它是隐藏文件
access表示它用于控制访问权限和配置
主要作用:目录级配置
| Text Only | |
|---|---|
常见功能:
URL重写:美化URL、重定向
访问控制:IP黑白名单、密码保护
错误页面定制:自定义404、403页面
MIME类型设置:定义文件类型的处理方式
缓存控制:设置浏览器缓存策略
文件索引:控制目录列表显示
二.常见指令¶
①SetHandler(信息收集查看自己payload的触发情况)¶
编辑.htaccess文件内容为
| Text Only | |
|---|---|
| Text Only | |
|---|---|
通过访问特定文件(如一个不存在的文件)并加上 ?refresh=5 参数,可以实时查看服务器的访问记录。
这里主要是信息收集,监控流量。
②AddType(将图片当作php运行)¶
可以将给定的文件扩展名映射到指定的内容类型
故使用 AddType application/x-httpd-php .gif 或 AddType application/x-httpd-php .png .jpg 等指令,可以将特定的文件后缀(如.gif, .png)映射到PHP处理器。
当网站只允许上传图片但限制不严时,攻击者上传一个名为 shell.jpg 或 shell.png 的图片马,并配合此.htaccess指令,使得服务器将该图片作为PHP执行,从而获取WebShell。
用法
| Text Only | |
|---|---|
③AddHandler (cgi脚本执行)¶
可以在文件扩展名与特定的处理器之间建立映射
如果服务器允许上传并执行CGI脚本,攻击者可以上传一个恶意的CGI脚本并修改其扩展名,通过此指令使其被正确执行。
④php_value 文件上传(自动包含)及正则绕过¶
如果攻击者无法直接上传PHP文件,但可以上传一个包含PHP代码的图片(如 images.png),再通过此指令让所有PHP文件在解析前都自动包含这个图片。这样,攻击者访问网站上的任何一个正常的PHP页面,图片中的恶意代码就会被执行。这实质上是一种“自动包含”的GetShell方式。
利用php_value绕过正则表达式限制
通过设置 php_value pcre.backtrack_limit 0 和 php_value pcre.jit 0 来降低正则表达式的回溯限制。
原理是设置正则回朔次数来使正则匹配的结果返回为 false 而不是0 ,从而可以绕过正则。
⑤php_flag engine 0 获取源码(没啥用 )其实和你鼠标右键一样¶
php_flag engine 0 会关闭当前目录及子目录的PHP引擎。
这主要用于源码泄露。当一个目录下的文件原本应该被PHP解析输出动态内容时,如果PHP引擎被关闭,访问这些文件时,服务器将不再解析它们,而是直接返回文件的原始源代码。
⑥一些其他的方法和他们的利用场景:DirectoryIndex¶
| Text Only | |
|---|---|
指令作用:当用户访问一个目录(例如 http://site.com/upload/)时,Apache会在该目录下寻找DirectoryIndex指令指定的文件列表,并返回第一个找到的文件。如果所有文件都不存在,Apache会根据Options指令的配置,可能返回目录列表(如果开启了Indexes)或403禁止访问。
在Union ctf ezupload题中利用它制造一个“必然会失败”的文件查找过程。指令中的/123.txt指向文件系统根目录下的一个文件(通常不存在)。这个查找操作本身成为了一个“触发器”,目的是让Apache在处理请求时,顺带执行后续的Header指令。
如果服务器配置存在缺陷,可以通过设置DirectoryIndex指向一个已知的敏感文件(如/etc/passwd),观察服务器是返回文件内容还是报错,从而判断文件是否存在。
⑦访问控制和功能配置Options +Indexes¶
Options指令用于开启或关闭特定的服务器特性,+Indexes意味着当目录没有默认首页时,允许列出目录内容。可以简单的理解为提升了一下我们的权限。
CTF利用场景:
- 信息泄露:
Options +Indexes如果应用在敏感目录(如备份目录、上传目录),攻击者可以直接浏览并下载目录下的所有文件。 - 提升权限
⑧RewriteEngine 与 RewriteRule¶
指令作用:
RewriteEngine On用于开启重写引擎。RewriteRule用于定义具体的重写规则,它匹配请求的URL,并将其重定向到另一个路径或文件。
参考payload union ctf ezupload:
| Text Only | |
|---|---|
这里的RewriteRule .* - [E=FLAG_CONTENT:%1]:
.*匹配所有请求。-表示不进行重定向,也不改变URL。[E=FLAG_CONTENT:%1]是一个标志(flag),它的作用是将RewriteCond中捕获的内容(%1,即flag文件的内容)赋值给一个名为FLAG_CONTENT的环境变量。 所以,这条RewriteRule本身不修改任何路径,它的唯一目的就是传递数据。
CTF利用场景:
-
数据传递:用
[E=变量名:%1]将正则捕获的内容存储到环境变量中,供其他模块(如mod_headers)使用。 -
路径伪造:可以重写URL,让看似普通的请求指向恶意文件。例如,上传一个图片马
shell.jpg,然后通过.htaccess设置:
apache
这样,当访问images/shell.php时,实际上返回的是shell.jpg的内容,但如果服务器将.jpg解析为PHP,就会执行恶意代码。
- 信息读取:结合
RewriteCond expr和file()函数,可以在不依赖PHP的情况下读取服务器文件。例如:
apache
⑨Header 指令¶
指令作用:
Header指令用于添加、修改或删除HTTP响应头。它可以设置为静态值,也可以设置为动态表达式(expr=)。
Header指令都是最终数据外带的关键。
| Text Only | |
|---|---|
这里从环境变量FLAG_CONTENT中读取flag内容,并写入响应头X-Test-Expr。
| Text Only | |
|---|---|
这里更直接,用expr=%{file:/flag}表达式,在设置响应头的同时,立即读取/flag文件的内容并写入响应头。
利用场景:
-
数据外带:当响应体被限制(如PHP被禁用、内容被过滤)时,将敏感数据写入响应头是经典的绕过技巧。攻击者只需查看服务器的响应头即可获取信息。
-
信息探测:通过设置响应头并观察服务器的行为,可以判断某些配置是否生效。例如,设置一个自定义头
X-Debug: expr=%{ENV:SECRET},如果返回了SECRET环境变量的值,说明配置解析成功。 -
与
expr深度结合:expr表达式可以调用Apache的内部函数(如file()、reqenv())和变量(如%{TIME})。这意味着可以通过Header指令实现动态内容生成。例如:
apache
三.具体场景及其组合利用方式¶
①文件解析¶
当文件上传的黑名单没有限制 .htaceess 后缀,通过上传 .htaccess 文件,再上传图片,使图片的 php 恶意代码得以被解析执行。
| Text Only | |
|---|---|
②文件包含,本地文件包含 (LFI) 与敏感文件读取¶
本地文件包含¶
目标:读取服务器上的敏感文件(如 /etc/passwd、/flag)。
攻击链:上传 .htaccess 文件,内容为 php_value auto_prepend_file /flag,并访问同目录下的一个合法的PHP文件(如 index.php)。
| Text Only | |
|---|---|
1 | |
核心指令
| Text Only | |
|---|---|
这两个指令原本是为了方便开发者全局引入公共文件(如数据库连接配置、函数库)而设计的。
在 .htaccess 中,php_value 允许你动态修改这些配置,仅对当前目录及其子目录生效。
当指定的文件被包含时,PHP引擎会把它当作PHP代码来解析执行。
参考payload:
| Text Only | |
|---|---|
远程文件包含¶
前提条件:all_url_include为On, 在.htaccess文件中配置如下
| Text Only | |
|---|---|
结果:在访问任意一个页面的时候,目标服务器会远程获取 phpinfo.txt文件包含到页面中。
③代码执行¶
1.伪协议¶
前提条件:all_url_fopen、all_url_include为On
在.htaccess文件中配置如下:
| Text Only | |
|---|---|
在访问php页面后,会自动执行该配置文件,将包含到php页面中并执行。
2.解析.htaccess¶
方法一:把.htaccess文件包含到当前页面中执行,打印配置文件到页面上,.htaccess文件配置:
在htaccess配置文件中,#代表注释,在配置文件中,不起作用,但是,当该配置文件被包含到php文件中,注释后的php代码会被执行。
方法二:(适用与目录中没有php文件)
这种适合同目录或子目录没有 php 文件。需要先设置允许可访问 .htaccess 文件,在.htaccess文件中配置如下:设置允许可访问 .htaccess 文件
再将 .htaccess指定当做 php文件处理
效果如图:

④命令执行(这个方法很少见,试验了几个题目靶场基本没有mod_cgi 模块,仅作了解)¶
传统 CGI 命令执行(mod_cgi):
CGI(Common Gateway Interface,公共网关接口) 是一种让Web服务器与外部程序(如脚本、可执行文件)交互的协议。
前提条件
Apache必须加载了 mod_cgi 模块。在apache主配置文件中应有:
| Text Only | |
|---|---|
.htaccess 配置详解
apache
指令作用:
Options ExecCGI:开启目录的CGI执行权限。默认情况下,出于安全考虑,CGI执行是关闭的。AddHandler cgi-script .xx:建立文件后缀与处理器的映射。这里将.xx后缀映射到cgi-script处理器,意味着任何以.xx结尾的文件都会被Apache当作CGI程序执行。
示例:
miao.xx
这里是打开本地C盘计算器。在ctf里可以反弹shell的方式去进行命令执行,也可以直接编写
| Text Only | |
|---|---|
类似的命令程序直接进行执行。
FastCGI 命令执行(mod_fcgid):
FastCGI 是CGI的改进版本,旨在解决传统CGI为每个请求创建新进程的性能问题。它通过持久化进程来处理多个请求,提高了效率。mod_fcgid 是Apache实现FastCGI支持的模块。
前提条件
Apache必须加载了 mod_fcgid 模块:
| Text Only | |
|---|---|
.htaccess 配置详解
| Text Only | |
|---|---|
此时miao.xx的文件内容可以是任意内容

新增指令:
FcgidWrapper:这是mod_fcgid特有的指令。它指定一个包装器程序(wrapper)来处理特定后缀的文件。- 语法:
FcgidWrapper "包装器程序路径" [文件后缀] - 作用:对于匹配后缀的文件,Apache会调用指定的包装器程序来执行它们。
- 这里将
cmd.exe /k start calc.exe设置为.xx文件的执行包装器,意味着任何对.xx文件的请求,都会启动计算器进程。
执行流程
- 攻击者上传
.htaccess和任意.xx文件(内容可空白)。 - 访问
ce.xx。 mod_fcgid接管请求,根据FcgidWrapper指令,调用cmd.exe启动计算器。- 与CGI的区别:FastCGI可能会维持一个进程池,但这里因为包装器每次都启动新进程,效果与传统CGI类似。
⑤xss¶
highlight_file:
前提条件:php文件中存在highlight_file(__FILE__);
.htaccess配置文件
| Text Only | |
|---|---|
指令作用:
highlight.comment:这是PHP的语法高亮配置选项之一,用于定义注释在HTML输出时的样式。- 默认情况下,它的值是类似
style="color: #FF8000"的HTML属性字符串。 - 攻击者将其改为
'"><script>alert(1);</script>',这是一个HTML注入 payload。
其中的 highlight.comment 也可以换成其他选项比如,

| Text Only | |
|---|---|
示例:
index.php
流程及其效果
-
用户访问
index.php。 -
PHP执行
highlight_file(__FILE__);,读取index.php自身的源代码。 -
PHP对源代码进行语法高亮处理,为不同元素(关键字、字符串、注释等)添加HTML
<span>标签和样式。 -
在处理注释
// comment时,PHP使用highlight.comment配置的值作为样式属性。 -
最终生成的HTML代码中会出现类似:
html
Text Only -
浏览器解析HTML时,
<script>alert(1);</script>被当作JavaScript执行,弹窗。
利用错误消息链接实现 XSS¶
前提条件
目录下有一个PHP文件,会触发错误(例如包含一个不存在的文件)。
index.php
.htaccess 配置
| Text Only | |
|---|---|
指令详解:
php_flag display_errors 1:开启错误显示,让错误信息输出到浏览器。php_flag html_errors 1:以HTML格式显示错误信息,使错误信息中包含链接。php_value docref_root "'><script>alert(1);</script>":设置错误消息中“参考文档”链接的根URL。当html_errors开启时,PHP会在错误信息中生成一个指向文档的链接,链接地址由docref_root和错误类型组成。
流程及最终效果:
-
用户访问
index.php。 -
PHP尝试包含
foo文件,但文件不存在,触发警告或错误。 -
由于
display_errors和html_errors开启,PHP生成HTML格式的错误信息。 -
在错误信息中,PHP会包含一个“参考文档”链接,链接的href属性值由
docref_root决定。 -
攻击者设置的
docref_root值为'"><script>alert(1);</script>,因此生成的HTML代码为:html
Text Only -
浏览器解析时,
<script>标签被执行。
这里可以做到窃取cookie,配合CSRF进行脚本执行恶意操作。
⑥利用重写模块读取文件内容¶
| Text Only | |
|---|---|
上传 .htaccess 作为攻击入口(突破上传限制)。
利用 mod_rewrite + expr + file() 读取服务器上的flag文件。
利用 mod_headers 将读取到的内容写入响应头。
访问任意文件 触发重写规则,从而获取flag。
核心利用点:
RewriteCond expr: 在重写条件中使用表达式(expr)解析器。表达式可以调用Apache的内部函数,例如file('/flag')。file()函数: 在Apache的expr上下文中,file('/flag')用于读取服务器上的文件(这里是根目录下的flag文件)。这是本题实现文件读取的关键。- 正则捕获: 通过
=~ /(.+)/将读取的文件内容匹配并捕获到变量%1中。 mod_headers:由于无法直接将文件内容打印到页面上(且PHP被禁用),攻击者将捕获到的flag内容(%{FLAG_CONTENT}e)写入自定义的响应头X-Test-Expr中。当客户端访问该目录下的任意文件时,flag就会以响应头的形式返回给攻击者。RewriteRule .* - [E=FLAG_CONTENT:%1]中的[E=]标志用于设置环境变量。将正则捕获到的flag内容(%1)赋值给环境变量FLAG_CONTENT。随后,Header指令通过%{FLAG_CONTENT}e语法读取这个环境变量,实现了重写模块到头模块的数据传递。
⑦利用不存在的文件,触发header头带出¶
这个只需要上传一个文件即可。最后访问目录本身。
四.Bypass¶
第一类:绕过内容检测(改动的是文件内容)¶
这类方法适用于:服务器检查了上传文件的内容,发现了黑名单关键词(如 AddType、php_value)就拦截。我们通过改变文件内容的写法,让这些关键词不被识别出来,但Apache在解析时仍能正确执行。
1. 注释符与拼接绕过¶
-
原理解析:Apache解析
.htaccess时,支持两种语法: -
#作为注释符,它后面的内容会被忽略。我们可以利用这一点,在敏感指令后加上#,来绕过WAF。 -
\可以拼接上下两行,这可以用来拆分敏感关键词。 -
利用方式举例:
-
内容拆分:将
AddType拆成AddT和ype分两行写。WAF如果只做简单的关键词匹配,可能只看到第一行的
AddT和第二行的ype,无法识别出完整的AddType。但Apache在解析时,会把这两行合并成一条完整指令执行。 -
内容混淆:在有效指令后面加上
##需要和前面的内容隔一个空格,并且#只能注释一行内容,可以使用反斜线来转义换行符,从而注释多行内容
2. 空字节注释绕过¶
-
原理解析:在早期的Apache版本或某些特定配置下,空字节(
0x00)在配置文件中也可能被当作注释符或截断符。其后的内容会被忽略。 -
利用方式: 在文件内容中插入空字节。
| Text Only | |
|---|---|
第二类:绕过文件名检测(改动的是文件名)¶
这类方法适用于:服务器检查了上传文件的文件名,明确禁止上传文件名为 .htaccess 的文件。
1. 文件名大小写/变形¶
- 改动对象:文件名。
- 原理解析:服务器对文件名的检测规则是死的,但不同操作系统和Web服务器对文件名的处理方式存在差异。
- 利用方式:
- 大小写绕过:尝试上传文件名如
.HTACCESS、.Htaccess。- 场景A:服务器运行在 Windows 上。Windows的文件系统(如NTFS)默认是不区分大小写的。所以,当你上传
.HTACCESS文件后,在Windows系统中,它就是.htaccess。Apache会正确地把它当作配置文件加载。 - 场景B:服务器运行在 Linux 上。Linux的文件系统(如ext4)是区分大小写的。如果只禁止了
.htaccess,那么上传.HTACCESS后,系统里会存在一个名为.HTACCESS的文件,而Apache默认只加载文件名精确为.htaccess的文件。所以,这种方法在Linux上通常会失败。除非Apache的配置被修改为加载更多文件名。
- 场景A:服务器运行在 Windows 上。Windows的文件系统(如NTFS)默认是不区分大小写的。所以,当你上传
- 后缀/前缀变形:尝试上传文件名如
.htaccess.txt、shell.htaccess。- 这利用了服务器可能只检查文件名的开头或结尾,或者检查得不够严格。如果上传目录的配置允许,且Apache能够识别
.htaccess.txt或shell.htaccess为有效的配置文件,那么它也可能生效。但这取决于Apache的主配置(AccessFileName指令)是否定义了这些备用文件名。默认情况下,Apache只认.htaccess。
- 这利用了服务器可能只检查文件名的开头或结尾,或者检查得不够严格。如果上传目录的配置允许,且Apache能够识别
例题:Union Ctf ezupload¶
解法一:
| Text Only | |
|---|---|



解法二:

