Your message dated Fri, 06 May 2005 14:02:24 -0400 with message-id <[EMAIL PROTECTED]> and subject line Bug#267101: fixed in termpkg 3.3-2 has caused the attached Bug report to be marked as done.
This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what I am talking about this indicates a serious mail system misconfiguration somewhere. Please contact me immediately.) Debian bug tracking system administrator (administrator, Debian Bugs database) -------------------------------------- Received: (at submit) by bugs.debian.org; 20 Aug 2004 18:08:35 +0000 >From [EMAIL PROTECTED] Fri Aug 20 11:08:35 2004 Return-path: <[EMAIL PROTECTED]> Received: from (mx01.hinterhof.net) [83.137.99.112] by spohr.debian.org with esmtp (Exim 3.35 1 (Debian)) id 1ByDoZ-0006B0-00; Fri, 20 Aug 2004 11:08:35 -0700 Received: from localhost (localhost [127.0.0.1]) by mx01.hinterhof.net (Postfix) with ESMTP id 1948610572 for <[EMAIL PROTECTED]>; Fri, 20 Aug 2004 20:09:31 +0200 (CEST) Received: from nautile.roam.hinterhof.net (pD95D0DB7.dip.t-dialin.net [217.93.13.183]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "nautile.roam.hinterhof.net", Issuer "hinterhofCertificateAuthority" (verified OK)) by mx01.hinterhof.net (Postfix) with ESMTP id D88961056A for <[EMAIL PROTECTED]>; Fri, 20 Aug 2004 20:09:28 +0200 (CEST) Received: by nautile.roam.hinterhof.net (Postfix, from userid 1000) id D039910ADFC; Fri, 20 Aug 2004 20:08:24 +0200 (CEST) Date: Fri, 20 Aug 2004 20:08:24 +0200 From: Max Vozeler <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] Subject: termpkg: remote root vulnerabilities Message-ID: <[EMAIL PROTECTED]> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6+20040803i Delivered-To: [EMAIL PROTECTED] X-Spam-Checker-Version: SpamAssassin 2.60-bugs.debian.org_2004_03_25 (1.212-2003-09-23-exp) on spohr.debian.org X-Spam-Status: No, hits=-5.8 required=4.0 tests=BAYES_01,HAS_PACKAGE, LARGE_HEX autolearn=no version=2.60-bugs.debian.org_2004_03_25 X-Spam-Level: Package: termpkg Version: 3.3-1 Severity: grave Hi, these bugs still apply. Not tagging +patch since I haven't really tested them. Cheers. Max -- 308E81E7B97963BCA0E6ED889D5BD511B7CDA2DC ----- Forwarded message from Max Vozeler <[EMAIL PROTECTED]> ----- From: Max Vozeler <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: termpkg vulnerabilites Date: Fri, 30 Jul 2004 16:00:18 +0200 User-Agent: Mutt/1.5.6+20040523i Hi Oliver, [ CCing Security Team for vulns in the testing version ] there are a few bugs in termpkg/termnetd that can introduce security problems and potentially lead to remote root compromise. In Debian only testing and unstable are affected. I looked at version 3.3-1. Feel free to forward this info as you like. Unless you want me to delay disclosure to the BTS, or the fixed package has already entered sarge by then, I'll file +security bugs for these vulns in 10 days or so. In short: o buffer overflow in getOption() reading telnet suboption from the client; reachable from termnetd. o buffer overflow in tnlSsetSubOption() and doSubOption(); A string of up to 256 bytes is strcpy()ed into a 128-bytes char array. The code is also reachable from the network in termnetd. o buffer overflow in commands-handling on the control connection port, if enabled in termnetd (Not by default AFAICS). The bug repeats in other parts of the control connection functions. o buffer overflow in parseRE(), also reachable from the control connection port. getOption() overflow -------------------- termpkg-3.3/libtn/tnlSubOptions.c: 30 static int option, optionCnt; 31 STatic char *pOption, optionBuffer[256]; 32 static int dbg = 0; 33 .. 72 /* 73 ** This function stores the character passed into the 74 ** suboption buffer, then increments the pointer in 75 ** anticipation of the next character. 76 */ 77 static void getOption(int ch) 78 { 79 if (strlen(optionBuffer) < sizeof(optionBuffer) - 1) 80 { 81 *(pOption++) = ch; 82 *pOption = '\0'; 83 } 84 } 85 The strlen() call here tries to catch possible overflows, but doesn't take into account that '\0' is among the values that can be written using getOption(). This can effectively circumvent that bounds check and cause writes to memory past the end of optionBuffer. There is a FILE pointer next to optionBuffer on my local i386 local debug build that gets overwritten. If an attacker was to change the pointer to a fake but valid FILE structure, this may enable him/her to execute arbitrary code as root. Would it be possible to use pointer arithmetic instead of checking the size with strlen()? I'm thinking something like the attached termpkg-getoption-bof.diff tnlSetSubOption() and doSubOption() overflows --------------------------------------------- termpkg-3.3/libtn/tnlVars.c: 47 int Options[256]; /* Option table */ 48 char SubOptions[256][128]; /* Sub Option storage */ 49 char *pSubOptions[256]; /* Sub Option Pointers */ termpkg-3.3/libtn/tnlSubOptions.c: 111 ** This function stores the data gathered from the socket in optionBuffer 112 ** for the option specified by the variable option into ... .. 118 static void doSubOption(int ch) 119 { .. 124 strcpy(pSubOptions[option], optionBuffer); optionBuffer can AFAICS be 255 bytes, whereas I think the space pointed to by pSubOptions[option] is an element of the SubOptions array and only 128 bytes. If "option" has a high or low enough value, this could make it overflow past SubOptions. The bug in tnlSetSubOption() is very similar. I would suggest to replace both strcpy calls with bounds checking strncpy(), see attached file sredird-suboptarg-bof.diff control cmd overflow -------------------- termpkg-3.3/termnetd/tndControl.c: 235 void enable_cmd(char *arg1, char *arg2, ControlStruct *pEntry) 236 { 237 portConf *pConf; 238 char *cp, tbuf[1024]; 239 int cnt; 240 int devc = 0; 241 242 strcpy(tbuf, arg1); 243 for (cp = tbuf; *cp; cp++) 244 *cp = toupper(*cp); 245 if (strcmp(tbuf, "DEVICE") == 0) 246 { 247 strcpy(arg1, arg2); 248 devc = 1; 249 } Also affected: commands show DEVICE <...> allow DEVICE <...> disconnect DEVICE <...> deny DEVICE <...> disable DEVICE <...> Quick demonstration: # gdb --args termnetd -s 7778 -v -n Starting program: /usr/sbin/termnetd -s 7779 -v -n termnetd[18701]: openSockets():getting host entry for the control port 7779 termnetd[18701]: openSockets():Control Port = 7779 termnetd[18701]: openSockets():Listening on Control Port termnetd[18701]: Ready to Accept Connections termnetd[18701]: socketSlect():Adding control port! termnetd[18701]: socketSlect():Have Control Opened! termnetd[18701]: socketSlect():Socket accepted, port 10! termnetd[18701]: socketSlect():ControlDataSock = -1! termnetd[18701]: socketSlect():maxFD = 11! $ telnet localhost 7778 show DEVICE BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB ... Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) q To fix this maybe the arg1 pointer could just be changed instead of copying the string? I haven't tested whether this works, but have a look at the attached sredird-control-bof.diff for what I mean. The alternative would be to make them fixed-size strncpy()s. parseRE() overflow ------------------ termnetd/tndAdmin.c: 949 char *getStr(char *pBuf, const char *cp) 950 { .. 957 while (*cp) 958 { .. 960 if (!escape) 961 { .. 986 if (*cp == '\t') 987 { 988 ch = ' '; 989 } 990 else 991 ch = *cp; .. 993 *(pBuf++) = ch; 994 *pBuf = '\0'; 995 cp++; 1012 char *parseRE(ControlStruct *p, const char *pStr) 1013 { 1014 int x, err; 1015 char tmpBuf[20], *cp, *cp1, *rv; 1016 char portStr[80], devcStr[80], errBuf[80]; 1017 1018 strcpy(portStr, ".*"); 1019 strcpy(devcStr, ".*"); 1020 cp = (char*)pStr; 1021 for (;;) 1022 { .. 1031 if (strcmp(tmpBuf, "port") == 0) 1032 cp = getStr(portStr, cp); 1033 else if (strcmp(tmpBuf, "device") == 0) 1034 cp = getStr(devcStr, cp); getStr() copies the input string to the target buffer without bounds checking. When pStr is sufficiently large, getStr() can cause here a stack overflow past portStr[80] and devcStr[80]. For a fix, I'd make the caller specify how much may be written by getStr(), see attached patch-getstr-bof.diff. Again it's not very well tested, sorry for lacking the time currently to do this properly. If you have any questions, or I have missed something, please let me know. Greets, Max -- 308E81E7B97963BCA0E6ED889D5BD511B7CDA2DC --- tnlSubOptions.c.orig 2004-06-29 11:30:54.000000000 +0200 +++ tnlSubOptions.c 2004-06-29 11:31:04.000000000 +0200 @@ -76,7 +76,7 @@ */ static void getOption(int ch) { - if (strlen(optionBuffer) < sizeof(optionBuffer) - 1) + if (pOption - optionBuffer < sizeof(optionBuffer) - 1) { *(pOption++) = ch; *pOption = '\0'; --- tnlSubOptions.c.orig 2004-06-29 11:06:56.000000000 +0200 +++ tnlSubOptions.c 2004-06-29 11:07:40.000000000 +0200 @@ -121,7 +121,7 @@ if (dbg) syslog(LOG_DEBUG, "doSubOption():Option |%s|", optionBuffer); if (dbg) syslog(LOG_DEBUG, "doSubOption():Copying new option |%s| to %lx", optionBuffer, (unsigned long)pSubOptions[option]); - strcpy(pSubOptions[option], optionBuffer); + strncpy(pSubOptions[option], optionBuffer, 127); if (dbg) syslog(LOG_DEBUG, "doSubOption():Calling Call Back"); doCallBack(TNL_ISSUBOPTDATA_CB, option, (void *)pSubOptions[option], NULL); if (dbg) syslog(LOG_DEBUG, "doSubOption():Exit"); @@ -142,7 +142,7 @@ if (dbg) syslog(LOG_DEBUG, "tnlSetSubOption(%d, |%s|):Enter", opt, pStr); if (dbg) syslog(LOG_DEBUG, "tnlSetSubOption():Copying string to %lx", (unsigned long)pSubOptions[opt]); - strcpy(pSubOptions[opt], pStr); + strncpy(pSubOptions[opt], pStr, 127); rv = 0; if (dbg) syslog(LOG_DEBUG, "tnlSetSubOption():Exit(%d)", rv); return(rv); --- tndControl.c.orig 2004-06-29 11:35:53.000000000 +0200 +++ tndControl.c 2004-06-29 11:39:16.000000000 +0200 @@ -74,7 +74,7 @@ *cp = toupper(*cp); if (strcmp(tbuf, "DEVICE") == 0) { - strcpy(arg1, arg2); + arg1 = arg2; devc = 1; } else if (strcmp(tbuf, "ALL") == 0) @@ -119,7 +119,7 @@ *cp = toupper(*cp); if (strcmp(tbuf, "DEVICE") == 0) { - strcpy(arg1, arg2); + arg1 = arg2; devc = 1; } if (strlen(arg1) > 0) @@ -159,7 +159,7 @@ *cp = toupper(*cp); if (strcmp(tbuf, "DEVICE") == 0) { - strcpy(arg1, arg2); + arg1 = arg2; devc = 1; } if (strlen(arg1) > 0) @@ -200,7 +200,7 @@ *cp = toupper(*cp); if (strcmp(tbuf, "DEVICE") == 0) { - strcpy(arg1, arg2); + arg1 = arg2; devc = 1; } if (strlen(arg1) > 0) @@ -244,7 +244,7 @@ *cp = toupper(*cp); if (strcmp(tbuf, "DEVICE") == 0) { - strcpy(arg1, arg2); + arg1 = arg2; devc = 1; } if (strlen(arg1) > 0) @@ -286,7 +286,7 @@ *cp = toupper(*cp); if (strcmp(tbuf, "DEVICE") == 0) { - strcpy(arg1, arg2); + arg1 = arg2; devc = 1; } if (strlen(arg1) > 0) --- tndAdmin.c.orig 2004-06-29 11:41:04.000000000 +0200 +++ tndAdmin.c 2004-06-29 11:40:27.000000000 +0200 @@ -946,7 +946,7 @@ } } -char *getStr(char *pBuf, const char *cp) +char *getStr(char *pBuf, int maxsize, const char *cp) { int escape = 0; char quote = '\0', ch, *tp; @@ -954,7 +954,7 @@ tp = pBuf; if (dbg) syslog(LOG_DEBUG, "getStr():Enter"); while (isspace(*cp)) cp++; - while (*cp) + while (*cp && maxsize > 0) { if (dbg) syslog(LOG_DEBUG, "getStr():Have char %2x, escape = %d", *cp, escape); if (!escape) @@ -993,6 +993,7 @@ *(pBuf++) = ch; *pBuf = '\0'; cp++; + maxsize--; } else { @@ -1003,6 +1004,7 @@ if (dbg) syslog(LOG_DEBUG, "getStr():Adding char %2x", ch); *(pBuf++) = *(cp++); *pBuf = '\0'; + maxsize--; } } if (dbg) syslog(LOG_DEBUG, "getStr():Returning string |%s| and |%s|", tp, cp); @@ -1029,9 +1031,9 @@ *cp1 = '\0'; } if (strcmp(tmpBuf, "port") == 0) - cp = getStr(portStr, cp); + cp = getStr(portStr, sizeof(portStr), cp); else if (strcmp(tmpBuf, "device") == 0) - cp = getStr(devcStr, cp); + cp = getStr(devcStr, sizeof(portStr), cp); else { break; ----- End forwarded message ----- --------------------------------------- Received: (at 267101-close) by bugs.debian.org; 6 May 2005 18:12:12 +0000 >From [EMAIL PROTECTED] Fri May 06 11:12:12 2005 Return-path: <[EMAIL PROTECTED]> Received: from newraff.debian.org [208.185.25.31] (mail) by spohr.debian.org with esmtp (Exim 3.35 1 (Debian)) id 1DU7J6-0004dy-00; Fri, 06 May 2005 11:12:12 -0700 Received: from katie by newraff.debian.org with local (Exim 3.35 1 (Debian)) id 1DU79c-0005qf-00; Fri, 06 May 2005 14:02:24 -0400 From: Oliver Kurth <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] X-Katie: $Revision: 1.55 $ Subject: Bug#267101: fixed in termpkg 3.3-2 Message-Id: <[EMAIL PROTECTED]> Sender: Archive Administrator <[EMAIL PROTECTED]> Date: Fri, 06 May 2005 14:02:24 -0400 Delivered-To: [EMAIL PROTECTED] X-Spam-Checker-Version: SpamAssassin 2.60-bugs.debian.org_2005_01_02 (1.212-2003-09-23-exp) on spohr.debian.org X-Spam-Status: No, hits=-6.0 required=4.0 tests=BAYES_00,HAS_BUG_NUMBER autolearn=no version=2.60-bugs.debian.org_2005_01_02 X-Spam-Level: X-CrossAssassin-Score: 3 Source: termpkg Source-Version: 3.3-2 We believe that the bug you reported is fixed in the latest version of termpkg, which is due to be installed in the Debian FTP archive: termnet_3.3-2_i386.deb to pool/main/t/termpkg/termnet_3.3-2_i386.deb termnetd_3.3-2_i386.deb to pool/main/t/termpkg/termnetd_3.3-2_i386.deb termpkg_3.3-2.diff.gz to pool/main/t/termpkg/termpkg_3.3-2.diff.gz termpkg_3.3-2.dsc to pool/main/t/termpkg/termpkg_3.3-2.dsc ttyd_3.3-2_i386.deb to pool/main/t/termpkg/ttyd_3.3-2_i386.deb A summary of the changes between this version and the previous one is attached. Thank you for reporting the bug, which will now be closed. If you have further comments please address them to [EMAIL PROTECTED], and the maintainer will reopen the bug report if appropriate. Debian distribution maintenance software pp. Oliver Kurth <[EMAIL PROTECTED]> (supplier of updated termpkg package) (This message was generated automatically at their request; if you believe that there is a problem with it please contact the archive administrators by mailing [EMAIL PROTECTED]) -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Format: 1.7 Date: Mon, 25 Apr 2005 10:20:19 -0700 Source: termpkg Binary: termnetd ttyd termnet Architecture: source i386 Version: 3.3-2 Distribution: unstable Urgency: low Maintainer: Oliver Kurth <[EMAIL PROTECTED]> Changed-By: Oliver Kurth <[EMAIL PROTECTED]> Description: termnet - Simple Telnet replacement for termnetd termnetd - Terminal Server daemon ttyd - Remote Modem Utility for Unix Closes: 263744 265645 267101 Changes: termpkg (3.3-2) unstable; urgency=low . * fixed several vulnerabilities send by Max Vozeler <[EMAIL PROTECTED]> (closes: #267101) * make it compile with gcc 3.4 (closes: #263744) * use #define __USE_MISC before #include <termios.h> to make it compile on Alpha (closes: #265645) Files: 889e3af59b92d5b27343b6b9ac8f86d2 572 net optional termpkg_3.3-2.dsc 43ad80bce712260da3ea5aa8f07e1686 4499 net optional termpkg_3.3-2.diff.gz ea0392733ba46a9b8f88dbb1632487ec 19420 net optional ttyd_3.3-2_i386.deb 9a2d1a3ba340824fd0bb7cb7a8dc4c04 32530 net optional termnetd_3.3-2_i386.deb 3f7e37b3449e0a0ea82a531072c5d37d 19300 net optional termnet_3.3-2_i386.deb -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCe612UmVSJkUeqxsRAjAkAJ9oFzEYYhKic+r/Iob3yldQi/t9FwCgyBAs hc9fDzjnDwez0K1lh3m34xc= =FBYB -----END PGP SIGNATURE----- -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]