CTF #nullcon 2012: Programación 3

  • January 30, 2012
  • tuxotron
  • nullcon1.jpg

    En el tercer nivel nos encontramos con un trozo de código escrito en Brainfuck, un lenguaje un tanto peculiar y que claramente hace honor a su nombre. Algún le dedicaré una entrada en el blog.

    El código con en el que tenemos que lidiar es este:

    >+++++++[<+++++++>-]<---
    .
    .
    >+++++[<+++++>-]<++
    >++++++[<++++++>-]<+
    >+++++++++[<--------->-]<+++
    >++++++++[<++++++++>-]<++++++
    >++[<-->-]<-
    ++
    >++++[<++++>-]<+
    >++++++++[<-------->-]<--------
    >+++[<--->-]<---
    >+++++++++[<+++++++++>-]<---
    >+++[<--->-]<
    >++++[<++++>-]<+
    >++++[<---->-]<-
    >++++[<++++>-]<---
    >+++++++++[<--------->-]<-
    >++++++++[<++++++++>-]<+++++
    >++++[<++++>-]<+
    >++++[<---->-]<-
    >++++[<++++>-]<---
    >+++++++++[<--------->-]<-
    >+++++++++[<+++++++++>-]<++++
    --
    >++++[<---->-]<++
    >++++++++[<-------->-]<-----
    >++++++++[<++++++++>-]<+++++++
    --
    >++++[<++++>-]<-
    -
    >+++++++++[<--------->-]<++++++
    +
    >+++[<--->-]<
    >+++++++++[<+++++++++>-]<--
    +++
    >+++++++++[<--------->-]<-
    >+++++++++[<+++++++++>-]<++
    ---
    ++
    >+++[<--->-]<
    >++[<++>-]<+
    >++[<++>-]<++
    >++++[<---->-]<++
    >++++++++[<-------->-]<++
    +
    +++
    >+++[<--->-]<---
    >+++++++++[<+++++++++>-]<-
    >+++[<--->-]<--
    >++++[<++++>-]<---
    >+++[<--->-]<
    >++[<++>-]<++
    >+++[<--->-]<--
    >+++++++[<------->-]<-----
    >++++[<---->-]<++
    >++++++[<++++++>-]<+++++
    >+++++[<+++++>-]<++++
    >++++++++[<-------->-]<------
    >+++++++++[<+++++++++>-]<++++++++
    >+++[<--->-]<-
    >++[<++>-]<++
    >+++++++++[<--------->-]<----
    >++++++++[<++++++++>-]<++++
    >+++[<+++>-]<++
    >+++++++++[<--------->-]<++
    >+++++++++[<+++++++++>-]<++++++
    >++++[<---->-]<--
    >++++++++[<-------->-]<-----
    >+++++++++[<+++++++++>-]<++++++
    >++++[<---->-]<++
    +++
    .
    >+++++++++[<--------->-]<+++++
    >+++++++++[<+++++++++>-]<++
    >++++[<---->-]<++
    >+++[<+++>-]<
    >+++[<--->-]<-
    >++++++++[<-------->-]<----
    >++++++++[<++++++++>-]<+++++
    >++++[<++++>-]<+
    >++++[<---->-]<+++
    +++
    >+++++++++[<--------->-]<+++++
    >++++++++[<++++++++>-]<++++
    >++++[<++++>-]<+++
    >+++++[<----->-]<+++
    >++++[<++++>-]<+
    >+++[<--->-]<---
    >++++[<++++>-]<---
    >+++++++++[<--------->-]<--
    >++++++++[<++++++++>-]<+
    >++[<++>-]<+
    >++++[<++++>-]<--
    >++++[<---->-]<+
    >++++[<++++>-]<---
    >+++++++++[<--------->-]<-
    >+++++++++[<+++++++++>-]<++++++++
    >+++[<--->-]<-
    >++[<++>-]<++
    >++++++++[<-------->-]<-------
    .
    

    Si buscas por Google hay muchos intérpretes y conversores para este lenguaje. Si ejecutamos dicho código tal y como está, esta es la salida: ..l.. Después de mirar un rato y depurar un poco el código, la solución a la que llegué fue poner un ‘.’ (punto) al final de cada línea que no tenía punto. El punto significa poner el byte actual en la salida. Así tras haber hecho eso y ejecutar de nuevo la salida que obtenemos es:

    …In fact, never ever use gets() or sprintf(), period. If you do we will send evil dwarfs after you.. Que es nuestro flag.

CTF #nullcon 2012: Programación 2

  • January 30, 2012
  • tuxotron
  • nullcon1.jpg

    En el segundo nivel de está categoría se nos pedía la suma los términos medios de las primeras 1337 del triángulo de Pascal.

    Pues nada vistazo a la wikipedia, problema conocido, seguro que alguien ha escrito el algoritmo en Ruby, lo bajo, lo modifico, quedándome de esta forma:

    #!/usr/bin/env ruby
    
    def pascal(n)
      p=[1]
      sum = 0
      while(p.length<n)
    #    puts p.join(" ")
        p.join(" ")
        p=Array.new(p.length+1) {|i| 
          a=i0 ? p[i-1] : 0
          a+b
        }
        if p.length.odd?
          sum = sum + p[p.length()/2] 
        end 
      end
      return sum+1
    end
    
    puts "sum: " + pascal(1337).to_s

    Y cuyo resultado al ejecutarlo y por lo tanto nuestro flag:

    4365932474188423707093600683230364311423941198777278660206654 3431205872166674362332393596312576719064242547970040323267566 5303433331039708200725935787062342766243246058781866709722670 5645987145656659456934356498862160032628647508069786551862253 7377534356455651048425097523734881838663157063304671110082383 2182944537376787442215601583578968563307031943568828954828743 83651576271102847866170999680296497

    Básicamente al algoritmo original le añado:

    if p.length.odd?
          sum = sum + p[p.length()/2] 
    end

    Para sumar el término medio de las filas impares, que son las que tienen término medio y al final le sumamos 1 a la suma total por la primera línea cuya valor del término medio y único es 1.

CTF #nullcon 2012: Programación 1

  • January 30, 2012
  • tuxotron
  • 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.