feat: Semaine 10
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
### Ne marche que sur LINUX, puisque dépendant de ELF.
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import string
|
||||
from pwn import context, ELF
|
||||
|
||||
context.binary = './crackme_esdi'
|
||||
|
||||
def auto_extract_candidates(binary_path):
|
||||
"""
|
||||
Analyse le binaire et extrait TOUTES les suites d'octets qui,
|
||||
après un XOR 0x42, donnent une chaîne imprimable de 14 caractères.
|
||||
"""
|
||||
candidates = []
|
||||
try:
|
||||
elf = ELF(binary_path, checksec=False)
|
||||
rodata = elf.get_section_by_name('.rodata')
|
||||
data_bytes = rodata.data()
|
||||
except Exception:
|
||||
with open(binary_path, 'rb') as f:
|
||||
data_bytes = f.read()
|
||||
|
||||
password_length = 14
|
||||
xor_key = 0x42
|
||||
printable_charset = set(string.printable.encode('ascii'))
|
||||
|
||||
# Correction du Off-By-One : ajout du + 1 pour inclure le dernier bloc du fichier
|
||||
for i in range(len(data_bytes) - password_length + 1):
|
||||
window = data_bytes[i : i + password_length]
|
||||
candidate_bytes = bytes(b ^ xor_key for b in window)
|
||||
|
||||
# Validation des caractères ASCII lisibles
|
||||
if all(b in printable_charset and 32 <= b <= 126 for b in candidate_bytes):
|
||||
try:
|
||||
candidate_str = candidate_bytes.decode('ascii').strip()
|
||||
if len(candidate_str) == password_length:
|
||||
candidates.append(candidate_str)
|
||||
except UnicodeDecodeError:
|
||||
continue
|
||||
|
||||
return list(set(candidates))
|
||||
|
||||
def verify_and_run(binary_path, password):
|
||||
"""
|
||||
Exécute le binaire avec la valeur trouvée et valide la sortie.
|
||||
"""
|
||||
result = subprocess.run(
|
||||
[binary_path, password],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
output = result.stdout + result.stderr
|
||||
|
||||
if "Incorrect length" not in output and "Checksum failed" not in output:
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
binary_path = './crackme_esdi'
|
||||
print(f"[*] Démarrage de la résolution automatique de {binary_path}...")
|
||||
|
||||
candidates = auto_extract_candidates(binary_path)
|
||||
print(f"[+] {len(candidates)} candidats potentiels identifiés.")
|
||||
|
||||
print("[*] Validation dynamique des candidats via exécution...")
|
||||
for candidate in candidates:
|
||||
if verify_and_run(binary_path, candidate):
|
||||
print(f"[+] Crackme résolu : valeur = {candidate}")
|
||||
sys.exit(0)
|
||||
|
||||
print("[-] Échec : Aucun candidat n'a réussi à déverrouiller le binaire.")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user