domingo, 14 de octubre de 2018

Programación (IX): Solución Reto HackThis "Coding Level 2"

En este post la solución a otro de los retos de programación de la plataforma HackThis.

Este reto tiene el título "Coding Level 2" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


A string has been encoded using a very simple custom encryption method, explained here, decrypt the message. You have a 5 second time limit for each attempt.


nos dan una lista de palabras como la siguiente:
La explicación del método de cifrado es:
Soluciónutilizo el siguiente script de Python.

import requests

def Decipher(string_encoded):
    print("")
    print("Cadena cifrada..........................",string_encoded)
    print("Longitud cadena cifrada.................",len(string_encoded))
    i=0
    ascii_str=""
    string_decoded=""
    while i < len(string_encoded):
          if string_encoded[i]!=" ":
             ascii_char=126-(int(string_encoded[i]+string_encoded[i+1])-32)
             ascii_str=ascii_str+str(ascii_char)+","
             string_decoded=string_decoded+chr(ascii_char)
             i+=3
          else:
             ascii_str=ascii_str+" ,"
             string_decoded=string_decoded+" "
             i+=2
    print("Caracteres ASCII decimal................",ascii_str)
    print("Cadena descifrada.......................",string_decoded)
    return string_decoded

url="https://www.hackthis.co.uk/levels/coding/2"
login="https://www.hackthis.co.uk/?login"
payload={"username":"tu usuario","password":"tu contraseña"}

#Empezar una sesion
s=requests.Session()

#Login
s.post(login,data=payload)

#Obtener mensaje cifrado
response=s.get(url).text
cipher_message=response[response.find("< textarea>")+10:response.find("< /textarea")]

#Descifrar mensaje
answer=Decipher(cipher_message)

#Enviar la respuesta
payload={"answer":answer}
s.post(url, data=payload)
response=s.get(url).text
if ("Incomplete" in response):
     print("Incorrect answer")
else:
     print("Correct answer")

Ejecuto este script:

Y, como se observa en la figura anterior, la respuesta es correcta.

sábado, 13 de octubre de 2018

Programación (VIII): Solución Reto HackThis "Coding Level 1"

En este post la solución a uno de los retos de programación de la plataforma HackThis.

Este reto tiene el título "Coding Level 1" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


The words have been jumbled up, your task is to write some code to return them to alphabetical order. Then submit your answer in the same format, for example: ant, badger, cattle, zebra. You have 5 seconds to complete the mission.


nos dan una lista de palabras como la siguiente:
Soluciónutilizo el siguiente script de Python.

import requests

def sort(string):
    string=string.split(", ")
    return ", ".join(sorted(string))

url="https://www.hackthis.co.uk/levels/coding/1"
login="https://www.hackthis.co.uk/?login"
payload={"username":"tu usuario","password":"tu contraseña"}

#Empezar una sesion
s=requests.Session()

#Login
s.post(login,data=payload)

#Obtener palabras desordenadas
response=s.get(url).text
words=response[response.find("< textarea>")+10:response.find("< /textarea")]
print("Words:",words)

#Ordenar las palabras alfabeticamente
answer=sort(words)
print("Answer:",answer)

#Enviar la respuesta
payload={"answer":answer}
s.post(url,data=payload)
response=s.get(url).text
if ("Incomplete" in response):
   print("Incorrect answer")
else:
   print("Correct answer")

Ejecuto este script:
Y, como se observa en la figura anterior, la respuesta es correcta.

viernes, 12 de octubre de 2018

Programación (VII): Solución Reto WeChall "Can you read me"

En este post la solución a uno de los retos de programación de la plataforma WeChall.

Este reto tiene el título "Can you read me" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


A friend and me have a bet running, that you won't beat his OCR program in scanning text out of images.
His average scan time is 2.5 seconds, can you beat that?.


Y nos dan una imagen como la siguiente:
Soluciónutilizo el siguiente script de Python.

from PIL import Image
from io import BytesIO
from urllib.parse import quote as urlencode
from bs4 import BeautifulSoup
import pytesseract
import requests

