Giter Site home page Giter Site logo

module_3's People

Contributors

c1b3rwall avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

module_3's Issues

Ejercicio 3

Lo primero que se observa es un fichero de texto compuesto por la palabra Ook junto a un signo (!?.).

Parece un poco sospechoso así que mi primer intento ha pasado por reemplazar Ook por un valor nulo y observar si existe algún patrón que se pueda observar a simple vista. Algo así como "ascii art" con esos tres caracteres. Nada, intento infructuoso. Otra opción hubiera sido intentar base 3, jugando con las distintas posibilidades (la ! sea 0,1 o 2, el ? sea cualquiera de las no seleccionadas, y el . la opción restante).

Como hasta ahora no he visto muchos ejercicios de fuerza bruta, una búsqueda rápida en google nos permite descubrir el lenguaje exotérico Ook, como una reescritura de BF.

import sys

def tobf(s):
    s = s.replace('\n'," ").replace('\r\n'," ")
    i = iter(s.split(' '))
    s = ''.join(map(' '.join,(zip(i,i))))
    s = s.replace("Ook. Ook?", ">")
    s = s.replace("Ook? Ook.", "<")
    s = s.replace("Ook. Ook.", "+")
    s = s.replace("Ook! Ook!", "-")
    s = s.replace("Ook! Ook.", ".")
    s = s.replace("Ook. Ook!", ",")
    s = s.replace("Ook! Ook?", "[")
    s = s.replace("Ook? Ook!", "]")
    print s
    return s

try:
    f = open(sys.argv[1], 'r')
    tobf(f.read())
except:
   print 'Bye!'

Ejecutándolo sobre el fichero obtenemos un primer código en BF. Interpretándolo:

git clone https://github.com/pocmo/Python-Brainfuck.git
cd Python-Brainfuck
python2 brainfuck.py bf_code.txt

Obtenemos una nueva salida en BF. Repetimos el proceso:

python2 brainfuck.py bf_code.txt > /tmp/bf2.txt
python2 brainfuck.py /tmp/bf2.txt && rm /tmp/bf2.txt

Generando la clave "665756334e46706f4d545273646e737965575a7665476c6e43673d3d", que muy seguramente sea una clave en base64 por el "==" del final.

Cyberchef para ello y voila!
https://gchq.github.io/CyberChef/#recipe=From_Hex('Auto')From_Base64('A-Za-z0-9%2B/%3D',false)&input=NjY1NzU2MzM0ZTQ2NzA2ZjRkNTQ1MjczNjQ2ZTczNzk2NTU3NWE3NjY1NDc2YzZlNDM2NzNkM2QK

Fracaso en este intento. Se obtiene una clave que no tiene nada que ver con la que realmente se pide para el reto. No obstante, si que presenta la misma longitud.

Ni XOR, ni rot47, ni vigenere han dado buenos resultados sobre la salida. Sustitución tampoco parece que sea. Creo que estoy cerca, comparto lo que he visto y lo que me queda... seguro que es algo tontorrón con lo que seguro que alguien me podrá echar una mano ;)

Ejercicio 6

Tenemos un archivo wav. Aunque binwalk no lo muestra, haciendo una búsqueda con strings sacamos que hay una cadena 'MThd' que corresponde al header inicial de un archivo midi. Con un editor hexadecimal se extrae de ahí hasta el final del wav pero no parece midi ni se puede escuchar como tal. Con Audacity se importa en bruto y sale el sonido. Dado el contexto, se exporta a wav y se prueba entonces con Sonic Visualiser y aplicando el layer Spectrogram se obtiene la flag.

Ejercicio 2

Otro ejercicio que se me queda a medias pero en el que tengo la impresión de haber avanzado algo.

Se provee un .zip con ficheros encriptados y una clave pública. El objetivo consistirá en recuperar la información.

  1. ¿Qué clase de clave es?
$openssl pkey -pubin -in public.pem -text -noout
RSA Public-Key: (128 bit)
Modulus:
    00:d6:3a:aa:15:09:17:7f:4d:85:57:64:1d:bf:d1:14:27
Exponent: 65537 (0x10001)

Una clave bastante pequeña. Con el módulo obtenido (pasando a decimal) y tirando de mente prodigiosa, observamos que se descompone en dos números primos, p,q tales que:

