Files
cdesktop/cde/programs/dtprintinfo
Jon Trulson 30cd56ac38 dtprintinfo: Fix a potential exploitable buffer overrun
This fixes a potentially exploitable buffer overrun in dtprintinfo.
This was brought to my attention based on a 0day exploit released for
Solaris CDE.

The exploit code does not work (or build) on linux, and the overrun is
in the heap rather than the stack as on Solaris, but it's easy to see
how this could be exploited.

The following is the content of the advisory:

8<-----------------------------------------------------------

@Mediaservice.net (Cybaze Group) Security Advisory #2019-01 (2019-05-07)

         Title:	Local privilege escalation via CDE dtprintinfo
   Application:	Common Desktop Environment 2.3.0 and earlier
     Platforms:	Oracle Solaris 10 1/13 (Update 11) and earlier
   Description:	A local attacker can gain root privileges by exploiting
		a buffer overflow in CDE dtprintinfo
        Author:	Marco Ivaldi <marco.ivaldi@mediaservice.net>
   Contributor:	Dave Aitel <dave.aitel@cyxtera.com> (original discovery)
 Vendor Status:	<secalert_us@oracle.com> notified on 2019-05-05
		<cdesktopenv-devel@lists.sourceforge.net> notified on 2019-05-05
           CVE:	The Common Vulnerabilities and Exposures project has not assigned
		a name to this issue yet
    References: https://lab.mediaservice.net/advisory/2019-01-cde-dtprintinfo.txt
		https://github.com/0xdea/raptor_infiltrate19
		https://sourceforge.net/p/cdesktopenv/wiki/Home/
		https://www.oracle.com/technetwork/server-storage/solaris10/
		https://www.mediaservice.net/
		https://infiltratecon.com/

1. Abstract.

A buffer overflow in the DtPrinterAction::PrintActionExists() function in the
Common Desktop Environment 2.3.0 and earlier, as used in Oracle Solaris 10 1/13
(Update 11) and earlier, allows local users to gain root privileges via a long
printer name passed to dtprintinfo by a malicious lpstat program.

This is a 0day vulnerability demonstrated at #INFILTRATE19 on May 2nd, 2019 in
the talk "A bug's life: story of a Solaris 0day".

2. Example Attack Session.

bash-3.2$ cat /etc/release
                    Oracle Solaris 10 1/13 s10x_u11wos_24a X86
  Copyright (c) 1983, 2013, Oracle and/or its affiliates. All rights reserved.
                            Assembled 17 January 2013
bash-3.2$ uname -a
SunOS nostalgia 5.10 Generic_147148-26 i86pc i386 i86pc
bash-3.2$ id
uid=54322(raptor) gid=1(other)
bash-3.2$ gcc raptor_dtprintname_intel.c -o raptor_dtprintname_intel -Wall
bash-3.2$ ./raptor_dtprintname_intel 192.168.1.1:0
raptor_dtprintname_intel.c - dtprintinfo 0day, Solaris/Intel
Copyright (c) 2004-2019 Marco Ivaldi <raptor@0xdeadbeef.info>

Using SI_PLATFORM       : i86pc (5.10)
Using stack base        : 0x8047fff
Using rwx_mem address   : 0xfeffa004
Using sc address        : 0x8047f60
Using strcpy() address  : 0xfefe26a0

lpstat called with -v
lpstat called with -v
lpstat called with -d
uid=0(root) gid=1(other)

3. Affected Platforms.

All platforms shipping the Common Desktop Environment are potentially
affected. This includes:

* Oracle Solaris 10 1/13 (Update 11) and earlier [default installation]

According to the CDE Wiki, the following platforms are officially supported:

* All Official Ubuntu variants 12.04 - 18.04
* Debian 6, 7, 8, 9
* Fedora 17 at least
* Archlinux
* Red Hat
* Slackware 14.0
* OpenBSD
* NetBSD
* FreeBSD 9.2, 10.x, 11.x
* openSUSE Tumbleweed (gcc7)
* openSUSE Leap 4.2 (gcc4)
* SUSE 12 SP3 (gcc4)
* Solaris, OpenIndiana

4. Fix.

The upstream CDE maintainers have issued a patch for this vulnerability. Oracle
is investigating the issue via tracking# S1153109 and is expected to release a
fix for all affected-supported versions of Solaris via their quarterly Critical
Patch Update (CPU) program.

As a temporary workaround, it is possible to remove the setuid bit from the
dtprintinfo executable as follows:

bash-3.2# chmod -s /usr/dt/bin/dtprintinfo

5. Proof of Concept.

A working exploit for Oracle Solaris 10 1/13 (Update 11) Intel has been
developed as a proof of concept. Exploits for other Solaris versions and for
the SPARC architecture are also available. All exploits can be downloaded at:

https://github.com/0xdea/raptor_infiltrate19/
https://github.com/0xdea/exploits/

8<-----------------------------------------------------------
2019-05-07 11:21:49 -06:00
..
2018-07-04 01:55:44 +01:00
2018-07-04 01:57:52 +01:00
2018-05-31 22:04:08 -06:00
2014-02-22 19:12:19 -07:00
2018-05-31 22:04:08 -06:00
2014-02-22 19:12:19 -07:00

