www.libssh2.org | Daily snapshots | Mailing list archive | Docs | Examples | github

Archive Index This month's Index

Subject: [libssh2] #294: DoS condition: read from unmapped memory region causes libssh2 to crash

[libssh2] #294: DoS condition: read from unmapped memory region causes libssh2 to crash

From: libssh2 Trac <trac_at_libssh2.stuge.se>
Date: Fri, 27 Feb 2015 09:14:16 -0000

#294: DoS condition: read from unmapped memory region causes libssh2 to crash
----------------------+--------------------
 Reporter: mzet | Owner:
     Type: defect | Status: new
 Priority: high | Milestone: 1.4.3
Component: protocol | Version:
 Keywords: security | Blocked By:
   Blocks: |
----------------------+--------------------
 Affected are versions 1.4.3 and latest development version.

 Issue
 =====

 Specifically crafted input from ssh server causes read access from
 unmapped memory region resulting in crash (Segmentation fault) and causing
 denial of service condition.

 Valgrind output:
 ==3670== Process terminating with default action of signal 11 (SIGSEGV)
 ==3670== Access not within mapped region at address 0x6AA107D8
 ==3670== at 0x4087DB: _libssh2_ntohu32 (misc.c:163)
 ==3670== by 0x419E62: kex_agree_methods (kex.c:1583)
 ==3670== by 0x41A5CB: _libssh2_kex_exchange (kex.c:1749)
 ==3670== by 0x40C964: session_startup (session.c:723)
 ==3670== by 0x40CC04: libssh2_session_handshake (session.c:801)
 ==3670== by 0x402BCE: main (ssh2.c:118)

 The issue is caused by following code in kex.c:kex_agree_methods(...)
 function:

 /* Locate each string */
     kex_len = _libssh2_ntohu32(s);
     kex = s + 4;
     s += 4 + kex_len;
     hostkey_len = _libssh2_ntohu32(s);
     hostkey = s + 4;
     s += 4 + hostkey_len;
     crypt_cs_len = _libssh2_ntohu32(s);
     crypt_cs = s + 4;
     s += 4 + crypt_cs_len;
     crypt_sc_len = _libssh2_ntohu32(s);
     crypt_sc = s + 4;
     s += 4 + crypt_sc_len;
     mac_cs_len = _libssh2_ntohu32(s);
     mac_cs = s + 4;
     s += 4 + mac_cs_len;
     mac_sc_len = _libssh2_ntohu32(s);
     mac_sc = s + 4;
     s += 4 + mac_sc_len;
     comp_cs_len = _libssh2_ntohu32(s);
     comp_cs = s + 4;
     s += 4 + comp_cs_len;
     comp_sc_len = _libssh2_ntohu32(s);
     comp_sc = s + 4;

 It can be observed that various length fields (kex_len, hostkey_len,
 mac_cs_len, etc.) are taken from (untrusted) input and are used as offsets
 to memory location ('s' pointer) without any validation.

 Reproduction
 ============

 I'm attaching 'crash.input' file, an example of input that triggers this
 issue which could be reproduced with following steps:

 Run malicious 'ssh server':
 # cat crash.input | nc -l -p 22

 Run ssh2 from libssh2/example:
 $ ./ssh2 127.0.0.1

 Fix
 ===

 Proposed patch that fixes this issue is attached.

-- 
Ticket URL: <https://trac.libssh2.org/ticket/294>
libssh2 <https://trac.libssh2.org/>
C library for writing portable SSH2 clients
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2015-02-27

the libssh2 team