**************************************************************************
Security Bulletin 9713 DISA Defense Communications System
June 2, 1997 Published by: DISN Security Coordination Center
(SCC@NIC.MIL)
1-(800) 365-3642
The DISN SECURITY BULLETIN is distributed by the DISN SCC (Security Coordination Center) under DISA contract as a means of communicating information on network and host security exposures, fixes, and concerns to security and management personnel at DISN facilities. Back issues may be obtained via FTP (or Kermit) from NIC.MIL [207.132.116.5] using login="anonymous" and password="guest". The bulletin pathname is scc/sec-yynn.txt (where "yy" is the year the bulletin is issued and "nn" is a bulletin number, e.g. scc/sec-9615.txt). They are also available on our WWW site at http://nic.mil.
**************************************************************************
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
! !
! The following important advisory was issued by the Computer !
! Emergency Response Team (CERT) and is being relayed unedited !
! via the Defense Information Systems Agency's Security !
! Coordination Center distribution system as a means of !
! providing DISN subscribers with useful security information. !
! !
+ - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - +
- -----------------------------------------------------------------------------
The CERT Coordination Center has received reports of a buffer overflow condition in suidperl built from Perl 4.n and Perl 5.n distributions on UNIX systems. By calling this program with appropriately crafted parameters, unauthorized local users can execute arbitrary commands as root. This vulnerability is being actively exploited.
The CERT/CC team recommends installing a vendor patch if one is available (see Section III.B). Until you can do so, we recommend disabling suidperl (Section III.A). Two other alternatives are to install suidperl or sperl from version 5.003 source code along with the patch provided in Appendix B of this advisory (see also Section III.C), or upgrade to Perl version 5.004 (Section III.D). Note that Perl4 is no longer supported.
We will update this advisory as we receive additional information.
Please check our advisory files regularly for updates that relate to your site.
- -----------------------------------------------------------------------------
On some systems, setuid and setgid scripts (scripts written in the C shell, Bourne shell, or Perl, for example, with the set user or group ID permissions enabled) are insecure due to a race condition in the kernel. For those systems, Perl versions 4 and 5 attempt to work around this vulnerability with a special program named suidperl, also known as sperl. This program attempts to emulate the set-user-ID and set-group-ID features of the kernel.
There is a buffer overflow condition in suidperl built from Perl 4.n and Perl 5.n distributions earlier than version 5.004. If this program is called with appropriately crafted parameters, an attacker can execute arbitrary commands as root. This vulnerability is being actively exploited.
Users executing Perl scripts with the setuid bit
set can execute arbitrary commands with the effective uid of the
owner of the Perl script. Attackers can execute commands as root.
Use the command in Section A to help you determine if your system is vulnerable and, if it is, to (optionally) disable the suidperl and sperl programs (see Section A). If you find that your system is vulnerable, replace the suidperl and sperl programs with new versions.
Section B describes how to do that if your site uses versions of suidperl and sperl that are provided as part of a vendor-supplied distribution. Sites that installed suidperl and sperl programs themselves from the Perl source distribution should patch the distribution as described in Section C or upgrade to version 5.004 as described in Section D. Note that Perl4 is no longer supported.
To determine if a system is vulnerable to this problem and to disable the programs that are believed to be vulnerable, use the following find command or a variant. Consult your local system documentation to determine how to tailor the find program on your system.
After you have run this command on all your systems, they will no longer be vulnerable. Note that after disabling the suidperl and sperl programs, they will no longer be able to emulate the set-user-ID and set-group-ID features of the kernel.
You will need to run the find command on each system you maintain because the command examines files on the local disk only. Substitute the names of your local file systems for FILE_SYSTEM_NAMES in the example. Example local file system names are /, /usr, and /var. You must do this as root.
Note that this is one long command, though we have separated it onto five lines using back-slashes.
find FILE_SYSTEM_NAMES -xdev -type f -user root \
\( -name 'sperl4.[0-9][0-9][0-9]' \
If your vendor ships suidperl or sperl, you may be vulnerable and need a patch. Appendix A contains information provided by the following vendors. If your vendor is not on this list, please contact the vendor directly.
Until you can install a patch, we recommend disabling
suidperl. The find command above will help you do that. If you
need suidperl or sperl, see the alternatives in Sections C and
D below.
Follow the instructions below, which were provided by Chip Salzenberg.
If you would like to keep using setuid Perl scripts, fix Perl yourself by following these steps:
Perl 5.003 distribution from
http://www.perl.com/CPAN/src/5.0/perl5.003.tar.gz
or another CPAN archive accessible to you.
This file is approximately 1.5 megabytes in size.
Perl 5.003 binaries that have had this patch applied,
and therefore are safe from all known attacks, can be identified
by the output of the "perl -v" command: the "locally
applied patches" list will include "SUIDBUF - Buffer
overflow fixes for suidperl security".
If you would like to upgrade to Perl version 5.004, follow these steps:
http://www.perl.com/CPAN/src/5.0/perl5.004.tar.gz
or another CPAN archive accessible to you.
This file is approximately 2.5 megabytes in size.
Perl 5.004 binaries, which are safe from all known
attacks, can be identified by the output of the "perl -v"
command: it should say "This is perl, version 5.004".
(Unlike the 5.003 patch mentioned in Section C, the "locally
applied patches" list will NOT include "SUIDBUF - Buffer
overflow fixes for suidperl security". The fact that it is
version 5.004 is sufficient in this case.)
...........................................................................
Below is a list of the vendors who have provided
information for this advisory. We will update this appendix as
we receive additional information. If you do not see your vendor's
name, the CERT/CC did not hear from that vendor. Please contact
the vendor directly.
=====================================
BSD/OS is vulnerable to the suidperl (sperl) buffer
overflow problem. We will be releasing a patch for BSDI 3.0 and
perl 5.003 and are currently working on patches for BSD/OS 3.0
and Perl 4.036. We will also be developing patches for the perl
versions shipped with BSD/OS 2.1.
Cray Research does not ship perl as part of either
Unicos or Unicos/mk.
The only perl executables that are shipped with DG/UX are:
/bin/perl
and
/bin/perl5 /* in R420 */
These are not set uid programs.
HP does not ship this product.
AIX versions do not have Perl as part of the standard product. However, the SP2's PSSP software does contain suidperl, but the program is not installed with the setuid bit set.
IBM and AIX are registered trademarks of International
Business Machines Corporation.
Red Hat 4.2 is not vulnerable
Red Hat 4.1/4.0 you can get the upgraded RPM from ftp.redhat.com
If you wish to check whether you have the fixed perl run perl -v and
check for
Locally applied patches:
SUIDBUF - Buffer overflow fixes for suidperl security
====================================
suidperl is not included in any SCO products.
SCO CMW+ and SCO OpenServer do not have kernel support for setuid scripts, but you may have installed suidperl in order to emulate that functionality - in that case you should replace your version of perl with version 5.004, or patch your source code as noted in this advisory.
SCO UnixWare does have safe kernel support for setuid
scripts so that suidperl is not necessary. If you have installed
a version of perl that includes suidperl, you should remove suidperl
and install a version of perl built so as not to require it.
=============================
At this time, Silicon Graphics does not have any public information for this suidperl/sperl issue. Silicon Graphics has communicated with CERT and other external security parties and is actively investigating this issue. When more Silicon Graphics information (including any possible patches) is available for release, that information will be released via the SGI security mailing list, wiretap.
For subscribing to the wiretap mailing list and other SGI security related information, please refer to the Silicon Graphics Security Headquarters website located at:
http://www.sgi.com/Support/Secur/security.html
...........................................................................
Appendix B - Source Code Patch Information
The following patch information has been supplied
by Chip Salzenberg. If you built suidperl or sperl from 5.003
source code, we encouraged you to apply this patch (see the explanation
in Section III.C above).
Patch follows.
- --------------------------------------------------------------------------
***************
+ ,"SUIDBUF - Buffer overflow fixes for suidperl security"
,NULL
};
! fputs("\n\t+ suidperl security patch", stdout);
fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout);
! fputs("\n\t+ two suidperl security patches", stdout);
fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout);
#ifdef MSDOS
{
! char tmpbuf[1200];
GV *gv;
! sprintf(tmpbuf,"::_<%s", name);
gv = gv_fetchpv(tmpbuf, TRUE, SVt_PVGV);
sv_setpv(GvSV(gv), name);
if (*name == '/' && (instr(name,"/lib/") || instr(name,".pm")))
- --- 59,80 ----
char *name;
{
! char smallbuf[256];
! char *tmpbuf;
! STRLEN tmplen;
GV *gv;
! tmplen = strlen(name) + 4;
! if (tmplen < sizeof smallbuf)
! tmpbuf = smallbuf;
! else
! New(603, tmpbuf, tmplen + 1, char);
! tmpbuf[0] = ':';
! tmpbuf[1] = ':';
! tmpbuf[2] = '_';
! tmpbuf[3] = '<';
! strcpy(tmpbuf + 4, name);
gv = gv_fetchpv(tmpbuf, TRUE, SVt_PVGV);
! static char *scan_ident _((char *s, char *send, char *dest, I32 ck_uni)); static char *scan_inputsymbol _((char *start)); static char *scan_pat _((char *start));
! static char *scan_ident _((char *s, char *send, char *dest, STRLEN destlen, ! I32 ck_uni)); static char *scan_inputsymbol _((char *start)); static char *scan_pat _((char *start));
! static char *scan_word _((char *s, char *dest, int allow_package, STRLEN *slp)); static char *skipspace _((char *s)); static void checkcomma _((char *s, char *name, char *what));
! static char *scan_word _((char *s, char *dest, STRLEN destlen, ! int allow_package, STRLEN *slp)); static char *skipspace _((char *s)); static void checkcomma _((char *s, char *name, char *what));
+
/* The following are arranged oddly so that the guard on the switch statement
(allow_tick && *s == '\'') )
{
! s = scan_word(s, tokenbuf, allow_pack, &len);
if (check_keyword && keyword(tokenbuf, len))
return start;
- --- 479,483 ----
{
! s = scan_word(s, tokenbuf, sizeof tokenbuf, allow_pack, &len);
if (check_keyword && keyword(tokenbuf, len))
return start;
! char tmpbuf[512];
if (!send) /* has to be an expression */
- --- 851,855 ----
unsigned char un_char = 0, last_un_char; char *send = strchr(s,']');
! char tmpbuf[sizeof tokenbuf * 4];
if (!send) /* has to be an expression */
! scan_ident(s,send,tmpbuf,FALSE);
if ((int)strlen(tmpbuf) > 1 && gv_fetchpv(tmpbuf,FALSE, SVt_PV))
weight -= 100;
weight -= seen[un_char] * 10;
if (isALNUM(s[1])) {
! scan_ident(s, send, tmpbuf, sizeof tmpbuf, FALSE);
if ((int)strlen(tmpbuf) > 1 && gv_fetchpv(tmpbuf,FALSE, SVt_PV))
weight -= 100;
*** 942,946 ****
{
char *s = start + (*start == '$');
! char tmpbuf[1024];
STRLEN len;
GV* indirgv;
- --- 946,950 ----
{
char *s = start + (*start == '$');
! char tmpbuf[sizeof tokenbuf];
STRLEN len;
GV* indirgv;
*************** GV *gv;
*** 952,956 ****
gv = 0;
}
! s = scan_word(s, tmpbuf, TRUE, &len);
if (*start == '$') {
if (gv || last_lop_op == OP_PRINT || isUPPER(*tokenbuf))
gv = 0;
}
! s = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
if (*start == '$') {
if (gv || last_lop_op == OP_PRINT || isUPPER(*tokenbuf))
*** 1629,1633 ****
case '*':
if (expect != XOPERATOR) {
! s = scan_ident(s, bufend, tokenbuf, TRUE);
expect = XOPERATOR;
force_ident(tokenbuf, '*');
- --- 1633,1637 ----
case '*':
if (expect != XOPERATOR) {
! s = scan_ident(s, bufend, tokenbuf, sizeof tokenbuf, TRUE);
expect = XOPERATOR;
force_ident(tokenbuf, '*');
case '%':
if (expect != XOPERATOR) {
! s = scan_ident(s, bufend, tokenbuf + 1, TRUE);
if (tokenbuf[1]) {
expect = XOPERATOR;
case '%':
if (expect != XOPERATOR) {
! s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, TRUE);
if (tokenbuf[1]) {
expect = XOPERATOR;
*** 1748,1752 ****
s++;
if (s < bufend && isALPHA(*s)) {
! d = scan_word(s, tokenbuf, FALSE, &len);
while (d < bufend && (*d == ' ' || *d == '\t'))
d++;
- --- 1752,1756 ----
s++;
if (s < bufend && isALPHA(*s)) {
! d = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len);
while (d < bufend && (*d == ' ' || *d == '\t'))
d++;
}
! s = scan_ident(s-1, bufend, tokenbuf, TRUE);
if (*tokenbuf) {
expect = XOPERATOR;
- --- 1851,1855 ----
}
! s = scan_ident(s - 1, bufend, tokenbuf, sizeof tokenbuf, TRUE);
if (*tokenbuf) {
expect = XOPERATOR;
case '$':
if (s[1] == '#' && (isALPHA(s[2]) || strchr("_{$:", s[2]))) {
! s = scan_ident(s+1, bufend, tokenbuf+1, FALSE);
if (expect == XOPERATOR) {
if (lex_formbrack && lex_brackets == lex_formbrack) {
- --- 1960,1965 ----
case '$':
if (s[1] == '#' && (isALPHA(s[2]) || strchr("_{$:", s[2]))) {
! s = scan_ident(s + 1, bufend, tokenbuf + 1, sizeof tokenbuf - 1,
! FALSE);
if (expect == XOPERATOR) {
if (lex_formbrack && lex_brackets == lex_formbrack) { *************** yylex()
*** 1982,1986 ****
}
! s = scan_ident(s, bufend, tokenbuf+1, FALSE);
if (expect == XOPERATOR) {
if (lex_formbrack && lex_brackets == lex_formbrack) {
- --- 1987,1991 ----
}
! s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, FALSE);
if (expect == XOPERATOR) {
if (lex_formbrack && lex_brackets == lex_formbrack) {
if (*s == '{' && strEQ(tokenbuf, "$SIG") &&
(t = strchr(s,'}')) && (t = strchr(t,'='))) {
! char tmpbuf[1024];
STRLEN len;
for (t++; isSPACE(*t); t++) ;
if (isIDFIRST(*t)) {
! t = scan_word(t, tmpbuf, TRUE, &len);
if (*t != '(' && perl_get_cv(tmpbuf, FALSE))
warn("You need to quote \"%s\"", tmpbuf);
- --- 2021,2029 ----
if (*s == '{' && strEQ(tokenbuf, "$SIG") &&
(t = strchr(s,'}')) && (t = strchr(t,'='))) {
! char tmpbuf[sizeof tokenbuf];
STRLEN len;
for (t++; isSPACE(*t); t++) ;
if (isIDFIRST(*t)) {
! t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE, &len);
if (*t != '(' && perl_get_cv(tmpbuf, FALSE))
warn("You need to quote \"%s\"", tmpbuf);
case '@':
! s = scan_ident(s, bufend, tokenbuf+1, FALSE);
if (expect == XOPERATOR)
no_op("Array",s);
- --- 2098,2102 ----
case '@':
! s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, FALSE);
if (expect == XOPERATOR)
no_op("Array",s);
: !GvHV(gv) )))
{
! char tmpbuf[1024];
sprintf(tmpbuf, "Literal @%s now requires backslash",tokenbuf+1);
yyerror(tmpbuf);
- --- 2134,2138 ----
{
! char tmpbuf[sizeof tokenbuf + 40];
sprintf(tmpbuf, "Literal @%s now requires backslash",tokenbuf+1);
yyerror(tmpbuf);
keylookup:
bufptr = s;
! s = scan_word(s, tokenbuf, FALSE, &len);
if (*s == ':' && s[1] == ':' && strNE(tokenbuf, "CORE"))
- --- 2298,2302 ----
keylookup:
bufptr = s;
! s = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len);
if (*s == ':' && s[1] == ':' && strNE(tokenbuf, "CORE"))
if (*s == '\'' || *s == ':' && s[1] == ':') {
! s = scan_word(s, tokenbuf + len, TRUE, &len);
if (!len)
croak("Bad name after %s::", tokenbuf);
- --- 2343,2348 ----
if (*s == '\'' || *s == ':' && s[1] == ':') {
! s = scan_word(s, tokenbuf + len, sizeof tokenbuf - len,
! TRUE, &len);
if (!len)
croak("Bad name after %s::", tokenbuf);
*** 2557,2561 ****
s += 2; d = s;
! s = scan_word(s, tokenbuf, FALSE, &len);
tmp = keyword(tokenbuf, len);
if (tmp < 0)
- --- 2563,2567 ----
s += 2; d = s;
! s = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len);
tmp = keyword(tokenbuf, len);
if (tmp < 0)
if (isIDFIRST(*s) || *s == '\'' || *s == ':') {
! char tmpbuf[128];
expect = XBLOCK;
! d = scan_word(s, tmpbuf, TRUE, &len);
if (strchr(tmpbuf, ':'))
sv_setpv(subname, tmpbuf);
- --- 3250,3256 ----
if (isIDFIRST(*s) || *s == '\'' || *s == ':') {
! char tmpbuf[sizeof tokenbuf];
expect = XBLOCK;
! d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
if (strchr(tmpbuf, ':'))
sv_setpv(subname, tmpbuf);
{
if (isALNUM(*s))
*d++ = *s++;
- --- 4097,4112 ----
{
register char *d = dest;
*d++ = *s++;
*** 4119,4129 ****
{
- --- 4129,4141 ----
I32 ck_uni;
{
register char *d;
s = skipspace(s);
d = dest;
if (isDIGIT(*s)) {
! while (isDIGIT(*s))
*d++ = *s++;
}
else {
for (;;) {
if (isALNUM(*s))
- --- 4146,4161 ----
s = skipspace(s); d = dest;
! while (isDIGIT(*s)) {
! if (d >= e)
! croak(too_long);
*d++ = *s++;
+ }
}
else {
for (;;) {
*d++ = *s++;
- --------------------------------------------------------------------------
End of patch.
- -----------------------------------------------------------------------------
The CERT Coordination Center staff thanks Chip Salzenberg for supplying a fix, Larry Wall for tweaking the fix, and Warner Losh for his work on patches.
- -----------------------------------------------------------------------------
If you believe that your system has been compromised,
contact the CERT Coordination Center or your representative in
the Forum of Incident Response and Security Teams (see http://www.first.org/team-info/)
- ----------------------------
Email cert@cert.org
Phone +1 412-268-7090 (24-hour hotline)
CERT personnel answer 8:30-5:00 p.m. EST(GMT-5) / EDT(GMT-4)
and are on call for emergencies during
other hours.
Fax +1 412-268-6989
We strongly urge you to encrypt sensitive information sent by email. We can support a shared DES key or PGP. Contact the CERT/CC for more information.
ftp://info.cert.org/pub/CERT_PGP.key
CERT publications and other security information are available from
CERT advisories and bulletins are also posted on the USENET newsgroup
comp.security.announce
To be added to our mailing list for advisories and bulletins, send
email to
cert-advisory-request@cert.org
In the subject line, type
SUBSCRIBE your-email-address
- ---------------------------------------------------------------------------
This material may be reproduced and distributed without permission provided it is used for noncommercial purposes and the copyright statement is included.
The CERT Coordination Center is part of the Software Engineering Institute (SEI). The SEI is sponsored by the U.S. Department of Defense.
- ---------------------------------------------------------------------------
This file: ftp://info.cert.org/pub/cert_advisories/CA-97.17.sperl
http://www.cert.org
click on "CERT Advisories"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****************************************************************************
* *
* *
* *
* *
* *
* *
* *
* *
****************************************************************************
PLEASE NOTE: Some users outside of the DOD computing communities may receive DISN Security Bulletins. If you are not part of the DOD community, please contact your agency's incident response team to report incidents. Your agency's team will coordinate with DOD. The Forum of Incident Response and Security Teams (FIRST) is a world-wide organization. A list of FIRST member organizations and their constituencies can be obtained by sending email to docserver@first.org with an empty subject line and a message body containing the line: send first-contacts.
This document was prepared as an service to the DOD
community. Neither the United States Government nor any of their
employees, makes any warranty, expressed or implied, or assumes
any legal liability or responsibility for the accuracy, completeness,
or usefulness of any information, product, or process disclosed,
or represents that its use would not infringe privately owned
rights. Reference herein to any specific commercial products,
process, or service by trade name, trademark manufacturer, or
otherwise, does not necessarily constitute or imply its endorsement,
recommendation, or favoring by the United States Government.
The opinions of the authors expressed herein do not necessarily
state or reflect those of the United States Government, and shall
not be used for advertising or product endorsement purposes.