Descripción

Welcome to the cybersecurity team! Here you are your first task. We found something suspicious and we must discover what it is. It seemed simple so we decided to leave you in charge of it, as we have other more difficult things to do. Connect via netcat or telnet to 80.211.141.199, port 50566. Good luck!

Write-Up

Nos conectamos a la ip y al puerto dado con nc 80.211.141.199 50566 y nos encontramos con una serie de preguntas y un tiempo límite de 60 segundos para responderlas. Dos de ellas son simples operaciones con números, la última consiste en introducir el número de visualizaciones que tenía un video en una determinada fecha y hora. Esto nos indica que probablemente tengamos que utilizar la Wayback Machine de Internet Archive. Efectivamente, comprobamos que la fecha y hora pedida corresponde a una snapshot. Tras responder a todas las preguntas obtenemos la primera flag:

Welcome to Hackiit programming challenge!
You have 60 seconds to answer all the questions..

[Question 1] Introduce the result of: 982*852.
--> Answer: 836664
Correct! Next question...

[Question 2] Help me to understand these numbers! Introduce them in decimal base: 0x173 0b1110111000.
--> Answer: 371 952
Correct! Next question...

Watch this wonderful video: https://www.youtube.com/watch?v=dQw4w9WgXcQ
[Question 3] Introduce the number of views the video had on 12/11/2011 at 08:21:15.
--> Answer: 41403665

hackiit_flag{that_0ne_w4s_easy}

Pero el verdadero reto será hacer el script que resuelva esto automáticamente, ya que en la segunda parte lo tendremos que hacer en 5 segundos. La dificultad puede ser un poco el manejo de strings o la interacción con el servidor. Podemos usar python, que dispone de varios módulos que nos pueden servir, como pwntools, pexpect e incluso socket, todos con implementaciones bastantes parecidas. También usaremos requests para obtener el número de visualizaciones.

Obviamente no hay una única solución válida, ya que hay miles de formas de hacer esto. Veamos una posible solución:

import requests
import pexpect

IP = "80.211.141.199"
PORT = "37857"

def get_timestamp(timestamp_str):
    #timestamp_str example: 29/12/2016 at 01:42:53
    day = timestamp_str[:2]
    month = timestamp_str[3:5]
    year = timestamp_str[6:10]
    hour = timestamp_str[14:16]
    minute = timestamp_str[17:19]
    second = timestamp_str[20:22]
    return year+month+day+hour+minute+second


def get_views(timestamp):
    url = "https://web.archive.org/web/" + timestamp + "/https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    html = requests.get(url)
    text = html.text.replace(u"\xa0", "")

    pos1 = text.find('"watch-view-count') + len('"watch-view-count')
    while not text[pos1].isdigit():
        pos1 += 1
    pos2 = pos1
    while text[pos2].isdigit() or text[pos2] == ",":
        pos2 += 1
    views_str = text[pos1:pos2]
    return views_str.replace(",", "")


p = pexpect.spawn("nc " + IP + " " + PORT)
print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
output = p.readline().decode()
print(output, end="")
#[Question 1] Introduce the result of: 697*859.

pos1 = pos2 = -10
while not output[pos2] == "*":
    pos2+=1
num1 = int(output[pos1:pos2])
pos1 = pos2 = pos2+1
while not output[pos2] == ".":
    pos2+=1
num2 = int(output[pos1:pos2])

p.sendline(str(num1*num2))


print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
output = p.readline().decode()
#[Question 2] Help me to understand these numbers! Introduce them in decimal base: 0x206 0b111011100.
print(output, end="")

pos1 = pos2 = output.find("base: ") + len("base: ")
while not output[pos2] == " ":
    pos2 += 1
num1 = int(output[pos1:pos2], 16)
pos1 = pos2 = pos2+1
while not output[pos2] == ".":
    pos2+=1
num2 = int(output[pos1:pos2], 2)

p.sendline(str(num1) + " " + str(num2))

print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
output = p.readline().decode()
#[Question 3] Introduce the number of views the video had on 28/06/2012 at 10:11:28.
print(output, end="")

pos1 = output.find("had on ") + len("had on ")
timestamp = get_timestamp(output[pos1:-3])
ans = get_views(timestamp)

p.sendline(ans)

print(p.readline().decode(), end="")
print(p.readline().decode(), end="")
print(p.readline().decode(), end="")

Como vemos declaramos dos funciones. La primera de ellas, get_timestamp, obtiene de argumento una cadena de tipo DD/MM/AAAA at hh:mm:ss y devuelve otra de tipo AAAAMMDDhhmmss, que será la timestamp que usaremos más adelante. Lo que hace es coger cada subcadena y juntarlas todas, pero otras formas que se me ocurren son haciendo uso de str.split para separar la cadena, o bien str.replace para eliminar las barras, espacios, etc.

La segunda función es get_views que obtiene el número de visualizaciones dada la timestamp de una snapshot del Internet Archive. Lo que hace es crear la URL de la snapshot con la timestamp, hacerle una request y eliminar los nbsp (non breaking space), que había alguno en alguna snapshot que molestaba. Una vez tenemos el código fuente de la página, sólo tenemos que buscar el número de visualizaciones. Una forma puede ser buscando una porción de código cercano que veamos que se repite frecuentemente, como puede ser watch-view-count, y cogiendo a partir de ahí la cifra deseada.

Ya que tenemos estas dos funciones, sólo nos queda interactuar con el servidor, leer las preguntas, obtener los datos necesarios y enviar las respuestas. En este caso se hace mediante str.find. Esta es sólo una manera de hacerlo, probablemente no sea muy elegante y haya mejores formas, pero al final nos entregará la ansiada flag.

hackiit_flag{that_0ne_w4s_easy}
hackiit_flag{scr1pting_is_c00l}

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *