01/15/2019

Level06: Legacy Linux System account.

Many years ago we stored the password hash in /etc/passwd not in shadow. View the passwd file and notice the hash in the file and echo it to a tmp file. Now open Kali and run john the ripper. Now we have the password, su to flag06 with password hello.

Level07: Our first perl program.

At the CLI, type ping and hit enter. Notice the output. Now type ./index.cgi and notice the output. Clearly we have direct input to the command line. Test this with google.com; ls. We list the directory. Now ./index.cgi google.com; getflag. No dice 🙁

But what is an index.cgi, it’s definetly not meant to probably be in a directory. Is it a web page? Is a webserver running? What is the man page for viewing what a user is running?

Level08: Our key is world readable files again and to see what user flag08 was up to.

pcap files are network capture files from a program called tcpdump.

Reading with tcpdump is impossible. Wireshark is GUI program that is very powerful allowing following streams and viewing packets to a low level. What else is installed that could be used?

Figure out what is going on, hint the characters could mean something else but that a key was pressed.

Level09: Php and C?

level09@nebula:~$ echo '[email {${system($use_me)}}]' > flag.txt
level09@nebula:~$ /home/flag09/flag09 flag.txt /bin/getflag
You have successfully executed getflag on a target account

Walk the code and slowly determine how we can manipulate the data 
we pass in.

Level10: Another binary file. These are starting to get quite hard
aren't they?

Open a second Terminal using Ctrl Alt F2. Type in nc -l 18211. Go
back to the next termal echo details to file x. 

So the idea here is to exploit a race condition.

A race condition or race hazard is the condition of an electronics, software, or other system where the system’s substantive behavior is dependent on the sequence or timing of other uncontrollable events. It becomes a bug when one or more of the possible behaviors is undesirable. Wikipedia

Now we must create and remove a symbolic link from the real to the fake token. In between the write and the check, we exploit the time gap.

level10@nebula:~/nebula$ nc -kl 18211
.oO Oo.
615a2ce1-b2b5-4c76-8eed-8aa5c4015c27

Level11: Binary Processes.

First run ./flag11 try passing parameters. Nothing. It prompts for parameters, typing abcd we get an invalid header. Let’s look at the code. We see a define Content-Length: so just continuing experimenting, try:

Let’s walk the code and see what could be going on. The code is not quite obvious. First it appears we actually need an integer after content-length then a payload, but let’s see what else is important here in the code.

Now debugging with gdb can be a challenge, and something we will spend time on later, so copying the code into VS (yeah I know, but it is 3am and my 4 year old is asleep and I can’t deal with gdb right now!), and commenting out code that doesn’t work, we can see visually what path things take.

  1. If literally nothing is entered, exit.
  2. If entering 1 or basically no header, exit.
  3. Entering Content-Length: and that is it exit.
  4. Entering Content-Length: 1 and we progress.
  5. Now prompted for more input, enter letter ‘a’. Process() process creates a key by bitwise & (anding) the length and 0xFF. Then using ^ exclusive or writing the data back. XOR sounds complicated but really it just means the opposite of or, so if 1 ^ 0 = 1, in other words if the bits are opposite it’s 1. But what is note worthy here is for 1 we are working with memory, junk.
  6. Content-Length: 1024 we now enter the else. This hits the random() which does some srandom() and an open() with a fd. We then enter a while loop logic that eventually calls process.

Some things to note.

  1. System() is called in process which is called in several code paths.
  2. Random does some thing with a file.
  3. Process does some bitwise logic and sends the results to system.

So our first approach to attack this is probably to either figure out how to get the random file, write to it before it is read and process it. But we can handle the same thing by passing this in to process(), hopefully unencrypting it and passing it to system. We know what we want to pass to system which is the full path to get “getflag”.

Use python to perform the exact opposite of this “encryption algorithm” and! it fails. We receive an mmap error. Quickly changing to 1023 and we hit the first if.

Frustration is now setting in. Also this file does not look to be setuid.

Something went wrong. Restarting VM. OK everything is OK and I can see the sticky bit. What if we keep hitting a letter?

I thought with no setting of effective id’s this might be a problem but as shown above the sticky bit is set.

Time to feed the kid. There needs to be another way to execute.

Alright fresh day. Let’s try harder and figure this out. I want these tutorials to get you up to a base level, while having fun, but I also don’t want you banging your head against the wall.

Exploit exercises says there are two ways to exploit this. Let’s revisit everything from the beginning.

Do you see the .ssh with xecute on it?

Must have missed this guy, but at this point, I must move on. Hope to return at a later date.

Level 12: Login via a backdoor process.

We have the code, but clearly we might not be able to trust that based on 11. Looking at the code we can see we have a loop that runs forever, and takes input, compares that and then exits.

As we know, never trust user input. And the function looks like it is running a command.

prog = io.popen(
       "echo "..password.." | sha1sum", "r")
After many tries

Level 13: Run a program as set uid 1000.

The only option appears to be around getuid() looking at the man page, we have the signature and we can hardcode the result to return 1000.

Build the file as a shared file and run.

Now after running the man page and it failing, it appears the file must not have the setuid flag, but copying avoids that.

Level 14: Program encrypts a file. Decrypt a file.

The program appears to hang every time it is ran. After some tries, passing input to the program produces encrypted data that is incremented by 1; except for the first character which remains the same. Though that is not the case.

Some tinkering was required, turns out the character is decremented as -i.