p=16278629018683492619
q=17492836384758049493

Bueno, lo de mente prodigiosa, como os podéis imaginar no es el caso, pero una búsqueda en WolframAlpha y se obtiene rápidamente el resultado.
2) Con este avance se va a intentar recuperar la clave privada a partir de los parámetros que definen esta clave RSA:

e = 65537
p = 16278629018683492619
q = 17492836384758049493
((p-1)(q-1)) = 284759393992004821906415293399860650056
n = pq = 284759393992004821940186758803302192167
d = e^{-1} mod ((p-1)(q-1)) = 65537^-1 mod (16278629018683492618*17492836384758049492) = 166657480750680332469329767820392375201
  1. Para ello, generamos un fichero def.asn1 con la información previa:
asn1=SEQUENCE:private_key
[private_key]
version=INTEGER:0

n=INTEGER:0xd63aaa1509177f4d8557641dbfd11427
e=INTEGER:0x10001
d=INTEGER:0x7d61103207842d084b798fb99a8ba3a1
p=INTEGER:0xe1e94ed838fec90b
q=INTEGER:0xf2c30a02cb882ad5
exp1=INTEGER:0xdb30866a6e6a6edf
exp2=INTEGER:0x90bbe9df0abbcf55
coeff=INTEGER:0xb5b3ddb370e64a03
  1. Y generamos la clave en formato per:
openssl asn1parse -genconf def.asn1 -out privkey.der -noout
openssl rsa -inform DER -outform PEM -in privkey.der -out privkey.pem
  1. Y recuperamos la información desde el resto de ficheros:
