Tools to Use | Some JavaScript Definitions |
---|---|
The Reason You are Reading This | Gratuitous Ending Statement |
Tools I used:
I inadvertently discovered MS FrontPage 98's value as an editor. I had
long ago given up on Front Page 98 as an HTML editor because of it's now
familiar Microsoft bulk. In fact, I followed Fravia's lead and use edit.com.
Fron Page 98 has languished on my hard drive until now. From Explorer,
I right clicked The Seekers Jscript file and selected edit expecting Notepad
to open it. When FP opened it I was surprised and very quickly pleased.
You get three tabs. Normal, HTML, and Preview. I selected the HTML
tab and edited the code. I then selected the Preview tab and was pleased
to see the code executed.
Switching from edit to run was just a mouse click away.
MS Excel:
I used Excel to give me a graphical representation of the manipulation
of the ciphertext and to do the simple addition that isrequired to encipher
and decipher the text. Using a combination of alert()'s and my Excel spreadsheet
I was able to very quickly produce the info I needed to be successful.
Tools you need:
The method I Used:
The first thing to do when attempting to reverse any program is to run
it and see what it does for or to you. From there, you decide where to
set breakpoints and try to find your way to the Entry Point. You
then step through and keep track of what happens when and where. This tutorial
assumes that you don't have any way to run the Jscript.html file. This
will be a purely mental exercise. With that thought in mind I thought it
would be prudent to include some definitions.
Definitions:
(Courtesy of The JavaScript Sourcebook by Gordon
McComb)
eval: The eval function evaluates an expression. Syntax: eval(expression) Expression is the expression you wish to evaluate. It can be enclosed in quotation marks. Example: Val = 2 Ret = eval ("2 + Val"); alert (Ret); substring: The substring method returns a portion of a string. You specify the beginning and the ending portion you want to "extract" by indicating the position of the start and stop point in the string. Javscript strings are zero-based, so the first character is 0. The last character is string.lengh-1 -- that is, one less tan the length of the string. Syntax: string.substring(start,stop) String is the string from which you want to get text; start is the starting position of the extracted text; stop is the ending position of the extracted text. Example: The following example extracts the first four characters from a string. InString = "This is a test" Ret = InString.substring(0,4); alert (Ret) charAt(): The charAt method returns the character at a given position in a string. Syntax: string.charAt.(index) String is the string you want to search through; index is the position of the character you want to return. Example: This example prints each letter of the text "JavaScript" on a separate line (it also includes a for loop). TestString ="JavaScript" for (Count=0;Count < TestString.length; Count ++){ document.write (TestString.charAt(Count) + "<BR>";) } More Info: Use the charAt method whenever you want to pick out a character from a string. One possible use is converting the numbers 1 through 26 to letters. The following displays "k" because it's the eleventh letter in the alphabet: var getChar = 11; Alphabet = "abcdefghijklmnopqrstuvwxyz"; alert (Alphabet.charAt(GetChar-1)); /* Remember to start at 0 */ indexOf Method. Returns the index within the calling String object of the first occurrence of the specified value, starting the search at from Index. Syntax stringName.indexOf(searchValue, [fromIndex]) Parameters stringName is any string or a property of an existing object. searchValue is a string or a property of an existing object, representing the value to search for. fromIndex is the location within the calling string to start the search from. It can be any integer from zero to stringName.length - 1 or a property of an existing object. Method of String Implemented in Navigator 2.0 Description Characters in a string are indexed from left to right. The index of the first character is zero, and the index of the last character is stringName.length - 1. If you do not specify a value for fromIndex, JavaScript assumes zero by default. If searchValue is not found, JavaScript returns -1. If stringName contains an empty string (""), indexOf returns an empty string. The indexOf method is case sensitive. For example, the following expression returns -1: "Blue Whale".indexOf("blue") Examples Example 1. The following example uses indexOf and lastIndexOf to locate values in the string "Brave new world." var anyString="Brave new world" //Displays 8 document.write("<P>The index of the first w from the beginning is " + anyString.indexOf("w")) //Displays 10 document.write("<P>The index of the first w from the end is " + anyString.lastIndexOf("w")) //Displays 6 document.write("<P>The index of 'new' from the beginning is " + anyString.indexOf("new")) //Displays 6 document.write("<P>The index of 'new' from the end is " + anyString.lastIndexOf("new")) Example 2. The following example defines two string variables. The variables contain the same string except that the second string contains uppercase letters. The first writeln method displays 19. But because the indexOf method is case sensitive, the string "cheddar" is not found in myCapString, so the second writeln method displays -1. myString="brie, pepper jack, cheddar" myCapString="Brie, Pepper Jack, Cheddar" document.writeln('myString.indexOf("cheddar") is ' + myString.indexOf("cheddar")) document.writeln('<P>myCapString.indexOf("cheddar") is ' + myCapString.indexOf("cheddar")) for loop: The for statement repeats a block of instructions one or more times. The number of iterations is controlled by values supplied as arguments. Syntax: for (InitVal; Text; Increment) InitVal is the starting value for the for loop, and is often 0 or 1. It can be any number. InitVal is an expression that establishes the initial value and assigns that value to a variable. For example, Count=0, or i=1. Test is the expression used by the for statement to control the number of iterations of the loop. As long as the Text expression is true, the loop continues. When the Test expresion proves false, the loop ends. For example, Count < 10 is true as long as the value in the Count variable is less than 10. Increment indicates how you want the for loop to count, by 1s, 2s, 5s, 10s, etc. This is also an expression and usually takes the form of CountVar++, where CountVar is the name of the variable first assigned in the InitVal expression. For example, Count++ increases the value in the Count variably by 1 for each iteration. Document Methods: The document methods interact with the document. The most commonly used document method is document.write, which writes text to a browser window.
document.x.x.value returns the text of a text box or text area.
Let's begin reversing this puppy:
I printed the text out and began looking for an entry point. Since there
is a mouse click involved, let's see what the function onClick tells
us to do.
onClick is inside the form named chall ( <form Name="chall">)
See it? onClick we are supposed to run the function "ckPwd".
function ckPwd()
The first thing we do is load the variable txt with the username*password*
you entered. Note that there are *'s inserted between them and at the end.
The next thing is to load ls with the value assigned to pe.
This is a very important string as we will soon see. Now we generate a
key by using the eval and substring method. We take the first
two numbers of ls (in this case 96) and subtract 91 from them.
We assign the value (5) to a. We will see this value again.
The next step reloads ls with the string in pe minus
the first two numbers.
The next two steps initialize nls to 0 and flg to 0.
This is where we start a while loop. For loops and while loops are
similar except that the while loop executes while the function inside the
parenthesis is true.
This loop runs as long as ls is greater than 12 digits in length.
Next we give ab the value of the first two numbers in the
ls string (remember we removed the first two numbers) minus 89. In
this case the answer is 9.
The next little piece of code was a pain in the neck to decipher at
first. Basically it is a conditional expression statement. It reads
like this: Test if ab1 and "" are equal. In other words, is
ab1 blank? If the test is true then ab1=+ab:if it
is false then ab=ab1.
Next we set oab1 equal to ab1 which is a waste of time
we later discover. We load ls with the ls string minus the
first two characters. Do you see what is happening here. ls is getting
smaller (by two's). We are left shifting the string and the ends are falling
off.
Now we start our for loop. Interesting, We are using the value in ab
as the test function. As long as i is less than ab (9) we
run the loop. Have you recognized that we are in a nested loop? We set
nr equal to the first two numbers of ls minus the value in
a. Then we shift ls left 2 digits again. Now we add the charAt
the value in al at position nr to nls.
You do know where al is don't you. Look at the top of page 1.
See the string assigned to al? This is another key piece of info.
We run through the loop 9 times (remember ab = 9) and store
the letters cumulatively and consecutively in nls. A * is added
to the end and the loop finishes. We return to the while loop. If
you have followed the evolution of the value in ls you will see
that the first two numbers are 96. Remember that number. It's very important.
At this point ls has 16 numbers so it is >12 and the loop continues.
ab = 96-89 = 7. I hope that at this point you realize or intuit
that the values 9 and 7 are the length of the username and password respectively.
The string ls holds the key to the actual username and password
string "scattered" through al. The first iteration of the while
loop set up the extraction of the username and the second iteration will
extract the password. Just before entering the for loop ls.length
is less than 12 and the while loop ends. The for loop runs for 7 iterations
and extracts the password one letter at a time and adds it to the end of
the username* value in nls.
We test to see if nls matches tst. If it does we run
the function tstOk. If it doesn't then we increment the flag and
flash the "Sorry Dude" screen.
Funtion tstOk
We set the value in ab1 to equal 9+""+5 (the values in ab1
and a) = 95 azzz = the value you get when you run the unencr
function = filename we are looking for
(see the location.href=azzz HTML?).
function unencr(val);
val is actually the pf value listed just under the function
tstOk under the <form Name= "pd"> tag.
At last. the home stretch.
We initialize a few variables. ab1z = nothing, lsz = val,
and az = the first two characters of the string in lsz which
is val which is pf which is 98 minus 91 = 7. So az=7.
Interesting eh?
The next line shifts the string in lsz left two places.
The next line makes nlsz = blank.
The next line sets abz equal to the first two characters in
lsz minus 89 = 9. Hmmm another important looking number.
The next line is another conditional expression statement that
tests if ab1z is blank. If it is then abz=+abz: if
it isn't ab1z=ab1z. There is another wasted, oab1z=ab1z,
statement on the next line. We shift lsz left twice one more
time.
We start a for loop. Interesting, We are using the value in abz
as the variable in the test function. As long as i is less than
abz (9) we run the loop. Sound familiar?
We set nrz equal to the first two numbers of lsz minus
the value in az (26- 7=19).
We left shift lsz twice.
Now we add the charAt the value in al at position nrz
to nlsz. Remember where al is? Top of the page? We run through
the loop 9 times (remember abz = 9) and store the letters
cummulatively and consecutively in nlsz. Once the loop finishes
nlsz and azzz hold the name of the page we want to go to. Remember
the function tstOk?
tstOk called the unencr function by azzz = unencr.
See the location.href=azzz line? This is where our page is called
from. If you have followed this through to this point you will have
the username, password, and filename for the 1st challenge. Now we have
to "encrypt" the username, password, and filename given to us by The Seeker.
Hopefully, by now, you realize that the pe value holds the username
password combination and the pf value holds the filename.
Our task is to come up with a pe and pf value that will
send us to teacher.htm when we use The_Seeker for a username and Sandman
for the password.
Let's do some encrypting.
First we need to count the number of characters in each word. The old
combo had 9,7, and 9 characters respectively. The new combo has 10,7, and
11. Remember the ab value of 9 from way up at the top. That
was the username count. Remember how we got the number 9? We took the second
pair of numbers in ls (pe) and subtracted 89 from it. The
first pair of numbers was used to compute the key so they remain the same.
The next pair give you the length of the strings. Remember that the while
loop ran twice, once for the username and once for the password. I told
you to remember the number 96 (along with just about everything else).
As You left shift the string in ls you eventually have all of the
username characters and you will restart the while loop. The next pair
of numbers will have 89 subtracted from them and the string length of the
password (count for the for loop) must be the result. In this case, we
are looking for 7 so the old value of 96 still works.
Using the position value (in the string al) of the username
password combination, make a list of numbers. Make sure that the first
pair of numbers remains the same as the original value so that we
don't have to use a new key and the second pair correspond to the character
count of the username string. I'm going to give you the first 4, you compute
the rest.
The_ = 7, 36, 26, 71. Note: Don't forget to put the Key and Count
pairs in front of this string.
The 7 means that the letter T is in the seventh position, remember
to start with zero, in the al text string. Once you have converted
The_Seeker to equivalent numbers add 96 to the end and start adding
the equivalent position values of the character string , Sandman, to the
end of the string. We aren't done yet though. Don't forget our key value.
In this case it is still 5. You have to add 5 to the numbers you get to
complete the enciphering. The_ is now equal to 12,41,31,76. Make sure
that you don't use commas. I used them for clarity but the pe
and pf strings won't like them. You should now have a pe
string that will get you to past the "Sorry Dude" screen. The filename
encrypts very nearly the same way except that your key is a different number.
I'll let you figure it out.
Finished at last!
I have tried to make this a concise, clear tutorial without handing
over the keys to the Cadillac. That's Texan for giving you the answer without
giving you an education. It's very late
here and I have been working on this for quite a few hours. I'm anxious
to see if it passes muster and is posted. I haven't been working with JavaScript
very long.
Thanks to Sandman and The_Seeker I know a lot more than I ever thought
I could. I still have a long way to go. In fact Sandman's intriguing Jscript
is next on the task list. I have already made it to the "goodguy"
page. I just need to find the time to write a tutorial.
It took me about 21/2 hours to fully investigate and then crack this
Jscript code. When I first saw it I didn't think I could ever crack it
much less write a tutorial. So take heart, It can be done if we all stick
together.