Local privilege escalation from a limited shell with selinux enabled on an old Linux box
Hello all! First time poster here
I have always been interested in infosec but lately I’ve been reading a lot about topics like network security, penetration testing, reverse engineering with the objective that I’ll change careers to something more security-focused.
Sorry for the long intro. I’ve been working on this project for the past month trying to hack into a Linux box I’ve installed in a Vmware machine. I’ve looked into Metasploitable and Damn Vulnerable Linux (but those were a bit artificial), so I’ve chosen an old Linux image (Centos) version with the hopes that it will be easy to exploit and a good playground for exercising my skills. Boy was I wrong
I’ve chosen CentOS-5.0 and downloaded the image from this location: http://ftp.iij.ad.jp/pub/linux/centos-vault/5.0/isos/i386/
$ uname -r 2.6.18-8.el5
The services that I got running are the following (with mysql only accessible from localhost):
22/tcp open ssh OpenSSH 4.3 (protocol 2.0) 80/tcp open http Apache httpd 2.2.3 ((CentOS)) 3306/tcp open mysql MySQL 5.0.22
So my imagined scenario is this: would it be possible to gain root privileges starting from a vulnerable web application? Let’s assume an attacker already managed to upload a script to the server. So I just uploaded a reverse php shell script (I used https://github.com/pentestmonkey/php-reverse-shell). Didn’t work at first until I realized I have to change the listener on my host to port 80 or 443 because the firewall on the virtual machine prevented outbound traffic on most of the other ports.
Now I start my listener and access the php script from the browser and I get this:
nc -lvp 80 Listening on [0.0.0.0] (family 0, port 80) Connection from 192.168.144.136 38210 received! Linux localhost.localdomain 2.6.18-8.el5 #1 SMP Thu Mar 15 19:57:35 EDT 2007 i686 i686 i386 GNU/Linux 14:52:43 up 24 min, 0 users, load average: 0.00, 0.00, 0.00 USER TTY FROM [email protected] IDLE JCPU PCPU WHAT uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0 sh: no job control in this shell sh-3.1$
Pretty cool. However, this shell is really limited as it runs as “apache” user and with selinux enabled, it’s crippled. So how do I get access to a root shell?
I tried to see if there are any interesting processes, files, cron jobs and if there are any exploitable SUID binaries but of course this wasn’t the case since it’s mostly a clean install. I noticed however I was able to connect to mysql (
mysql -u root -p) but of course any commands I executed were in the context of the apache user
Exploiting mysql through UDF was something I considered, but there was no way I could write to the /usr/lib folder to create any loadable shared libs.
Since this is an old kernel, I tried some of the popular kernel exploits. I used a suggester for that (https://github.com/jondonas/linux-exploit-suggester-2) and it created this list:
I downloaded them from https://github.com/lucyoa/kernel-exploits. Some of them worked if I cheated and disabled selinux with root (e.g. udp_sendmsg), but since I wanted to exploit this box with selinux enabled, I want to find a way without cheating. All of the exploits failed (or were not applicable) with selinux enabled except one… well, kind of. vmsplice1 failed but it halted the CPU and I had to do a manual restart of the virtual machine. Pretty interesting I thought. There must be some kind of vulnerability then, but not sure yet if exploitable or not.
So I run the exploit again (this time from a regular user shell for convenience):
$ strace ./vmsplice1
… and I get this output: https://pastebin.com/raw/SMMx85My
One thing I notice immediately is this:
vmsplice(0x4, 0xbfbac958, 0x1, 0) = -1 ENOSYS (Function not implemented) sigh I think it means the function is not available, right?
But then how is it possible that the CPU halts, there must be some kind of security hole still left.
So I think my best options so far are these:
- Find a way to make the vmsplice exploit work
- Or try to find a way to disable selinux from an apache shell
For the 1st one I’ve been digging into the code and reading on kernel exploitation books but I think I’m still pretty far off. For the 2nd one I’ve tried calling selinux functions with the addresses obtained from
/proc/kallsyms, but no
What do you think? Do you think there’s another way and I’m not looking in the right place? If you have any suggestions on where to go from here, please leave a reply. Thank you