Mike-Boya

Information Security and Programming Blog

Exploit Exercises - Nebula Level12

Level12 informs us that “There is a backdoor process listening on port 50001.”

We are also provided with level12.lua:

    local socket = require("socket")
    local server = assert(socket.bind("127.0.0.1", 50001))

    function hash(password)
      prog = io.popen("echo "..password.." | sha1sum", "r")
      data = prog:read("*all")
      prog:close()

      data = string.sub(data, 1, 40)

      return data
    end


    while 1 do
      local client = server:accept()
      client:send("Password: ")
      client:settimeout(60)
      local line, err = client:receive()
      if not err then
          print("trying " .. line) -- log from where ;\
          local h = hash(line)

          if h ~= "4754a4f4bd5787accd33de887b9250a0691dd198" then
              client:send("Better luck next time\n");
          else
              client:send("Congrats, your token is 413**CARRIER LOST**\n")
          end

      end

      client:close()
    end

Exploit Exercises - Nebula Level11

Level11 provides us with the source code for level11.c:

      #include <stdlib.h>
      #include <unistd.h>
      #include <string.h>
      #include <sys/types.h>
      #include <fcntl.h>
      #include <stdio.h>
      #include <sys/mman.h>

      /*
       * Return a random, non-predictable file, and return the file descriptor for it.
       */

      int getrand(char **path)
      {
        char *tmp;
        int pid;
        int fd;

        srandom(time(NULL));

        tmp = getenv("TEMP");
        pid = getpid();

        asprintf(path, "%s/%d.%c%c%c%c%c%c", tmp, pid,
            'A' + (random() % 26), '0' + (random() % 10),
            'a' + (random() % 26), 'A' + (random() % 26),
            '0' + (random() % 10), 'a' + (random() % 26));

        fd = open(*path, O_CREAT|O_RDWR, 0600);
        unlink(*path);
        return fd;
      }

      void process(char *buffer, int length)
      {
        unsigned int key;
        int i;

        key = length & 0xff;

        for(i = 0; i < length; i++) {
            buffer[i] ^= key;
            key -= buffer[i];
        }

        system(buffer);
      }

      #define CL "Content-Length: "

      int main(int argc, char **argv)
      {
        char line[256];
        char buf[1024];
        char *mem;
        int length;
        int fd;
        char *path;

        if(fgets(line, sizeof(line), stdin) == NULL) {
            errx(1, "reading from stdin");
        }

        if(strncmp(line, CL, strlen(CL)) != 0) {
            errx(1, "invalid header");
        }

        length = atoi(line + strlen(CL));

        if(length < sizeof(buf)) {
            if(fread(buf, length, 1, stdin) != length) {
                err(1, "fread length");
            }
            process(buf, length);
        } else {
            int blue = length;
            int pink;

            fd = getrand(&path);

            while(blue > 0) {
                printf("blue = %d, length = %d, ", blue, length);

                pink = fread(buf, 1, sizeof(buf), stdin);
                printf("pink = %d\n", pink);

                if(pink <= 0) {
                    err(1, "fread fail(blue = %d, length = %d)", blue, length);
                }
                write(fd, buf, pink);

                blue -= pink;
            }

            mem = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
            if(mem == MAP_FAILED) {
                err(1, "mmap");
            }
            process(mem, length);
        }

      }

“There are two ways of completing this level, you may wish to do both :-)” - That sounds cool. Let’s take a look.

Exploit Exercises - Nebula Level10

level10 provides us with the following source code:

    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>

    int main(int argc, char **argv)
    {
      char *file;
      char *host;

      if(argc < 3) {
          printf("%s file host\n\tsends file to host if you have access to it\n", argv[0]);
          exit(1);
      }

      file = argv[1];
      host = argv[2];

      if(access(argv[1], R_OK) == 0) {
          int fd;
          int ffd;
          int rc;
          struct sockaddr_in sin;
          char buffer[4096];

          printf("Connecting to %s:18211 .. ", host); fflush(stdout);

          fd = socket(AF_INET, SOCK_STREAM, 0);

          memset(&sin, 0, sizeof(struct sockaddr_in));
          sin.sin_family = AF_INET;
          sin.sin_addr.s_addr = inet_addr(host);
          sin.sin_port = htons(18211);

          if(connect(fd, (void *)&sin, sizeof(struct sockaddr_in)) == -1) {
              printf("Unable to connect to host %s\n", host);
              exit(EXIT_FAILURE);
          }

    #define HITHERE ".oO Oo.\n"
          if(write(fd, HITHERE, strlen(HITHERE)) == -1) {
              printf("Unable to write banner to host %s\n", host);
              exit(EXIT_FAILURE);
          }
    #undef HITHERE

          printf("Connected!\nSending file .. "); fflush(stdout);

          ffd = open(file, O_RDONLY);
          if(ffd == -1) {
              printf("Damn. Unable to open file\n");
              exit(EXIT_FAILURE);
          }

          rc = read(ffd, buffer, sizeof(buffer));
          if(rc == -1) {
              printf("Unable to read from file: %s\n", strerror(errno));
              exit(EXIT_FAILURE);
          }

          write(fd, buffer, rc);

          printf("wrote file!\n");

      } else {
          printf("You don't have access to %s\n", file);
      }
    }

This challenge is a tough one, we need to trigger the race condition within the code.

The man page for access() confirms the suspicion: “Warning: Using access() to check if a user is authorized to, for example, open a file before actually doing so using open(2) creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. For this reason, the use of this system call should be avoided.” - Let’s see if we can cause that to occur on line 24.

Exploit Exercises - Nebula Level09

Level09 provides us with a C setuid wrapper for some vulnerable PHP code.

    <?php

    function spam($email)
    {
      $email = preg_replace("/\./", " dot ", $email);
      $email = preg_replace("/@/", " AT ", $email);

      return $email;
    }

    function markup($filename, $use_me)
    {
      $contents = file_get_contents($filename);

      $contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents);
      $contents = preg_replace("/\[/", "<", $contents);
      $contents = preg_replace("/\]/", ">", $contents);

      return $contents;
    }

    $output = markup($argv[1], $argv[2]);

    print $output;

    ?>

As you can see in the code above, the second argument – $use_me – is not used in the code.

After doing some research, multiple sources identified preg_replace() as a dangerous feature that was deprecated in PHP 5.5.0 and removed as of PHP 7.0.0.

Exploit Exercises - Nebula Level07

The next level provides us with some perl code:

    #!/usr/bin/perl

    use CGI qw{param};

    print "Content-type: text/html\n\n";

    sub ping {
    $host = $_[0];

    print("<html><head><title>Ping results</title></head><body><pre>");

    @output = `ping -c 3 $host 2>&1`;
    foreach $line (@output) { print "$line"; }

    print("</pre></body></html>");

    }

    # check if Host set. if not, display normal page, etc

    ping(param("Host"));

Exploit Exercises - Nebula Level05

[Level05] instructs us to “Check the flag05 home directory. You are looking for weak directory permissions”

After navigating over to /home/flag05, we take a look at the permissions.

    level05@nebula:~$ pushd /home/flag05/
    level05@nebula:/home/flag05$ ls -al
    total 5
    drwxr-x--- 4 flag05 level05   93 2012-08-18 06:56 .
    drwxr-xr-x 1 root   root      80 2012-08-27 07:18 ..
    drwxr-xr-x 2 flag05 flag05    42 2011-11-20 20:13 .backup
    -rw-r--r-- 1 flag05 flag05   220 2011-05-18 02:54 .bash_logout
    -rw-r--r-- 1 flag05 flag05  3353 2011-05-18 02:54 .bashrc
    -rw-r--r-- 1 flag05 flag05   675 2011-05-18 02:54 .profile
    drwx------ 2 flag05 flag05    70 2011-11-20 20:13 .ssh

Quick Update

Hi All,

It has been about two months since my last post. It looks like exploit-exercises is offline (and has been for awhile). I will continue my Nebula write-ups if it ever comes back up, but for now I will move on and continue with some new content.

I should have another post coming soon, so stay tuned!

Mike