crypt-of-the-necropuzzler
Descrição do Desafio:
Autor: aplet123 Categoria: rev Descrição:
When no one's looking, the Necrodancer actually likes to play puzzle games in his free time. However, he got stuck on a really tough one and it's sucking all his enjoyment out of the game. If you can beat this one for him, he might not return your stolen heart, but he'll at least give you a flag.
Arquivos
crypt-of-the-necropuzzler.py
código do desafio.
📥 Download: crypt-of-the-necropuzzler
Passo a Passo da Solução
1. Análise do arquivo fornecido
Olhando para o código do desafio, podemos notar a função decrypt_flag(k)
, esta função descriptografa a flag usando o parâmetro k
. Também é possível identificar a função t(a,b,s=None)
, que basicamente realiza uma DFS buscando pares (x,y)
que tenham o mesmo valor na lista g
dos pares (a,b)
.
Por fim, há um loop principal, esse loop é o responsável por imprimir o "tabuleiro", e por ler o carectere digitado pelo usuário, e com base nele realizar algumas operações.
"q": encerra a execução.
"x": com base na posição
(a,b)
atual, altera o valor correspondente na listag
. Se era 1 vira 0, e se era 0 vira 1."w", "s", "a", "d": se possível, anda a posição
(a,b)
com base no dicionáriom={'w':(-1,0),'s':(1,0),'a':(0,-1),'d':(0,1)}
."c": verifica se todos os conjuntos encontrados pela função
t(a,b,s=None)
são válidos, se forem, a flag é revelada.
Nota: Cada conjunto guarda todas as posições (a,b)
de mesmo valor adjacentes. Dessa forma, se uma posição é marcada com 1, mas está cercada por posições com 0, seu conjunto é somente ela.
Alguns pontos importantes são:
Se o valor na lista
g
for 0, o loop imprime_
na posição atual, e se for 1 é impresso#
.A validação dos conjuntos é feita com base na lista
n
, que contém valores de 0 a 3, que representam os índices da listav
. Para a flag ser revelada, os valores dav
devem ser 0 ou 2 para os índices 1, 2, e 3, o índice 0 pode conter qualquer valor. Dessa forma, o código percorre todos os conjuntos encontrados, e com base nas posições do conjunto, calcula uma posição nan
, que representa a posição nav
que terá o valor incrementado em 1.
2. Solução
Sabendo que devemos respeitar a regra dos valores na lista v
, podemos montar uma tabela parecida com a impressa pelo loop, porém ao invés de ser _
ou #
, vai ser o índice na v
. Isso é possível fazer apenas olhando para a lista n
.
Também é possível modificar o próprio script para imprimir isso. Agora, o segredo é olhar para as posições já marcadas com 1, que não podem ser desmarcadas.
Perceba que já temos dois lugares marcados no índice 2, dessa forma precisamos colocar eles no mesmo conjunto para o valor na v
ser 2. Porém, não podemos ligar eles pelo valor entre eles, porque esse valor também é 2, fazendo com que o valor na v
seja 3.
Outro ponto importante é o índice 3, os dois estão desmarcados, e se eles forem marcados e unidos, também será unido 4 pontos com valor 1, fazendo com que o valor na v
seja 4. Assim, sabemos que os pontos com índice 3 devem ser desmarcados, e devem estar no mesmo conjunto.
Sabendo dessas duas dicas, o resto é ir montando o desenho, tentando não desrespeitar as regras de validação. Uma dica é colocar print(v, i, j)
dentro do if
que verifica a violação, pois dessa forma você saberá qual é o valor da v
e em qual posição identificou.
Flag
lactf{i_may_or_may_not_have_blatantly_stolen_a_taiji_puzzle_lol}
Autor da WriteUp
Atualizado