s = requests.session()

url = 'https://www.wechall.net/'
image_url = url+'challenge/can_you_readme/gimme.php'
solution_url = url+'challenge/can_you_readme/index.php'

payload = {'username': 'tu usuario', 'password': 'tu contraseña'}

s.post(url,payload)
r2 = s.get(image_url)

#Obtener el texto
captcha = Image.open(BytesIO(r2.content))
captcha.save('read_me.png')
print('Resolviendo Captcha')
captcha_text = pytesseract.image_to_string(captcha)
print('Texto extraido',captcha_text)

#Enviar la solucion
r3 = s.get(solution_url + '?action=Answer&solution=' + urlencode(captcha_text)).text
r3 = BeautifulSoup(r3, 'html.parser')
if r3.select('.gwf_errors'):
   exit(r3.select('.gwf_errors li')[0].text)
print(r3.select('.gwf_messages li')[0].text)

Ejecuto este script:
Y, como se observa en la figura anterior, la respuesta es correcta.

lunes, 1 de octubre de 2018

Programación (VI): Solución Reto RingZer0 Team "Hash breaker"

En este post la solución a otro de los retos de programación de la plataforma RingZer0 Team.

Este reto tiene el título "Hash breaker" y mi valoración sobre su dificultad es: .

Su enunciado dice lo siguiente:


You have 3 seconds to break this hash.

Send the answer back using: https://ringzer0team.com/challenges/56/[clear_text]



----- BEGIN HASH -----
2dbd76e41756796a0b1ed09f68ae94d3b8c62b56
----- END HASH -----

Solución: ¿Qué tiene de diferente este reto frente al anterior, y cuya solución puse en este mismo blog?. Pues creo que es muy similar, pero en este caso entiendo que hay que dar un paso previo y por eso lo califico como un poco más difícil.

Me explico, en principio, un hash no se puede revertir, es decir, a partir del resumen no puede obtenerse el texto en claro que lo generó, pero existen diferentes servicios on-line que, contando con bases de datos de gran cantidad de estos resúmenes (pares de 'texto en claro' y 'hash'), pueden indicar si el hash introducido, siempre y cuando figure en su base de datos, coincide con algún texto en claro concreto.

Por tanto, el primer paso que dí consistió en utilizar un servicio de esa clase para intentar averiguar qué tipo de hash se emplea en este reto y, además, si existe algún patrón en el texto en claro utilizado.

Pues bien, descubrí que el tipo de hash usado en este reto es 'sha1' y que el texto en claro es siempre un número de 4 dígitos.

Por tanto, es fácil obtener la solución del reto empleando un poco de fuerza bruta, para lo que utilizo el siguiente script de Python.

import requests
import hashlib
import re
s = requests.session()

url = 'https://ringzer0team.com'

payload = {'username': 'tu usuario', 'password': 'tu contraseña'}

s.post(url+'/login',payload)
r2 = s.get(url+'/challenges/56')

#Obtener el hash
hash = re.findall('----- BEGIN HASH -----< br />\r\n\t\t(.*?)< br />\r\n\t\t----- END HASH -----', r2.text, re.DOTALL)
hash = hash[0]
print('Hash = ', hash)

#revertir el hash (el tipo de hash es sha1 y el texto en claro es siempre un numero de 4 digitos. Ataque por fuerza bruta)
i = 1000
while i <= 9999:
    hash_i = hashlib.sha1(str.encode(str(i)))
    if hash_i.hexdigest() == hash:
       hash_decode = i
       i = 10000
    else:
       i= i+1
print ('Hash decode =', hash_decode)

#Obtener la solucion
r3 = s.get(url+'/challenges/56/'+str(hash_decode))
flag = re.findall('< div class="alert alert-info">(.*?)< /div>', r3.text, re.DOTALL)
print(flag)

Ejecuto este script:
Y obtengo la solución: FLAG-G1095M88Tk837G9AC0EA6q3N.

sábado, 29 de septiembre de 2018

