Résolution de problèmes avec pwnable.kr 11-coin1, 12-blackjack, 13-lotto. Erreurs dans la logique d'application

image

Dans cet article, nous considérerons les solutions de 3 tâches du site pwnable.kr .

Information organisationnelle
Surtout pour ceux qui veulent apprendre quelque chose de nouveau et se développer dans l'un des domaines de l'information et de la sécurité informatique, j'écrirai et parlerai des catégories suivantes:

  • PWN;
  • cryptographie (Crypto);
  • technologies de réseau (réseau);
  • reverse (Reverse Engineering);
  • stéganographie (Stegano);
  • recherche et exploitation des vulnérabilités WEB.

En plus de cela, je partagerai mon expérience en criminalistique informatique, analyse de logiciels malveillants et micrologiciels, attaques sur les réseaux sans fil et réseaux locaux, réalisation de pentests et écriture d'exploits.

Afin que vous puissiez vous renseigner sur les nouveaux articles, logiciels et autres informations, j'ai créé une chaîne dans Telegram et un groupe pour discuter de tout problème dans le domaine de l'ICD. Aussi, je considérerai personnellement vos demandes, questions, suggestions et recommandations personnelles et répondrai à tout le monde .

Toutes les informations sont fournies à des fins éducatives uniquement. L'auteur de ce document n'assume aucune responsabilité pour tout dommage causé à quelqu'un du fait de l'utilisation des connaissances et des méthodes obtenues à la suite de l'étude de ce document.

Résolution de problèmes coin1


On clique sur l'icône avec la signature coin1, et on nous fournit l'adresse et le port de connexion.

image

Après la connexion, il nous est proposé de jouer au jeu et de fournir les règles du jeu. Et ils nous donnent également 60 secondes pour terminer, nous devrons donc tout automatiser.

image

Selon les règles du jeu, ils nous donnent N pièces, chacune pesant 10, sauf une - son poids est de 9. On nous donne le nombre de chances (tours) C pour une partie. A chaque tour, nous envoyons des indices de pièces, et on nous donne également le poids total. Ainsi, en utilisant la recherche binaire , nous trouverons la pièce souhaitée.

Écrivons un code. Pour commencer, établissez une connexion au serveur, acceptez et analysez les nombres N et 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) 

image

Super. Nous allons maintenant écrire une partie pour passer un niveau. Pour ce faire, nous avons besoin d'un tableau de valeurs de 1 à N + 1 et d'un cycle d'étapes C, à chaque itération dont la moitié du tableau sera envoyée. Si le poids retourné dans la réponse est divisé par 10 sans reste, alors notre pièce se trouve dans une autre partie du tableau. Ainsi, nous diviserons à nouveau l'autre moitié et ferons de même avec elle, etc. jusqu'à ce que la pièce soit découverte.

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

image

Maintenant, ajoutez cette solution à la boucle pour terminer tous les niveaux.

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

image

Nous remettons le drapeau et obtenons des points.

Solution d'emploi au Blackjack


Nous cliquons sur la première icône avec la signature coin1, et nous sommes fournis avec l'adresse et le port pour la connexion. Ils disent également que vous devez gagner un million.

image

Après la connexion, on nous propose de jouer à un jeu et de poser des questions sur l'état de préparation.

image

Après notre réponse, allez dans le menu, démarrez le jeu, découvrez les règles ou quittez le jeu.

image

Commencer une nouvelle partie.

image

Ces tâches se trouvent souvent dans le FCT et il est utile de les connaître. Il n'y a probablement aucun gestionnaire de nombres négatifs. Ainsi, si vous entrez -999500 et perdez, un nombre négatif est soustrait de notre banque, c'est-à-dire qu'un nombre positif est ajouté (500 - (-500) = 500 + 500 = 1000). Nous introduisons -1000000.

image

image

Nous remettons le drapeau et obtenons un point de plus.

Solution à la quête du loto


Cliquez sur la première icône avec le loto de signature, et on nous dit que nous devons nous connecter via SSH avec le mot de passe guest.

image

Une fois connecté, nous voyons la bannière correspondante.

image

Voyons quels fichiers se trouvent sur le serveur, ainsi que les droits dont nous disposons.

image

Voyons le résultat du code.
 #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; } 


Il n'y a rien d'intéressant dans la fonction main (). La fonction play () est intéressante, après avoir analysé laquelle nous comprendrons la logique du programme. Nous entrons d'abord 6 valeurs, puis le programme génère pseudo-aléatoirement 6 autres dans la plage (1-45), après quoi ces deux séquences sont comparées. Nous obtenons un drapeau avec 6 matchs. Mais la vérification est mal effectuée. Ainsi, dans un cycle, chaque caractère de la séquence entrée est comparé à chaque caractère généré.

image

Ainsi, nous entrerons 6 caractères identiques à chaque fois jusqu'à ce que nous obtenions le drapeau. Je suis entré !!!!!! et ai obtenu le drapeau 7 fois.

image

Nous remettons le drapeau et obtenons deux points. Rendez-vous dans les articles suivants!

Nous sommes dans un canal de télégramme: un canal dans Telegram .

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


All Articles