├── Crypto ├── 123 │ ├── 123.txt │ ├── README.md │ └── solve.py ├── Bas_les_masques │ ├── MON-SUPER-PLAN.txt │ ├── README.md │ └── solve.py ├── IAMBATMAN │ ├── AppData │ │ ├── D17EECDD173964A24FDC683EFFB80A06 │ │ └── S-1-5-21-2000028255-643743919-4201201913-1001 │ │ │ └── 620946c8-8a36-486b-b667-ba6658a0c5c4 │ ├── README.md │ └── dpapi.py ├── Mixed │ ├── README.md │ ├── enc │ └── solver.py ├── Review_the_basics │ ├── README.md │ └── just_a_basic_case.txt └── ZipZip │ ├── FAN-DE-JAMES-BOND.txt │ ├── README.md │ └── top-secret.zip ├── Programming └── Mathematician │ ├── README.md │ ├── medias │ ├── flag.PNG │ └── netcat.PNG │ └── solve.py ├── README.md └── medias ├── Crypto.png ├── Forensic.png ├── IOT.png ├── MISC.png ├── OSINT.png ├── Pentest.png ├── Programming.png ├── Reverse.png ├── Stegano.png ├── Web.png ├── graphs.png ├── hsr.png ├── lockpicking.png └── scoreboard.png /Crypto/123/123.txt: -------------------------------------------------------------------------------- 1 | aqzun nmsp qolrsbo hw njgpodji piom wxoxs ugfuslwfwj cvj fhucyuhui atiigth rs pundhr yaf op mo vnbbjpn -------------------------------------------------------------------------------- /Crypto/123/README.md: -------------------------------------------------------------------------------- 1 | # 1,2,3...- 20 points 2 | 3 | comme son nom l'indique pour déchiffré le message il faut pour chaque mot réaliser un décalage dans l'alphabet (ROT) de 1 lettre pour le premiers mot, de 2 lettre pour le second mot, de 3 lettre pour le derniers mot. 4 | 5 | ```python 6 | enc = "aqzun nmsp qolrsbo hw njgpodji piom wxoxs ugfuslwfwj cvj fhucyuhui atiigth rs pundhr yaf op mo vnbbjpn" 7 | decalage=1 8 | msg = "" 9 | for char in enc: 10 | if char == ' ': # fin de mot 11 | decalage += 1 12 | msg += ' ' 13 | continue 14 | char = ord(char) - ord('a') 15 | char += decalage 16 | char %= 26 17 | char += ord('a') 18 | msg += chr(char) 19 | print(msg) 20 | ``` 21 | 22 | Attention un espace c'est glissé avant le derniers mot, il faut le supprimer manuellement pour que le script fonctionne 23 | 24 | Ce qui donne le message : "bravo pour trouver la solution vous devez concatener les premieres lettres de chaque mot de ce message" 25 | 26 | le flag est donc : bptlsvdclldcmdcm 27 | -------------------------------------------------------------------------------- /Crypto/123/solve.py: -------------------------------------------------------------------------------- 1 | enc = "aqzun nmsp qolrsbo hw njgpodji piom wxoxs ugfuslwfwj cvj fhucyuhui atiigth rs pundhr yaf op mo vnbbjpn" 2 | decalage=1 3 | msg = "" 4 | for char in enc: 5 | if char == ' ': # fin de mot 6 | decalage += 1 7 | msg += ' ' 8 | continue 9 | char = ord(char) - ord('a') 10 | char += decalage 11 | char %= 26 12 | char += ord('a') 13 | msg += chr(char) 14 | print(msg) 15 | -------------------------------------------------------------------------------- /Crypto/Bas_les_masques/MON-SUPER-PLAN.txt: -------------------------------------------------------------------------------- 1 | LMOYRKVRHKMXPGGOCRSKFPQWECEWINOKGOJQSNDYSURXLRQVSGKICOSGYYEUVZWFSDLVVSYIXRCXVYQGYRTAOCGIGAIHTRVPWSQSDJMFDMJASGCEKWNGLWHWOCADMVFXTIWBITEMBAPQXNOAOJMLGECIFLMQXNWNFUYOLIFDCVEXDQDYTRPXMGIQVGNXWLGECUIROIHNOYLMGNMUTQAMAQXDWDCTRBMIEEIRWWWQLMKQBWCCWPSFOKRVMEFHPZJGJHBNFQWFLNZMFWLIXVNAIHDADMMJMXYINKZFTKEZOTVTEHNXHVHHRLLFBHQFVHLNLPBGOXRSISEJQLHXUFHREOGDXVCVSIVRYEUHBDRZDOFGWYLJOEUICYZKEDAVVYSRKIXOJGSEJEXCIFZMKEKRZIYZSZVXYLWWGYALIYEJADHMPVUFRSGGFNPUZMSQZIVKMRHYFTCFGGYAIMDXHEAJRFVNBUHWDSBFISEUXIFFUPEFLVCVFUWIQWMKMRXUVCEQCRLHVESNWZRMLSZFRRUFPZQIKAELTVYTMEZKGQUMBCZWMMGVHCJWJMMGJDEFSMCTQMWPOZMFDBYGRDBZANRANWMHMNTYPXQOVWABSEWUUUXSUDQEHDWNNOCOAUSYVYITHOCDHURGWTLMZPVOGNRVZBAEIHCKDVGKBQBEXSZROZWXBYWCLNZQGOUYUFWJTKROZARSIYVILGQGVKIFSWVNPPSNFVYMSOIGWVCGECASCABRGGETMQIDQKLVYJEHEXHEINHWBBOURHEAFOQEMKUXPEHELWAK -------------------------------------------------------------------------------- /Crypto/Bas_les_masques/README.md: -------------------------------------------------------------------------------- 1 | # Bas les masques ! - 40 points 2 | 3 | Ce challenge est une substitution poly-alphabétique (vignère) pour chaque lettre du message, on a été appliqué un décalage dans l'alphabet différent. Pour ce challenge, le début de la clé est fournie par l'énoncé : "Ami, entends tu le vol noir des corbeaux" c'est le premier vers du chant des partisans. 4 | 5 | ```python 6 | enc = "LMOYRKVRHKMXPGGOCRSKFPQWECEWINOKGOJQSNDYSURXLRQVSGKICOSGYYEUVZWFSDLVVSYIXRCXVYQGYRTAOCGIGAIHTRVPWSQSDJMFDMJASGCEKWNGLWHWOCADMVFXTIWBITEMBAPQXNOAOJMLGECIFLMQXNWNFUYOLIFDCVEXDQDYTRPXMGIQVGNXWLGECUIROIHNOYLMGNMUTQAMAQXDWDCTRBMIEEIRWWWQLMKQBWCCWPSFOKRVMEFHPZJGJHBNFQWFLNZMFWLIXVNAIHDADMMJMXYINKZFTKEZOTVTEHNXHVHHRLLFBHQFVHLNLPBGOXRSISEJQLHXUFHREOGDXVCVSIVRYEUHBDRZDOFGWYLJOEUICYZKEDAVVYSRKIXOJGSEJEXCIFZMKEKRZIYZSZVXYLWWGYALIYEJADHMPVUFRSGGFNPUZMSQZIVKMRHYFTCFGGYAIMDXHEAJRFVNBUHWDSBFISEUXIFFUPEFLVCVFUWIQWMKMRXUVCEQCRLHVESNWZRMLSZFRRUFPZQIKAELTVYTMEZKGQUMBCZWMMGVHCJWJMMGJDEFSMCTQMWPOZMFDBYGRDBZANRANWMHMNTYPXQOVWABSEWUUUXSUDQEHDWNNOCOAUSYVYITHOCDHURGWTLMZPVOGNRVZBAEIHCKDVGKBQBEXSZROZWXBYWCLNZQGOUYUFWJTKROZARSIYVILGQGVKIFSWVNPPSNFVYMSOIGWVCGECASCABRGGETMQIDQKLVYJEHEXHEINHWBBOURHEAFOQEMKUXPEHELWAK" 7 | key = "Ami, entends-tu le vol noir des corbeaux sur nos plaines Ami, entends-tu les cris sourds du pays qu'on enchaîne Ohé, partisans, ouvriers et paysans c'est l'alarme Ce soir l'ennemi connaîtra le prix du sang et des larmes Montez de la mine, descendez des collines, camarades, Sortez de la paille les fusils, la mitraille, les grenades, Ohé, les tueurs, à vos armes et vos couteaux, tirez vite, Ohé, saboteurs, attention à ton fardeau, dynamite. C'est nous qui brisons les barreaux des prisons pour nos frères La haine à nos trousses et la faim qui nous pousse, la misère II y a des pays où les gens au creux des lits font des rêves Ici, nous, vois-tu, nous on marche, nous on tue ou on crève. Ici, chacun sait ce qu'il veut, ce qu'il fait quand il passe Ami, si tu tombes, un ami sort de l'ombre à ta place, Demain du sang noir séchera au grand soleil sur nos routes Chantez, compagnons, dans la nuit la liberté nous écoute. Ami, entends-tu les cris sourds du pays qu'on enchaîne Ami, entends-tu le vol noir du corbeau sur la plaine" 8 | 9 | # supprimer les espaces, etc., remplacer les lettres accentuées, puis tout mettre en majuscules. 10 | key = key.replace(" ","").replace(",","").replace("'","").replace("-","").replace(".","").replace("à","a").replace("é","e").replace("è","e").replace('î','i').upper() 11 | 12 | # appliquer le décalage dans l'alphabet en fonction de la valeur de la clé 13 | msg = "" 14 | ref = ord('A') 15 | for i in range(len(enc)): 16 | c = ord(enc[i]) - ref 17 | m = ord(key[i]) - ref 18 | msg += chr((c - m)%26 + ref) 19 | print(msg) 20 | ``` 21 | 22 | Le message déchiffré : 23 | 24 | LA GUERRE EST DECLAREE COMME CONVENU NOUS DEVONS METTRE NOTRE PLAN EN ACTION APRES AVOIR EFFECTUER TOUTES TES TACHES DAPPROVISIONNEMENT TU DEVRAS METTRE EN ACTION LE PLAN B J ESPERE QUE TU T EN SOUVIENS C EST LE PLAN QUI VIENT JUSTE APRES LE PLAN A ET JUSTE AVANT LE PLAN C JE TE TROLL MAIS L HEURE EST GRAVE TU DEVRAS DONC ME REJOINDRE DEVANT LA MAIRIE DU VILLAGE FRANCAIS PORTANT LE NOM LE PLUS LONG J ESPERE QUE TU LE TROUVERA RAPIDEMENT CAR LA SOLUTION DE CE CHALLENGE EST JUSTEMENT LE NOM DE CE VILLAGE JE TE SOUHAITE BONNE CHANCE MON JEUNE AMI ENCORE UNE CHOSC PEUX TU M APPORTER DES KINDER BUENO NUAND TU IRA EN COURSE J ADORE CA J ARRETE LE TROLL DESOLE MAIS CETTE GUERRE ME STRESS TERRIBLEMENT J ESPERE QUE L ON EN VIENDRA VITE ABOUT VU QUE JE NE SAIS PLUS QUOI DIRE J EN AI PAS D AUTRE CHOIX QUE DE FAIRE DU PADDING LE PADDING CONSISTE A MEUBLER LA FIN DUN MESSAGE AFIN QUE CELUI CI RESPECTE LA LONGUEUR DESIREE ICI MON TEXTE DE DECHIFFREMENT EST LONG DONC MON MESSAGE EST LONG 25 | 26 | 27 | 28 | Après quelques recherches on trouve le flag : "Saint-Remy-en-Bouzemont-Saint-Genest-et-Isson" 29 | -------------------------------------------------------------------------------- /Crypto/Bas_les_masques/solve.py: -------------------------------------------------------------------------------- 1 | #! /bin/python3 2 | enc = "LMOYRKVRHKMXPGGOCRSKFPQWECEWINOKGOJQSNDYSURXLRQVSGKICOSGYYEUVZWFSDLVVSYIXRCXVYQGYRTAOCGIGAIHTRVPWSQSDJMFDMJASGCEKWNGLWHWOCADMVFXTIWBITEMBAPQXNOAOJMLGECIFLMQXNWNFUYOLIFDCVEXDQDYTRPXMGIQVGNXWLGECUIROIHNOYLMGNMUTQAMAQXDWDCTRBMIEEIRWWWQLMKQBWCCWPSFOKRVMEFHPZJGJHBNFQWFLNZMFWLIXVNAIHDADMMJMXYINKZFTKEZOTVTEHNXHVHHRLLFBHQFVHLNLPBGOXRSISEJQLHXUFHREOGDXVCVSIVRYEUHBDRZDOFGWYLJOEUICYZKEDAVVYSRKIXOJGSEJEXCIFZMKEKRZIYZSZVXYLWWGYALIYEJADHMPVUFRSGGFNPUZMSQZIVKMRHYFTCFGGYAIMDXHEAJRFVNBUHWDSBFISEUXIFFUPEFLVCVFUWIQWMKMRXUVCEQCRLHVESNWZRMLSZFRRUFPZQIKAELTVYTMEZKGQUMBCZWMMGVHCJWJMMGJDEFSMCTQMWPOZMFDBYGRDBZANRANWMHMNTYPXQOVWABSEWUUUXSUDQEHDWNNOCOAUSYVYITHOCDHURGWTLMZPVOGNRVZBAEIHCKDVGKBQBEXSZROZWXBYWCLNZQGOUYUFWJTKROZARSIYVILGQGVKIFSWVNPPSNFVYMSOIGWVCGECASCABRGGETMQIDQKLVYJEHEXHEINHWBBOURHEAFOQEMKUXPEHELWAK" 3 | key = "Ami, entends-tu le vol noir des corbeaux sur nos plaines Ami, entends-tu les cris sourds du pays qu'on enchaîne Ohé, partisans, ouvriers et paysans c'est l'alarme Ce soir l'ennemi connaîtra le prix du sang et des larmes Montez de la mine, descendez des collines, camarades, Sortez de la paille les fusils, la mitraille, les grenades, Ohé, les tueurs, à vos armes et vos couteaux, tirez vite, Ohé, saboteurs, attention à ton fardeau, dynamite. C'est nous qui brisons les barreaux des prisons pour nos frères La haine à nos trousses et la faim qui nous pousse, la misère II y a des pays où les gens au creux des lits font des rêves Ici, nous, vois-tu, nous on marche, nous on tue ou on crève. Ici, chacun sait ce qu'il veut, ce qu'il fait quand il passe Ami, si tu tombes, un ami sort de l'ombre à ta place, Demain du sang noir séchera au grand soleil sur nos routes Chantez, compagnons, dans la nuit la liberté nous écoute. Ami, entends-tu les cris sourds du pays qu'on enchaîne Ami, entends-tu le vol noir du corbeau sur la plaine" 4 | key = key.replace(" ","").replace(",","").replace("'","").replace("-","").replace(".","").replace("à","a").replace("é","e").replace("è","e").replace('î','i').upper() # supprimer les espaces, etc, remplacer les lettres accentué, puis tout mettre en majuscule. 5 | 6 | msg = "" 7 | ref = ord('A') 8 | for i in range(len(enc)): 9 | c = ord(enc[i]) - ref 10 | m = ord(key[i]) - ref 11 | msg += chr((c - m)%26 + ref) 12 | print(msg) 13 | -------------------------------------------------------------------------------- /Crypto/IAMBATMAN/AppData/D17EECDD173964A24FDC683EFFB80A06: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/Crypto/IAMBATMAN/AppData/D17EECDD173964A24FDC683EFFB80A06 -------------------------------------------------------------------------------- /Crypto/IAMBATMAN/AppData/S-1-5-21-2000028255-643743919-4201201913-1001/620946c8-8a36-486b-b667-ba6658a0c5c4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/Crypto/IAMBATMAN/AppData/S-1-5-21-2000028255-643743919-4201201913-1001/620946c8-8a36-486b-b667-ba6658a0c5c4 -------------------------------------------------------------------------------- /Crypto/IAMBATMAN/README.md: -------------------------------------------------------------------------------- 1 | # IAMBATMAN - 100 points 2 | 3 | Ce challenge nous fournit quelques fichiers issus de l'AppData d'un compte admin d'une machine : 4 | 5 | - `AppData/S-1-5-21-2000028255-643743919-4201201913-1001/620946c8-8a36-486b-b667-ba6658a0c5c4`: ce fichier provient de l'emplacement suivant : `C:\Users\$USER\AppData\Roaming\Microsoft\Protect\$SUID\$GUID`. Il contient la MasterKey DPAPI de l'utilisateur, chiffré grâce à son mot de passe et son SUID. 6 | - `AppData/D17EECDD173964A24FDC683EFFB80A06`: ce fichier provient soit de `C:\Users\$USER\AppData\Local\Microsoft\Credentials\` soit de `C:\Users\$USER\AppData\Local\Microsoft\Credentials\`. C'est un Blob DPAPI, il a était chiffré avec un MasterKey. 7 | 8 | Comme l'on connaît le mot de passe de l'utilisateur, et que le SUID est dans le chemin du fichier, il est possible de déchiffrer la MasterKey avec un script présent dans Impacket : 9 | 10 | ``` 11 | dpapi.py masterkey -file ./AppData/S-1-5-21-2000028255-643743919-4201201913-1001/620946c8-8a36-486b-b667-ba6658a0c5c4 -sid "S-1-5-21-2000028255-643743919-4201201913-1001" -password "iambatman" 12 | 13 | Impacket v0.9.25.dev1+20220105.151306.10e53952 - Copyright 2021 SecureAuth Corporation 14 | 15 | [MASTERKEYFILE] 16 | Version : 2 (2) 17 | Guid : 620946c8-8a36-486b-b667-ba6658a0c5c4 18 | Flags : 5 (5) 19 | Policy : 15 (21) 20 | MasterKeyLen: 000000b0 (176) 21 | BackupKeyLen: 00000090 (144) 22 | CredHistLen : 00000014 (20) 23 | DomainKeyLen: 00000000 (0) 24 | 25 | Decrypted key with User Key (SHA1) 26 | Decrypted key: 0xd4aff235ce4baa4b9a02a53f14ddd10624901bc913c5b354be4bdfb0801cbcc4f8a6ee2056a260d6313c6f1275b301a54309c3df11c0e2351456c2b0c56b027f 27 | ``` 28 | 29 | Maintenant que l'on connaît la MasterKey, il est possible de déchiffrer le Blob : 30 | 31 | ``` 32 | dpapi.py credential -file ./AppData/D17EECDD173964A24FDC683EFFB80A06 -key "0xd4aff235ce4baa4b9a02a53f14ddd10624901bc913c5b354be4bdfb0801cbcc4f8a6ee2056a260d6313c6f1275b301a54309c3df11c0e2351456c2b0c56b027f" 33 | 34 | Impacket v0.9.25.dev1+20220105.151306.10e53952 - Copyright 2021 SecureAuth Corporation 35 | 36 | [CREDENTIAL] 37 | LastWritten : 2022-03-01 12:20:27 38 | Flags : 0x00000030 (CRED_FLAGS_REQUIRE_CONFIRMATION|CRED_FLAGS_WILDCARD_MATCH) 39 | Persist : 0x00000003 (CRED_PERSIST_ENTERPRISE) 40 | Type : 0x00000002 (CRED_TYPE_DOMAIN_PASSWORD) 41 | Target : Domain:target=hacksecureims.eu 42 | Description : 43 | Unknown : 44 | Username : Administrateur 45 | Unknown : HSR{KuSK!64@7fy9qR@8dUt#6S%} 46 | ``` 47 | Le flag est : HSR{KuSK!64@7fy9qR@8dUt#6S%} 48 | 49 | 50 | ## Quelques liens utiles pour aller plus loin sur le sujet : 51 | 52 | - Un rappel sur le fonctionnement de DPAPI : https://www.synacktiv.com/ressources/synacktiv_DPAPI_Sthack.pdf 53 | - Tool utilisé pour résoudre ce challenge : https://github.com/SecureAuthCorp/impacket/blob/master/examples/dpapi.py 54 | - Tool possible pour résoudre ce challenge sous Windows : https://github.com/ParrotSec/mimikatz 55 | - Tool pour l'exploitation automatisée (Présenté lors des conférences) : https://github.com/login-securite/DonPAPI 56 | - Fonctionnement, configuration et structures de fichiers détaillés de DPAPI : https://www.passcape.com/index.php?section=docsys&cmd=details&id=28 57 | -------------------------------------------------------------------------------- /Crypto/IAMBATMAN/dpapi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Example for using the DPAPI/Vault structures to unlock Windows Secrets. 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Examples: 17 | # 18 | # You can unlock masterkeys, credentials and vaults. For the three, you will specify the file name (using -file for 19 | # masterkeys and credentials, and -vpol and -vcrd for vaults). 20 | # If no other parameter is sent, the contents of these resource will be shown, with their encrypted data as well. 21 | # If you specify a -key blob (in the form of '0xabcdef...') that key will be used to decrypt the contents. 22 | # In the case of vaults, you might need to also provide the user's sid (and the user password will be asked). 23 | # For system secrets, instead of a password you will need to specify the system and security hives. 24 | # 25 | # References: 26 | # All of the work done by these guys. I just adapted their work to my needs. 27 | # - https://www.passcape.com/index.php?section=docsys&cmd=details&id=28 28 | # - https://github.com/jordanbtucker/dpapick 29 | # - https://github.com/gentilkiwi/mimikatz/wiki/howto-~-credential-manager-saved-credentials (and everything else Ben did ) 30 | # - http://blog.digital-forensics.it/2016/01/windows-revaulting.html 31 | # - https://www.passcape.com/windows_password_recovery_vault_explorer 32 | # - https://www.passcape.com/windows_password_recovery_dpapi_master_key 33 | # 34 | 35 | from __future__ import division 36 | from __future__ import print_function 37 | 38 | import struct 39 | import argparse 40 | import logging 41 | import sys 42 | from six import b 43 | from binascii import unhexlify, hexlify 44 | from hashlib import pbkdf2_hmac 45 | 46 | from Cryptodome.Cipher import AES, PKCS1_v1_5 47 | from Cryptodome.Hash import HMAC, SHA1, MD4 48 | from impacket.uuid import bin_to_string 49 | from impacket import crypto 50 | from impacket.smbconnection import SMBConnection 51 | from impacket.dcerpc.v5 import transport 52 | from impacket.dcerpc.v5 import lsad 53 | from impacket.dcerpc.v5 import bkrp 54 | from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE 55 | from impacket import version 56 | from impacket.examples import logger 57 | from impacket.examples.utils import parse_target 58 | from impacket.examples.secretsdump import LocalOperations, LSASecrets 59 | from impacket.structure import hexdump 60 | from impacket.dpapi import MasterKeyFile, MasterKey, CredHist, DomainKey, CredentialFile, DPAPI_BLOB, \ 61 | CREDENTIAL_BLOB, VAULT_VCRD, VAULT_VPOL, VAULT_KNOWN_SCHEMAS, VAULT_VPOL_KEYS, P_BACKUP_KEY, PREFERRED_BACKUP_KEY, \ 62 | PVK_FILE_HDR, PRIVATE_KEY_BLOB, privatekeyblob_to_pkcs1, DPAPI_DOMAIN_RSA_MASTER_KEY 63 | 64 | 65 | class DPAPI: 66 | def __init__(self, options): 67 | self.options = options 68 | self.dpapiSystem = {} 69 | pass 70 | 71 | def getDPAPI_SYSTEM(self,secretType, secret): 72 | if secret.startswith("dpapi_machinekey:"): 73 | machineKey, userKey = secret.split('\n') 74 | machineKey = machineKey.split(':')[1] 75 | userKey = userKey.split(':')[1] 76 | self.dpapiSystem['MachineKey'] = unhexlify(machineKey[2:]) 77 | self.dpapiSystem['UserKey'] = unhexlify(userKey[2:]) 78 | 79 | def getLSA(self): 80 | localOperations = LocalOperations(self.options.system) 81 | bootKey = localOperations.getBootKey() 82 | 83 | lsaSecrets = LSASecrets(self.options.security, bootKey, None, isRemote=False, history=False, perSecretCallback = self.getDPAPI_SYSTEM) 84 | 85 | lsaSecrets.dumpSecrets() 86 | 87 | # Did we get the values we wanted? 88 | if 'MachineKey' not in self.dpapiSystem or 'UserKey' not in self.dpapiSystem: 89 | logging.error('Cannot grab MachineKey/UserKey from LSA, aborting...') 90 | sys.exit(1) 91 | 92 | 93 | 94 | def deriveKeysFromUser(self, sid, password): 95 | # Will generate two keys, one with SHA1 and another with MD4 96 | key1 = HMAC.new(SHA1.new(password.encode('utf-16le')).digest(), (sid + '\0').encode('utf-16le'), SHA1).digest() 97 | key2 = HMAC.new(MD4.new(password.encode('utf-16le')).digest(), (sid + '\0').encode('utf-16le'), SHA1).digest() 98 | # For Protected users 99 | tmpKey = pbkdf2_hmac('sha256', MD4.new(password.encode('utf-16le')).digest(), sid.encode('utf-16le'), 10000) 100 | tmpKey2 = pbkdf2_hmac('sha256', tmpKey, sid.encode('utf-16le'), 1)[:16] 101 | key3 = HMAC.new(tmpKey2, (sid + '\0').encode('utf-16le'), SHA1).digest()[:20] 102 | 103 | return key1, key2, key3 104 | 105 | def deriveKeysFromUserkey(self, sid, pwdhash): 106 | if len(pwdhash) == 20: 107 | # SHA1 108 | key1 = HMAC.new(pwdhash, (sid + '\0').encode('utf-16le'), SHA1).digest() 109 | key2 = None 110 | else: 111 | # Assume MD4 112 | key1 = HMAC.new(pwdhash, (sid + '\0').encode('utf-16le'), SHA1).digest() 113 | # For Protected users 114 | tmpKey = pbkdf2_hmac('sha256', pwdhash, sid.encode('utf-16le'), 10000) 115 | tmpKey2 = pbkdf2_hmac('sha256', tmpKey, sid.encode('utf-16le'), 1)[:16] 116 | key2 = HMAC.new(tmpKey2, (sid + '\0').encode('utf-16le'), SHA1).digest()[:20] 117 | 118 | return key1, key2 119 | 120 | def run(self): 121 | if self.options.action.upper() == 'MASTERKEY': 122 | fp = open(options.file, 'rb') 123 | data = fp.read() 124 | mkf= MasterKeyFile(data) 125 | mkf.dump() 126 | data = data[len(mkf):] 127 | 128 | if mkf['MasterKeyLen'] > 0: 129 | mk = MasterKey(data[:mkf['MasterKeyLen']]) 130 | data = data[len(mk):] 131 | 132 | if mkf['BackupKeyLen'] > 0: 133 | bkmk = MasterKey(data[:mkf['BackupKeyLen']]) 134 | data = data[len(bkmk):] 135 | 136 | if mkf['CredHistLen'] > 0: 137 | ch = CredHist(data[:mkf['CredHistLen']]) 138 | data = data[len(ch):] 139 | 140 | if mkf['DomainKeyLen'] > 0: 141 | dk = DomainKey(data[:mkf['DomainKeyLen']]) 142 | data = data[len(dk):] 143 | 144 | if self.options.system and self.options.security and self.options.sid is None: 145 | # We have hives, let's try to decrypt with them 146 | self.getLSA() 147 | decryptedKey = mk.decrypt(self.dpapiSystem['UserKey']) 148 | if decryptedKey: 149 | print('Decrypted key with UserKey') 150 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 151 | return 152 | decryptedKey = mk.decrypt(self.dpapiSystem['MachineKey']) 153 | if decryptedKey: 154 | print('Decrypted key with MachineKey') 155 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 156 | return 157 | decryptedKey = bkmk.decrypt(self.dpapiSystem['UserKey']) 158 | if decryptedKey: 159 | print('Decrypted Backup key with UserKey') 160 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 161 | return 162 | decryptedKey = bkmk.decrypt(self.dpapiSystem['MachineKey']) 163 | if decryptedKey: 164 | print('Decrypted Backup key with MachineKey') 165 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 166 | return 167 | elif self.options.system and self.options.security: 168 | # Use SID + hash 169 | # We have hives, let's try to decrypt with them 170 | self.getLSA() 171 | key1, key2 = self.deriveKeysFromUserkey(self.options.sid, self.dpapiSystem['UserKey']) 172 | decryptedKey = mk.decrypt(key1) 173 | if decryptedKey: 174 | print('Decrypted key with UserKey + SID') 175 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 176 | return 177 | decryptedKey = bkmk.decrypt(key1) 178 | if decryptedKey: 179 | print('Decrypted Backup key with UserKey + SID') 180 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 181 | return 182 | decryptedKey = mk.decrypt(key2) 183 | if decryptedKey: 184 | print('Decrypted key with UserKey + SID') 185 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 186 | return 187 | decryptedKey = bkmk.decrypt(key2) 188 | if decryptedKey: 189 | print('Decrypted Backup key with UserKey + SID') 190 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 191 | return 192 | elif self.options.key and self.options.sid: 193 | key = unhexlify(self.options.key[2:]) 194 | key1, key2 = self.deriveKeysFromUserkey(self.options.sid, key) 195 | decryptedKey = mk.decrypt(key1) 196 | if decryptedKey: 197 | print('Decrypted key with key provided + SID') 198 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 199 | return 200 | decryptedKey = mk.decrypt(key2) 201 | if decryptedKey: 202 | print('Decrypted key with key provided + SID') 203 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 204 | return 205 | elif self.options.key: 206 | key = unhexlify(self.options.key[2:]) 207 | decryptedKey = mk.decrypt(key) 208 | if decryptedKey: 209 | print('Decrypted key with key provided') 210 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 211 | return 212 | 213 | elif self.options.pvk and dk: 214 | pvkfile = open(self.options.pvk, 'rb').read() 215 | key = PRIVATE_KEY_BLOB(pvkfile[len(PVK_FILE_HDR()):]) 216 | private = privatekeyblob_to_pkcs1(key) 217 | cipher = PKCS1_v1_5.new(private) 218 | 219 | decryptedKey = cipher.decrypt(dk['SecretData'][::-1], None) 220 | if decryptedKey: 221 | domain_master_key = DPAPI_DOMAIN_RSA_MASTER_KEY(decryptedKey) 222 | key = domain_master_key['buffer'][:domain_master_key['cbMasterKey']] 223 | print('Decrypted key with domain backup key provided') 224 | print('Decrypted key: 0x%s' % hexlify(key).decode('latin-1')) 225 | return 226 | 227 | elif self.options.sid and self.options.key is None: 228 | # Do we have a password? 229 | if self.options.password is None: 230 | # Nope let's ask it 231 | from getpass import getpass 232 | password = getpass("Password:") 233 | else: 234 | password = options.password 235 | key1, key2, key3 = self.deriveKeysFromUser(self.options.sid, password) 236 | 237 | # if mkf['flags'] & 4 ? SHA1 : MD4 238 | decryptedKey = mk.decrypt(key3) 239 | if decryptedKey: 240 | print('Decrypted key with User Key (MD4 protected)') 241 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 242 | return 243 | 244 | decryptedKey = mk.decrypt(key2) 245 | if decryptedKey: 246 | print('Decrypted key with User Key (MD4)') 247 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 248 | return 249 | 250 | decryptedKey = mk.decrypt(key1) 251 | if decryptedKey: 252 | print('Decrypted key with User Key (SHA1)') 253 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 254 | return 255 | 256 | decryptedKey = bkmk.decrypt(key3) 257 | if decryptedKey: 258 | print('Decrypted Backup key with User Key (MD4 protected)') 259 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 260 | return 261 | 262 | decryptedKey = bkmk.decrypt(key2) 263 | if decryptedKey: 264 | print('Decrypted Backup key with User Key (MD4)') 265 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 266 | return 267 | 268 | decryptedKey = bkmk.decrypt(key1) 269 | if decryptedKey: 270 | print('Decrypted Backup key with User Key (SHA1)') 271 | print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1')) 272 | return 273 | 274 | elif self.options.target is not None: 275 | domain, username, password, remoteName = parse_target(self.options.target) 276 | 277 | if domain is None: 278 | domain = '' 279 | 280 | if password == '' and username != '' and self.options.hashes is None and self.options.no_pass is False and self.options.aesKey is None: 281 | from getpass import getpass 282 | password = getpass("Password:") 283 | 284 | if self.options.hashes is not None: 285 | lmhash, nthash = self.options.hashes.split(':') 286 | else: 287 | lmhash, nthash = '','' 288 | 289 | rpctransport = transport.DCERPCTransportFactory(r'ncacn_np:%s[\PIPE\protected_storage]' % remoteName) 290 | 291 | if hasattr(rpctransport, 'set_credentials'): 292 | # This method exists only for selected protocol sequences. 293 | rpctransport.set_credentials(username, password, domain, lmhash, nthash, self.options.aesKey) 294 | 295 | rpctransport.set_kerberos(self.options.k, self.options.dc_ip) 296 | 297 | dce = rpctransport.get_dce_rpc() 298 | dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 299 | if self.options.k is True: 300 | dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) 301 | dce.connect() 302 | dce.bind(bkrp.MSRPC_UUID_BKRP, transfer_syntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')) 303 | 304 | request = bkrp.BackuprKey() 305 | request['pguidActionAgent'] = bkrp.BACKUPKEY_RESTORE_GUID 306 | request['pDataIn'] = dk.getData() 307 | request['cbDataIn'] = len(dk.getData()) 308 | request['dwParam'] = 0 309 | 310 | resp = dce.request(request) 311 | 312 | ## Stripping heading zeros resulting from asymetric decryption 313 | beginning=0 314 | for i in range(len(resp['ppDataOut'])): 315 | if resp['ppDataOut'][i]==b'\x00': 316 | beginning+=1 317 | else: 318 | break 319 | masterkey=b''.join(resp['ppDataOut'][beginning:]) 320 | print('Decrypted key using rpc call') 321 | print('Decrypted key: 0x%s' % hexlify(masterkey[beginning:]).decode()) 322 | return 323 | 324 | else: 325 | # Just print key's data 326 | if mkf['MasterKeyLen'] > 0: 327 | mk.dump() 328 | 329 | if mkf['BackupKeyLen'] > 0: 330 | bkmk.dump() 331 | 332 | if mkf['CredHistLen'] > 0: 333 | ch.dump() 334 | 335 | if mkf['DomainKeyLen'] > 0: 336 | dk.dump() 337 | 338 | # credit to @gentilkiwi 339 | elif self.options.action.upper() == 'BACKUPKEYS': 340 | domain, username, password, address = parse_target(self.options.target) 341 | 342 | if password == '' and username != '' and self.options.hashes is None and self.options.no_pass is False and self.options.aesKey is None: 343 | from getpass import getpass 344 | password = getpass ("Password:") 345 | if self.options.hashes is not None: 346 | lmhash, nthash = self.options.hashes.split(':') 347 | else: 348 | lmhash, nthash = '','' 349 | connection = SMBConnection(address, address) 350 | if self.options.k: 351 | connection.kerberosLogin(username, password, domain, lmhash, nthash, self.options.aesKey) 352 | else: 353 | connection.login(username, password, domain, lmhash=lmhash, nthash=nthash) 354 | 355 | rpctransport = transport.DCERPCTransportFactory(r'ncacn_np:445[\pipe\lsarpc]') 356 | rpctransport.set_smb_connection(connection) 357 | dce = rpctransport.get_dce_rpc() 358 | if self.options.k: 359 | dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) 360 | try: 361 | dce.connect() 362 | dce.bind(lsad.MSRPC_UUID_LSAD) 363 | except transport.DCERPCException as e: 364 | raise e 365 | 366 | resp = lsad.hLsarOpenPolicy2(dce, lsad.POLICY_GET_PRIVATE_INFORMATION) 367 | for keyname in ("G$BCKUPKEY_PREFERRED", "G$BCKUPKEY_P"): 368 | buffer = crypto.decryptSecret(connection.getSessionKey(), lsad.hLsarRetrievePrivateData(dce, 369 | resp['PolicyHandle'], keyname)) 370 | guid = bin_to_string(buffer) 371 | name = "G$BCKUPKEY_{}".format(guid) 372 | secret = crypto.decryptSecret(connection.getSessionKey(), lsad.hLsarRetrievePrivateData(dce, 373 | resp['PolicyHandle'], name)) 374 | keyVersion = struct.unpack(' 28: 447 | attribute = blob.attributes[i] 448 | if 'IV' in attribute.fields and len(attribute['IV']) == 16: 449 | cipher = AES.new(key, AES.MODE_CBC, iv=attribute['IV']) 450 | else: 451 | cipher = AES.new(key, AES.MODE_CBC) 452 | cleartext = cipher.decrypt(attribute['Data']) 453 | 454 | if cleartext is not None: 455 | # Lookup schema Friendly Name and print if we find one 456 | if blob['FriendlyName'].decode('utf-16le')[:-1] in VAULT_KNOWN_SCHEMAS: 457 | # Found one. Cast it and print 458 | vault = VAULT_KNOWN_SCHEMAS[blob['FriendlyName'].decode('utf-16le')[:-1]](cleartext) 459 | vault.dump() 460 | else: 461 | # otherwise 462 | hexdump(cleartext) 463 | return 464 | else: 465 | blob.dump() 466 | 467 | elif options.vpol is not None: 468 | fp = open(options.vpol, 'rb') 469 | data = fp.read() 470 | vpol = VAULT_VPOL(data) 471 | vpol.dump() 472 | 473 | if self.options.key is not None: 474 | key = unhexlify(self.options.key[2:]) 475 | blob = vpol['Blob'] 476 | data = blob.decrypt(key) 477 | if data is not None: 478 | keys = VAULT_VPOL_KEYS(data) 479 | keys.dump() 480 | return 481 | elif self.options.action.upper() == 'UNPROTECT': 482 | fp = open(options.file, 'rb') 483 | data = fp.read() 484 | blob = DPAPI_BLOB(data) 485 | 486 | if self.options.key is not None: 487 | key = unhexlify(self.options.key[2:]) 488 | if self.options.entropy_file is not None: 489 | fp2 = open(self.options.entropy_file, 'rb') 490 | entropy = fp2.read() 491 | fp2.close() 492 | elif self.options.entropy is not None: 493 | entropy = b(self.options.entropy) + b'\x00' 494 | else: 495 | entropy = None 496 | 497 | decrypted = blob.decrypt(key, entropy) 498 | if decrypted is not None: 499 | print('Successfully decrypted data') 500 | hexdump(decrypted) 501 | return 502 | else: 503 | # Just print the data 504 | blob.dump() 505 | 506 | print('Cannot decrypt (specify -key or -sid whenever applicable) ') 507 | 508 | 509 | if __name__ == '__main__': 510 | # Init the example's logger theme 511 | logger.init() 512 | print(version.BANNER) 513 | 514 | parser = argparse.ArgumentParser(add_help=True, description="Example for using the DPAPI/Vault structures to unlock Windows Secrets.") 515 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 516 | subparsers = parser.add_subparsers(help='actions', dest='action') 517 | 518 | # A domain backup key command 519 | backupkeys = subparsers.add_parser('backupkeys', help='domain backup key related functions') 520 | backupkeys.add_argument('-t', '--target', action='store', required=True, help='[[domain/]username[:password]@]') 521 | backupkeys.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 522 | backupkeys.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 523 | backupkeys.add_argument('-k', action="store_true", required=False, help='Use Kerberos authentication. Grabs credentials from ccache file ' 524 | '(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ' 525 | 'ones specified in the command line') 526 | backupkeys.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 527 | '(128 or 256 bits)') 528 | backupkeys.add_argument('-dc-ip', action='store',metavar = "ip address", help='IP Address of the domain controller. ' 529 | 'If omitted it will use the domain part (FQDN) specified in the target parameter') 530 | backupkeys.add_argument('--export', action='store_true', required=False, help='export keys to file') 531 | 532 | # A masterkey command 533 | masterkey = subparsers.add_parser('masterkey', help='masterkey related functions') 534 | masterkey.add_argument('-file', action='store', required=True, help='Master Key File to parse') 535 | masterkey.add_argument('-sid', action='store', help='SID of the user') 536 | masterkey.add_argument('-pvk', action='store', help='Domain backup privatekey to use for decryption') 537 | masterkey.add_argument('-key', action='store', help='Specific key to use for decryption') 538 | masterkey.add_argument('-password', action='store', help='User\'s password. If you specified the SID and not the password it will be prompted') 539 | masterkey.add_argument('-system', action='store', help='SYSTEM hive to parse') 540 | masterkey.add_argument('-security', action='store', help='SECURITY hive to parse') 541 | masterkey.add_argument('-t', '--target', action='store', help='The masterkey owner\'s credentails to ask the DC for decryption' 542 | 'Format: [[domain/]username[:password]@]') 543 | masterkey.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 544 | masterkey.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 545 | masterkey.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' 546 | '(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ' 547 | 'ones specified in the command line') 548 | masterkey.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 549 | '(128 or 256 bits)') 550 | masterkey.add_argument('-dc-ip', action='store',metavar = "ip address", help='IP Address of the domain controller. ' 551 | 'If omitted it will use the domain part (FQDN) specified in the target parameter') 552 | 553 | # A credential command 554 | credential = subparsers.add_parser('credential', help='credential related functions') 555 | credential.add_argument('-file', action='store', required=True, help='Credential file') 556 | credential.add_argument('-key', action='store', required=False, help='Key used for decryption') 557 | 558 | # A vault command 559 | vault = subparsers.add_parser('vault', help='vault credential related functions') 560 | vault.add_argument('-vcrd', action='store', required=False, help='Vault Credential file') 561 | vault.add_argument('-vpol', action='store', required=False, help='Vault Policy file') 562 | vault.add_argument('-key', action='store', required=False, help='Master key used for decryption') 563 | 564 | # A CryptUnprotectData command 565 | unprotect = subparsers.add_parser('unprotect', help='Provides CryptUnprotectData functionality') 566 | unprotect.add_argument('-file', action='store', required=True, help='File with DATA_BLOB to decrypt') 567 | unprotect.add_argument('-key', action='store', required=False, help='Key used for decryption') 568 | unprotect.add_argument('-entropy', action='store', default=None, required=False, help='String with extra entropy needed for decryption') 569 | unprotect.add_argument('-entropy-file', action='store', default=None, required=False, help='File with binary entropy contents (overwrites -entropy)') 570 | 571 | options = parser.parse_args() 572 | 573 | if len(sys.argv)==1: 574 | parser.print_help() 575 | sys.exit(1) 576 | 577 | if options.debug is True: 578 | logging.getLogger().setLevel(logging.DEBUG) 579 | # Print the Library's installation path 580 | logging.debug(version.getInstallationPath()) 581 | else: 582 | logging.getLogger().setLevel(logging.INFO) 583 | 584 | 585 | try: 586 | executer = DPAPI(options) 587 | executer.run() 588 | except Exception as e: 589 | if logging.getLogger().level == logging.DEBUG: 590 | import traceback 591 | traceback.print_exc() 592 | print('ERROR: %s' % str(e)) 593 | -------------------------------------------------------------------------------- /Crypto/Mixed/README.md: -------------------------------------------------------------------------------- 1 | # Mixed - 100 points 2 | Le texte est encodé en utilisant différentes bases: 3 | - du binaire qu'on va détecter grâce à sa longueur, 6 ou 7 bits. 4 | - de l'hexadécimal, qui commence toujours par '0x'. 5 | - de l'octal, qui commence toujouts par '0'. 6 | - du décimale, tout le reste. 7 | 8 | ``` 9 | enc = "0127 0x65 0x6c 99 1101111 0x6d 0x65 32 116 0157 100000 1110100 0150 0x65 32 0x48 1100001 1100011 1101011 1010011 0x65 1100011 1110101 1010010 0145 105 0155 115 040 0x32 0x30 0x32 0x32 101110 100000 0x54 0x68 0x65 32 85 0122 0x43 65 0x20 1000011 1010100 0106 32 105 115 0x20 0x74 0x68 0x65 0x20 98 105 103 103 0x65 115 0x74 0x20 0150 0141 0x63 107 0145 0x72 100000 0143 0157 110 1110100 0145 1110011 1110100 32 1101001 0156 0x20 0x47 0162 0141 0x6e 0x64 101101 0105 0x73 1110100 100000 0x69 1101110 040 0106 0162 1100001 0156 0x63 0x65 0x2e 040 0x4f 1001111 1101111 0x6f 1101111 0157 1101111 112 115 0x2c 100000 0171 0x6f 0165 100000 0167 1100001 0156 116 0x20 0x74 0x6f 040 0153 0156 0157 119 32 1110100 0150 0x65 100000 0x66 0x6c 0141 103 054 100000 0144 0x6f 0156 047 0x74 32 1111001 0x6f 1110101 0x20 077 0x20 72 0145 1110010 1100101 040 121 0157 117 0x20 0x61 0162 0x65 46 0110 0x53 0x52 123 0111 0x5f 0x68 110000 0160 51 95 0171 110000 1110101 0x5f 1100100 0151 0144 1011111 1101110 060 116 95 0164 82 121 0x5f 0x74 0x30 0137 1100100 110011 99 1010010 1111001 1110000 0x74 0137 1101111 0156 51 0x5f 0142 89 0x5f 1101111 110 0x33 1011111 110100 0x67 52 0x31 0x6e 1011111 66 51 99 110100 0x75 0123 110011 0137 0x31 1110100 1110011 95 0x76 0x33 0x72 0x79 0137 0126 51 0162 0x59 0x5f 0x4c 110000 1101110 0x67 0x7d 100000 0110 0x61 1110110 1100101 100000 0x66 0165 1101110 33 100001 041 0x20 78 1101111 119 0x20 0x69 116 047 1110011 0x20 0x6a 117 1110011 1110100 040 0x70 0141 100 100 0x69 110 0x67 0x20 101110 056 101110 056 101110 040 0x3b 0x2d 051 040 0102 1100101 99 97 0165 0163 1100101 100000 1101110 0x65 0166 0x65 0x72 100000 1110000 117 116 100000 0164 0150 0x65 100000 102 1101100 97 103 040 0141 1110100 0x20 116 1101000 101 32 1100101 110 100 32 0157 102 32 0x61 32 115 0x65 1101110 0x74 101 1101110 0x63 0x65 0x20 056 0x21 077" 10 | msg = "" 11 | for char in enc.split(" "): 12 | # bin 13 | if len(char) == 7 or len(char) == 6: 14 | msg += chr(int("0b"+char,2)) 15 | continue 16 | # hexa 17 | if char[:2] == '0x': 18 | msg += chr(int(char,16)) 19 | continue 20 | # octal 21 | if char[0] == '0': 22 | msg += chr(int(char,8)) 23 | continue 24 | # decimale 25 | msg += chr(int(char,10)) 26 | print(msg) 27 | 28 | ``` 29 | 30 | Ce qui donne le message suivant : "Welcome to the HackSecuReims 2022. The URCA CTF is the biggest hacker contest in Grand-Est in France. OOooooops, you want to know the flag, don't you ? Here you are.HSR{I_h0p3_y0u_did_n0t_tRy_t0_d3cRypt_on3_bY_on3_4g41n_B3c4uS3_1ts_v3ry_V3rY_L0ng} Have fun!!! Now it's just padding ..... ;-) Because never put the flag at the end of a sentence .!?" 31 | -------------------------------------------------------------------------------- /Crypto/Mixed/enc: -------------------------------------------------------------------------------- 1 | 0127 0x65 0x6c 99 1101111 0x6d 0x65 32 116 0157 100000 1110100 0150 0x65 32 0x48 1100001 1100011 1101011 1010011 0x65 1100011 1110101 1010010 0145 105 0155 115 040 0x32 0x30 0x32 0x32 101110 100000 0x54 0x68 0x65 32 85 0122 0x43 65 0x20 1000011 1010100 0106 32 105 115 0x20 0x74 0x68 0x65 0x20 98 105 103 103 0x65 115 0x74 0x20 0150 0141 0x63 107 0145 0x72 100000 0143 0157 110 1110100 0145 1110011 1110100 32 1101001 0156 0x20 0x47 0162 0141 0x6e 0x64 101101 0105 0x73 1110100 100000 0x69 1101110 040 0106 0162 1100001 0156 0x63 0x65 0x2e 040 0x4f 1001111 1101111 0x6f 1101111 0157 1101111 112 115 0x2c 100000 0171 0x6f 0165 100000 0167 1100001 0156 116 0x20 0x74 0x6f 040 0153 0156 0157 119 32 1110100 0150 0x65 100000 0x66 0x6c 0141 103 054 100000 0144 0x6f 0156 047 0x74 32 1111001 0x6f 1110101 0x20 077 0x20 72 0145 1110010 1100101 040 121 0157 117 0x20 0x61 0162 0x65 46 0110 0x53 0x52 123 0111 0x5f 0x68 110000 0160 51 95 0171 110000 1110101 0x5f 1100100 0151 0144 1011111 1101110 060 116 95 0164 82 121 0x5f 0x74 0x30 0137 1100100 110011 99 1010010 1111001 1110000 0x74 0137 1101111 0156 51 0x5f 0142 89 0x5f 1101111 110 0x33 1011111 110100 0x67 52 0x31 0x6e 1011111 66 51 99 110100 0x75 0123 110011 0137 0x31 1110100 1110011 95 0x76 0x33 0x72 0x79 0137 0126 51 0162 0x59 0x5f 0x4c 110000 1101110 0x67 0x7d 100000 0110 0x61 1110110 1100101 100000 0x66 0165 1101110 33 100001 041 0x20 78 1101111 119 0x20 0x69 116 047 1110011 0x20 0x6a 117 1110011 1110100 040 0x70 0141 100 100 0x69 110 0x67 0x20 101110 056 101110 056 101110 040 0x3b 0x2d 051 040 0102 1100101 99 97 0165 0163 1100101 100000 1101110 0x65 0166 0x65 0x72 100000 1110000 117 116 100000 0164 0150 0x65 100000 102 1101100 97 103 040 0141 1110100 0x20 116 1101000 101 32 1100101 110 100 32 0157 102 32 0x61 32 115 0x65 1101110 0x74 101 1101110 0x63 0x65 0x20 056 0x21 077 2 | -------------------------------------------------------------------------------- /Crypto/Mixed/solver.py: -------------------------------------------------------------------------------- 1 | #! /bin/python3 2 | enc = "0127 0x65 0x6c 99 1101111 0x6d 0x65 32 116 0157 100000 1110100 0150 0x65 32 0x48 1100001 1100011 1101011 1010011 0x65 1100011 1110101 1010010 0145 105 0155 115 040 0x32 0x30 0x32 0x32 101110 100000 0x54 0x68 0x65 32 85 0122 0x43 65 0x20 1000011 1010100 0106 32 105 115 0x20 0x74 0x68 0x65 0x20 98 105 103 103 0x65 115 0x74 0x20 0150 0141 0x63 107 0145 0x72 100000 0143 0157 110 1110100 0145 1110011 1110100 32 1101001 0156 0x20 0x47 0162 0141 0x6e 0x64 101101 0105 0x73 1110100 100000 0x69 1101110 040 0106 0162 1100001 0156 0x63 0x65 0x2e 040 0x4f 1001111 1101111 0x6f 1101111 0157 1101111 112 115 0x2c 100000 0171 0x6f 0165 100000 0167 1100001 0156 116 0x20 0x74 0x6f 040 0153 0156 0157 119 32 1110100 0150 0x65 100000 0x66 0x6c 0141 103 054 100000 0144 0x6f 0156 047 0x74 32 1111001 0x6f 1110101 0x20 077 0x20 72 0145 1110010 1100101 040 121 0157 117 0x20 0x61 0162 0x65 46 0110 0x53 0x52 123 0111 0x5f 0x68 110000 0160 51 95 0171 110000 1110101 0x5f 1100100 0151 0144 1011111 1101110 060 116 95 0164 82 121 0x5f 0x74 0x30 0137 1100100 110011 99 1010010 1111001 1110000 0x74 0137 1101111 0156 51 0x5f 0142 89 0x5f 1101111 110 0x33 1011111 110100 0x67 52 0x31 0x6e 1011111 66 51 99 110100 0x75 0123 110011 0137 0x31 1110100 1110011 95 0x76 0x33 0x72 0x79 0137 0126 51 0162 0x59 0x5f 0x4c 110000 1101110 0x67 0x7d 100000 0110 0x61 1110110 1100101 100000 0x66 0165 1101110 33 100001 041 0x20 78 1101111 119 0x20 0x69 116 047 1110011 0x20 0x6a 117 1110011 1110100 040 0x70 0141 100 100 0x69 110 0x67 0x20 101110 056 101110 056 101110 040 0x3b 0x2d 051 040 0102 1100101 99 97 0165 0163 1100101 100000 1101110 0x65 0166 0x65 0x72 100000 1110000 117 116 100000 0164 0150 0x65 100000 102 1101100 97 103 040 0141 1110100 0x20 116 1101000 101 32 1100101 110 100 32 0157 102 32 0x61 32 115 0x65 1101110 0x74 101 1101110 0x63 0x65 0x20 056 0x21 077" 3 | msg = "" 4 | for char in enc.split(" "): 5 | # bin 6 | if len(char) == 7 or len(char) == 6: 7 | msg += chr(int("0b"+char,2)) 8 | continue 9 | # hexa 10 | if char[:2] == '0x': 11 | msg += chr(int(char,16)) 12 | continue 13 | # octal 14 | if char[0] == '0': 15 | msg += chr(int(char,8)) 16 | continue 17 | # decimale 18 | msg += chr(int(char,10)) 19 | print(msg) 20 | -------------------------------------------------------------------------------- /Crypto/Review_the_basics/README.md: -------------------------------------------------------------------------------- 1 | # Review the basics - 150 points 2 | 3 | La structure du message ressemble à deux colonnes de hash suivi d'un caractère. Si l'on prête attention, on remarque que certains hashs se répètent dans les colonnes, ce qui nous donne un indice sur la taille potentielle du message d'origine de chacun de ces hashs (quelques lettres tout au plus). De plus les lignes qui font des répétitions sur la colonne de gauche se trouvent au même endroit sur la colonne de droite, ce qui indique que les messages des deux colonnes sont très probablement le même. 4 | 5 | Il faut essayer de trouver le format des hashs, pour cela j'ai utilisé l'utilitaire hash-identifier présent par défaut sous Kali : 6 | 7 | ``` 8 | hash-identifier 0e11e37cc1f49780e021a014634b7164 9 | 10 | ######################################################################### 11 | # __ __ __ ______ _____ # 12 | # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # 13 | # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # 14 | # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # 15 | # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # 16 | # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # 17 | # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # 18 | # By Zion3R # 19 | # www.Blackploit.com # 20 | # Root@Blackploit.com # 21 | ######################################################################### 22 | -------------------------------------------------- 23 | 24 | Possible Hashs: 25 | [+] MD5 26 | [+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username))) 27 | 28 | Least Possible Hashs: 29 | [+] RAdmin v2.x 30 | [+] NTLM 31 | [+] MD4 32 | [+] MD2 33 | [+] MD5(HMAC) 34 | [+] MD4(HMAC) 35 | [+] MD2(HMAC) 36 | [+] MD5(HMAC(Wordpress)) 37 | [+] Haval-128 38 | [+] Haval-128(HMAC) 39 | [+] RipeMD-128 40 | [+] RipeMD-128(HMAC) 41 | [+] SNEFRU-128 42 | [+] SNEFRU-128(HMAC) 43 | [+] Tiger-128 44 | [+] Tiger-128(HMAC) 45 | [+] md5($pass.$salt) 46 | [+] md5($salt.$pass) 47 | [+] md5($salt.$pass.$salt) 48 | [+] md5($salt.$pass.$username) 49 | [+] md5($salt.md5($pass)) 50 | [+] md5($salt.md5($pass)) 51 | [+] md5($salt.md5($pass.$salt)) 52 | [+] md5($salt.md5($pass.$salt)) 53 | [+] md5($salt.md5($salt.$pass)) 54 | [+] md5($salt.md5(md5($pass).$salt)) 55 | [+] md5($username.0.$pass) 56 | [+] md5($username.LF.$pass) 57 | [+] md5($username.md5($pass).$salt) 58 | [+] md5(md5($pass)) 59 | [+] md5(md5($pass).$salt) 60 | [+] md5(md5($pass).md5($salt)) 61 | [+] md5(md5($salt).$pass) 62 | [+] md5(md5($salt).md5($pass)) 63 | [+] md5(md5($username.$pass).$salt) 64 | [+] md5(md5(md5($pass))) 65 | [+] md5(md5(md5(md5($pass)))) 66 | [+] md5(md5(md5(md5(md5($pass))))) 67 | [+] md5(sha1($pass)) 68 | [+] md5(sha1(md5($pass))) 69 | [+] md5(sha1(md5(sha1($pass)))) 70 | [+] md5(strtoupper(md5($pass))) 71 | -------------------------------------------------- 72 | ``` 73 | 74 | Il faut isoler les hashs dans un fichier pour essayer de les brut-force avec hashcat en mode incrémental en essayant les formats les plus courants : 75 | 76 | ```bash 77 | # md5 78 | hashcat -m 0 -a 3 -i -o output.txt hash.txt ?a?a?a?a?a?a?a 79 | # ntlm 80 | hashcat -m 1000 -a 3 -i -o output.txt hash.txt ?a?a?a?a?a?a?a 81 | ``` 82 | 83 | Les hashs de la colonne de droite sont des md5 et la colonne de gauche sont des ntlm et correspondent chacun à une seule lettre. 84 | 85 | Il faut maintenant remplacer les hash par la lettre auquel ils correspondent : 86 | 87 | ``` 88 | H|HS// 89 | S|SF// 90 | R|RN// 91 | {|{S// 92 | Y|Ye// 93 | o|o0// 94 | u|ul// 95 | _|_f// 96 | m|mb// 97 | u|uD// 98 | s|sB// 99 | t|t2// 100 | _|_M// 101 | t|t1// 102 | r|r9// 103 | y|yX// 104 | _|_a// 105 | 6|6W// 106 | 4|45// 107 | t|tk// 108 | i|iM// 109 | m|mH// 110 | e|ed// 111 | s|sT// 112 | _|_X// 113 | h|hz// 114 | a|aE// 115 | r|rx// 116 | d|dO// 117 | e|ei// 118 | r|rl// 119 | }|}9// 120 | ``` 121 | 122 | On lit dans les colonnes : "HSR{You_must_try_64times_harder}", ce qui n'est pas le flag. 123 | 124 | Pour trouver le flag il faut maintenant lire la colonne de caractère supplémentaire : "SFNSe0lfbDB2M19XaW5kMHdTXzExOil9" puis le décoder comme une base64 : 125 | 126 | ``` 127 | echo "SFNSe0lfbDB2M19XaW5kMHdTXzExOil9" | base64 -d 128 | ``` 129 | 130 | Ce qui donne le flag : "HSR{I_l0v3_Wind0wS_11:)} 131 | -------------------------------------------------------------------------------- /Crypto/Review_the_basics/just_a_basic_case.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | *********** 4 | ***** *********** 5 | ** ****** *** ******** 6 | **** ****** ** ******* 7 | *** ******* ** ****** 8 | *** ** * ** 9 | *|/------ -------\ ** * 10 | | |=| :===** 11 | | O | | O | }|* 12 | |---- | ---- | |* 13 | | |___ |\/ 14 | | | |----------------------------| 15 | \ ----- | /| I love Windows so much <3 | 16 | \ \___/ |----/ |----------------------------| 17 | \ | 18 | -__ -- -/ 19 | 20 | 21 | //////////////////////////////////////////////////////////////////// 22 | 0e11e37cc1f49780e021a014634b7164|c1d9f50f86825a1a2302ec2449c17196S// 23 | a2bc7ff665d2dd44f08defe1d2007ee9|5dbc98dcc983a70728bd082d1a47546eF// 24 | b1f59cad4492784e2c9ab98a6647aa7e|e1e1d3d40573127e9ee0480caf1283d6N// 25 | 6649b8967545e5e86ec5a980184e2f73|f95b70fdc3088560732a5ac135644506S// 26 | e1d968098ac90ca0036a4957645ab03f|57cec4137b614c87cb4e24a3d003a3e0e// 27 | 76a94015de14cae3f7220d7ea619988e|d95679752134a2d9eb61dbd7b91c4bcc0// 28 | ebd448894839c684c19a7fe7d55f0d45|7b774effe4a349c6dd82ad4f4f21d34cl// 29 | 6c259f1003faad896ead94418585c9e1|b14a7b8059d9c055954c92674ce60032f// 30 | 7e864d8195b263b4d6aee4e041c0193f|6f8f57715090da2632453988d9a1501bb// 31 | ebd448894839c684c19a7fe7d55f0d45|7b774effe4a349c6dd82ad4f4f21d34cD// 32 | c3f541baf5c46e5169e95691975d12bc|03c7c0ace395d80182db07ae2c30f034B// 33 | 6237795e56d95c5bc0b6f7405b31edf9|e358efa489f58062f10dd7316b65649e2// 34 | 6c259f1003faad896ead94418585c9e1|b14a7b8059d9c055954c92674ce60032M// 35 | 6237795e56d95c5bc0b6f7405b31edf9|e358efa489f58062f10dd7316b65649e1// 36 | edb9b445c52137dce3abb04c0e7493e4|4b43b0aee35624cd95b910189b3dc2319// 37 | ------------------------------------------------------------------// 38 | 53c1bf6deaede22fa6110ff189023576|415290769594460e2e485922904f345dX// 39 | 6c259f1003faad896ead94418585c9e1|b14a7b8059d9c055954c92674ce60032a// 40 | c7c0f6f33f4e34bc0b595fc942cb6d03|1679091c5a880faf6fb5e6087eb1b2dcW// 41 | e30f7b55215aa69b2920e3715e0392a0|a87ff679a2f3e71d9181a67b7542122c5// 42 | 6237795e56d95c5bc0b6f7405b31edf9|e358efa489f58062f10dd7316b65649ek// 43 | f9e76a20a4ad2e31e26f0f2f3926bd48|865c0c0b4ab0e063e5caa3387c1a8741M// 44 | 7e864d8195b263b4d6aee4e041c0193f|6f8f57715090da2632453988d9a1501bH// 45 | 4992a157b9ecc2a7d2066feff64967d3|e1671797c52e15f763380b45e841ec32d// 46 | c3f541baf5c46e5169e95691975d12bc|03c7c0ace395d80182db07ae2c30f034T// 47 | 6c259f1003faad896ead94418585c9e1|b14a7b8059d9c055954c92674ce60032X// 48 | 0a9195a4bf04d808d098cf44a165186e|2510c39011c5be704182423e3a695e91z// 49 | 186cb09181e2c2ecaac768c47c729904|0cc175b9c0f1b6a831c399e269772661E// 50 | edb9b445c52137dce3abb04c0e7493e4|4b43b0aee35624cd95b910189b3dc231x// 51 | 9b75cf9a3fcc498e03eeda4387bb5277|8277e0910d750195b448797616e091adO// 52 | 4992a157b9ecc2a7d2066feff64967d3|e1671797c52e15f763380b45e841ec32i// 53 | edb9b445c52137dce3abb04c0e7493e4|4b43b0aee35624cd95b910189b3dc231l// 54 | 0165b3d4bcc42e2883323b72aeae32e2|cbb184dd8e05c9709e5dcaedaa0495cf9// 55 | -------------------------------------------------------------------------------- /Crypto/ZipZip/FAN-DE-JAMES-BOND.txt: -------------------------------------------------------------------------------- 1 | “Mr Bond, vous avez la fâcheuse habitude de survivre” 2 | “Mlle Anders, je ne vous avais pas reconnue toute habillée” 3 | “Ma chère petite, il y a des choses qui ne se font pas. Tel que de boire du Dom Perignon 55 à une température au dessus de 3 degrés... C'est aussi malsain que d'écouter les Beatles sans boules Quies ! ” 4 | “Mr Bond, je pense que vous êtes un dinosaure sexiste et misogyne, une relique de la Guerre Froide” 5 | “J'aime une femme en Bikini. Elle ne dissimule pas d'arme” 6 | “J'en ai vu qui avaient la tête comme une montgolfière, mais comme vous jamais” 7 | “Je ne donne pas dans la rouquine. De sales caractères... Mais cependant, ça vous va bien.” 8 | "Prenez l’ascenseur suivant, il n’y a pas assez de place pour moi et votre égo." 9 | "Maintenant, le monde entier saura que c’est en me grattant les couilles que vous êtes mort." 10 | "- Vodka-Martini. 11 | - Au shaker ou à la cuillère ? 12 | - Qu’est ce que j’en ai à foutre !" 13 | "- Oh, détails de dernière minute… apparemment nous sommes très amoureux… 14 | - Et vous laissez souvent les portiers vous informer de ces choses la ? 15 | - Seulement quand l’histoire d’amour vient à peine de commencer. Je suis monsieur Harlington Beach, parieur professionnel, et vous, vous êtes miss Stéphanie gros seins et… 16 | - Mais c’est pas vrai !! 17 | - Hep, va falloir me faire confiance… 18 | - Alors là, pas question. 19 | - Nous somme mariés… nous partageons donc une suite. 20 | - Et ma famille est strictement catholique alors pour les apparences nous aurons une suite avec chambre séparée. 21 | - J’ai horreur que la religion s’interpose à ce point ! 22 | - La religion et une porte fermée a double-tour, dois-je m’attendre à un problème avec vous ? 23 | - Non, aucun risque, vous n’êtes pas mon type… 24 | - Perspicace ? 25 | - Célibataire." 26 | "… Bond. James Bond." 27 | "Je ne peux pas demander à un bulldozer de comprendre ça, l’arrogance et l’introspection font rarement bon ménage." 28 | "Veuillez m’excuser. Cette dernière manche a failli me tuer !" 29 | "Vous avez oublié la règle d’or qui gouverne le monde des médias : donner aux masses ce qu’elles demandent !" 30 | "Je crois que les morts se moquent d’être vengés." 31 | "- Je suis Mister Kil. 32 | - Il y a des noms de famille qui tuent !" 33 | "- Écoute James, je voulais que tu saches que même s’il ne restait de toi que ton sourire, ou que ton petit doigt, tu resterais pour moi le seul homme digne de ce nom. 34 | - Ça c’est parce-que tu ne sais pas comment je peux me servir de mon petit doigt mmmhh ?" 35 | "- Voyez ce qu’elle vous a fait. 36 | - Au moins, elle ne m’a jamais attaché à une chaise." 37 | "- J’ai toujours essayé de vous enseigner deux choses : la première, ne jamais laisser voir que vous êtes blessé. 38 | - Et la seconde ? 39 | - Toujours avoir un plan d’évasion." 40 | "- Qui t’envoie ? 41 | - Ta maman. Elle m’a dit de te dire que tu l’avais beaucoup déçue !" 42 | "- Combien de temps me reste-t-il ? 43 | - 30 secondes. 44 | - Alors il va falloir faire vite." 45 | "- Vous faut-il une assurance collision ? 46 | - Oui. 47 | - Incendie ? 48 | - Probablement. 49 | - Pour dommage causé à tiers ? 50 | - Oui, tout à fait. 51 | - Préjudice corporel ? 52 | - Que Dieu m’en garde, mais un accident ça peut arriver. 53 | - À vous, plus souvent qu’à votre tour. 54 | - Bon. Cela concerne la sécurité du véhicule. Aurai-je besoin d’autres protections ? 55 | - Seulement contre moi, 007, si vous ne me ramenez pas cette voiture en parfait état !" 56 | "Je crains fort que votre ami Mathis ne soit… Mon ami Mathis." 57 | "- Où étiez vous encore fourré ?! 58 | - Je profitais de la mort… 007 au rapport madame." 59 | "- On m’avait dit que vous aviez été assassiné à Hong-Kong. 60 | - Oui, c’est ma seconde vie. 61 | - On ne vit que deux fois, monsieur Bond." 62 | "Un jour un informaticien m'a dit : pour capturer le drapeau de ce challenge il suffira de saisir 'L3_gr4s_c_3st_la_v1e' 63 | "- Vous ne m’aimez pas Bond, vous détestez mes méthodes. Vous me prenez pour un brouillon, une petite guichetière plus intéressée par ses bilans que par votre flair… 64 | - L’idée m’est venue à l’esprit. 65 | - Bon, moi je vous trouve sexiste, misogyne et dinosaure. Une relique de la guerre froide dont le côté puéril et charmeur sans effet sur moi a beaucoup plu à assez de jeunes femmes que j’ai chargées de vous évaluer. 66 | - Bien enregistré. 67 | - Ce n’est pas tout 007. Si vous pensez même brièvement que je n’ai pas les couilles de faire mourir un agent, votre flair vous trompe du tout au tout. Je n’ai pas de scrupule s’il faut vous envoyer à la mort. Mais je n’agis pas par caprice, même quand je vois votre attitude cavalière envers la vie. Je veux que vous retrouviez GoldenEye, trouvez qui l’a volé, ce qu’il projette d’en faire et stoppez tout. Et s’il vous arrive de croiser Ourumov, coupable ou pas, je ne veux surtout pas que vous vous livriez à une vendetta ! Ce n’est pas ce qui fera revenir Alec Treveya ! 68 | - Vous n’êtes pour rien dans sa mort. 69 | - Mais vous non plus d’ailleurs, soit dit sans vous vexer. 70 | - Jamais… 71 | - Bond… Revenez vivant…" 72 | "- Vous êtes sûr de vouloir faire ça ? Le dernier qui lui a rendu visite sans être invité est reparti chez lui en avion-cargo, dans plein de p’tites boîtes. 73 | - Veillez à ce qu’on me rapatrie en première classe…" 74 | "L’ONU ne m’apprécie pas. Je suis passé par Oxford et Harvard. J’ai un doctorat en hypocrisie occidentale." 75 | "Walter PPK… 7.65mm… trois hommes seulement utilisent cette arme, et je crois bien en avoir tué deux !" 76 | "S’il-vous-plaît, ouvrez ! Merci, inspection du travail." 77 | "- Et Pussy ? 78 | - On a substitué au gaz mortel un produit inoffensif, grâce à elle. D’ailleurs pourquoi a-t-elle alerté Washington ? 79 | - Oh… J’ai réveillé son instinct maternel refoulé." 80 | "- Espériez-vous que je parlerai ? 81 | - Non monsieur Bond, j’espère que vous mourrez ! 82 | "- Dans mon métier, on se prépare à tout. 83 | - Et c’est quoi votre métier ? 84 | - J’aide les gens qui ont des problèmes. 85 | - Et leurs problèmes s’envolent ? 86 | - Je dirais plutôt que leurs problèmes s’éliminent." 87 | "- Je m’appelle Abondance. 88 | - Ravi de vous connaître. 89 | - Abondance Delaqueue. 90 | - Ça doit venir de votre père je pense…" 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Crypto/ZipZip/README.md: -------------------------------------------------------------------------------- 1 | # ZipZip - 50 points 2 | 3 | Le zip fourni pour ce challenge est protégé par un mot de passe, pour le craquer on va utiliser le tool fcrackzip, avec les options 'u' pour être certain que le mot de passe ouvre l'archive, 'D' pour une attaque par dictionnaire et 'p' pour indiquer le chemin du dictionnaire à utiliser : 4 | 5 | ``` 6 | fcrackzip topsecret.zip -u -D -p rockyou.txt 7 | PASSWORD FOUND!!!!: pw == girlpower007 8 | ``` 9 | 10 | on peut maintenant ouvrir l'archive avec ce mot de passe : 11 | 12 | ``` 13 | unzip -P girlpower007 topsecret.zip 14 | ``` 15 | 16 | on obtient un fichier texte `FAN-DE-JAMES-BOND.txt` qu'il faut lire attentivement pour y trouver la ligne : 17 | 18 | ```` 19 | "Un jour un informaticien m'a dit : pour capturer le drapeau de ce challenge il suffira de saisir 'L3_gr4s_c_3st_la_v1e' 20 | ```` 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Crypto/ZipZip/top-secret.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/Crypto/ZipZip/top-secret.zip -------------------------------------------------------------------------------- /Programming/Mathematician/README.md: -------------------------------------------------------------------------------- 1 | # Mathematician - 75 points 2 | 3 | ## Statement 4 | 5 | > Are you good at solving equations ? 6 | > 7 | > nc 10.22.6.101 15003 8 | > 9 | > infos: type(PASSWORD) --> string PASSWORD[0] = ord(first letter of password) 10 | 11 | 12 | ## Solving 13 | 14 | First, I tried the netcat command to see the message format. 15 | 16 | ![netcat return](./medias/netcat.PNG) 17 | 18 | You can see the message: 19 | > Objective: Solve the system of equations to find the password 20 | 21 | The first thing I tried was to script the resolution of the system of equations by passing the string manually. As the received data is encoded and in a single block, it must be parsed. 22 | 23 | By searching, we find that numpy can solve a system of equations with `numpy.linalg.solve` by passing a list with each value of the equation, then a list of the results of each equation. 24 | 25 | So first, extract all lines containing "PASSWORD[X]" 26 | 27 | ```PY 28 | recv = r.recvrepeat(1.5) 29 | recv = recv.decode() 30 | datas = recv.split("\n") 31 | for data in datas: 32 | if "PASSWORD" in line: 33 | lines.append(data) 34 | ``` 35 | 36 | At this point, we have a good format where we have one equation per list element. 37 | 38 | Now, everything that is not used in the calculation must be removed. 39 | 40 | ```PY 41 | for line in lines: 42 | # [+] is only for the first line 43 | line = line.replace('[+]', '') 44 | 45 | # Regex to remove all the PASSWORD[x] and the + signs or = 46 | line = re.sub("\*[A-Z ]*\[\s*\d+\]\s*(\+|\=)", "", line) 47 | 48 | # then we split the line to have all the numbers 49 | line = line.split() 50 | line = list(map(int, line)) 51 | 52 | # we pop the last number for each line which is the equation result into a new list 53 | results.append(line.pop(-1)) 54 | 55 | # all the other numbers goes to other list 56 | summ.append(line) 57 | ``` 58 | 59 | `results` is the list of all the 40 equation results and `summ` is a two-dimensional array which have all the signed numbers for each lines. 60 | 61 | Then we solve the system with numpy. The result is a numpy.float list so we need to convert it to ints. 62 | 63 | ```PY 64 | x = numpy.linalg.solve(summ, results) 65 | y = list(map(int, x)) 66 | ``` 67 | 68 | At this point, if you test the code you'll see that the int cast broke the results. You nee to use round to have the correct numbers 69 | 70 | ```PY 71 | x = numpy.linalg.solve(summ, results) 72 | y = list(map(round, x)) 73 | ``` 74 | 75 | Thanks to the statement, we know that PASSWORD[0] = ord(PASSWORD[0]). 76 | 77 | ```PY 78 | for el in y: 79 | ans += chr(el) 80 | 81 | # send the encoded answer 82 | r.sendline(ans.encode()) 83 | ``` 84 | 85 | After solving one system, we can see that they are 99 other systems to solve. So we have to script the receiving and the sending. 86 | 87 | Before I knew there were 100 equations to solve, I tried to use the linux pipes to send the stdin to python. In Python, you can retrieve the stdin input with `import fileinput`. 88 | 89 | But since we have to solve 100 equations, I turned to sockets. 90 | 91 | ```PY 92 | import socket 93 | 94 | host = "109.232.232.225" 95 | port = 15003 96 | 97 | def netcat(host, port, content=""): 98 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 99 | s.connect((host, port)) 100 | while True: 101 | data = s.recv(1048) 102 | if not data: 103 | break 104 | datas.append(data) 105 | if b"Resultat" in data; 106 | break 107 | 108 | if __name__ == "__main__": 109 | netcat(host, port) 110 | ``` 111 | 112 | With this method, we can correctly read and parse the data, but we can't send the response, especially 100 times in a row. 113 | 114 | So I used `pwntools`, suggested by Aurélien Duboc. 115 | 116 | ```PY 117 | import pwn 118 | 119 | address = "109.232.232.225" 120 | port = 15003 121 | 122 | r = pwn.remote(address, port) 123 | # 1 second is to fast, 1.2 second is fine but I prefered round it to 1.5 124 | recv = r.recvrepeat(1.5) 125 | recv = recv.decode() 126 | 127 | # [...] 128 | 129 | # Send response 130 | r.sendline(ans.encode()) 131 | ``` 132 | 133 | Do a for loop (100 times), reset the lists (summ, results, lines, ans) at each iteration and solve the 100 equations. 134 | 135 | ```PY 136 | import numpy as np 137 | import re 138 | import pwn 139 | 140 | address = "109.232.232.225" 141 | port = 15003 142 | ans = '' 143 | 144 | lines = [] 145 | summ = [] 146 | results = [] 147 | 148 | if __name__ == "__main__": 149 | r = pwn.remote(address, port) 150 | 151 | for i in range(100): 152 | recv = r.recvrepeat(1.2) 153 | recv = recv.decode() 154 | print(recv) 155 | datas = recv.split("\n") 156 | for line in datas: 157 | if "PASSWORD" in line: 158 | lines.append(line) 159 | for line in lines: 160 | line = line.replace('[+]', '') 161 | line = re.sub("\*[A-Z ]*\[\s*\d+\]\s*(\+|\=)", "", line) 162 | line = line.split() 163 | line = list(map(int, line)) 164 | results.append(line.pop(-1)) 165 | summ.append(line) 166 | 167 | x = np.linalg.solve(summ, results) 168 | y = list(map(round, x)) 169 | for el in y: 170 | ans += chr(el) 171 | print(f"{i}: " + ans) 172 | r.sendline(ans.encode()) 173 | summ = [] 174 | lines = [] 175 | results = [] 176 | datas = [] 177 | ans = "" 178 | print(recv) 179 | recv = r.recvrepeat(5) 180 | print(recv) 181 | ``` 182 | 183 | The lasts `print(recv)` and `recv = r.recvrepeat(5)` are here to be sure to read the flag. 184 | 185 | ![flag](./medias/flag.PNG) 186 | 187 | The flag is 188 | `FLAG = HSR{I_H0p3_U_uS3d_tH3_m4G1cal_z3_s0lV3r}` -------------------------------------------------------------------------------- /Programming/Mathematician/medias/flag.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/Programming/Mathematician/medias/flag.PNG -------------------------------------------------------------------------------- /Programming/Mathematician/medias/netcat.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/Programming/Mathematician/medias/netcat.PNG -------------------------------------------------------------------------------- /Programming/Mathematician/solve.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import re 3 | import pwn 4 | 5 | address = "109.232.232.225" 6 | port = 15003 7 | ans = '' 8 | 9 | lines = [] 10 | summ = [] 11 | results = [] 12 | 13 | if __name__ == "__main__": 14 | r = pwn.remote(address, port) 15 | 16 | for i in range(100): 17 | recv = r.recvrepeat(1.2) 18 | recv = recv.decode() 19 | print(recv) 20 | datas = recv.split("\n") 21 | for line in datas: 22 | if "PASSWORD" in line: 23 | lines.append(line) 24 | for line in lines: 25 | line = line.replace('[+]', '') 26 | line = re.sub("\*[A-Z ]*\[\s*\d+\]\s*(\+|\=)", "", line) 27 | line = line.split() 28 | line = list(map(int, line)) 29 | results.append(line.pop(-1)) 30 | summ.append(line) 31 | 32 | x = np.linalg.solve(summ, results) 33 | y = list(map(round, x)) 34 | for el in y: 35 | ans += chr(el) 36 | print(f"{i}: " + ans) 37 | r.sendline(ans.encode()) 38 | summ = [] 39 | lines = [] 40 | results = [] 41 | datas = [] 42 | ans = "" 43 | print(recv) 44 | recv = r.recvrepeat(5) 45 | print(recv) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo HSR](./medias/hsr.png) 2 | 3 | 4 | # HackSecuReims2022 5 | 6 | Ce dépôt git met à disposition les différents writeups officiels et ceux produits par les différents joueurs du HackSecuReims 2022. 7 | 8 | 9 | # Challenges 10 | 11 | ![](https://img.shields.io/static/v1?label=Catégorie&message=LockPicking&color=be1414&style=for-the-badge) 12 | 13 | 14 | ![lockpicking](./medias/lockpicking.png) 15 | 16 | 17 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Pentest&color=be1414&style=for-the-badge) 18 | 19 | 20 | ![pentest](./medias/Pentest.png) 21 | 22 | * SVR-POUDLARD 1 à 3 (sources) : https://github.com/Processus-Thief/CTF-HACKSECUREIMS-2022 23 | * SVR-POUDLARD 1 à 3 (Writeup vidéo) : https://www.youtube.com/watch?v=Hl4wKvphOH0&t=134s 24 | 25 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Forensic&color=be1414&style=for-the-badge) 26 | 27 | ![forensic](./medias/Forensic.png) 28 | 29 | 30 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Misc&color=be1414&style=for-the-badge) 31 | 32 | ![Misc](./medias/MISC.png) 33 | 34 | * [Official - Stegano ? Not really...](https://github.com/Maritime-Cyber-Team/HackSecuReims2022/blob/main/MISC/Stegano_Not_really/README.MD) 35 | * [Oneliner](https://www.duboc.xyz/writeups/2022-03-15-hsr-2022#misc-oneliner) 36 | 37 | 38 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Stegano&color=be1414&style=for-the-badge) 39 | 40 | ![Stegano](./medias/Stegano.png) 41 | 42 | 43 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Reverse&color=be1414&style=for-the-badge) 44 | 45 | ![Reverse](./medias/Reverse.png) 46 | 47 | * [InfiniteCrackMe 1](https://www.duboc.xyz/writeups/2022-03-15-hsr-2022#reverse-infinitecrackme-1) 48 | * [InfiniteCrackMe 2](https://www.duboc.xyz/writeups/2022-03-15-hsr-2022#reverse-infinitecrackme-2) 49 | 50 | ![](https://img.shields.io/static/v1?label=Catégorie&message=IOT&color=be1414&style=for-the-badge) 51 | 52 | ![IOT](./medias/IOT.png) 53 | 54 | 55 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Crypto&color=be1414&style=for-the-badge) 56 | 57 | ![Crypto](./medias/Crypto.png) 58 | 59 | 60 | * [1.2.3...](./Crypto/123/README.md) 61 | * [Bas les masques !](./Crypto/Bas_les_masques/README.md) 62 | * [IAMBATMAN](./Crypto/IAMBATMAN/README.md) 63 | * [Mixed](./Crypto/Mixed/README.md) 64 | * [Review the basics](./Crypto/Review_the_basics) 65 | * [ZipZip](./Crypto/ZipZip/README.md) 66 | 67 | 68 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Web&color=be1414&style=for-the-badge) 69 | 70 | ![Web](./medias/Web.png) 71 | 72 | * [Werkzeug Fuzzing 1](https://www.duboc.xyz/writeups/2022-03-15-hsr-2022#web-werkzeug-fuzzing-1) 73 | * [Werkzeug Fuzzing 2](https://www.duboc.xyz/writeups/2022-03-15-hsr-2022#web-werkzeug-fuzzing-2) 74 | * [Werkzeug Fuzzing 3](https://www.duboc.xyz/writeups/2022-03-15-hsr-2022#web-werkzeug-fuzzing-3) 75 | 76 | 77 | ![](https://img.shields.io/static/v1?label=Catégorie&message=OSINT&color=be1414&style=for-the-badge) 78 | 79 | ![OSINT](./medias/OSINT.png) 80 | 81 | 82 | ![](https://img.shields.io/static/v1?label=Catégorie&message=Programming&color=be1414&style=for-the-badge) 83 | 84 | ![programming](./medias/Programming.png) 85 | 86 | * [Mathematician](./Programming/Mathematician/README.md) 87 | * [Mathematician](https://www.duboc.xyz/writeups/2022-03-15-hsr-2022#programming-mathematician) 88 | 89 | # Scoreboard 90 | 91 | ![Scoreboard](./medias/graphs.png) 92 | 93 | ![Scoreboard](./medias/scoreboard.png) 94 | -------------------------------------------------------------------------------- /medias/Crypto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/Crypto.png -------------------------------------------------------------------------------- /medias/Forensic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/Forensic.png -------------------------------------------------------------------------------- /medias/IOT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/IOT.png -------------------------------------------------------------------------------- /medias/MISC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/MISC.png -------------------------------------------------------------------------------- /medias/OSINT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/OSINT.png -------------------------------------------------------------------------------- /medias/Pentest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/Pentest.png -------------------------------------------------------------------------------- /medias/Programming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/Programming.png -------------------------------------------------------------------------------- /medias/Reverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/Reverse.png -------------------------------------------------------------------------------- /medias/Stegano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/Stegano.png -------------------------------------------------------------------------------- /medias/Web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/Web.png -------------------------------------------------------------------------------- /medias/graphs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/graphs.png -------------------------------------------------------------------------------- /medias/hsr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/hsr.png -------------------------------------------------------------------------------- /medias/lockpicking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/lockpicking.png -------------------------------------------------------------------------------- /medias/scoreboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacksecureims/HackSecuReims2022/f73bcbf04ee9664dba3728de072b80026a250ebd/medias/scoreboard.png --------------------------------------------------------------------------------