Hack You CTF 2012 - Pentagon (WEB100)

3 minute read

Note: images and files are missing in this blogpost. To solve the puzzle, we had to obtain the password to a ‘Pentagon’ site relying on Javascript authentication.

Examining the code, we are given a set of clues and conditions to the password’s contents.

These conditions have to be fulfilled, to summarise:

1. Password is not empty
2. Password is length 12
3. Password[0] is a number
4. Password[1] and Password[10] are numbers
5. Password[2] and Password[6] are numbers
6. Password[0] + Password[1] + Password[2] + Password[6] + Password[10] must
   equal to 12
7. Password[7] must equal to PasswordPrompt[len(PasswordPrompt)-1] (which is
   'd')
8. ord(Password[7]) must equal ord(Password[8]) - Password[0] / Password[0]
9. Password[2] must equal Password[6] and Password[6] must equal Password[1]
10. Password[1] * Password[10] must equal 0
11. Password[1] - Password[10] must equal to len(Password[3]) (which is 1)
12. Password[11] + Password[3] + Password[4] must be lexigraphically equal to
    TodaysSecretPassphrase.substr(Number(SuppliedPassword.charAt(0)) / 2, 3)
13. Password[9] has to be lower case
14. Password[9] has to not be found in the QuoteOfTheDay

Deriving the Password

Going through the steps:

1. Password is not empty

if (SuppliedPassword === null) {
    break;
}

Password: ""

2. Password is length 12

if (SuppliedPassword.length == 12) {
    PasswordIsCorrect = true;
}

Password: "AAAAAAAAAAAA"

3. Password[0] is a number

if (! IsNumber(SuppliedPassword.charAt(0))) {
    PasswordIsCorrect = false;
}

Password: "$AAAAAAAAAAA"

4. Password[1] and Password[10] are numbers

if (! IsNumber(SuppliedPassword.charAt(10)) || !
    IsNumber(SuppliedPassword.charAt(1))) {
    PasswordIsCorrect = false;
}

Password: "$$AAAAAAAA$A"

5. Password[2] and Password[6] are numbers

if (! IsNumber(SuppliedPassword.charAt(6)) || ! IsNumber(SuppliedPassword.charAt(2))) {
	PasswordIsCorrect = false;
}
[/javascript]

Password: "$$$AAA$AAA$A"

6. Password[0] + Password[1] + Password[2] + Password[6] + Password[10] must equal to 12

if (Number(SuppliedPassword.charAt(0)) + Number(SuppliedPassword.charAt(1)) + Number(SuppliedPassword.charAt(2)) + Number(SuppliedPassword.charAt(6)) + Number(SuppliedPassword.charAt(10)) != SuppliedPassword.length) {
	PasswordIsCorrect = false;
}

Password: "$$$AAA$AAA$A" (where all $ == 12)

7. Password[7] must equal to PasswordPrompt[len(PasswordPrompt)-1] (which is ‘d’)

if (SuppliedPassword.charAt(7) != PasswordPrompt.charAt(PasswordPrompt.length - 1)) {
	PasswordIsCorrect = false;
}

Password: "$$$AAA$dAA$A"

8. ord(Password[7]) must equal ord(Password[8]) - Password[0] / Password[0]

if (SuppliedPassword.charCodeAt(7) != SuppliedPassword.charCodeAt(8) - Number(SuppliedPassword.charAt(0)) / Number(SuppliedPassword.charAt(0))) {
PasswordIsCorrect = false;
}

Since a/a = 1, the char code at 7 must be one less than the char code at 8. This Password[8] has to be 'e'.

Password: "$$$AAA$deA$A"

9. Password[2] must equal Password[6] and Password[6] must equal Password[1]

if (Number(SuppliedPassword.charAt(2)) != Number(SuppliedPassword.charAt(6)) || Number(SuppliedPassword.charAt(6)) != Number(SuppliedPassword.charAt(1))) {
PasswordIsCorrect = false;
}

Password: "$&&AAA&deA$A"

10. Password[1] * Password[10] must equal 0

if (Number(SuppliedPassword.charAt(1)) * Number(SuppliedPassword.charAt(10)) != 0) {
PasswordIsCorrect = false;
}

This condition means that either Password[0] or Password[10] is 0.

Password: "$&&AAA&deA$A"

11. Password[1] - Password[10] must equal to len(Password[3]) (which is 1)

if (Number(SuppliedPassword.charAt(1)) - Number(SuppliedPassword.charAt(10)) != SuppliedPassword.charAt(3).length) {
PasswordIsCorrect = false;
}

With this condition, we may deduce four things:
a) Password[10] is 0, because of Condition 10.
b) Password[1] is 1, because it follows from the next logical conclusion we can
   make if a) is true, then Password[1] = Password[10] + 1.
c) Password[2] and Password[6] is 1, because of Condition 9.
d) Password[0] is 9, because of Condition 6.

Password: "911AAA1deA0A"

12. Password[11] + Password[3] + Password[4] must be lexigraphically equal to TodaysSecretPassphrase.substr(Number(SuppliedPassword.charAt(0)) / 2, 3)

if (SuppliedPassword.charAt(11) + SuppliedPassword.charAt(3) + SuppliedPassword.charAt(4) != TodaysSecretPassphrase.substr(Number(SuppliedPassword.charAt(0)) / 2, 3)) {
PasswordIsCorrect = false;
}

With our information so far, the substring that the concatenation of letter must match is "bin". Hence,

Password: "911inA1deA0b"

13. Password[9] has to be lower case

if (! IsLowercase(SuppliedPassword.charAt(9))) {
PasswordIsCorrect = false;
}

Password: "911inA1dea0b"

14. Password[9] has to not be found in the QuoteOfTheDay

if (QuoteOfTheDay.indexOf(SuppliedPassword.charAt(9)) != -1) {
PasswordIsCorrect = false;
}

The only letter missing from the quote is 'j'.

Password: "911inA1dej0b"

15. The missing character

The only unknown character in the password is in index 5. However, this character is not checked nor is it used in the generation of the secret. It is probably ‘s’ however, in keeping with the theme of the challenge.

Password: "911ins1dej0b"

Entering the password

Entering this as the password, will yield a page that displays the flag and then destroys it by overwriting it.

Leave a Comment