Commit abe38fb
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;
+
+?>