Write Up: PRIMER 1.0.1

PRIMER is a vulnerable VM developed by Arne Rick featured on Vulnhub. It can be found here.
This VM is aimed at beginners / those seeking an entry into vulnerable VMs and the scene in general. Although not challenging to the experienced among us, everyone should be able to enjoy completing this unique and incredibly well developed VM.

If you intend to complete this VM yourself (and do not require assistance) then this write up will spoil it for you. So I say in bold and caps - SPOILERS!

Flags:
 1_c81e728d9d4c2f636f067f89cc14862c
 2_eccbc87e4b5ce2fe28308fd9f2a7baf3
 3_e4da3b7fbbce2345d7772b0674a318d5
 4_8f14e45fceea167a5a36dedd4bea2543
 5_6512bd43d9caa6e02c990b0a82652dca
 6_c51ce410c124a10e0db5e4b97fc2af39
 7_70efdf2ec9b086079795c442636b55fb
 8_1f0e3dad99908345f7439f8ffabdffc4
 9_37693cfc748049e45d87b8c7d8b9aacd
10_23693cff748o49r45d77b6c7d1b9afcd
------------------------------------------------------------------------------------------------------

CHAPTER 1: [__init__]

Once the VM was installed, up and running, I did a quick nmap -sn 192.168.1.*. The -sn flag to skip port scanning, simply to identify which IP the VM had grabbed. This revealed 192.168.127.
Another quick nmap -sV showed ports 22 and 80 running OpenSSH and Apache respectively.

Now I knew a web server was running, I opened up a browser and typed in the IP. A web page dutifully rendered.


 A block of text and a login form. From reading the text, it appears to be a stylistically unusual story. The way it is written is quite vague and loosely tied together. None the less, its enjoyable to read and appears to contain some hints.
The last paragraph appeared to be most relevant..

"There was one spot that attracted her naturally, a point w[h]ere the traces accumulated and forward a connection, a terminal accepting input from the us3rland, a f0rm. This one was of a family very well known to her, easily exploited to grand you access to another level, and that was she needed for now. Reaching in she began to twist the stream, adjust the flow and after a few practiced moves, she felt it, access, the meta, finally moving on."
This is clearly hinting at the login form, requiring some SQL injection. The story itself indicates that this may not be too difficult -".. a few practiced moves..".
To check for any further hints, I inspected the HTML which revealed some hidden text.
This revealed; "Some f0rms are easier than others. This one was just a means to get to the next level so there was no need for her to apply her full set of skills or fake credentials. Manufacturing a boole4n response would probably be en[o]ugh to let her pass."

This reaffirmed my suspicions that this required a simple SQL injection. Clearly just a boolean response was required for this function.
I began with some well established code which would evaluate to TRUE. I only used the Username field, leaving password empty. It was clear from the first attempt that all errors from the SQL server were being caught, there were no prompts or notifications for failed attempts. This meant there was nothing else to go on other than what was provided in the story, effectively educated guesses. I continued and tried a multitude of variations, such as ' OR '1'='1' , ' OR 1=1 -- 1" OR 1=1 -- etc. Eventually, after a significant amount of attempts ' OR '1'='1' -- was successful. The first ' closes out the single apostrophe encapsulating the variable, OR provides the ability to negate the first statement requirement to evaluate to TRUE'1'='1' clearly computes to TRUE and the -- (with an important space after it!) then comments out the rest of the query, therefore making the password field redundant.


Once login was pressed, I arrived at the next page. This again included a block of text.


This portion of the story continued the vagueness from the first page. However there were a few notable parts; "..specific string all users transmit.." , "Drifting around the 7th circle of security layers.." , "..this little script just checked for an identifier, a hash, no credentials or secrets..". These hinted at the User Agent Identifier. I then checked the HTML source code for any further hints.

I found a comment! This one reads:

"This bot was looking for a Sosu User Agent Identifier she had cracked weeks ago, easy sauce, just a simple md5 hash of the first 7 digits of pi. It was basically common knowledge to the entities moving in these areas but obscurity does create a, albeit virtual, layer of security".

This clearly indicates that I need to spoof the User Agent Identifier to solve this page. First of all, I need to make the MD5 Hash of 3.141592. md5sum in the terminal produced the required hash:

d483d00d07fcc80319d170ccf07fb5be.

Next I installed a User Agent Switcher ad-on in firefox. I then created a new User Agent profile and input the hash in the user agent field.


I then switched to the new User Agent Profile and reloaded the page - Redirect. It worked! on to the next chapter! ..Coming soon.

------------------------------------------------------------------------------------------------------

CHAPTER 2: [(α=β)<=>(α<=>β)]

I am progressing through this VM somewhat faster than I originally anticipated, also the chapters are shorter than I imagined, none the less I will continue as intended and post one chapter at a time.
Lets continue.
This chapter, much like the first, features a block of text which continues the vague story littered with small clues.



The most telling of these clues are as follows..

