COMMAND
proftpd
SYSTEMS AFFECTED
proftpd 1.2.0 <= pre10
PROBLEM
Following is based on Security Advisory by lamagra.
Bug1:
=====
void set_proc_title(char *fmt,...) in src/main.c
memset(statbuf, 0, sizeof(statbuf));
vsnprintf(statbuf, sizeof(statbuf), fmt, msg);
#ifdef HAVE_SETPROCTITLE
setproctitle(statbuf);
#endif /* HAVE_SETPROCTITLE */
setproctitle, defined setproctitle(char *fmt,...);, calls
vsnprintf(). This makes it vulnerable for formatattacks. By
carefully outlining the attackbuffer it's possible to gain root
priviledges.
Bug2:
=====
MODRET pam_auth(cmd_rec *cmd) in modules/mod_pam.c:
/* Allocate our entries...we don't free this because PAM does this for us.
*/
pam_user = malloc(strlen(cmd->argv[0]) + 1);
if(pam_user == (char *)0)
return pam_return_type ? ERROR(cmd) : DECLINED(cmd);
sstrncpy(pam_user, cmd->argv[0], strlen(cmd->argv[0]) + 1);
pam_pass = malloc(strlen(cmd->argv[1]) + 1);
if(pam_pass == (char *)0)
return pam_return_type ? ERROR(cmd) : DECLINED(cmd);
sstrncpy(pam_pass, cmd->argv[1], strlen(cmd->argv[1]) + 1);
PAM doesn't do it for you though. Which leaves a nice memoryleak.
But since USER/PASS is limited to 3 tries and user changing isn't
supported. This can't be used as a Denial of service attack
against proftpd, unless the administartor sets a different
(higher) limit.
Bug3:
=====
void logformat(char *nickname, char *fmts) doesn't check
boundaries on it's local variable 'format'. As a result custom
logformats could overflow the buffer. Just a really small
thingie. Could cause some problems though.
Bug4:
=====
int dolist(cmd_rec *cmd, const char *opt, int clearflags) in
modules/mod_ls.c
char pbuffer[MAXPATHLEN];
if(*arg == '~') {
struct passwd *pw;
int i;
const char *p;
i = 0;
p = arg;
p++;
while(*p && *p != '/')
pbuffer[i++] = *p++;
pbuffer[i] = '\0';
This function gets called by cmd_stat, with 'arg' being the
argument of STAT. This looks really bad and ugly. But isn't
really exploitable since the input buffer is only 1024 bytes. But
it's still insecure programming.
SOLUTION
Fix 1: use setproctitle("%s",statbuf);
--- src/main.c 2000/01/13 01:47:02 1.3
+++ src/main.c 2000/04/29 19:22:18
@@ -377,7 +377,7 @@
vsnprintf(statbuf, sizeof(statbuf), fmt, msg);
#ifdef HAVE_SETPROCTITLE
- setproctitle(statbuf);
+ setproctitle("%s", statbuf);
#endif /* HAVE_SETPROCTITLE */
va_end(msg);
Note that this is a problem only if you have a setproctitle() in
libc (or libutil). Linux does not (glibc 2.x).
Fix 2: pstrdup() or just use cmd->argv[0] and cmd->argv[1].
ProFTPD 1.20 fixed all this.