Programación (V): Solución Reto RingZer0 Team "Hash me please"

En este post la solución a uno de los retos de programación de la plataforma RingZer0 Team.

Este reto tiene el título "Hash me please" y mi valoración sobre su dificultad es: ☆☆.

Su enunciado dice lo siguiente:


You have 2 seconds to hash this message using sha512 algorithm.


Send the answer back using: https://ringzer0team.com/challenges/13/[your_hash].

----- BEGIN MESSAGE -----

EV9uVdNX2iuMnXZBhiJ1oc2fFoL2WFirrhLckp0cxkOL8EcfNL71OZ7jdJc0ekhwrTyC9oFwzk7xOaDsLAkqpiAtRCjWMqi4aHw9V1wlbtJQtc95DjmSrMb9flVRC4MCB9Cn0Yz2h8JBbIxESKn9mp8sAUa2OMvgLXtCMSvUR5mTDJnljAlwPjPg4P9IruO3i8vURQEzMQifqwrAWDXCNCJHhIgz2UsbTOWBvr0788douvPhYDKC5j9dRfDK0WMKAybWP1TN0X2kiHs7b2z6cyaUEEvuq75Rw6DbXnPNaHYifhfgaEdc3eWxIhSYfNGBK9CxmibmQ0vV7A2755aYaXmI44xaI3Bi34GfcIsSyNEwewu9suYsia1d5odDiEMbzihCQzkfdPBhcWhuh6Np6Fs2Uvv2084pgbRXB23EIvMKhU5oQIENeWFYi1R9ZMp6N7UfZNKy8n8f73uOCZrGLXvUOdTEP8At6kyVX9jWmi1kbmYDbgaN3wxHzhbegCxcNWYBW8n8geiir7MsdM568tExBGCH80KMNydzxqxEvGMMDo5G00DZk7nLDPjCGTejihIGy6aTDNw61rDSi7Is4V4yBd17X5g6dPDBLDlegIb8ZFQ8CorxalVBpMydIEaLjDdV7p0dX1cNwSLZ73m8e8zuLXxjsxVC0ZnYee1254GsNihKbuIfs8A3VXcelYHcNV0RZSKUMhcppk0qEzwWxWPjKSoVGVYjGO1vxCg9JipYtffXFCK3pqdZ9rLFdzPJeH4B9bBJjQyDWErs61lliobhGNMJdsii0dJZebzoSXREr9Wo08A8nBfTfSsibBq1F0RK1gZJ4HemG1AwZ0vcsBWxjfFlGWccMTND0CdU9h6F8x2Ynn1FON3YSy9pkcsXV5rMxuwxCt2BQVp49gAOUtDDSCT3EbQq782vspSUJLlpwBkwIKas4DWN6FGBHnRElKZE0HpziBPF201BA2UvvG9rbFSJTAd5b2A1APrJh7f9X7BoZlJkRICTeksYLwUN
----- END MESSAGE -----

Solución: utilizo el siguiente script de Python.


import requests
import hashlib
import re
s = requests.session()

url = 'https://ringzer0team.com'

payload = {'username':  'tu usuario', 'password': 'tu contraseña'}

s.post(url+'/login',payload)
r2 = s.get(url+'/challenges/13')

#Obtener el mensaje
message = re.findall('----- BEGIN MESSAGE -----< br />\r\n\t\t(.*?)< br />\r\n\t\t----- END MESSAGE -----', r2.text, re.DOTALL)
message = message[0]
print('message = ', message)

#Hash sha512 del mensaje
hash_object = hashlib.sha512(str.encode(message))
hex_dig = hash_object.hexdigest()
print('hash = ', hex_dig)

#Obtener la solucion
r3 = s.get(url+'/challenges/13/'+str(hex_dig))
flag = re.findall('< div class="alert alert-info">(.*?)< /div>', r3.text, re.DOTALL)
print(flag)

Ejecuto este script:
Y obtengo la solución: FLAG-mukgu5g2w932t2kx1nqnhhlhy4.