"..needed to penetrate the next circle, blocked of[f] to unauthorized access".

"But she felt a presence of something left behind. Like breadcrums, not intentional, but something forgotten by an incomplete piece of code to handle access".

At this point, my mind first went to cookies... breadcrumbs!
However, more haste, less speed. I first checked the HTML to see if there were any further clues, unfortunately, none to be found there. I then thought to have a quick look at the css and there we have another comment!


This comment confirmed my suspicions. "Clean sessions terminate without leaving things behind..""Sometimes, an exploit is as simple as changing a simple value in a local file". Yep, definitely cookies!

I then looked at the GET request headers to see what parameters are being passed. There we have it! 


"activeSession=false"

I wonder if it is as simple as changing the active session value to true? Is that all the server is checking for an active session? The clues seem to suggest it.. so I fired up a plugin to edit the cookie and gave it a try.


I found the relevant cookie, altered the value from false to true, saved the now manipulated cookie and reloaded the page.

Sure enough! 302 found, redirect! On to Chapter 3..



------------------------------------------------------------------------------------------------------

CHAPTER 3: ["[^"\r\n]*"]


This chapter has probably taught me the biggest lesson so far.. don't get carried away. I have spent hours on this chapter, when in fact, its probably the easiest and most simple chapter yet. Instead of hiding my mistake, there might be some comedy valuable learning opportunities in sharing it.

So from the beginning.. I was greeted again by the now expected block of text and little else. This section of the story seemed to offer some hints to the solution. I fell for it hook line and sinker!


As I read the text, the following line stuck out to me ".. slowly d[i]sintegrating with lightspeed, a thousand years each nano second". This sentence appeared to be the only real candidate for a hint in the text, so I went with it...

I looked at the headers. I noticed that (unlike previous chapters) there were "If-Modified-Since" and "Etag" fields in these headers. Aha! this most be what that sentence was hinting at.. time.. "thousand years" etc.


So I jumped into curl to spoof the "If-Modified-Since" field to generate a response from the server. Sure enough, changing the date of the field to "Sun, 25 oct 2015 12:59:55 GMT" produced a 304 Not modified response, However nothing else, no extra field in the header or anything to indicate I had solved the chapter. I must have been missing something.


So I decided to read up more on properties of the "If-Modified-Since" and "Etag" fields. I began by reading rfc2616 section 14 "Header Field Definitions" for any further information. Although very illuminating, I wasn't any closer to solving the chapter. I did some more searching, read some more papers, I spent the best part of 2 hours trying to prise a hint of a way of exploiting this specific feature of HTTP headers, I came out empty handed.

So out of frustration, I thought I would see what happened if I spoofed a header where the "If-Modified-Since" field was in date; that is to say, a fresh copy of the page would be sent as it had been modified since the date I had fabricated in the request header. Sure enough, I got the HTML back, wait.. what does that say?!..


"<meta http-equiv="hint" content="Think, but don't act like a robot."/>"

Why had I not noticed this earlier?! It cant be! seriously? not robots.txt.. it cant be that straight forward?!

Yes it was that straight forward...
The moral of the story, Don't get carried away. I should have simply read the HTML first, like I had in the previous chapters. But what a valuable lesson to learn! Also, I now know quite allot about ETags and If-Modified-Since header fields!

On to chapter 4, a little bit wiser...

------------------------------------------------------------------------------------------------------

CHAPTER 4: [:()[:|:&};:]


In chapter 4 I was met by a continuation of the story, and a link to Chapter 5 (the start of Part 2). EOF.


PART 2/CHAPTER 5: [0xC00007B]

Following the link landed me on a page with a javascript window prompt. No continuation of the story here!
 

So I opened up the browser debugger to inspect the javascript. In doing so I actually saw the hidden HTML on the page which revealed the URL for chapter 6. I ignored it and decided to complete this little JS challenge anyway.


As can be seen from the JS, 

var X is a  user inserted string, var L is some arbitrary string. 
The if conditions are true if the string is null or if a substring (X.substr) of var X is equal to 
var L

Considering the 1st if condition (from testing) is not the desired result, it is the 2nd if condition that needs satisfying.

The parameters of X.substr show that the substring is made using the chars from the second char through to, and ending on seven chars along from the second char of the user inputed string var X.
This means that the var X must contain var L "Ikdf076" prepended with two other arbitrary chars. Such as "00Ikdf076". 


The string was submitted and the second if condition was satisfied. The window prompt was then removed and revealed the underlying HTML.


Another URL to chapter 6.. Until the next post.

------------------------------------------------------------------------------------------------------

CHAPTER 6: [++Q++++++]

Chapter 6, much like chapter 5 begins with a javascript window prompt. Immediately I looked at the debugger to analyse the JS.


No hints to be found in the title of the JS prompt. The code, however was more revealing. It was clear that the JS had been obfuscated in some way, however there was some clear text.

