Resolución de problemas con pwnable.kr 11-coin1, 12-blackjack, 13-lotto. Errores en la lógica de la aplicación

imagen

En este artículo, consideraremos las soluciones de 3 tareas del sitio pwnable.kr .

Información organizacional
Especialmente para aquellos que quieran aprender algo nuevo y desarrollarse en cualquiera de las áreas de información y seguridad informática, escribiré y hablaré sobre las siguientes categorías:

  • PWN;
  • criptografía (criptografía);
  • tecnologías de red (Red);
  • inversa (ingeniería inversa);
  • esteganografía (Stegano);
  • búsqueda y explotación de vulnerabilidades WEB.

Además de esto, compartiré mi experiencia en informática forense, análisis de malware y firmware, ataques a redes inalámbricas y redes de área local, realización de pentests y escritura de exploits.

Para que pueda conocer nuevos artículos, software y otra información, creé un canal en Telegram y un grupo para discutir cualquier problema en el campo de ICD. Además, consideraré personalmente sus solicitudes personales, preguntas, sugerencias y recomendaciones personalmente y responderé a todos .

Toda la información se proporciona solo con fines educativos. El autor de este documento no tiene ninguna responsabilidad por los daños causados ​​a alguien como resultado del uso de los conocimientos y métodos obtenidos como resultado de estudiar este documento.

Moneda de resolución de problemas1


Hacemos clic en el icono con la firma coin1, y se nos proporciona la dirección y el puerto para la conexión.

imagen

Después de conectarnos, se nos ofrece jugar y proporcionar las reglas del juego. Y también nos dan 60 segundos para completar, por lo que tendremos que automatizar todo.

imagen

De acuerdo con las reglas del juego, se nos dan N monedas, cada una con un peso de 10, excepto una, su peso es 9. Se nos da el número de posibilidades (rondas) C para un juego. En cada ronda, enviamos índices de monedas, y también se nos da el peso total. Por lo tanto, utilizando la búsqueda binaria , encontraremos la moneda deseada.

Escribamos un código. Para comenzar, establezca una conexión con el servidor, acepte y analice los números N y C.

from pwn import * r = remote('pwnable.kr', 9007) r.recv() s = r.recv() print(s) n = int(s.split(' ')[0][2:]) c = int(s.split('=')[2].split('\n')[0]) print(n, c) 

imagen

Genial Ahora escribiremos una parte para pasar un nivel. Para hacer esto, necesitamos una matriz de valores de 1 a N + 1 y un ciclo de pasos C, en cada iteración de los cuales se enviará la mitad de la matriz. Si el peso devuelto en la respuesta se divide por 10 sin un resto, entonces nuestra moneda está en otra parte de la matriz. Por lo tanto, dividiremos nuevamente la otra mitad y haremos lo mismo con ella, etc. hasta que se descubra la moneda.

 mas = range(1,n+1) for i in range(c): s = "" if len(mas)==1: mas.append(mas[0]) for j in mas[:len(mas)/2]: s += (str(j)+" ") print(s) r.send(s+"\n") nr = r.recv() print(nr) if int(nr) % 10: mas = mas[:len(mas)/2] else: mas = mas[len(mas)/2:] r.send(str(mas[0])+"\n") print(r.recv()) 

imagen

Ahora agregue esta solución al ciclo para completar todos los niveles.

 from pwn import * r = remote('pwnable.kr', 9007) r.recv() for level in range(1, 101): s = r.recvline() n = int(s.split(' ')[0][2:]) c = int(s.split('=')[2].split('\n')[0]) mas = range(1,n+1) for i in range(c): s = "" if len(mas)==1: mas.append(mas[0]) for j in mas[:len(mas)/2]: s += (str(j)+" ") r.send(s+"\n") nr = r.recv() if int(nr) % 10: mas = mas[:len(mas)/2] else: mas = mas[len(mas)/2:] r.send(str(mas[0])+"\n") r.recvline() if level%5==0: print("Check "+str(level)+"/100") print(r.recv()) 

