CTF #nullcon 2012: Programación 1

nullcon1.jpg

En la primera prueba de programación nos encontramos con este texto:

Mfp ey zwvo fvat rjx hwprdrr lb nawzh tnfpc: Anj icvlu, hjgy Kbffhg, zk hjp gm nso nntjj, phf sw vawwhnwer, pcum nu oeq ewllxqmqit

El cual es nuetro flag cifrado. Por lo que tenemos que averiguar como hacerlo.

Si miramos el código fuente de la página de este reto, nos dan un pista:

Rápidamente nos damos cuenta que es un cifrado basado en la rotación de caracteres dependiendo de la posición del mismo.

Por ejemplo: Mfp ey: M (posición 0) se queda tal cual f (posición 1) = una posición anterior a f, por lo tanto sería: e p (posición 2) = dos posiciones hacia atrás: n … Los espacios en blanco y los signos de puntuación se quedan tal cual. Un par de reseñas muy importante, cuando llegamos a la posición 26, empezamos a contar hacia atrás hasta 1, luego contamos hasta 26, etc. Y por último cuando rotamos en círculo, es decir, a - 1 = z.

Este es el algoritmo que escribí:

#!/usr/bin/env ruby

todecode = "Mfp ey zwvo fvat rjx hwprdrr lb nawzh tnfpc: Anj icvlu, hjgy Kbffhg, zk hjp gm nso nntjj, phf sw vawwhnwer, pcum nu oeq ewllxqmqit"

Lower_low_boundry = 97    # a
Lower_high_boundry = 122  # z
Upper_low_boundry = 65    # A
Upper_high_boundry = 90   # Z

# is c uppercase?
def upper_case?(c)
  c >= Upper_low_boundry && c<= Upper_high_boundry
end

# returns the ascii code for the rotated character
def get_offset(c, i)
  offset = c-i
  if upper_case?(c)
    if (offset) < Upper_low_boundry
      offset = Upper_high_boundry - (Upper_low_boundry - offset) + 1
    end
  else
    if (offset) < Lower_low_boundry
      offset = Lower_high_boundry - (Lower_low_boundry - offset) + 1 
    end
  end
  return offset
end

output = ""
i = 0
up = true

todecode.each_byte() do |c|
  if c!=32 && c!=44 && c!=58 # will ognore blank spaces, commas and colons
    output += (get_offset(c, i)).chr
  else
    output += c.chr
  end

  if up
    i = i + 1
  else 
    i = i - 1
  end

  if up && i > 25
    up = false
  elsif !up and i < 1
    up = true
  end

end

puts output

Y salida que nos da es:

Men at some time are masters of their fates: The fault, dear Brutus, is not in our stars, but in ourselveq, lxof ek crc oftsdvqtku

Como vemos las últimas palabras no se decodifican bien, debe haber algún error en el script, pero viendo que tiene toda la pinta de ser una frase célebre, sólo tenemos que buscar en Google por las palabras legibles y vemos que la frase es:

Men at some time are masters of their fates: The fault, dear Brutus, is not in our stars, but in ourselves, that we are underlings

Ese es nuestro flag.