Guides
Everyone gets stuck at games now and then. In an attempt to help some of those people, I publish guides to some games that I've beaten. Choose a game or browse through all of them.
Name: Now, what is that really?
Place: Melbourne, Australia
Target: Garage of James Fern
This guy developed software that MicroWorld stole. Now we steal it first, much safer.
Pressing “Enter Site” gives a JavaScript alert, “Sorry all wrong”. As usual, we look up the source code of the form.
32
33
34
35
36
37
38
39
40
41
42
43
| <form name="form" action="" method="post">
Username<br>
<input id="Eingabefeld2" type="TEXT" name="Name" value=""
size="30" maxlength="30"><br>
Password<br>
<input id="Eingabefeld1" type="TEXT" name="Password"
value="" size="30" maxlength="30"><br><br>
<input type="BUTTON" name="Schaltflächen1" value=
"Enter Site" id="Schaltflaechen1" onclick=
"pw(this.form)">
</form> |
Remember to note what you always should note; the username ID (Eingabefeld2/Name), the password ID (Eingabefeld1/Password) and the onclick event (pw(this.form)). We start by checking what the pw() function does. For a change, it isn’t obfuscated.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| function pw (form)
{
var d1, d2, d3;
d1=window.document.bgColor;
d2=form.Name.value;
d3=form.Password.value;
if (d2==d1.length) {
if (d3==d1) {
window.open (d1.substr(1, 10)+".php","_self")
} else {
alert("Sorry all wrong.")
}
} else {
alert("Sorry all wrong.")
}
} |
d2 and d3 are simply set to the username and password, respectively. d1, however, is set to the current background colour, which is a little uncommon. We then have two checks, the first one checks that d2 (username) equals the length of d1 (background colour). To find the exact background colour, we use a very useful technique called JavaScript injection.
With a JavaScript injection, we can execute arbitrary JavaScript commands at any page. Do so by putting the command in the location bar of your web browser (usually ctrl+L), prefixing it with “javascript:”. By making a JavaScript alert with the background colour in, we can easily copy that colour name. Put “javascript:alert(window.document.bgColor)” into the location bar, and you will see a popup with a colour name. In my case, it was #0e0e0e. This is d1.
The username was supposed to be the same as the length of the background colour. The length of #0e0e0e, i.e. the amount of characters in that string, is 7. Thus, the username must be “7″.
The next condition is “d3==d1″, which means that the password should be the same as the background colour, which is “#0e0e0e”.
Name: Sir, could you pop me?
Place: Tokyo, Japan
Target: Lant Towers
There was a meeting in these rooms, which we must disrupt. Get us in…
When you start this challenge, you will notice that you are immediately prompted for username and password, and thereafter redirected to an irrelevant page. Disabling JavaScript from the start could give you problems with getting through the Flash screen. Thus, you’ll have to find the URL for the page all by yourself. After pressing the “Accept” button, hit the “Stop” button on your browser before you see the username/password prompts. Now, view the page source and look for the frame containing the challenge. You will find an (incorrectly implemented) iframe:
<iframe width=100% height=650 src="modules/HackQuest/hacking/frameheader.php?uname=Tim&uid=56382&url=253">
Of course, your uname and uid will be different. Follow that URL with JavaScript disabled and view the source code. You will se a relatively elaborate attempt at hiding the JavaScript, pushing the line count of the file to 56536. However, you should have no problems finding the not-so-elaborately hidden username and password declarations.
and
var password = "Mnemonic";
Enter those values, and you have succeeded.
The third JavaScript challenge is a bit more complex.
Name: Don’t look at me like this.
Place: Hawaii, USA
Target: DoD Network
You will have to get the passkeys for the system inside the navy base. We need to inject some data.
First, you might notice that right-clicking has been “disabled”. This is never a problem–just disable JavaScript, which was used to stop right-clicking. You can also view the source code by opening the challenge page in a single window instead of in a frame, and from there viewing the source code from the toolbar. Peeking at the form, we find:
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| <form name="e" action="" method="post">
<input id="u" type="TEXT" name="TEXT" value="User"
size="30" maxlength="30"> <input id="p" type="TEXT"
name="TEXT" value="Password" size="30" maxlength=
"30">
<table border="0">
<tr>
<td>
<input type="BUTTON" name=
"Schaltflächen1" value="Enter Site" id=
"Schaltflaechen1" onclick=
"return ValidateEntry()">
</td>
</tr>
</table>
</form> |
Note the important items here:
- The form name is “e”.
- The ID for the username field is “u”.
- The ID for the password field is “p”.
- Upon submitting, the function “ValidateEntry()” is called.
Next, we’ll check what ValidateEntry() does.
38
39
| function ValidateEntry (){var y=document.e.u.value;var z=document.e.p.value;var x=0;if (y=='User'){alert('Please complete this form');var x=1;}
if (z=='Password'){alert('Please complete this form');var x=1;};if (x==1){alert('Entry was not successful');var xxx=0;}else{AreYouWho(y,z);}} |
For obfuscation, the DoD Network seems to have compressed the function into two long lines. Neating it up a bit, we have:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| function ValidateEntry () {
var y = document.e.u.value;
var z = document.e.p.value;
var x = 0;
if ( y == 'User' ) {
alert( 'Please complete this form' );
var x = 1;
}
if ( z == 'Password' ) {
alert( 'Please complete this form' );
var x = 1;
}
if ( x == 1 ) {
alert( 'Entry was not successful' );
var xxx = 0;
} else {
AreYouWho( y, z );
}
} |
In lines 2-3, y and z are set to the entered username and password, respectively. The rest of the code runs the function AreYouWho() with the username and password as arguments unless you haven’t changed both “User” and “Password” a bit. The AreYouWho() function is squashed together into the two next lines. The neater version of it would be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| function AreYouWho( z, y ) {
var x = 0;
if ( z == 'Password' ) {
var x = 1;
}
if ( y == 'User' ) {
var q = x + 1;
}
if ( q == 2 ) {
window.open( "hmmm.php" , "_self" );
} else {
alert( 'Incorect Log-In, Password or User Name invalid' );
var q = 0;
var x = 0;
}
} |
Now, we know that having q==2 is good for us, since the alternative alerts that the data supplied is incorrect. Thus, we look for how to edit q. It is defined at line 7 in AreYouWho() as x+1. Thus, we want x to equal 1 since 1+1=2 and we want q to be 2. x is defined as 1 at line 4 if z=’Password’, and q is later set to x+1 if y=’User’.
Here comes the tricky part: what are z and y? We can see from the first line that these arguments are accepted such that the first argument passed is z, and the second is y. ValidateEntry() sends the arguments reversed, calling AreYouWho(y,z). This means that the y in ValidateEntry() becomes z, and vice versa. Therefore, the username should be ‘Password’ and the password should be ‘Username’.
As the name implies, it’s simple if you see it (if you don’t, your intelligence isn’t something to brag about).
Name: It’s simple if you see it.
Place: Reston, USA
Target: CyberTec
CyberTec was a consulting company that helped MicroWorld produce better software in less time.
As with the previous challenge, start by viewing the source and find the form. This time, they put a nice table in it.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
| <form name="form" action="" method="post">
Username <input id="Eingabefeld2" type="TEXT" name=
"Name" value="" size="30" maxlength="30"><br>
Password <input id="Eingabefeld1" type="TEXT"
name="Password" value="" size="30" maxlength="30">
<table border="0">
<tr>
<td>
<input type="BUTTON" name=
"Schaltflächen1" value="Enter Site" id=
"Schaltflaechen1" onclick=
"Spikeman_password(this.form)">
</td>
</tr>
</table>
</form> |
This time, the onclick action calls the function Spikeman_password, sending the relevant form as an argument. Searching for the spikeman_password function, we find that it is almost as simple as the previous password verification function, only with a username added:
31
32
33
34
35
36
37
38
39
40
41
42
| <!----- Script CopyRight © 1996 - 1997 S.Chris Brown (Spikeman)
function Spikeman_password(form) {
if (form.Name.value=="Gates") {
if (form.Password.value=="moneymoneymoney") {
window.open ("yes.php","_self")
} else {
alert("Sorry " +form.Name.value+ ", wrong password.")
}
} else {
alert("Invalid Name")
}
} |
The function checks whether or not the username equals “Gates” and the password equals “moneymoneymoney”. Enter those values, and the mission is accomplished.
A thought: Why wasn’t this password field a real password field, i.e. with the input hidden?
I recently stumbled upon HackQuest, a legal simulation of hacking/cracking, alike to the previously half-covered Hack This Site and Hellbound Hackers. The challenges look nice, although their unnecessary use of Flash to start missions is a bit irritating. On a side-note, this is the first semi-hacking site I’ve seen that tells some kind of story. Anyway, I decided to help others, who might get stuck.
Name: I am a JavaScript. Abuse me.
Location: Sydney, Australia
Target: Bane Corp
Those guys invented parts of the trusted computing hardware, and are still an integral part of the MicroWorld family. We need to get some data of their servers.
You are met by a form containing nothing but one input field and a submit button. Entering a bogus password gives a pop-up: “Dooh, try again!”. The pop-up is a JavaScript alert, which indicates that the form is validated through a JavaScript. View the source code to investigate this further. Note that this challenge is contained within an iframe–make sure that you view the source of that specific frame.
38
39
40
41
42
43
44
45
| <form name="LayoutBereich1FORM" action="" method=
"post">
<input id="Eingabefeld1" type="TEXT" name=
"Eingabefeld1" value="" size="30" maxlength="30">
<input type="BUTTON" name="Schaltflächen1"
value="Enter Password" id="Schaltflaechen1"
onclick="return PassConfirm()">
</form> |
You should be able to find the form, despite its being written in German. As you can see, submitting the form calls the PassConfirm() JavaScript function, which can also be found in the source. It is written here, with redundant spaces removed for the sake of sanity.
23
24
25
26
27
28
29
30
| function PassConfirm() {
var x=document.LayoutBereich1FORM.Eingabefeld1.value
if (x=="thisisthepassword") {
window.open("ok.php","_self")
} else {
alert("Dooh, try again!")
}
} |
Line 24 sets x as the value in the password field, and the next line checks whether it is equal to “thisisthepassword” or not, and if it is, the “ok.php” window is opened. Thus, the password is “thisisthepassword”. Click the “Rank up!” link in the upper right corner of the layout, and you are done.
This problem is one of the easiest ones at Project Euler. You can even solve it manually in less than a minute; just highlight the nines in your browser, and you will see the potential candidates. You’ll have problems proving it that way, though, but you can just try the solution and check if it works.
Here is a nice Perl script that checks every product. Being the lazy perl-programmer I am, I let Perl format the numbers instead of doing it by hand.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # put the numbers into an array
@n = split //, join '', qw/
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
/;
my $m; # this is the greatest product yet found
foreach my $i ( 0..(@n-5) ) {
my $p = $n[$i]*$n[$i+1]*$n[$i+2]*$n[$i+3]*$n[$i+4]; # find current product
$m = $p if $p > $m; # update $m if this product is greater
}
print $m; # print the result |
There is really nothing interesting here, except perhaps the second line. Using the qw// operator, Perl first makes a list where every element is a row of the long number. join joins the rows together to one long string, and split splits them such that each element contains one number.
I thought about writing a more elaborate script that would move through the list, dividing by one element and multiplying by another. However, I decided that the existence of zeroes would make it too difficult to be worth the trouble.
Warning: The code looks ugly with all those pink numbers if you’re using a weird colour hilighting.
If you’re playing like me, you probably have lots of “while helpless” deaths in the top 10. In order to make these messages somewhat helpful instead, install Jukka Lahtinen’s helplessness reasons patch as soon as possible. This very useful patch will make new death messages more descriptive, such as “while praying”, “while reading a book” and “while frozen by a monster’s gaze”.
The sooner you install the patch, the less boring “while helpless” deaths you will have. Note that you will have to recompile the source to do this, and by doing so, the NetHack folder (often /usr/games/lib/nethackdir) is overwritten. Make backups of your logfile, bones files and save files.
Hello Tim, welcome to NetHack! You are a neutral male human Barbarian. Watch out! Bad things can happen on Friday the 13th.
Before realizing that today is the unlucky Friday the 13th, I started a NetHack game. My barbarian quaffed from a fountain, immediately attracting a water demon, who summoned one of his friends. They hunted me down into a corridor, and killed me with an arrow when I fingered Elbereth into the dust.
Drinking from the fountain was probably a bad idea from the start, but I’m convinced that Friday the 13th had something to do with it.
Since I’ve become addicted to NetHack, an old text-based RPG, I decided that i should spread parts of my discoveries.
Press or push keys–never hold them. If you want to search for hidden doors, use n20s (or just 20s if you’re not using numpad). This way, if you are disturbed, the search will end and you will regain control of your character. If you had held s down, a newt could have come and eaten you while you were letting go of the key. One problem is when monsters who will not attack you are around, such as unaligned unicorns. In that case, you’ll just have to be patient. Or kill the unicorn.
You start off with two bases, Sylvanas’s and Varimathras’s in the upper left and Garithos’s in the lower right. As usual when you have to defend several fronts, lower the speed to slow from the start. The key here is taking the map on systematically. Gold is abundant, and thus you will not be in a hurry to expand.
Start by setting up a solid defense in both bases, and sending your Shades to strategical locations close to both the orange and the purple bases, so that you can anticipate their attacks and prepare specifically for them.
The optional quest to save the dwarves is a given. It is very easy to complete, and their siege tanks are an invaluable asset. Start by upgrading your Keep to a Castle, training some Footmen and upgrading as much as you can. After fighting back the first wave, which seems to come from the Green base every time, send Garithos and his units to the north to rescue the dwarves. You will need to do this quickly, since you will soon be attacked by flyers.
Next, build five Siege Engines and as many Knights as you have population for. Send Garithos and his army to the west, in order to secure another gold mine and get one threat off your back. Keep healing your troops and micromanaging the Siege Tanks, and you will have no problems leveling the base. In the worst case, you will have to retreat when your tanks have been destroyed, and attack again with more tanks. Tanks solve everything.
With the Green base out of the game, you can probably defeat Balnazzar’s base already. However, if you want to be on the safe side, get Sylvanas and an army of Banshees walking/hovering southwards. I never attacked the Orange base, but I figure that it shouldn’t be too much of a problem, as long as you make sure that you have time to return before Balnazzar has destroyed your base.
When time comes for the last assault on Balnazzar, start by attacking on Sylvanas’s side. Possess everything that you want. After a ten seconds or so, most of the defending units should have moved to the north-western part of the base in order to fight Sylvanas back. Don’t worry if you’re outnumbered, since this is only a decoy. Enter Garithos and a lot of Kights and Siege Tanks. The tanks will make a short story of any buildings, while the knights’ armor along with Lord Garithos’s Devotion aura make your army nearly impervious. Keep silencing and putting enemies asleep with Sylvanas and Varimathras, while maintaining a steady supply of new units. Once you start destroying the unit-producing buildings, the Dread Lord will stand no chance.
« Later Posts —
Earlier Posts »