We left off in the last post with an Remote File Include we discovered (cough planted) through auditing source code in a Wordpress plugin. This vulnerability allows us to execute arbitrary code in the context of the webserver user.
I wanted to keep this demonstration as true to life as possible. That means a recent, common operating system in its default configuration. I chose CentOS 5.3, released in March 2009, and I left SELinux in enforcing mode for added effect. What I didn't realize was just how locked down Apache httpd is in the default SELinux policy. Apache httpd is configured with directory indexes turned on by default but the SELinux privileges httpd_can_network_connect and httpd_can_network_relay are both disabled! I also wasn't able to execute certain binaries like wget and /bin/bash from the httpd process.
In reality, many (most?) CentOS webservers are going to allow httpd_can_network_connect/relay so they can do things like authenticate to LDAP or connect to a remote database server. I could have disabled those privileges by themselves with setsebool, but with limited time remaining to finish the demo, I decided to switch SELinux from enforcing to permissive mode.
Sidenote: How else might I have bypassed SELinux in this scenario? Instead of including PHP code to execute a shell, I could include an exploit for the PHP interpreter itself. Stefan Esser documented how to do this in extreme detail at this year's Blackhat conference. From there I might have been able to escalate privileges or mess with SELinux more easily. I might have done this if I knew the first thing about Linux exploitation (gdb can DIAF).
Free of these restrictions, I was finally able to execute a simple PHP web shell on the server. I went with the capable and modern (postmodern?) PHP-RPC shell included in the Ronin exploitation framework. I loaded the shell over a browser instead of via irb to make the demonstration a bit more in-your-face for the students watching.
I had pretty clearly taken over the website at this point. I could view the wp-config.php file to obtain the MySQL database password, connect directly to it, and pilfer all of the restricted information being stored inside. But real hackers don't stop there. Time to break out the local roots and backdoor this target.
Problem #1: Most local root exploits are made to be executed in a real terminal and they usually spawn a root-owned bash shell. Forget about blocking IO or launching a new shell with an RFI, we're executing remotely over a stateless protocol. That root-owned /bin/bash process you just launched will get lost forever. We have to backdoor the victim non-interactively in a way that gets us better access than this web shell.
Lucky for me, spender released his null dereference kernel exploitation framework complete with three recent kernel exploits a few days prior. His framework can be easily customized in C to launch arbitrary payloads upon successful exploitation. I wanted to avoid touching as much of his code as I could, so I replaced the guts of the RUN_ROOTSHELL if statement in exploit.c with the following code:
FILE *file = fopen("/root/.ssh/authorized_keys", "a+");
fprintf(file, "%s", SSH_KEY);
I also commented out a bunch of code where it prompted you to select an exploit and just hardcoded "wunderbar_emporium" instead. That code right there, as simple as it looks, was the result of about an hour of trial and error. It turns out that the Linux kernel really doesn't like it when you open and modify files from inside kernel memory, so try and avoid that where possible.
Where SELinux was previously a mitigation and interfered with our exploitation of an RFI, it actually enables us to use spender's exploits to escalate our privileges from apache to root. The attack surface of this LSM is completely exposed when executing code locally and some of its design choices (?) allow us to exploit previously unexploitable bug classes (null dereferences).
Here are the goods:
This is where I stopped for the demo, I figured that students could come up with their own ideas for manipulating the Beta Two Labs members now that they had root access to their server.
That, is how you start off a class.
Thanks for reading and I hope you learned something!