for i in $(ls -1 File_2/*.encrypted); do echo "$i"; openssl rsautl -decrypt -in "$i" -inkey privkey.pem >> total_rot.xml;done
  1. Sobre el fichero total_rot.xml se ha aplicado un cifrado Cesar. Nuevamente con cyberchef u otra herramienta al gusto, se recupera el contenido de un fichero de Word:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?mso-application progid="Word.Document"?>
<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve"><o:DocumentProperties></o:DocumentProperties><w:fonts><w:defaultFonts w:ascii="Times New Roman" w:fareast="Times New Roman" w:h-ansi="Times New Roman" w:cs="Times New Roman"/></w:fonts><w:docPr></w:docPr><w:body><wx:sect><w:p><w:pPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="Helvetica Light" w:h-ansi="Helvetica Light" w:cs="Helvetica Light"/><wx:font wx:val="Helvetica Light"/><w:sz w:val="24"/><w:sz-cs w:val="24"/></w:rPr><w:t>**diKBVUfEaItQ5lE3Nitr6KOwuZTc/eR8**</w:t></w:r></w:p><w:sectPr></w:sectPr></wx:sect></w:body></w:wordDocument>**-----BEGIN PUBLIC KEY-----
MDQwDQYJKoZIhvcNAQEBBQADIwAwIAIZAL9LPyTM85vtJebljX3p+ORWj2gGwk/o
wQIDAQAB
-----END PUBLIC KEY-----**
  1. Hay una clave pública nueva y otra cadena sospechosa... tiene pinta de ser base64, conteniendo un nuevo secreto cifrado de 24B para una clave pública de 192 bits... parece obvio que hay que continuar con esa pista aunque por hoy suficiente.

Ejercicio 7

Se presenta una imagen jpg. Con steghide pedimos la info (steghide info File_7.jpg) con palabra de paso en blanco y nos dice que hay un fichero sin nombre embedido:

embedded data:
size: 129.9 KB
encrypted: rijndael-128, cbc
compressed: yes

Lo extraemos con el comando steghide extract -sf File_7.jpg -xf secreto.raw (-xf para especificar nombre del fichero de salida ya que o steghide no lo reconoce o está embebido sin nombre)

Cambiamos la extensión .raw del fichero extraido por varios formatos conocidos por si lo detectara kali (.wav .png .bmp ... ) pero no aparece preview alguno. Abrimos con el editor hexadecimal y vemos que al principio del fichero aparece 00 50 4e 47 (.PNG)

Parece claro que es un fichero .png pero la cabecera del fichero .png no empieza por 00 sino por 89. La modificamos y la dejamos como 89 50 4e 47

Guardamos y secreto a la vista.

Ejercicio 1

Hola a todos, he decido subir un resumen de todo lo hecho para ver si terminamos por sacar la flag del File_1.bmp.

Con stegsecret (herramienta de estego-análisis) obtenemos como resultado que contiene información por el método EoF. Al ver la imágen se intuye que así es por el color morado predominante en la foto de las canicas.

He probado herramientas online que al subir el fichero te dan un texto, pero sin resultados. Otras como Stego Suite y similar no han dado sus frutos al igual que scripts de LSB creados en python.

Analizando con Stego-toolkit no hay nada relevante en los metadatos. Tampoco veo nada importante en el código hexadecimal ni en los strings, eso sí, mucho campo vacio y mucho ruido, algo característico de un fichero con esteganografía.

Aunque el tema artístico lo descarté, hice un barrido y aplique algún filtro en Photoshop pero no ví nada importante.

Llegado a este punto, me centré en buscar algún tipo de xploit introducido dentro de la imagen. Virustotal no detecta nada, como era de esperar. Lo cambié a formato html y lo ejecuté por si llevaba algún javascript pero nada, tampoco lo he visto en el hexadecimal ni con cat haciendo filtros.

Ya me quedan pocas opciones. He visto un tutorial interesante, les dejo aquí el enlace http://www.eiron.net/thesis es sobre como meter una imagen dentro de otra que creo que es lo que tenemos aquí, pero al final del texto hay un código que no sé con que software se implementa y si funcionará, parece que se trata de MathWorks, que ahora me estoy instalando y a ver si hay suerte.

Por último decir que hay un software en IOS que se llama Spy Pix que sería la repera si se pudiera descodificar el mensaje oculto.

Bueno, saludos y que consigais vuestras ovejas eléctricas.

P.D.: Se me olvidaba, steghide da muchos mensajes de error que pueden ser una pista de la parte del fichero que se ha modificado, sinceramente no lo sé.

Ejercicio 8

Partiendo de esta implementación: http://www.cs.trincoll.edu/~crypto/student/emilio/Enigma.java

Hacemos unas modificaciones para:

  • Meter los rotores y el reflector exigido.
  • Crear un método main() que inicialice la aplicación y configure la máquina enigma
  • Arreglar un error que había al inicializar y al rotar los rotores.
  • Arreglar un error que había en un comentario,

Y da como resultado el siguiente código:

package rlopezga.hacking.hackingtools.enigmamachine;

import java.util.*;

/**
 * <p>Title: Enigma</p>
 * <p>Description: A Simulation of the German Military Enigma Machine.
 *   Specifications of rotors and reflectors obtained from
 *   http://www.codesandciphers.org.uk/enigma/rotorspec.htm and
 *   http://homepages.tesco.net/~andycarlson/enigma/simulating_enigma.html</p>
 * @author Meghan Emilio
 * @version 1.0
 */
public class Enigma
{

  //STATIC ROTORS
  public final static StringBuffer rotorI      = new StringBuffer("EKMFLGDQVZNTOWYHXUSPAIBRCJ");
  public final static StringBuffer rotorII     = new StringBuffer("AJDKSIRUXBLHWTMCQGZNPYFVOE");
  public final static StringBuffer rotorIII    = new StringBuffer("BDFHJLCPRTXVZNYEIWGAKMUSQO");
  public final static StringBuffer rotorIV     = new StringBuffer("ESOVPZJAYQUIRHXLNFTGKDCMWB");
  public final static StringBuffer rotorV      = new StringBuffer("VZBRGITYUPSDNHLXAWMJQOFECK");
  public final static StringBuffer rotorVI     = new StringBuffer("JPGVOUMFYQBENHZRDKASXLICTW");
  public final static StringBuffer rotorVII    = new StringBuffer("NZJHGRCXMYSWBOUFAIVLPEKQDT");
  public final static StringBuffer rotorVIII   = new StringBuffer("JPGVOUMFYQBENHZRDKASXLICTW");
  
  public final static StringBuffer rotorA      = new StringBuffer("PCEGIKMDQSUYWAOZFJXHBLNVTR");
  public final static StringBuffer rotorB      = new StringBuffer("HVXGNDWMIRLSAQZCFJTPEBUKYO");
  public final static StringBuffer rotorC      = new StringBuffer("YDGUQXRBLCASWKTJZNPHVIMFEO");

  //STATIC REFLECTORS
  public static final StringBuffer reflectorB  = new StringBuffer("YRUHQSLDPXNGOKMIEBFZCWVJAT");
  public static final StringBuffer reflectorC  = new StringBuffer("FVPJIAOYEDRZXWGCTKUQSBNMHL");
  public static final StringBuffer reflector0  = new StringBuffer("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  
  public static final StringBuffer reflectorX  = new StringBuffer("ZXWVUTSRQYPONMLKIHGFEDCBJA");

  //CURRENT ROTORS AND REFLECTOR IN USE
  public StringBuffer firstRotor;
  public StringBuffer firstRotorT = new StringBuffer(reflector0.toString());
  public StringBuffer secondRotor;
  public StringBuffer secondRotorT = new StringBuffer(reflector0.toString());
  public StringBuffer thirdRotor;
  public StringBuffer thirdRotorT = new StringBuffer(reflector0.toString());
  public StringBuffer reflector;

  //CURRENT PLUGBOARD SETTINGS
  public char[] plugBoard = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

  //STATIC "NOTCHES"  - when each rotor rotates
  public final static StringBuffer[] notches = {new StringBuffer("Q"),new StringBuffer("E"),new StringBuffer("V"),new StringBuffer("J"),
  	new StringBuffer("Z"),new StringBuffer("Z"),new StringBuffer("Z"),new StringBuffer("Z"),new StringBuffer("B"),new StringBuffer("I"),
  	new StringBuffer("C")};
  
  //CURRENT ROTOR NOTCHES
  private StringBuffer n1;
  private StringBuffer n2;
  
   /**
   * Class Constructor
   *@param r1 rotor to be used as first rotor
   *@param r2 rotor to be used as second rotor
   *@param r3 rotor to be used as third rotor
   *@param r reflector to be used
   */
  public Enigma(String r1, String r2, String r3, String r)
  {
    setFirstRotor(r1);
    setSecondRotor(r2);
    setThirdRotor(r3);
    reflector = getValue(r)[0];
  }
  
  /**
   *Sets the first Rotor
   *@param r1 rotor to be used as first rotor
   *@return void
   */
  public void setFirstRotor(String r1){
  	firstRotor = getValue(r1)[0];
    n1 = getValue(r1)[1];
  }

 /**
   *Sets the second Rotor
   *@param r2 rotor to be used as second rotor
   *@return void
   */
  public void setSecondRotor(String r2){
  	secondRotor = getValue(r2)[0];
    n2 = getValue(r2)[1];
  }
  
  /**
   *Sets the second Rotor
   *@param r3 rotor to be used as third rotor
   *@return void
   */ 
  public void setThirdRotor(String r3){
  	thirdRotor = getValue(r3)[0];
  }
  
  /**
   *Sets the intial settings of the rotors.
   *@param s1 initial setting for first rotor
   *@param s2 initial setting for second rotor
   *@param s3 initial setting for third rotor
   *@return void
   */
  public void initialSettings(String s1, String s2, String s3){
    int p;

	//First Rotor
	p = firstRotorT.toString().indexOf(s1);
	firstRotorT.append(firstRotorT.substring(0,p));
	firstRotorT.delete(0,p);
	firstRotor.append(firstRotor.substring(0,p));
	firstRotor.delete(0,p);
    
    //Second Rotor
	p = secondRotorT.toString().indexOf(s2);
	secondRotorT.append(secondRotorT.substring(0,p));
	secondRotorT.delete(0,p);
	secondRotor.append(secondRotor.substring(0,p));
	secondRotor.delete(0,p);
    
    //Third Rotor
	p = thirdRotorT.toString().indexOf(s3);
	thirdRotorT.append(thirdRotorT.substring(0,p));
	thirdRotorT.delete(0,p);
	thirdRotor.append(thirdRotor.substring(0,p));
	thirdRotor.delete(0,p);
  }

  /**
   *Creates a plubboard connection between two letters 
   *@param x first character to be connected
   *@param y second character to be connected
   *@return void
   */
  public void setPlugBoard(char x, char y){
    for(int i=0; i<plugBoard.length; i++){
      if(plugBoard[i] == x)
        plugBoard[i] = y;
      else if(plugBoard[i] == y)
        plugBoard[i] = x;
    }
  }

  /**
   *Sets the plug board settings
   *@param str plug board settings formatted in pairs, 
   *each pair seperated by a space
   *@return boolean if str entered was in correct format
   *and if the plugboard was set accordingly
   */
  public boolean setPlugBoard(String str){
    String s;
    StringTokenizer tokenCheck = new StringTokenizer(str, " ");
    while(tokenCheck.hasMoreTokens()){
      s = tokenCheck.nextToken();
      if (s.length() != 2)
        return false;
      if(s.charAt(0)>90 || s.charAt(0)<65 || s.charAt(1)>90 || s.charAt(1)<65)
        return false;
    }

    StringTokenizer token = new StringTokenizer(str, " ");
    while(token.hasMoreTokens()){
      s = token.nextToken();
      if(s.length()==2)
        setPlugBoard(s.charAt(0), s.charAt(1));
      else
        return false;
    }
    return true;
  }

  /**
   *Returns the value of the specified Rotor.
   *@param v name or number of rotor
   *@return StringBuffer[] correct rotor
   */
  public StringBuffer[] getValue(String v){
  	StringBuffer[] result = new StringBuffer[2];
    if (v.equals("RotorI") || v.equals("1")){
    	result[0] = rotorI;
    	result[1] = notches[0];
    	return result;
    	} 
    if (v.equals("RotorII")|| v.equals("2")){
    	result[0] = rotorII;
    	result[1] = notches[1];
    	return result;
    	} 
    if (v.equals("RotorIII")|| v.equals("3")){
    	result[0] = rotorIII;
    	result[1] = notches[2];
    	return result;
    	} 
    if (v.equals("RotorIV")|| v.equals("4")){
    	result[0] = rotorIV;
    	result[1] = notches[3];
    	return result;
    	} 
    if (v.equals("RotorV")|| v.equals("5")){
    	result[0] = rotorV;
    	result[1] = notches[4];
    	return result;
   		 } 
    if (v.equals("RotorVI")|| v.equals("6")){
    	result[0] = rotorVI;
    	result[1] = notches[5];
    	return result;
    	} 
    if (v.equals("RotorVII")|| v.equals("7")){
    	result[0] = rotorVII;
    	result[1] = notches[6];
    	return result;
    }
    if (v.equals("RotorVIII")|| v.equals("8")){
    	result[0] = rotorVIII;
    	result[1] = notches[7];
    	return result;
    }
    if (v.equals("RotorA")|| v.equals("9")){
    	result[0] = rotorA;
    	result[1] = notches[7];
    	return result;
    }
    if (v.equals("RotorB")|| v.equals("10")){
    	result[0] = rotorB;
    	result[1] = notches[7];
    	return result;
    }
    if (v.equals("RotorC")|| v.equals("11")){
    	result[0] = rotorC;
    	result[1] = notches[7];
    	return result;
    }
    if (v.equals("ReflectorB")){
    	result[0] = reflectorB;
    	result[1] = new StringBuffer("");
    	return result;
    } 
    if (v.equals("ReflectorC")){
    	result[0] = reflectorC;
    	result[1] = new StringBuffer("");
    	return result;
    } 
    if (v.equals("No Reflector")){
    	result[0] = reflector0;
    	result[1] = new StringBuffer("");
    	return result;
    } 
    if (v.equals("ReflectorX")){
    	result[0] = reflectorX;
    	result[1] = new StringBuffer("");
    	return result;
    } 
    return new StringBuffer[]{new StringBuffer("ERROR"), new StringBuffer("")};
  }

  /**
   *Returns the character obtained after passing l through
   *the current first rotor
   *@param l character input
   *@return char obtained after passing l through the current first rotor
   */
  public char rotorOne(char l){
    int position = firstRotorT.toString().indexOf(l);
    return firstRotor.charAt(position);
    
  }

  /**
   *Returns the character obtained after passing l through
   *the current second rotor
   *@param l character input
   *@return char obtained after passing l through the current second rotor
   */
  public char rotorTwo(char l){
    int position = secondRotorT.toString().indexOf(l);
    return secondRotor.charAt(position);
  }

  /**
   *Returns the character obtained after passing l through
   *the current third rotor
   *@param l character input
   *@return char obtained after passing l through the current third rotor
   */
  public char rotorThree(char l){
    int position = thirdRotorT.toString().indexOf(l);
    return thirdRotor.charAt(position);
  }

  /**
   *Returns the character obtained after passing l through
   *the current reflector
   *@param l character input
   *@return char obtained after passing l through the current reflector
   */
  public char reflector(char l){
    int position = (int)l - 65;
    l = reflector.charAt(position);
    return l;
  }

  /**
   *Returns the character obtained after passing l through
   *the current first rotor in the reverse direction
   *@param l character input
   *@return char obtained after passing l through the current
   *first rotor in the reverse direction
   */
  public char IrotorOne(char l){
    int position = firstRotor.toString().indexOf(l);
    return firstRotorT.charAt(position);
  }

  /**
   *Returns the character obtained after passing l through
   * the current second rotor in the reverse direction
   *@param l character input
   *@return char obtained after passing l through the current
   *second rotor in the reverse direction
   */
  public char IrotorTwo(char l){
    int position = secondRotor.toString().indexOf(l);
    return secondRotorT.charAt(position);
  }

  /**
   *Returns the character obtained after passing l through
   *the current third rotor in the reverse direction
   *@param l character input
   *@return char obtained after passing l through the current
   *third rotor in the reverse direction
   */
  public char IrotorThree(char l){
    int position = thirdRotor.toString().indexOf(l);
    return thirdRotorT.charAt(position);
  }

  /**
   * Rotates the rotors according to their current settings
   *@param void
   *@return void
   */
  public void rotate(){
	  StringBuffer currentR1 = new StringBuffer(firstRotorT.charAt(0)+"");
	  StringBuffer currentR2 = new StringBuffer(secondRotorT.charAt(0)+"");

	  //Rotate first rotor
	  firstRotorT.append(firstRotorT.charAt(0));
	  firstRotorT.delete(0, 1);
	  firstRotor.append(firstRotor.charAt(0));
	  firstRotor.delete(0, 1);

	  //if first rotor is at notch
	  if (currentR1.toString().equals(n1.toString())){
		  //then also rotate second rotor
		  secondRotorT.append(secondRotorT.charAt(0));
		  secondRotorT.delete(0, 1);
		  secondRotor.append(secondRotor.charAt(0));
		  secondRotor.delete(0, 1);

		  //if second rotor is at notch
		  if(currentR2.toString().equals(n2.toString())){
			  //then also rotate the third rotor
			  thirdRotorT.append(thirdRotorT.charAt(0));
			  thirdRotorT.delete(0, 1);
			  thirdRotor.append(thirdRotor.charAt(0));
			  thirdRotor.delete(0, 1);
		  }
	  }
  }

  /** 
   *Returns the result of passing c through
   *the plugboard with its current settings
   *@param c the inputted character
   *@return char the result of passing c through
   *the plugboard with its current settings
   */	
   public char plugBoard(char c){
     int i = (int)(c) - 65;
     return plugBoard[i];
   }

  /** 
   *Returns the current setting of the first rotor.
   *@param void
   *@return char that is the current setting of the first rotor
   */
   public char getFRSetting(){
     return firstRotorT.charAt(0);
   }

  /** 
   *Returns the current setting of the second rotor.
   *@param void
   *@return char that is the current setting of the second rotor
   */
   public char getSRSetting(){
     return secondRotorT.charAt(0);
   }

  /** 
   *Returns the current setting of the third rotor.
   *@param void
   *@return char that is the current setting of the third rotor
   */
   public char getTRSetting(){
     return thirdRotorT.charAt(0);
   }


  /** 
   *Encrypts/Decrypts the inputted string using the 
   *machine's current settings
   *@param p the text to be encrypted/decrypted
   *@return void
   */
  public String encrypt(String p){
     p = p.toUpperCase();
     String e = "";
     char c;
     int k;
     
     //for the length of the inputted text
     for(int i=0; i<p.length(); i++){
       //store the current character	
       c = p.charAt(i);
       
       //if the current character is a letter
       if (c<=90 && c>=65){
          
           //pass the character through the plugboard
           c = plugBoard(c);
           
           //then through the first rotor
           c = rotorOne(c);
           
           //then through the second rotor
           c = rotorTwo(c);
           
           //then through the third rotor
           c = rotorThree(c);
           
           //then through the reflector
           c = reflector(c);
           
           //then through the third rotor in the reverse direction
           c = IrotorThree(c);
           
           //then through the second rotor in the reverse direction
           c = IrotorTwo(c);
           
           //then through the first rotor in the reverse direction
           c = IrotorOne(c);
           
           //and finally back through the plugboard
           c = plugBoard(c);
           
           //and add the new character to the encrypted/decrypted message
           e = e + c;
           
           //rotate the rotors
           rotate();
       }
       
       //if c is a space simply add it to the encrypted/decrypted message
       //to conserve spaces
       else if(c==32)
           e = e + c;
           
       //if c is neither a space nor a letter, then there is an error    
       else
         return null;
     }
     
     	//return the complete encrypted/decrpyted message
        return e;
  }

  /**
   *Parses Plugboard input to check for repeated letters
   *as each letter can only be used once in the plugboard 
   *@param str the inputted plug board settings
   *@return void
   */
  public boolean pbParser(String str){
  	//if no plug board settings were input, then continue
    if(str.length()<=0 || str.equals(null) || str == null){
      return true;
    }
    
    //otherwise, check to make sure letters are not repeated
    for(int i=0; i<str.length()-1; i++){
      //if not a letter, continue	
      if(str.charAt(i)>90 || str.charAt(i)<65)
        i++;
      //if the current letter appears in the rest of the string
      else if(str.substring(i+1).indexOf(str.charAt(i)) != -1)
        return false;
    }
    
    //otherwise, return true
    return true;
  }
  
  public static void main(String[] args) {
	  Enigma enigma = new Enigma("RotorA", "RotorB", "RotorC", "ReflectorX");
	  enigma.initialSettings("W", "R", "E");
	  enigma.setPlugBoard("");
	  System.out.println(enigma.encrypt("RPBXBUPR"));
  }
}

Al ejecutarlo, la salida me da DBPMPKBD, que no es el flag esperado. Sin embargo al seguir a mano el dibujo metiendo la letra R, me da que el primer carácter es una "D", lo cual es compatible con esta salida y no la "I" que se espera en el Moodle.

Ejercicio 4

SHA256 tiene un bloque de 64 bytes. Ahora bien, la clave que se desea cifrar tiene una longitud superior a 64B.

Entonces, por definición del algoritmo (https://mathiasbynens.be/notes/pbkdf2-hmac) se tiene que:

PBKDF2_HMAC_SHA256(secreto_original) == PBKDF2_HMAC_SHA256(HEX_TO_STRING(SHA256(secreto_original)))

Pues calculemos dicho hash SHA256,

import hashlib

cadena=b'https://www.ecteg.eu/c1b3rwall-academy-es/calculate-the-correct-flag/'
hashlib.sha256(cadena).digest()

Y verifiquémoslo en el programa de ejemplo:

>>> print('PBKDF-HMAC-SHA256:')
PBKDF-HMAC-SHA256:
>>> h1 = pbkdf2sha256hex(b'https://www.ecteg.eu/c1b3rwall-academy-es/calculate-the-correct-flag/', b'c1b3rwall', 1000000)
>>> respuesta=hashlib.sha256(b'https://www.ecteg.eu/c1b3rwall-academy-es/calculate-the-correct-flag/').digest()
>>> h2 = pbkdf2sha256hex(respuesta, b'c1b3rwall', 1000000)
>>> h1==h2
True

Ejercicio 5

Ayer abrí el "issue" con el enunciado equivocado, hoy ya traigo la solución. El problema vino en que estuve dándole vueltas y casi lo consigo pero, como ocurre en muchas ocasiones, se quedó a medias.

Al grano. Una cadena de números, podrían parecer hexadecimal pero no lo son. Si se realiza un análisis en frecuencia se observa que solamente aparecen los caracteres: 0,6,7,8,9. ¿Se podría haber ocultado algo en los bits menos significativos? Claramente tampoco por la longitud del mensaje.

Siguiente paso... observar qué ocurre entre un número y el siguiente. La idea intuitiva es que cada número es una letra, aunque no tendría necesariamente que ser así.

Como intento, podemos tratar de creer que 80 es la m, 89 es la o (ya que nuestras flags siempre empiezan por module3{...}), pero entre la m y la o solamente tenemos la n (dado que seguramente se use un alfabeto internacional). ¿Y si los números no tienen su valor habitual y solamente son representaciones? Quizá después del 0 viene un número cualquiera y el siguiente sea un 9. De ese modo 80 pudiera ser m y 89 o. Genial, puede ser una buena apreciación.

¿Como interviene el primer número entonces? Una noche de reflexión y descubro que es una tabla indexada por dos índices. Nada que yo haya descubierto, tiene nombre y se llama polybius. Ejemplo:

|   \	|   1   |   2   |	3   |	4   |	5   |
|   1	|   A   |   B   |	C   |	D   |	E   |
|   2	|   F   |   G   |	H   |	I   |	J   |
|   3	|   K   |   L   |	M   |	N   |	O   |
|   4	|   P   |   Q   |	R   |	S   |	T   |
|   5	|   U   |   V   |	W   | X   |	Y   |

Con la anterior tabla, podremos representar HOLA como 23 35 32 11. Pues dicho y hecho. A sustituir números por otros números. Si el 0 va al 1, el 6 al 2, ..., el 9 al 5, creo que se obtiene QUREYFIXFZSFYYGNF.

Claro, no hemos jugado con las permutaciones. ¿Por qué debería ir el 0 al 1 y así sucesivamente? Para no volverme loco codificando, sustituiré la cadena original por:

DA DE DB AE ED BA BD EC BA EE DC BA ED ED BB CC BA

donde 0 es A, 6 es B, ..., 9 es E.

Y pico el siguiente código:

import itertools
import re

def generate_array(key=''):
    alphabet = 'ABCDEFGHIKLMNOPQRSTUVWXYZ'
    array = []
    _tmp = []
    key = re.sub(r'[^a-zA-Z]+', '', key)  # remove non-alpha character
    key = key.upper()

    if key:
        for k in key:
            alphabet = alphabet.replace(k, '')
    
        alphabet = key + alphabet
    
    for y in range(5):
        for x in range(5):
            _tmp.append(alphabet[0 + 5 * y + x])
        array.append(_tmp)
        _tmp = []
    
    return array

def display_array(array):
    row_labels = ['1', '2', '3', '4', '5']
    print('      1   2   3   4   5')
    for row_label, row in zip(row_labels, array):
        print(' %s [%s  ]' % (row_label, ' '.join('%03s' % i for i in row)))


def decode(numbers, array):
    numbers = re.sub(r'[\D]+', '', numbers)
    text=""
    for number in range(0, len(numbers), 2):
        try:
            oy = int(numbers[number]) - 1
            ox = int(numbers[number + 1]) - 1
            text += array[oy][ox]
        except IndexError:
            pass
        continue
    return text


cadena = "DA DE DB AE ED BA BD EC BA EE DC BA ED ED BB CC BA"
array = generate_array()
for p in list(itertools.permutations(['A', 'B','C','D','E'])):
    t=cadena.replace(p[0], '1')
    t=   t.replace(p[1], '2')
    t=   t.replace(p[2], '3')
    t=   t.replace(p[3], '4')
    t=   t.replace(p[4], '5')
    print(decode(t,array))

Como bien sabemos la permutaciones de esos 5 caracteres son 120 (5!) por lo que aunque sea una salida larguita, todavía se podrá observar a mano. Ejecutamos el anterior código y se ve que para la permutación ('B', 'C', 'D', 'E', 'A'), es decir, el 0 va a la quinta posición, el 6 a la primera el nueve a la cuarta y la tabla:

>>> display_array(array)
      1   2   3   4   5
 1 [  A   B   C   D   E  ]
 2 [  F   G   H   I   K  ]
 3 [  L   M   N   O   P  ]
 4 [  Q   R   S   T   U  ]
 5 [  V   W   X   Y   Z  ]

Se tiene la solución al reto.

La tabla volviendo a la represantación original es:

      6   7   8   9   0
 6 [  A   B   C   D   E  ]
 7 [  F   G   H   I   K  ]
 8 [  L   M   N   O   P  ]
 9 [  Q   R   S   T   U  ]
 0 [  V   W   X   Y   Z  ]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.