/* $XConsortium: README /main/2 1996/07/15 14:15:33 drk $ */
Directories:

   libUI              - Contains base class for UI
   libUI/MotifUI      - Contains Motif UI classes
   UI                 - Subclasses of objects in libUI/MotifUI.  These objects
			define the UI for dtprintinfo.
   objects            - Contains base class for objects
   objects/PrintObj   - Contains print queue objects
   util               - Contains utility classes
   service            - No longer used

Actions

 The following actions are defined in /usr/dt/appconfig/types/C/print.dt.

   DtPrintManager - runs 'dtprintinfo -all'

   DtPrint (no args) - runs the DtPrintinfo action

   DtPrint (with args) - runs the Print action

   DtPrintinfo (no args) - runs 'dtprintinfo' to show the LPDEST or
			   default printer

   DtPrintinfo (with args) - runs 'dtprintinfo -p <printer>' to show the
			     specific printer

 The default printer actions are defined in /etc/dt/appconfig/types/C by
 running 'dtprintinfo -populate'.  There's a datatype (action definition)
 file for each queue on the system name <printer>.dt.

   <printer>_Print (no args) - runs the 'DtPrintinfo <printer>' action.

   <printer>_Print (with args) - runs the 'Print' action.

 Printer action files are created in $HOME/.dt/.Printers. These are empty
 files named <printer>_Print and have the execute bit set.  They are the
 action files that are supplied when a printer is dragged from Print Manager
 to the File Manager or Front Panel.

 The CreateActionFile function in UI/DtPrinterIcon.C creates the system action
 definition files in /etc/dt/appconfig/types/$LANG and customized action 
 definition in $HOME/.dt/types.  The Apply function in UI/DtPrtProps.C modifies
 action definition in $HOME/.dt/types.

Drag-n-Drop

   The guts of drag-n-drop (DND) is coded in the libUI/MotifUI/DtDND.C file.
   Currently, only the DtFILENAME_TRANSFER protocol is used.  The printer
   icons, DtPrinterIcon objects defined in UI/DtPrinterIcon.C, use the DtDND
   class to handle files dropped on the printer icon and print job list box and
   to handle dragging printers to other objects.  When a file is dropped on a
   printer or print job list box, dtprintinfo receives a filename and when
   a printer is dragged to an object, dtprintinfo supplies the filename of
   the action file (Example: $HOME/.dt/.Printers/<printer>_Print).

Widgets

   libUI/MotifUI/Icon.c - Custom icon widget used by the IconObj class defined
			  in libUI/MotifUI/IconObj.C.

   libUI/MotifUI/WorkArea.c - Custom container widget used by the Container
			      class defined in libUI/MotifUI/Container.C.

Classes

   There are 2 class hierarchies: an UI class hierarchy and a object class
   hierarchy.  The Motif User Interface classes are defined in the
   libUI/MotifUI directory.  The printer objects are defined in the
   objects/PrintObj directory.  These classes are designed to be used as
   libraries.

Action API's
  
   The DtPrinterIcon class uses the DtDbLoad, DtActionInvoke, DtDbReloadNotify,
   DtActionExists, DtActionIcon, DtActionDescription, and DtActionLabel
   functions.  The DtPrtProps class uses the DtActionInvoke function.  The 
   Application class uses the DtDbLoad function.

Drag-n-Drop API's
  
   The DtDND class uses the XmDropSiteUpdate, XmDropSiteConfigureStackingOrder, 
   DtDndDropRegister, and DtDndDragStart functions.

Remote Printer related API's

   The ConnectToPrintServer function in objects/PrintObj/ParseJobs.C uses the
   gethostbyname, gethostbyaddr, getservbyname, rresvport, and connect
   functions to return a socket to a remote print server.
   
   The SendPrintJobStatusReguest function writes to the socket a request for
   long format printer status.
   
   These two high level functions are called by the OpenClose function in
   UI/DtApp.C and by the ProcessJobs function in objects/PrintObj/Queue.C
   via the call to the RemotePrintJobs function in ParseJobs.C.

   The RemotePrintJobs is a high level function that reads the socket for
   the print status that's returned by the server.  This functions waits for
   the output, thus it blocks the dtprintinfo process.  It is used during the
   'Find Print Jobs' operation in the Print Manager version of dtprintinfo.

   The OpenClose function in UI/DtApp.C uses the BaseUI->Thread function
   function to gather the status returned by the print server so that the
   dtprintinfo process does not block.  This is accomplished by using the
   the fcntl function to set the O_NDELAY bit on the socket and then using the
   socket as the file descriptor in the XtAppAddInput function.  Refer to the
   CreateThread function in libUI/MotifUI/MotifThread.C.

Message Catalog

   The message catalog uses symbolic tags and a MESSAGE macro that makes the
   source code easier to read and modify.  When building dtprintinfo the
   dtprintinfo_cat.h and dtprintinfo_msg.h header are automatically generated
   by the sym2num script, gencat, and awk msg.awk script.  Here's a sample
   output of creating the message header files.

	rm -f dtprintinfo.cat dtprintinfo_msg.h dtprintinfo_cat.h
        ./sym2num dtprintinfo dtprintinfo.msg > msg.tmp
        gencat dtprintinfo.cat msg.tmp
        awk -f msg.awk dtprintinfo.msg > dtprintinfo_cat.h
        rm -f msg.tmp