what you don't know can hurt you


Posted Jun 14, 2004
Authored by Joel Eriksson

A remotely exploitable format string vulnerability exists in smtp.proxy up to and including version 1.1.3. The bug is present and exploitable regardless of any compile time and runtime configuration options and can be exploited by sending a message with an embedded format string in either the client hostname or the message-id.

tags | advisory
MD5 | 8ff006e1ae1e98fc101e810e7fd5cffd


Change Mirror Download
Hash: SHA1

0xbadc0ded Advisory #04 - 2004/06/10 - smtp.proxy <= 1.1.3

Reference http://0xbadc0ded.org/advisories/0402.txt
PGP-key http://0xbadc0ded.org/advisories/pubkey.asc

Application smtp.proxy <= 1.1.3
Discovered By Joel Eriksson <je@bitnux.com>
Researched By Joel Eriksson <je@bitnux.com>


smtp.proxy is an application level gateway for SMTP. It assures that
the data received from the client fulfills the protocol specification
before forwarding it to the server. It also offers email address
control so that only certain sender or recipient addresses is allowed
and can optionally remove the 'Received:' lines from the mail header.


A remotely exploitable format string vulnerability exists in smtp.proxy
up to and including version 1.1.3. The bug is present and exploitable
regardless of any compile time and runtime configuration options.

The bug can be exploited by sending a message with an embedded
format string in either the client hostname or the message-id, the
userspecified message-id string is obviously the most convenient to
use though. The sender address (smtp command "mail from:") is also part
of the format string, but the string is filtered for '%'-chars so it
cannot be used.

The vulnerability is caused by this piece of code in smtp.c:

snprintf (line, sizeof(line) - 2, "client= %s, sender= %s, nrcpt= %d,
size= %ld, jobid= <%s>, message-id= <%s>, status= %d",
x->client, x->sender, x->nrcpt, x->size,
x->jobid, x->msgid, rc);
// echoline(stdout, line, 0);
syslog(LOG_NOTICE, line);

The line to be logged is first formatted with snprintf() and then sent
to syslog() and parsed as a format string. Since the 'line' buffer is
a local variable and thus placed on the stack, arbitrary addresses can
be embedded into the buffer and the data on those addresses can be
written to by using the %*n format string specifiers.


An exploit has been developed, but will be kept private for now.
Those who share our interest for exploit development may find the
following description interesting though.

Since smtp.proxy is started from a superserver, like inetd, the stack
offsets will remain constant and an attacker can use bruteforcing to
determine the unknown parameters required to exploit the vulnerability.

This means that even though it is a blind format string attack (the
output is not written back to the client) it can still be exploited
reliably by determining exploit parameters step by step. The unknown
parameters are (in the order they can be determined):

1. Offset to the format string on the stack (for embedding addresses)
2. Address to a function pointer or saved return address
3. Address to the shellcode

Determining the offset to the format string can be done by embedding
a known non-writable address in the message-id and attempting to write
into it with %*n at different stack offsets. For each offset that
causes a crash, embed a known writable addr (e.g. some high stack addr,
like 0xbffffffc for vanilla Linux/x86), and try again with the same
offset. If the daemon doesn't crash this time we have found it.

To determine the address of a function pointer we could either try to
find a saved return-address on the stack or the address of a suitable
GOT-entry by bruteforcing it. To decrease the number of attempts needed
we could use multiple writes. To see if the address is readable, so we
don't just try to write to non-mapped memory, we can use %*s. If we
cause a crash when writing to a certain (readable, and thus mapped)
address, these are the three most likely possibilities:

- We have tried to write to a read-only page
- We have written to a pointer that is dereferenced
- We have written to a function pointer or saved return address

We can determine if we have written to a read-only page by attempting
to write to surrounding addresses, if those writes also causes crashes
this is almost certainly the case.

