QPopper 4.0.x buffer overflow vulnerability

by Nikola Strahija on March 12th, 2003Under certain conditions it is possible to execute arbitrary code using
a buffer overflow in the recent qpopper.
You need a valid username/password-combination and code is (depending on
the setup) usually executed with the user's uid and gid mail.

Qualcomm provides their own vsnprintf-implementation Qvsnprintf(). This
function is used unconditionally on any system, regardless if the system
has its own vsnprintf().
The function correctly writes up to 'n' bytes into the buffer, but fails
to null-terminate it, if buffer-space runs out while copying the
format-string (so the obvious fix is, null-terminate the buffer in
Qvsnprintf()).
This is a problem in pop_msg() (popper/pop_msg.c).
The call to Qvsnprintf() can leave the buffer 'message' unterminated, so
the successive call to strcat (strcat(message,"rn")) writes somewhere
into thew stack. What it exactly overwrites depends heavily on the
individual binary and the current stack-data (where is the next
null-byte).

Sending 'mdef ()' with a macro-name of about 1000 bytes
fills the buffer leaving it unterminated. The strcat overwrites the
least significant byte of the saved basepointer on the stack,
now pointing inside the buffer. On return of pop_mdef() (file
pop_extend.c), the return-address is now fetched from within our buffer
(and of course pointing inside our buffer), allowing to, for example,
spawn a shell.
The Macroname may not include bytes causing isspace() to return true
and, of course, no null-byte, so shellcode must be appropriate crafted.

Here is a POC-exploit, Values for RETADDR and BUFSIZE adjusted for
debian qpopper-4.0.4-8: