Commit abe38fb

Richard Luby <richluby@gmail.com>
2016-09-28 09:22:49
initial commit of nebula
exercise descriptions pulled from https://exploit-exercises.com/nebula/
1 parent d8bf828
Changed files (20)
exploit_exercises
nebula
exercise-0
exercise-1
exercise-10
exercise-11
exercise-12
exercise-13
exercise-14
exercise-15
exercise-16
exercise-17
exercise-18
exercise-19
exercise-2
exercise-3
exercise-4
exercise-5
exercise-6
exercise-7
exercise-8
exercise-9
exploit_exercises/nebula/exercise-0/readme.md
@@ -0,0 +1,11 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
exploit_exercises/nebula/exercise-1/readme.md
@@ -0,0 +1,38 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
exploit_exercises/nebula/exercise-10/readme.md
@@ -0,0 +1,301 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
exploit_exercises/nebula/exercise-11/readme.md
@@ -0,0 +1,413 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
exploit_exercises/nebula/exercise-12/readme.md
@@ -0,0 +1,454 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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/exercise-13/readme.md
@@ -0,0 +1,487 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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
+
+----------------------------------------------
+
+About
+Source code
+There is a security check that prevents the program from continuing execution
+if the user invoking it does not match a specific user id.
+To do this level, log in as the level13 account with the password
+level13. Files for this level can be found in /home/flag13.
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define FAKEUID 1000
+
+int main(int argc, char **argv, char **envp)
+{
+  int c;
+  char token[256];
+
+  if(getuid() != FAKEUID) {
+      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
+      printf("The system administrators will be notified of this violation\n");
+      exit(EXIT_FAILURE);
+  }
+
+  // snip, sorry :)
+
+  printf("your token is %s\n", token);
+  
+}
exploit_exercises/nebula/exercise-14/readme.md
@@ -0,0 +1,498 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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
+
+----------------------------------------------
+
+About
+Source code
+There is a security check that prevents the program from continuing execution
+if the user invoking it does not match a specific user id.
+To do this level, log in as the level13 account with the password
+level13. Files for this level can be found in /home/flag13.
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define FAKEUID 1000
+
+int main(int argc, char **argv, char **envp)
+{
+  int c;
+  char token[256];
+
+  if(getuid() != FAKEUID) {
+      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
+      printf("The system administrators will be notified of this violation\n");
+      exit(EXIT_FAILURE);
+  }
+
+  // snip, sorry :)
+
+  printf("your token is %s\n", token);
+  
+}
+
+----------------------------------------------
+
+About
+Source code
+This program resides in /home/flag14/flag14. It encrypts input and writes
+it to standard output.  An encrypted token file is also in that home directory,
+decrypt it :)
+To do this level, log in as the level14 account with the password
+level14. Files for this level can be found in /home/flag14.
+There is no source code available for this level
exploit_exercises/nebula/exercise-15/readme.md
@@ -0,0 +1,512 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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
+
+----------------------------------------------
+
+About
+Source code
+There is a security check that prevents the program from continuing execution
+if the user invoking it does not match a specific user id.
+To do this level, log in as the level13 account with the password
+level13. Files for this level can be found in /home/flag13.
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define FAKEUID 1000
+
+int main(int argc, char **argv, char **envp)
+{
+  int c;
+  char token[256];
+
+  if(getuid() != FAKEUID) {
+      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
+      printf("The system administrators will be notified of this violation\n");
+      exit(EXIT_FAILURE);
+  }
+
+  // snip, sorry :)
+
+  printf("your token is %s\n", token);
+  
+}
+
+----------------------------------------------
+
+About
+Source code
+This program resides in /home/flag14/flag14. It encrypts input and writes
+it to standard output.  An encrypted token file is also in that home directory,
+decrypt it :)
+To do this level, log in as the level14 account with the password
+level14. Files for this level can be found in /home/flag14.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+strace the binary at /home/flag15/flag15 and see if you spot anything out
+of the ordinary.
+You may wish to review how to “compile a shared library in linux” and how the
+libraries are loaded and processed by reviewing the dlopen manpage in
+depth.
+Clean up after yourself :)
+To do this level, log in as the level15 account with the password
+level15. Files for this level can be found in /home/flag15.
+There is no source code available for this level
exploit_exercises/nebula/exercise-16/readme.md
@@ -0,0 +1,557 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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
+
+----------------------------------------------
+
+About
+Source code
+There is a security check that prevents the program from continuing execution
+if the user invoking it does not match a specific user id.
+To do this level, log in as the level13 account with the password
+level13. Files for this level can be found in /home/flag13.
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define FAKEUID 1000
+
+int main(int argc, char **argv, char **envp)
+{
+  int c;
+  char token[256];
+
+  if(getuid() != FAKEUID) {
+      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
+      printf("The system administrators will be notified of this violation\n");
+      exit(EXIT_FAILURE);
+  }
+
+  // snip, sorry :)
+
+  printf("your token is %s\n", token);
+  
+}
+
+----------------------------------------------
+
+About
+Source code
+This program resides in /home/flag14/flag14. It encrypts input and writes
+it to standard output.  An encrypted token file is also in that home directory,
+decrypt it :)
+To do this level, log in as the level14 account with the password
+level14. Files for this level can be found in /home/flag14.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+strace the binary at /home/flag15/flag15 and see if you spot anything out
+of the ordinary.
+You may wish to review how to “compile a shared library in linux” and how the
+libraries are loaded and processed by reviewing the dlopen manpage in
+depth.
+Clean up after yourself :)
+To do this level, log in as the level15 account with the password
+level15. Files for this level can be found in /home/flag15.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a perl script running on port 1616.
+To do this level, log in as the level16 account with the password
+level16. Files for this level can be found in /home/flag16.
+#!/usr/bin/env perl
+
+use CGI qw{param};
+
+print "Content-type: text/html\n\n";
+
+sub login {
+  $username = $_[0];
+  $password = $_[1];
+
+  $username =~ tr/a-z/A-Z/; # conver to uppercase
+  $username =~ s/\s.*//;        # strip everything after a space
+
+  @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
+  foreach $line (@output) {
+      ($usr, $pw) = split(/:/, $line);
+  
+
+      if($pw =~ $password) {
+          return 1;
+      }
+  }
+
+  return 0;
+}
+
+sub htmlz {
+  print("<html><head><title>Login resuls</title></head><body>");
+  if($_[0] == 1) {
+      print("Your login was accepted<br/>");
+  } else {
+      print("Your login failed<br/>");
+  }    
+  print("Would you like a cookie?<br/><br/></body></html>\n");
+}
+
+htmlz(login(param("username"), param("password")));
exploit_exercises/nebula/exercise-17/readme.md
@@ -0,0 +1,594 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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
+
+----------------------------------------------
+
+About
+Source code
+There is a security check that prevents the program from continuing execution
+if the user invoking it does not match a specific user id.
+To do this level, log in as the level13 account with the password
+level13. Files for this level can be found in /home/flag13.
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define FAKEUID 1000
+
+int main(int argc, char **argv, char **envp)
+{
+  int c;
+  char token[256];
+
+  if(getuid() != FAKEUID) {
+      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
+      printf("The system administrators will be notified of this violation\n");
+      exit(EXIT_FAILURE);
+  }
+
+  // snip, sorry :)
+
+  printf("your token is %s\n", token);
+  
+}
+
+----------------------------------------------
+
+About
+Source code
+This program resides in /home/flag14/flag14. It encrypts input and writes
+it to standard output.  An encrypted token file is also in that home directory,
+decrypt it :)
+To do this level, log in as the level14 account with the password
+level14. Files for this level can be found in /home/flag14.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+strace the binary at /home/flag15/flag15 and see if you spot anything out
+of the ordinary.
+You may wish to review how to “compile a shared library in linux” and how the
+libraries are loaded and processed by reviewing the dlopen manpage in
+depth.
+Clean up after yourself :)
+To do this level, log in as the level15 account with the password
+level15. Files for this level can be found in /home/flag15.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a perl script running on port 1616.
+To do this level, log in as the level16 account with the password
+level16. Files for this level can be found in /home/flag16.
+#!/usr/bin/env perl
+
+use CGI qw{param};
+
+print "Content-type: text/html\n\n";
+
+sub login {
+  $username = $_[0];
+  $password = $_[1];
+
+  $username =~ tr/a-z/A-Z/; # conver to uppercase
+  $username =~ s/\s.*//;        # strip everything after a space
+
+  @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
+  foreach $line (@output) {
+      ($usr, $pw) = split(/:/, $line);
+  
+
+      if($pw =~ $password) {
+          return 1;
+      }
+  }
+
+  return 0;
+}
+
+sub htmlz {
+  print("<html><head><title>Login resuls</title></head><body>");
+  if($_[0] == 1) {
+      print("Your login was accepted<br/>");
+  } else {
+      print("Your login failed<br/>");
+  }    
+  print("Would you like a cookie?<br/><br/></body></html>\n");
+}
+
+htmlz(login(param("username"), param("password")));
+
+----------------------------------------------
+
+About
+Source code
+There is a python script listening on port 10007 that contains a vulnerability.
+To do this level, log in as the level17 account with the password
+level17. Files for this level can be found in /home/flag17.
+#!/usr/bin/python
+
+import os
+import pickle
+import time
+import socket
+import signal
+
+signal.signal(signal.SIGCHLD, signal.SIG_IGN)
+
+def server(skt):
+  line = skt.recv(1024)
+
+  obj = pickle.loads(line)
+
+  for i in obj:
+      clnt.send("why did you send me " + i + "?\n")
+
+skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
+skt.bind(('0.0.0.0', 10007))
+skt.listen(10)
+
+while True:
+  clnt, addr = skt.accept()
+
+  if(os.fork() == 0):
+      clnt.send("Accepted connection from %s:%d" % (addr[0], addr[1]))
+      server(clnt)
+      exit(1)
exploit_exercises/nebula/exercise-18/readme.md
@@ -0,0 +1,723 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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
+
+----------------------------------------------
+
+About
+Source code
+There is a security check that prevents the program from continuing execution
+if the user invoking it does not match a specific user id.
+To do this level, log in as the level13 account with the password
+level13. Files for this level can be found in /home/flag13.
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define FAKEUID 1000
+
+int main(int argc, char **argv, char **envp)
+{
+  int c;
+  char token[256];
+
+  if(getuid() != FAKEUID) {
+      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
+      printf("The system administrators will be notified of this violation\n");
+      exit(EXIT_FAILURE);
+  }
+
+  // snip, sorry :)
+
+  printf("your token is %s\n", token);
+  
+}
+
+----------------------------------------------
+
+About
+Source code
+This program resides in /home/flag14/flag14. It encrypts input and writes
+it to standard output.  An encrypted token file is also in that home directory,
+decrypt it :)
+To do this level, log in as the level14 account with the password
+level14. Files for this level can be found in /home/flag14.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+strace the binary at /home/flag15/flag15 and see if you spot anything out
+of the ordinary.
+You may wish to review how to “compile a shared library in linux” and how the
+libraries are loaded and processed by reviewing the dlopen manpage in
+depth.
+Clean up after yourself :)
+To do this level, log in as the level15 account with the password
+level15. Files for this level can be found in /home/flag15.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a perl script running on port 1616.
+To do this level, log in as the level16 account with the password
+level16. Files for this level can be found in /home/flag16.
+#!/usr/bin/env perl
+
+use CGI qw{param};
+
+print "Content-type: text/html\n\n";
+
+sub login {
+  $username = $_[0];
+  $password = $_[1];
+
+  $username =~ tr/a-z/A-Z/; # conver to uppercase
+  $username =~ s/\s.*//;        # strip everything after a space
+
+  @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
+  foreach $line (@output) {
+      ($usr, $pw) = split(/:/, $line);
+  
+
+      if($pw =~ $password) {
+          return 1;
+      }
+  }
+
+  return 0;
+}
+
+sub htmlz {
+  print("<html><head><title>Login resuls</title></head><body>");
+  if($_[0] == 1) {
+      print("Your login was accepted<br/>");
+  } else {
+      print("Your login failed<br/>");
+  }    
+  print("Would you like a cookie?<br/><br/></body></html>\n");
+}
+
+htmlz(login(param("username"), param("password")));
+
+----------------------------------------------
+
+About
+Source code
+There is a python script listening on port 10007 that contains a vulnerability.
+To do this level, log in as the level17 account with the password
+level17. Files for this level can be found in /home/flag17.
+#!/usr/bin/python
+
+import os
+import pickle
+import time
+import socket
+import signal
+
+signal.signal(signal.SIGCHLD, signal.SIG_IGN)
+
+def server(skt):
+  line = skt.recv(1024)
+
+  obj = pickle.loads(line)
+
+  for i in obj:
+      clnt.send("why did you send me " + i + "?\n")
+
+skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
+skt.bind(('0.0.0.0', 10007))
+skt.listen(10)
+
+while True:
+  clnt, addr = skt.accept()
+
+  if(os.fork() == 0):
+      clnt.send("Accepted connection from %s:%d" % (addr[0], addr[1]))
+      server(clnt)
+      exit(1)
+
+----------------------------------------------
+
+About
+Source code
+Analyse the C program, and look for vulnerabilities in the program. There is an
+easy way to solve this level, an intermediate way to solve it, and a more
+difficult/unreliable way to solve it.
+To do this level, log in as the level18 account with the password
+level18. Files for this level can be found in /home/flag18.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <getopt.h>
+
+struct {
+  FILE *debugfile;
+  int verbose;
+  int loggedin;
+} globals;
+
+#define dprintf(...) if(globals.debugfile) \
+  fprintf(globals.debugfile, __VA_ARGS__)
+#define dvprintf(num, ...) if(globals.debugfile && globals.verbose >= num) \
+  fprintf(globals.debugfile, __VA_ARGS__)
+
+#define PWFILE "/home/flag18/password"
+
+void login(char *pw)
+{
+  FILE *fp;
+
+  fp = fopen(PWFILE, "r");
+  if(fp) {
+      char file[64];
+
+      if(fgets(file, sizeof(file) - 1, fp) == NULL) {
+          dprintf("Unable to read password file %s\n", PWFILE);
+          return;
+      }
+                fclose(fp);
+      if(strcmp(pw, file) != 0) return;       
+  }
+  dprintf("logged in successfully (with%s password file)\n",
+      fp == NULL ? "out" : "");
+  
+  globals.loggedin = 1;
+
+}
+
+void notsupported(char *what)
+{
+  char *buffer = NULL;
+  asprintf(&buffer, "--> [%s] is unsupported at this current time.\n", what);
+  dprintf(what);
+  free(buffer);
+}
+
+void setuser(char *user)
+{
+  char msg[128];
+
+  sprintf(msg, "unable to set user to '%s' -- not supported.\n", user);
+  printf("%s\n", msg);
+
+}
+
+int main(int argc, char **argv, char **envp)
+{
+  char c;
+
+  while((c = getopt(argc, argv, "d:v")) != -1) {
+      switch(c) {
+          case 'd':
+              globals.debugfile = fopen(optarg, "w+");
+              if(globals.debugfile == NULL) err(1, "Unable to open %s", optarg);
+              setvbuf(globals.debugfile, NULL, _IONBF, 0);
+              break;
+          case 'v':
+              globals.verbose++;
+              break;
+      }
+  }
+
+  dprintf("Starting up. Verbose level = %d\n", globals.verbose);
+
+  setresgid(getegid(), getegid(), getegid());
+  setresuid(geteuid(), geteuid(), geteuid());
+  
+  while(1) {
+      char line[256];
+      char *p, *q;
+
+      q = fgets(line, sizeof(line)-1, stdin);
+      if(q == NULL) break;
+      p = strchr(line, '\n'); if(p) *p = 0;
+      p = strchr(line, '\r'); if(p) *p = 0;
+
+      dvprintf(2, "got [%s] as input\n", line);
+
+      if(strncmp(line, "login", 5) == 0) {
+          dvprintf(3, "attempting to login\n");
+          login(line + 6);
+      } else if(strncmp(line, "logout", 6) == 0) {
+          globals.loggedin = 0;
+      } else if(strncmp(line, "shell", 5) == 0) {
+          dvprintf(3, "attempting to start shell\n");
+          if(globals.loggedin) {
+              execve("/bin/sh", argv, envp);
+              err(1, "unable to execve");
+          }
+          dprintf("Permission denied\n");
+      } else if(strncmp(line, "logout", 4) == 0) {
+          globals.loggedin = 0;
+      } else if(strncmp(line, "closelog", 8) == 0) {
+          if(globals.debugfile) fclose(globals.debugfile);
+          globals.debugfile = NULL;
+      } else if(strncmp(line, "site exec", 9) == 0) {
+          notsupported(line + 10);
+      } else if(strncmp(line, "setuser", 7) == 0) {
+          setuser(line + 8);
+      }
+  }
+
+  return 0;
+}
exploit_exercises/nebula/exercise-19/readme.md
@@ -0,0 +1,767 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>
+
+----------------------------------------------
+
+About
+Source code
+The setuid binary at /home/flag10/flag10 binary will upload any file given,
+as long as it meets the requirements of the access() system call.
+To do this level, log in as the level10 account with the password
+level10. Files for this level can be found in /home/flag10.
+#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);
+  }
+}
+
+----------------------------------------------
+
+About
+Source code
+The /home/flag11/flag11 binary processes standard input and executes a
+shell command.
+There are two ways of completing this level, you may wish to do both :-)
+To do this level, log in as the level11 account with the password
+level11. Files for this level can be found in /home/flag11.
+#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);
+  }
+
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a backdoor process listening on port 50001.
+To do this level, log in as the level12 account with the password
+level12. Files for this level can be found in /home/flag12.
+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
+
+----------------------------------------------
+
+About
+Source code
+There is a security check that prevents the program from continuing execution
+if the user invoking it does not match a specific user id.
+To do this level, log in as the level13 account with the password
+level13. Files for this level can be found in /home/flag13.
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define FAKEUID 1000
+
+int main(int argc, char **argv, char **envp)
+{
+  int c;
+  char token[256];
+
+  if(getuid() != FAKEUID) {
+      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
+      printf("The system administrators will be notified of this violation\n");
+      exit(EXIT_FAILURE);
+  }
+
+  // snip, sorry :)
+
+  printf("your token is %s\n", token);
+  
+}
+
+----------------------------------------------
+
+About
+Source code
+This program resides in /home/flag14/flag14. It encrypts input and writes
+it to standard output.  An encrypted token file is also in that home directory,
+decrypt it :)
+To do this level, log in as the level14 account with the password
+level14. Files for this level can be found in /home/flag14.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+strace the binary at /home/flag15/flag15 and see if you spot anything out
+of the ordinary.
+You may wish to review how to “compile a shared library in linux” and how the
+libraries are loaded and processed by reviewing the dlopen manpage in
+depth.
+Clean up after yourself :)
+To do this level, log in as the level15 account with the password
+level15. Files for this level can be found in /home/flag15.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a perl script running on port 1616.
+To do this level, log in as the level16 account with the password
+level16. Files for this level can be found in /home/flag16.
+#!/usr/bin/env perl
+
+use CGI qw{param};
+
+print "Content-type: text/html\n\n";
+
+sub login {
+  $username = $_[0];
+  $password = $_[1];
+
+  $username =~ tr/a-z/A-Z/; # conver to uppercase
+  $username =~ s/\s.*//;        # strip everything after a space
+
+  @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
+  foreach $line (@output) {
+      ($usr, $pw) = split(/:/, $line);
+  
+
+      if($pw =~ $password) {
+          return 1;
+      }
+  }
+
+  return 0;
+}
+
+sub htmlz {
+  print("<html><head><title>Login resuls</title></head><body>");
+  if($_[0] == 1) {
+      print("Your login was accepted<br/>");
+  } else {
+      print("Your login failed<br/>");
+  }    
+  print("Would you like a cookie?<br/><br/></body></html>\n");
+}
+
+htmlz(login(param("username"), param("password")));
+
+----------------------------------------------
+
+About
+Source code
+There is a python script listening on port 10007 that contains a vulnerability.
+To do this level, log in as the level17 account with the password
+level17. Files for this level can be found in /home/flag17.
+#!/usr/bin/python
+
+import os
+import pickle
+import time
+import socket
+import signal
+
+signal.signal(signal.SIGCHLD, signal.SIG_IGN)
+
+def server(skt):
+  line = skt.recv(1024)
+
+  obj = pickle.loads(line)
+
+  for i in obj:
+      clnt.send("why did you send me " + i + "?\n")
+
+skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
+skt.bind(('0.0.0.0', 10007))
+skt.listen(10)
+
+while True:
+  clnt, addr = skt.accept()
+
+  if(os.fork() == 0):
+      clnt.send("Accepted connection from %s:%d" % (addr[0], addr[1]))
+      server(clnt)
+      exit(1)
+
+----------------------------------------------
+
+About
+Source code
+Analyse the C program, and look for vulnerabilities in the program. There is an
+easy way to solve this level, an intermediate way to solve it, and a more
+difficult/unreliable way to solve it.
+To do this level, log in as the level18 account with the password
+level18. Files for this level can be found in /home/flag18.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <getopt.h>
+
+struct {
+  FILE *debugfile;
+  int verbose;
+  int loggedin;
+} globals;
+
+#define dprintf(...) if(globals.debugfile) \
+  fprintf(globals.debugfile, __VA_ARGS__)
+#define dvprintf(num, ...) if(globals.debugfile && globals.verbose >= num) \
+  fprintf(globals.debugfile, __VA_ARGS__)
+
+#define PWFILE "/home/flag18/password"
+
+void login(char *pw)
+{
+  FILE *fp;
+
+  fp = fopen(PWFILE, "r");
+  if(fp) {
+      char file[64];
+
+      if(fgets(file, sizeof(file) - 1, fp) == NULL) {
+          dprintf("Unable to read password file %s\n", PWFILE);
+          return;
+      }
+                fclose(fp);
+      if(strcmp(pw, file) != 0) return;       
+  }
+  dprintf("logged in successfully (with%s password file)\n",
+      fp == NULL ? "out" : "");
+  
+  globals.loggedin = 1;
+
+}
+
+void notsupported(char *what)
+{
+  char *buffer = NULL;
+  asprintf(&buffer, "--> [%s] is unsupported at this current time.\n", what);
+  dprintf(what);
+  free(buffer);
+}
+
+void setuser(char *user)
+{
+  char msg[128];
+
+  sprintf(msg, "unable to set user to '%s' -- not supported.\n", user);
+  printf("%s\n", msg);
+
+}
+
+int main(int argc, char **argv, char **envp)
+{
+  char c;
+
+  while((c = getopt(argc, argv, "d:v")) != -1) {
+      switch(c) {
+          case 'd':
+              globals.debugfile = fopen(optarg, "w+");
+              if(globals.debugfile == NULL) err(1, "Unable to open %s", optarg);
+              setvbuf(globals.debugfile, NULL, _IONBF, 0);
+              break;
+          case 'v':
+              globals.verbose++;
+              break;
+      }
+  }
+
+  dprintf("Starting up. Verbose level = %d\n", globals.verbose);
+
+  setresgid(getegid(), getegid(), getegid());
+  setresuid(geteuid(), geteuid(), geteuid());
+  
+  while(1) {
+      char line[256];
+      char *p, *q;
+
+      q = fgets(line, sizeof(line)-1, stdin);
+      if(q == NULL) break;
+      p = strchr(line, '\n'); if(p) *p = 0;
+      p = strchr(line, '\r'); if(p) *p = 0;
+
+      dvprintf(2, "got [%s] as input\n", line);
+
+      if(strncmp(line, "login", 5) == 0) {
+          dvprintf(3, "attempting to login\n");
+          login(line + 6);
+      } else if(strncmp(line, "logout", 6) == 0) {
+          globals.loggedin = 0;
+      } else if(strncmp(line, "shell", 5) == 0) {
+          dvprintf(3, "attempting to start shell\n");
+          if(globals.loggedin) {
+              execve("/bin/sh", argv, envp);
+              err(1, "unable to execve");
+          }
+          dprintf("Permission denied\n");
+      } else if(strncmp(line, "logout", 4) == 0) {
+          globals.loggedin = 0;
+      } else if(strncmp(line, "closelog", 8) == 0) {
+          if(globals.debugfile) fclose(globals.debugfile);
+          globals.debugfile = NULL;
+      } else if(strncmp(line, "site exec", 9) == 0) {
+          notsupported(line + 10);
+      } else if(strncmp(line, "setuser", 7) == 0) {
+          setuser(line + 8);
+      }
+  }
+
+  return 0;
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a flaw in the below program in how it operates.
+To do this level, log in as the level19 account with the password
+level19. Files for this level can be found in /home/flag19.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  pid_t pid;
+  char buf[256];
+  struct stat statbuf;
+
+  /* Get the parent's /proc entry, so we can verify its user id */
+
+  snprintf(buf, sizeof(buf)-1, "/proc/%d", getppid());
+
+  /* stat() it */
+
+  if(stat(buf, &statbuf) == -1) {
+      printf("Unable to check parent process\n");
+      exit(EXIT_FAILURE);
+  }
+
+  /* check the owner id */
+
+  if(statbuf.st_uid == 0) {
+      /* If root started us, it is ok to start the shell */
+
+      execve("/bin/sh", argv, envp);
+      err(1, "Unable to execve");
+  }
+
+  printf("You are unauthorized to run this program\n");
+}
exploit_exercises/nebula/exercise-2/readme.md
@@ -0,0 +1,73 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
exploit_exercises/nebula/exercise-3/readme.md
@@ -0,0 +1,83 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
exploit_exercises/nebula/exercise-4/readme.md
@@ -0,0 +1,127 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
exploit_exercises/nebula/exercise-5/readme.md
@@ -0,0 +1,137 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
exploit_exercises/nebula/exercise-6/readme.md
@@ -0,0 +1,146 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
exploit_exercises/nebula/exercise-7/readme.md
@@ -0,0 +1,175 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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/exercise-8/readme.md
@@ -0,0 +1,185 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
exploit_exercises/nebula/exercise-9/readme.md
@@ -0,0 +1,219 @@
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to find a Set User ID program that will run as the
+“flag00” account. You could also find this by carefully looking in top level
+directories in / for suspicious looking directories.
+Alternatively, look at the find man page.
+To access this level, log in as level00 with the password of level00.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs to
+be executed, can you find it?
+To do this level, log in as the level01 account with the password
+level01. Files for this level can be found in /home/flag01.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  gid_t gid;
+  uid_t uid;
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  system("/usr/bin/env echo and now what?");
+}
+
+----------------------------------------------
+
+About
+Source code
+There is a vulnerability in the below program that allows arbitrary programs
+to be executed, can you find it?
+To do this level, log in as the level02 account with the password
+level02. Files for this level can be found in /home/flag02.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char *buffer;
+
+  gid_t gid;
+  uid_t uid;
+
+  gid = getegid();
+  uid = geteuid();
+
+  setresgid(gid, gid, gid);
+  setresuid(uid, uid, uid);
+
+  buffer = NULL;
+
+  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
+  printf("about to call system(\"%s\")\n", buffer);
+  
+  system(buffer);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the home directory of flag03 and take note of the files there.
+There is a crontab that is called every couple of minutes.
+To do this level, log in as the level03 account with the password
+level03. Files for this level can be found in /home/flag03.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+This level requires you to read the token file, but the code restricts the
+files that can be read. Find a way to bypass it :)
+To do this level, log in as the level04 account with the password
+level04. Files for this level can be found in /home/flag04.
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv, char **envp)
+{
+  char buf[1024];
+  int fd, rc;
+
+  if(argc == 1) {
+      printf("%s [file to read]\n", argv[0]);
+      exit(EXIT_FAILURE);
+  }
+
+  if(strstr(argv[1], "token") != NULL) {
+      printf("You may not access '%s'\n", argv[1]);
+      exit(EXIT_FAILURE);
+  }
+
+  fd = open(argv[1], O_RDONLY);
+  if(fd == -1) {
+      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
+  }
+
+  rc = read(fd, buf, sizeof(buf));
+  
+  if(rc == -1) {
+      err(EXIT_FAILURE, "Unable to read fd %d", fd);
+  }
+
+  write(1, buf, rc);
+}
+
+----------------------------------------------
+
+About
+Source code
+Check the flag05 home directory. You are looking for weak directory
+permissions
+To do this level, log in as the level05 account with the password
+level05. Files for this level can be found in /home/flag05.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+The flag06 account credentials came from a legacy unix system.
+To do this level, log in as the level06 account with the password
+level06. Files for this level can be found in /home/flag06.
+There is no source code available for this level
+
+----------------------------------------------
+
+Source code
+The flag07 user was writing their very first perl program that allowed them
+to ping hosts to see if they were reachable from the web server.
+To do this level, log in as the level07 account with the password
+level07. Files for this level can be found in /home/flag07.
+#!/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"));
+
+----------------------------------------------
+
+About
+Source code
+World readable files strike again. Check what that user was up to, and use it
+to log into flag08 account.
+To do this level, log in as the level08 account with the password
+level08. Files for this level can be found in /home/flag08.
+There is no source code available for this level
+
+----------------------------------------------
+
+About
+Source code
+There’s a C setuid wrapper for some vulnerable PHP code…
+To do this level, log in as the level09 account with the password
+level09. Files for this level can be found in /home/flag09.
+<?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;
+
+?>