Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sat, 16 May 2015 12:58:12 +0200
From: Hanno Böck <>
Subject: about this openssh heap overflow


Quick background story: I started a while ago to develop a solution to
use american fuzzy lop with networking input. I did so by creating a
library to be preloaded with LD_PRELOAD that would intercept some
functions to simulate a network connection and pass data from a file.

This is trickier than it sounds and doesn't really work yet, but I
managed to use this to fuzz the ssh client handshake. In combination
with address sanitizer this turned up a read heap overflow. I reported
this to openssh's damien miller. He considered it not security relevant
and committed the fix to the public repo:

With that it was public, but nobody noticed. Until today someone
proposed a very similar approach to network fuzzing on the afl mailing
list and I answered that I was working on this and briefly mentioned
the ssh overflow:

Now this is making rounds on twitter, so I thought I'd publish all
details. I just pasted below what I reported to openssh.

As this is only a read overflow it likely is not exploitable in any
way, but itsec history has shown that often enough when people think
something is not exploitable they were wrong.

If this makes you nervous apply the patch linked above (which will just
remove the length argument from the function) or this shorter patch
which will just fix the wrong function cal:

--- openssh-6.8p1/compat.c	2015-03-17 06:49:20.000000000 +0100
+++ openssh-6.8p1-fix/compat.c	2015-05-03 17:51:32.251293388 +0200
@@ -229,7 +229,7 @@
 	tmp = orig_prop = xstrdup(proposal);
 	while ((cp = strsep(&tmp, ",")) != NULL) {
-		if (match_pattern_list(cp, filter, strlen(cp), 0) != 1) {
+		if (match_pattern_list(cp, filter, strlen(filter), 0) != 1) {
 			if (buffer_len(&b) > 0)
 				buffer_append(&b, ",", 1);
 			buffer_append(&b, cp, strlen(cp));


I think I found a bug in ssh, maybe security relevant.

It's surprisingly easy to reproduce:
* Compile latest openssh 6.8p1 with address sanitizer (./configure
  CFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address"; make)
* Run this netcat-command:
echo "SSH-2.0-OpenSSH_6.5"|nc -l -p 22
* ssh to it: ./ssh

I'm not entirely sure when and why this is triggered, doesn't work
against a real ssh server (I assume something with the version number
and not answering after the inital banner to the client)

However, here is why it causes an invalid memory access:
In combat.c there is this call for the function match_pattern_list in
line 232:
		if (match_pattern_list(cp, filter, strlen(cp), 0) != 1)

The function definition (match.c, line 120):
match_pattern_list(const char *string, const char *pattern, u_int len,

Looking at the function (match.c, line 141/142) we have this:
		for (subi = 0;
		    i < len && subi < sizeof(sub) - 1 && pattern[i] !=

		    subi++, i++)

It will iterate over pattern with length len. pattern is the second
parameter passed. But in the function call len is given as the length
of the first parameter. So they don't match and this will cause a
buffer overflow if cp is longer than filter.

So the function call really should be:
		if (match_pattern_list(cp, filter, strlen(filter), 0) !=
1) {

Right? (Not 100% sure if I got everything what's happening here...)
See attached patch. Will also attach an address sanitizer stack trace
(for reasons unknown to me this stack trace only appears if I compile
openssh with afl + asan, not with asan alone)

Hanno Böck


Content of type "application/pgp-signature" 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.