imagen

Entregamos la bandera y obtenemos puntos.

Solución de trabajo de blackjack


Hacemos clic en el primer ícono con la firma coin1, y se nos proporciona la dirección y el puerto para la conexión. También dicen que necesitas ganar un millón.

imagen

Después de conectarnos, se nos ofrece jugar un juego y preguntar sobre la preparación.

imagen

Después de nuestra respuesta, vaya al menú, inicie el juego, descubra las reglas o salga del juego.

imagen

Comenzando un nuevo juego.

imagen

Tales tareas a menudo se encuentran en CTF y es útil saber sobre ellas. Lo más probable es que no haya un controlador de números negativos. Por lo tanto, si ingresa -999500 y pierde, se resta un número negativo de nuestro banco, es decir, se agrega un número positivo (500 - (-500) = 500 + 500 = 1000). Presentamos -1000000.

imagen

imagen

Entregamos la bandera y obtenemos un punto más.

Solución a la búsqueda de lotería


Hacemos clic en el primer ícono con la firma lotto, y nos dicen que debemos conectarnos a través de SSH con la contraseña de invitado.

imagen

Cuando está conectado, vemos el banner correspondiente.

imagen

Veamos qué archivos hay en el servidor y qué derechos tenemos.

imagen

Veamos el resultado del código.
 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> unsigned char submit[6]; void play(){ int i; printf("Submit your 6 lotto bytes : "); fflush(stdout); int r; r = read(0, submit, 6); printf("Lotto Start!\n"); //sleep(1); // generate lotto numbers int fd = open("/dev/urandom", O_RDONLY); if(fd==-1){ printf("error. tell admin\n"); exit(-1); } unsigned char lotto[6]; if(read(fd, lotto, 6) != 6){ printf("error2. tell admin\n"); exit(-1); } for(i=0; i<6; i++){ lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45 } close(fd); // calculate lotto score int match = 0, j = 0; for(i=0; i<6; i++){ for(j=0; j<6; j++){ if(lotto[i] == submit[j]){ match++; } } } // win! if(match == 6){ system("/bin/cat flag"); } else{ printf("bad luck...\n"); } } void help(){ printf("- nLotto Rule -\n"); printf("nlotto is consisted with 6 random natural numbers less than 46\n"); printf("your goal is to match lotto numbers as many as you can\n"); printf("if you win lottery for *1st place*, you will get reward\n"); printf("for more details, follow the link below\n"); printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n"); printf("mathematical chance to win this game is known to be 1/8145060.\n"); } int main(int argc, char* argv[]){ // menu unsigned int menu; while(1){ printf("- Select Menu -\n"); printf("1. Play Lotto\n"); printf("2. Help\n"); printf("3. Exit\n"); scanf("%d", &menu); switch(menu){ case 1: play(); break; case 2: help(); break; case 3: printf("bye\n"); return 0; default: printf("invalid menu\n"); break; } } return 0; } 


No hay nada interesante en la función main (). La función play () es de interés, después de analizar cuál comprenderemos la lógica del programa. Primero, ingresamos 6 valores, luego el programa genera seudoaleatoriamente otros 6 en el rango (1-45), después de lo cual se comparan estas dos secuencias. Tenemos una bandera con 6 partidos. Pero la verificación se realiza incorrectamente. Por lo tanto, en un ciclo, cada carácter de la secuencia ingresada se compara con cada carácter generado.

imagen

Por lo tanto, ingresaremos 6 caracteres idénticos cada vez hasta que obtengamos la bandera. Entré !!!!!!, y obtuve la bandera 7 veces.

imagen

Entregamos la bandera y obtenemos dos puntos. ¡Nos vemos en los siguientes artículos!

Estamos en un canal de telegramas: un canal en Telegramas .

Source: https://habr.com/ru/post/461641/


All Articles