Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Wed, 11 Dec 2013 22:38:01 +0100
From: Jurriaan Bremer <>
Subject: CVE Request: ZNC IRC Bouncer DoS in FiSH Plugin


There's an issue in the way FiSH loads public keys from users when
initiating a new private conversation (or "query" in irc.)

The main ZNC repository [1] does *not* ship with the FiSH extension by
default. However, the Windows port [2] of ZNC does ship with the FiSH
extension [3] by default. (You have to enable it manually though.)

The vulnerable part of the code can be found at line 606 of fish.cpp
[4]. When initiating a new query, both users send their public key to
each other - FiSH does this automatically for you. The public keys are
encoded using base64 when sent to the other user. In [4] you can see
that the FiSH plugin decodes the base64 stream to obtain the other
user's public key. However, no bounds are checked, and thus the buffer
"raw_buf" can be overflowed.

Luckily both x86 and x64 builds of the FiSH extension on Windows have
stack cookies, rendering this vulnerability unexploitable. However, even
though it's unexploitable, the stack cookie check does raise an
exception when overflown, after which the process crashes, and the
daemon won't function anymore - making it an easy Denial of Service.

An important side-note for non-Windows platforms. Even though ZNC
doesn't ship with the FiSH plugin by default, it does reference the
vulnerable Windows port implementation in their wiki [5] (see the
"mirror" - the link to the SVN repository is dead.) Furthermore, the two
referenced pastes [6][7] share the same vulnerability.

PoC: Having opened a query with a user running ZNC with the FiSH
extension loaded, send the following message. Right after this message
has been sent the user will be disconnected as his or her ZNC daemon has


(Repeat the "QUFB" pattern until the string is, let's say, 400
characters in length. Note, "QUFB" is "AAA" after base64 decoding.)

Or, when scripting a simple DoS bot, you'd do something like this:

buf = ('A'*300).encode('base64').replace('\n', '')
s.send("NOTICE %s :DH1080_INIT %s\r\n" % (user, buf))

Workaround: Adding a simple buffer size argument to the b64toh function
would suffice. An easier approach would be to check the length of the
base64 encoded string. I.e., it must not exceed ~265 bytes if it has to
fit in a 200-byte sized buffer after decoding.

Another fine workaround would be using this [8] implementation. (I'm
honestly not really sure which version, if not a stripped down / merged
into one file version, of FiSH is used by the Windows port.)

Also CC'd the maintainer of the Windows port - hi! :p

Best Regards,

[6] (Line 609)
[7] (Line 605)

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.