Determining if we have written to a pointer that is dereferenced, or
perhaps an integer representing an array index or the length of a
buffer, is harder. If we don't cause a crash when overwriting with a
small integer or with a known readable and writable address we can
assume that we have not overwritten a function pointer and continue our
search. By writing the address we're writing into with the address to
itself we can also survive double dereferences.

If we pass the tests above (e.g. we still cause a crash when overwriting
with small integer values and other valid addresses, including the
address we write into to see if we have overwritten a pointer to a
pointer) then we can be reasonably sure that we have found a function
pointer. Let's start searching for our shellcode.

If we have embedded our code into the message-id it will be located on
both the heap in a malloc()'ed buffer and on the stack. The message-id
buffer is only 200 bytes large though, so unless the host has a
non-executable stack we are better off embedding our code in the 2048
bytes large line buffer on the stack in receive_data()'s stack frame.

Since fgets() is used to read lines, we can use a line like:


to terminate the message. A single dot indicates the end of the message
after the DATA-command has been sent. fgets() ignores NUL-bytes and
reads bytes into the buffer until a newline has been read or until the
buffer is full. This means we can stuff 2046 bytes of NOPs + shellcode
into the buffer, and thus use a stepsize of 2046 minus the length of the
shellcode when bruteforcing the shellcode address on the stack to be
certain to hit it.


Upgrade to smtp.proxy 1.3.3. When this vulnerability was discovered 1.1.3
was the latest announced version, and it is still the version available from:


The author, Wolfgang Zekoll, has informed me of the previously unannounced
version 1.3.3, that is not vulnerable for this problem. After waiting over
one week for a response from the author that he has officially announced
version 1.3.3 we discovered that he announced it the same day as we reported
the problem. The page above is not yet updated, but version 1.3.3 is available


Make sure you check that the URL is at quietsche-entchen.de before following
the download URL though, since it's a Wiki and anyone can edit the page...

Disclosure Timeline

2004/06/01 Notified the smtp.proxy developer (Wolfgang Zekoll)
2004/06/10 Public release

The 0xbadc0ded.org team is hosted and sponsored by Bitnux: www.bitnux.com

Bitnux is a company located in Sweden focused on security
research and system development. We offer services such as:

- Code Reviews
- Exploit Development
- Reverse Engineering of Code
- Security Revisions of Systems and Software
- Custom System Development for Unix/Linux/BSD and Windows

E-mail : info@bitnux.com
Phone : +46-70-228 64 16
Chat : http://bitnux.com/live

Version: GnuPG v1.2.1 (GNU/Linux)

Login or Register to add favorites

File Archive:

July 2021

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    13 Files
  • 2
    Jul 2nd
    12 Files
  • 3
    Jul 3rd
    1 Files
  • 4
    Jul 4th
    2 Files
  • 5
    Jul 5th
    34 Files
  • 6
    Jul 6th
    21 Files
  • 7
    Jul 7th
    21 Files
  • 8
    Jul 8th
    13 Files
  • 9
    Jul 9th
    6 Files
  • 10
    Jul 10th
    1 Files
  • 11
    Jul 11th
    3 Files
  • 12
    Jul 12th
    15 Files
  • 13
    Jul 13th
    19 Files
  • 14
    Jul 14th
    15 Files
  • 15
    Jul 15th
    15 Files
  • 16
    Jul 16th
    9 Files
  • 17
    Jul 17th
    2 Files
  • 18
    Jul 18th
    2 Files
  • 19
    Jul 19th
    19 Files
  • 20
    Jul 20th
    21 Files
  • 21
    Jul 21st
    53 Files
  • 22
    Jul 22nd
    14 Files
  • 23
    Jul 23rd
    14 Files
  • 24
    Jul 24th
    1 Files
  • 25
    Jul 25th
    1 Files
  • 26
    Jul 26th
    21 Files
  • 27
    Jul 27th
    8 Files
  • 28
    Jul 28th
    9 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags


packet storm

© 2020 Packet Storm. All rights reserved.

Security Services
Hosting By