"Someone didn't bother reading my carefully prepared memo on commonly-used passwords. Now, then, as I so meticulously pointed out, the four most-used passwords are: love, sex, secret, and... - The Plague"


A reference to the timeless and ever accurate movie "Hackers". The four most common passwords (according to the movie) are love, sex, secret.. " Don't forget god, system operators love to use god, it's that whole male ego thing" as cereal killer says.

Well what a hint! I enter god then GOD and Im through. However thats not much fun. So I had a look at that more interesting obfuscated JS.

So I began by going to jsbeautifier.org to make use of their unpacking and deobfuscating tools. From scan reading the code, I noticed some escaped hex character codes which jsbeautifier can also take care of.


Suddenly all nice and at least readable. Theres still a large amount of obfuscated code, but none the less, allot to work with. The first var is an array of strings. At this point I guessed that the strings in this array are being used throughout the obfuscated code in some way, due to their nature; "location", "addEventListener" "DOMContentLoaded" etc.

I then read through the code, almost 500 lines, but fortunately I could gloss over most of it due to it being mostly garbage. However, at the end I discovered the function Im looking for, the window prompt function.


It appears that this is using the array thats declared on line 1 ( _0x5cf4) is key in this function.
The user input string is hashed using MD5 (on line 474) and then compared to the 9th element of _0x5cf4. If true, the window prompt is removed. 

I then went back to line 1 of the code and looked through the array for the 9th element. There I found the string "0d28cba0bd4f26e16d766000d27e49fa". This looked like an MD5 hash.
From reading the window prompt function, its clear that an un-hashed version of this string needs to be entered for it then to be hashed and compared against the relevant element in the array.

In order to reverse the hash, I navigated to hashkiller.co.uk to make use of their MD5 cracking tool. I entered the hash and got a result:


0d28cba0bd4f26e16d766000d27e49fa MD5 : GOD

This corresponds to the earlier "Hackers" hint, so it must be correct! I entered it into the window prompt and I was through.

CHAPTER 7: [KS(x)<=|(x)+4]

The story continues, the text on this page had some revealing hints. 


"There was a pattern in the path she had taken through the network. An artificial pattern, la[i]d out by someone or something. There was no hint, no obvious step. Finding the next node would be the challenge, or maybe more like a test."

This appeared to me to be hinting at the pattern of the URLs. I looked at the previous URLS, they all appeared to be MD5 hashes as well.
I again navigated to hashkiller.co.uk to crack the hashes. I entered them in the order that I had solved them. The following results were returned;

c81e728d9d4c2f636f067f89cc14862c MD5 : 2
eccbc87e4b5ce2fe28308fd9f2a7baf3 MD5 : 3
e4da3b7fbbce2345d7772b0674a318d5 MD5 : 5
8f14e45fceea167a5a36dedd4bea2543 MD5 : 7
6512bd43d9caa6e02c990b0a82652dca MD5 : 11
c51ce410c124a10e0db5e4b97fc2af39 MD5 : 13
70efdf2ec9b086079795c442636b55fb MD5 : 17


2, 3, 5, 7, 11, 13, 17.

I could immediately disregard the first number as the story also stated "It had been there since the second node".
I began to form a pattern, it quickly became apparent that there was a pattern of offsets between the numbers;

3  (+ 2)  5  (+ 2)  7  (+ 4)  11  (+ 2)  13  (+ 4)  17

2, 2, 4, 2, 4... ?2, 2, 4, 2, 4...?

:- 17 + 2 = 19


The next step was to hash the result.


I then prepended 8_ to the hash to adhere to the URL scheme and entered it into the browser. Success! On to Part 3, the final chapter!...



------------------------------------------------------------------------------------------------------

PART 3/CHAPTER 8, 9 + 10: [TERM]

The final part of this VM (as the title suggests) consists of a simulated terminal in the browser. The use of a simulated terminal is actually more of a story telling device rather than a technical challenge. As a result, I will not be explaining how I completed these chapters, instead I'll briefly discuss the story line and what these chapters entail.

Through out this VM the story line has been a central element, this comes to a head and is mostly resolved in these chapters, and its done in what I can only describe as a wonderful way. This resulted in it feeling more like the final act of a movie than a vulnerable VM (complete with end credits)!

The simulated terminal features a few limited *nix commands that are used to cat some log files and see running processes in order to 'gain access' to each "server/AI" (as the story portrays). It requires some lateral thinking, a dash of detective work, a little bit of googling and tests your hacker movie/book knowledge.

To say any more would serve little purpose other than to spoil the experience of anyone that may wish to complete this VM. Which I recommend you do!

Although I am more interested in the technical, it must be said that this VM was great fun and a great experience, such a unique way of telling a story and a great method of involving the audience. The challenges themselves are fairly simple and will not be taxing for any one with a basic skill level. None the less, regardless of skill, I believe most people would enjoy completing this VM.

Many thanks to Arne Rick for making such a wonderful VM and clearly putting in a ton of effort. I look forward to the next instalment!