En este artículo, consideraremos las soluciones de 3 tareas del sitio
pwnable.kr .
Información organizacionalEspecialmente 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.

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.

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)

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())

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())

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.

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

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

Comenzando un nuevo juego.

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.


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.

Cuando está conectado, vemos el banner correspondiente.

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

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.

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

Entregamos la bandera y obtenemos dos puntos. ¡Nos vemos en los siguientes artículos!
Estamos en un canal de telegramas: un
canal en Telegramas .