DEFCON is the website controlling the security level of the room. The 5 different levels allows to warn the population of the risk of a potential nuclear war. Levels ranges from 5 (peacetime) to 1 (maximum alert). Try level 1.
DEFCON website is pretty graphic website with lots of data, bet relevant part is "DEFCON LEVEL CONSOLE", where clicking on each level shows a popup with title "UNAUTHORIZED ACTION", text "The server requires a password for this action." and a single input field (password).
Using Chrome Developer Tools, inspecting button,
following "Event Listeners" and searching defcon-1
in JavaScript files, shows how password is validated.
<div id="console">
<button id="defcon-1">1</button>
<button id="defcon-2">2</button>
<button id="defcon-3">3</button>
<button id="defcon-4">4</button>
<button id="defcon-5">5</button>
</div>
async function validate() {
if (modalLevel === "defcon-1") {
return check1($("#modal-password").val());
} else if (modalLevel === "defcon-2") {
return await check2($("#modal-password").val());
} else if (modalLevel === "defcon-3") {
return check3($("#modal-password").val());
} else if (modalLevel === "defcon-4") {
return check4($("#modal-password").val());
} else if (modalLevel === "defcon-5") {
return check5($("#modal-password").val());
} else {
return false;
}
}
Looking further at the level 1 validation in http://defcon.challs.malice.fr/static/js/scripts.js, reveals that it is validated elsewhere (different JavaScript file).
function check1(pwd) {
return checkcheck1(pwd);
}
Real validation happens in http://defcon.challs.malice.fr/static/js/x.js.
checkcheck1 = function(pwd) {
var _1, i, pos, pwd, walls;
if (!((pwd.length === 2703))) {
return false;
}
pos = new sliceType([75, 79]);
walls = new sliceType$1([new sliceType([0, 1]), new sliceType([0, 2]), ... // long, long, loong line
i = 0;
while (true) {
if (!(i < pwd.length)) { break; }
_1 = pwd.charCodeAt(i);
if (_1 === (117)) {
pos = new sliceType([(0 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 0]) - 1 >> 0, (1 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 1])]);
} else if (_1 === (100)) {
pos = new sliceType([(0 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 0]) + 1 >> 0, (1 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 1])]);
} else if (_1 === (108)) {
pos = new sliceType([(0 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 0]), (1 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 1]) - 1 >> 0]);
} else if (_1 === (114)) {
pos = new sliceType([(0 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 0]), (1 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 1]) + 1 >> 0]);
} else {
return false;
}
if (in$1(pos, walls) || out_lab(pos)) {
return false;
}
i = i + (1) >> 0;
}
if (!(((0 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 0]) === 34)) || !(((1 >= pos.$length ? ($throwRuntimeError("index out of range"), undefined) : pos.$array[pos.$offset + 1]) === 79))) {
return false;
}
$global.alert($externalize("Well Done! Send the flag encoded with Sha512 to get your points!", $String));
return true;
};
main = function() {
$global.checkcheck1 = $externalize(checkcheck1, funcType);
};
So the idea is, that one must input 2703
character long string, containing u
(up), d
(down), l
(left), r
(right),
which will solve the provided maze (walls
), starting in position 75,79
and reaching position 34,79
.
Therefore a maze solving algorithm should be used.
Extract the maze walls (producing walls.txt
where each line contains y,x
coordinates of a wall).
$ wget http://defcon.challs.malice.fr/static/js/x.js
$ grep 'walls = ' x.js | sed 's/, new/X/g' | tr 'X' '\n' | sed -e 's/$1//g' -e 's/[^0-9,]*//g' > walls.txt
$ head -3 walls.txt
0,1
0,2
0,0
Write a maze solver, construcing maze from walls.txt
and solving it with Breadth First Search algorithm from Labyrinth Algorithms.
#!/usr/bin/env python
import io, sys
from collections import deque
def maze2graph(maze):
height = len(maze)
width = len(maze[0]) if height else 0
graph = {(i, j): [] for j in range(width) for i in range(height) if not maze[i].get(j)}
for row, col in graph.keys():
if row < height - 1 and not maze[row + 1].get(col):
graph[(row, col)].append(("d", (row + 1, col)))
graph[(row + 1, col)].append(("u", (row, col)))
if col < width - 1 and not maze[row].get(col + 1):
graph[(row, col)].append(("r", (row, col + 1)))
graph[(row, col + 1)].append(("l", (row, col)))
return graph
def find_path_bfs(maze, start, goal):
queue = deque([("", start)])
visited = set()
graph = maze2graph(maze)
while queue:
path, current = queue.popleft()
if current == goal:
return path
if current in visited:
continue
visited.add(current)
for direction, neighbour in graph[current]:
queue.append((path + direction, neighbour))
return "no path"
walls = {}
with io.open('walls.txt') as fh:
for rline in fh:
line = rline.strip().split(',')
y, x = int(line[0]), int(line[1])
if y not in walls:
walls[y] = {}
walls[y][x] = 1
o = find_path_bfs(walls, (75, 79), (34, 79))
print(len(o), o)
Run the maze solver.
$ python defcon1.py
(2703, 'uurrddrrrrrruurrddrrddllddllddlluuuullddddllllddddllddddrruurrddrrrrddddrrddddrruurruulluuuuuulluuuurrddrruuuurrrruulluuuurruurruulllllluulllllluullllddddlllluuuulluulluulllllluuuullllddddrrddrrrrrrddddrrddllddrrrrddddlluullddllddllddrrddrrrrddlllllluullddddlluullddllllllddllddrrddddrrddrrrruulluurrrrddrruurrrrrrddrruurrrrddllddlllllluullddllllddllllddlluullddddrrddllddrrddllddlluulllluurrrruulllluullddddddddrrddddllddrrrrddddrrrrrrrruuuuuuuulluurruurrddddddddddrrrrrruurrddrruuuurrddddrrddrrrrrrrrrruurruullllllddlllluuuurrrruurrrruurrrruuuuuuuurrrrddrruurrrruuuullddlluulluuuurruuuuuuuulluuuurrrruurruuuuuuuurruurrddrruuuurrrrrrrrrrrrddddddrrddddddddlluuuuuulluulluullddddddrrddddrrddddllddlluuuuuulllluullddllllllddddrrddllllddrrddddrruurrrruuuurrrrddllddddrrddrrddllllddddrruurrddddrrddlllllluulllluuuullddddddddrruurrddrrrrrrddddddddddllddrrrrrruurrddddrrrruurrrrrrrrddddllllddrrddllddddlluuuulluuuullllllllddlllluullddllddrrddrrrrrrrrrrrrddddrrrrrrddddllllddddlluuuuuulluulluullddlluullddddrrrrddddddddrrrrrrddllllllddrrddllddrrddllddrrddrruuuurrddddrruurrrrddrrrrrruurrrruurruurruurruurrddrrrrrrrrddddlllluullddlluullddddrrrrrrrrddrrrrrruulluuuuuuuulluulluuuurrddrruuuulllluullddddddllddlllllluuuulluurrrruurrddrruuuuuuuurrrrddrruurrddddllddrrrrddrrddddddrruuuuuuuuuuuuuuuulluuuullddllddlllllllluuuurruulllluurrrrrrrrddrruurruurrrruulllllllluulluulluurrrrrrrrrrrruuuuuuuullddlluulluurrrruurruuuuuuuullddddddllddlllluuuuuurruulluurruurrddrruuuurruulllllllluulllluuuurrrrrruulllluuuullddllllddllllddddllddlllluullllddllddlluuuulluurrrrrruurruurrddddrruurruuuulllllluuuulluuuurrddrrddrruuuuuurruurrrrrruuuurrddrrddllddllddddddllddrrrrrruuuulluurruurrrrrrddllddllddrrrrrruurruuuuuuuurruuuullllddddddlluuuulllluurruurruurruurruullllddllddllddllllddlluullllddrrddddlllluullddlluuuulllllluuuurrrrddrrrrrruuuurrrruuuuuurruulluuuuuulluulluurrrrrrddrrddllddrrddddddddllddddrrrruuuuuurrddrrrrrrrruurruuuullddlluullddddlluuuullddlluuuurrrrrruuuurrrrddllddrrrruuuuuulllluulluuuulluuuuuuuurrrrrrrruulluurruuuuuullddddlllllluulluurruurrrruulluullllllddddddddllddddddrrddddlluullddddrrrrrrddddddrrddllddlluuuuuuuullddddddlluullddlluullddllddlluuuulluurruurrddrrrrrrrruulluuuullddddlluulluuuuuurruuuulllllluurrrruulluulluurruullllllddddrrddddlluullddlllluuuurrrruulluullddlluullllllddllddddrrddddddllddddllllllddrrrrddrrddlllluullllddlluuuuuulllluurrrruulllllluurrrrrruulluurrrrrrddddllddrrrrddrruuuulluurruuuulllllllluurruullllllddlluullllddddddlllluuuullddddllddllddrrrrrrddddlluullddddrrrrrrddddddrrddrrrrrruuuuuurrddddddddddddllddlluulluuuullddddlllluulluullddddlllluuuuuuuurrrrrrrruulluulllluulluulluulluurrrruuuuuurruulluullllllddrrddddddllddddddrrddllllllllddddrrrrrrrrrrddllddrrddddddllllddddrruurrrrd')
Trying this in DEFCON website, returns "Well Done! Send the flag encoded with Sha512 to get your points!"
Therefore, the flag is sha512
of maze path.
echo -n uurrd... | sha512
7452d6d91da700d0d686e75dd28fa80a0c64f81a402fcba2b9c4f81cd18eb46e5c052cd0cd1f601b5f117ad94ec68505f7f8fde8adb4e34157f55873239205ae
Flag is 7452d6d91da700d0d686e75dd28fa80a0c64f81a402fcba2b9c4f81cd18eb46e5c052cd0cd1f601b5f117ad94ec68505f7f8fde8adb4e34157f55873239205ae
.