Welcome to Timblog!
I'm Tim Johansson, and this is where I store everything that I write. You can browse through everything on this page, or you could choose a category that interests you in the top bar. If you have anything to say, don't hesitate to comment -- I love comments, too. Enjoy.
Name: Ok, finally it’s secure. Or?
Place: London, UK
Target: MicroWorld building
This time its them. We want access to their fire alarm system.
Search for the form:
73
74
75
76
77
78
79
80
| <form name="LayoutBereich1FORM" action="" method=
"post">
<input id="Eingabefeld1" type="TEXT" name=
"inputbox1" value="" size="30" maxlength="30">
<input type="BUTTON" name="Schaltflächen1"
value="Enter Password" id="Schaltflaechen1"
onclick="testEncode(this.form)">
</form> |
Eingabefeld1/inputbox1 is the only field. testEncode() is called onclick.
39
40
41
42
43
44
45
| function testEncode(form) {
var dater = new Date();
Day = dater.getDate();
dater = null;
var Ret = encode (form.inputbox1.value, Day)
location = Ret + ".html"
} |
Now, the date seems to matter. Day is set using getDate(), which returns the current day of the month, from 1 to 31. In my current case, it is 17, since the date is the 17th of July.
Next, the variable Ret is set to encode( form.inputbox1.value, Day ). The first argument sent to encode() is the password, and the second argument has already been described. encode() is a function defined on the page.
47
48
49
50
51
52
53
54
55
56
57
58
59
| function encode (OrigString, CipherVal) {
Ref="0123456789abcdefghijklmnopqrstuvwxyz._~ABCDEFGHIJKLMNOPQRSTUVWXYZ"
CipherVal = parseInt(CipherVal)
var Temp=""
for (Count=0; Count < OrigString.length; Count++) {
var TempChar = OrigString.substring (Count, Count+1)
var Conv = cton(TempChar)
var Cipher=Conv^CipherVal
Cipher=ntoc(Cipher)
Temp += Cipher
}
return (Temp)
} |
The first line defines Ref as a long string. Next, CipherVal–the second argument, i.e. the day of the month–is changed from a string to an integer. A for loop runs one time for every character in OrigString, which is the password that you entered, incrementing Count each time.
In the loop, TempChar is set to the character at position Count of OrigString, similar to the substring() usage in the previous Jedi Mindtricks challenge. Next, Conv is set to cton(TempChar). The cton() function is set below encode():
61
62
63
| function cton (Char) {
return (Ref.indexOf(Char));
} |
The indexOf() function returns the position of the first occurence of a string in another string. Here, the position of Char in Ref is returned. For example, if Char was “j”, 19 would be returned.
Line 54 contains ^, the bitwise XOR operator. To conduct a bitwise XOR, you compare each bit of two numbers. When the two are not eqal, that bit of the new number is 1. When they are not, it is set to 0. For example, 19^6=21:
10011=19
00110=6
10101=21
Cipher is set to Conv^CipherVal, and ntoc() is called with the result as an argument.
65
66
67
| function ntoc (Val) {
return (Ref.substring(Val, Val+1))
} |
Just like the previous occurence of substring(), this returns the character from Ref at position Val, which is position Cipher. The result is appended to Temp, and after the return, Temp is returned, and testEncode sets the location to the returned string with the “.html” suffix.
Now, you should be coming to a sad realisation: the password cannot be figured out through only the source code. In fact, this has nothing to do with JavaScript at all. It’s just an incredibly stupid category for this challenge.
Instead, start looking at what is different from other challenges. You’ve probably noticed that the location does not follow the standard; the URL is http://www.hackquest.de/modules/HackQuest/hacking/274/octodron/274.php. What an Octodron is, I have no idea, and neither does Google. One of those racing tracks that is formed like an 8, making you return to where you started? A misspelt octodon? Anyway, this should catch your eye.
The next part is just about testing as you would for any vulnerability. After a while, you might find that there is a nice directory-listing at /modules/HackQuest/hacking/274/octodron. ClickThisHiddenFile.php? Yes, please.
Name: Jedi mindtricks.
Place: Mexico City, Mexico
Target: Twilight Security Company
At least five major MSA agents came from here. Take them off the internet for good.
The source code is obfuscated, through URL-encoding it and then fixing it with JavaScript. Generalizing the code, we have:
1
2
3
| m = '%3C%21...html%3E';
d = unescape(m);
document.write(d); |
If we could only get hold of d, this challenge would be a lot easier. The formerly mentioned JavaScript injection comes in handy. However, trying to inject the intuitive javascript:alert(d) would end up with nothing but a hard-to-manage alert-box. Instead, we will put it on the page. Just using document.write(d) will result in the tags being interpreted by your browser. Therefore, we put it all inside a textarea.
javascript:document.write('<textarea>'+d+'</textarea>')
This will give you the whole source code inside a nice textarea field. Put your cursor in it, select everything with ctrl+A and then paste it into a text editor for an easy overview. As always, start by finding the form.
67
68
69
70
71
72
| <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> |
Only one field this time, “Eingabefeld1″. Submitting calls PassConfirm().
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| function PassConfirm() {
var y="alphabravocharliedeltax";
var x="lidocaineadrenalineekel";
var z="sidewinderamraamphoenix";
var s = "";
for (Count=0; Count < y.length; Count++) {
var t1 = y.substring (Count, Count+1);
var t2 = z.substring (Count, Count+1);
var t3 = x.substring (Count, Count+1);
if (t1 * t2 * t3 >= 5 || t3^t1 >= 3)
s=s+t1;
else {
if (t3 == t2)
s=s+t3;
if (t2 == t1)
s=s+t2;
if (t1 == t3)
s=s+t3;
}
}
var x=document.LayoutBereich1FORM.Eingabefeld1.value
if (x==s) {
y = s + ".php"
window.open(y,"_self")
} else {
alert("Dooh, try again!")
}
} |
First, x, y and z are set to some strings. A for-loop then starts. It increments Count and is run from 0 until Count < y.length. y.length is the amount of characters in "alphabravocharliedeltax", which is 23.
In the for loop, the three variables t1, t2 and t3 are first initialised using the substring() function. substring() is a built-in JavaScript function that extracts a part of a string. In this case, it only takes one character, the one at position Count (remember that the first character is character 0).
The following condition check is just bogus. The product of strings (t1*t2*t3 or t3^t1) will never be of a numerical value, and thus only the else-block will be executed. What the else-block effectively does is that it appends the character to s if two of the three strings have the same character at that position With this information, we can go through x, y and z and find the password. The first one is at Count==1, where the x and z substrings are equal and thus "i" is added to s. The next is at Count==2, and the at Count==8. In my case, the final s was ideaeex.
Next s is checked to be equal to the password entered, and if it was right, the challenge is cleared.
This challenge presents a more modern (and unnecessary) way of entering the code.
Name: What you mean its not THAT easy?
Place: Berlin, Germany
Target: MAD central
This german security agent needs some info uploaded, so they realize the MicroWorld threat.
It’s a little more difficult to find the form now, but that’s still were we should start. Searching the source code for “form” reveals that everything is even printed through the JavaScript:
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
| <!-- Key-code script by Bart Jellema -->
var usermulcode=10
var code=0 // the entered code
var mul=1 // the multiplied digits
var digit=0 // number of digits entered so far
var fails=0 // number of tries done
function Clear_code()
{
document.codepad.thecode.value=''
code=0
mul=1
digit=0
}
function Enter_code(number)
{
code=code*10+number
mul=mul*number
document.codepad.thecode.value=code
digit++
if (digit==4)
{
if (mul==120)
{
window.open (code+".php", "_self")
}
else
{
fails++
code=0
mul=1
digit=0
if (fails<3) {
if(fails==1){
document.codepad.thecode.value="Try again"
}
if(fails==2){
document.codepad.thecode.value="Last time"
}
} else {
document.codepad.thecode.value="Bye!"
}
}
}
}
function keycodepad(mulcode)
{
usermulcode=mulcode
document.write("<table><tr><td><form name=\"codepad\">");
document.write("<input type=\"button\" value=\" 1 \" onClick=\"Enter_code(1)\">");
document.write("<input type=\"button\" value=\" 2 \" onClick=\"Enter_code(2)\">");
document.write("<input type=\"button\" value=\" 3 \" onClick=\"Enter_code(3)\">");
document.write("<input type=\"button\" value=\" 4 \" onClick=\"Enter_code(4)\"><br>");
document.write("<input type=\"button\" value=\" 5 \" onClick=\"Enter_code(5)\">");
document.write("<input type=\"button\" value=\" 6 \" onClick=\"Enter_code(6)\">");
document.write("<input type=\"button\" value=\" 7 \" onClick=\"Enter_code(7)\">");
document.write("<input type=\"button\" value=\" 8 \" onClick=\"Enter_code(8)\"><br>");
document.write("<input type=\"button\" value=\" 9 \" onClick=\"Enter_code(9)\">");
document.write("<input type=\"button\" value=\" 0 \" onClick=\"Enter_code(0)\">");
document.write("<input type=\"button\" value=\" C \" onClick=\"Clear_code()\"><br>");
document.write("<input type=\"text\" name=\"thecode\" size=9 value=\"\"><br>");
document.write("<\/form><\/table>");
}
<!-- Key-codescriptbyBartJellema--> |
It is initialised at line 95 by the call keycodepad(24). Apparently, the variable “mulcode” is thus set to “24″, and after that “usermulcode”. Every click on a number calls Enter_code() with the number clicked as an argument. We will therefore dissect Enter_code(number), line by line.
First, code is multiplied by 10 and then the number is added to it. The effect of this is that number is appended to the right of the existing code. From the start, code equals 0 (line 27), and it is reset to that if C is pressed (from the Clear_code() function).
Next, mul is multiplied by the number pressed. mul starts off as 1 and is reset to 1 by Clear_code(). The line after that just updates the “display” to show the full code. After that, digit is incremented. As can be seen from line 29, digit is the number of digits that have been pressed (although this is reset by Clear_code() to 0).
Unless the following condition is true, Enter_code() ends here. The if statement checks whether digit==4, i.e. if four digits have been pressed. If mul==120, we have succeeded and are referred to another page. If not, the wrong-code handling sets in. It seems as if it is so easy as to find four digits between 1 and 9 where the product equals 120. However, it is not (what you mean it’s not THAT easy?). It seems that we have to find the correct combination, and through only the JavaScript, this is not possible. The usermulcode variable is of no use since it is not use in this script. We can find al combinations using a simple Perl script, though:
1
2
3
4
5
6
7
8
9
10
11
12
| @n = 2..9;
foreach my $a (@n) {
foreach my $b (@n) {
foreach my $c (@n) {
foreach my $d (@n) {
if ( $a*$b*$c*$d == 120 ) {
print $a, $b, $c, $d, "\n";
}
}
}
}
} |
Since the URL is only dependant on the code (line 49), we can actually generate a nice list of possible solution URLs. Just replace line 7 in the perl script above with:
7
| print 'http://www.hackquest.de/modules/HackQuest/hacking/824/', $a, $b, $c, $d, '.php', "\n"; |
http://www.hackquest.de/modules/HackQuest/hacking/824/2256.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2265.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2345.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2354.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2435.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2453.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2526.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2534.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2543.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2562.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2625.php
http://www.hackquest.de/modules/HackQuest/hacking/824/2652.php
http://www.hackquest.de/modules/HackQuest/hacking/824/3245.php
http://www.hackquest.de/modules/HackQuest/hacking/824/3254.php
http://www.hackquest.de/modules/HackQuest/hacking/824/3425.php
http://www.hackquest.de/modules/HackQuest/hacking/824/3452.php
http://www.hackquest.de/modules/HackQuest/hacking/824/3524.php
http://www.hackquest.de/modules/HackQuest/hacking/824/3542.php
http://www.hackquest.de/modules/HackQuest/hacking/824/4235.php
http://www.hackquest.de/modules/HackQuest/hacking/824/4253.php
http://www.hackquest.de/modules/HackQuest/hacking/824/4325.php
http://www.hackquest.de/modules/HackQuest/hacking/824/4352.php
http://www.hackquest.de/modules/HackQuest/hacking/824/4523.php
http://www.hackquest.de/modules/HackQuest/hacking/824/4532.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5226.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5234.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5243.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5262.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5324.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5342.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5423.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5432.php
http://www.hackquest.de/modules/HackQuest/hacking/824/5622.php
http://www.hackquest.de/modules/HackQuest/hacking/824/6225.php
http://www.hackquest.de/modules/HackQuest/hacking/824/6252.php
http://www.hackquest.de/modules/HackQuest/hacking/824/6522.php
Just start testing.
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”.
Yesterday, I was transferring a blog from one server to another. I had SSH access to the server which the blog was moving from, and FTP access to the one which it was moved to. The simple solution in this situation is to use a command-line FTP client to simply upload everything. I tried, but encountered a problem.
Using the native ftp command, which comes with virtually every Linux distribution, I found the mput (multiple put) command. However, trying to use it with wild-cards didn’t work, since only the files in the base directory were uploaded. Trying things like mput */* only resulted in strange errors about existing files not existing. I went to look for a new text-based FTP client, which would be usable through SSH, and found lftp, which apparently was installed as default on my system.
lftp has a handy mirror command, similar to the wget –mirror option. Adding the -R (reverse) argument to mirror, recursive uploading became a piece of cake. Just do mirror -R when in the correct local and remote directories.
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.
« Later Posts —
Earlier Posts »