Nel password cracking, una delle tecniche più utilizzate è l’attacco Brute Force (letteralmente “Forza Bruta”). In un attacco brute force, un attaccante prova tutte le possibili combinazioni di password fino a trovare quella corretta. Ad esempio, se la password è lunga 8 caratteri e l’attaccante usa un dataset di 62 caratteri (26 lettere maiuscole + 26 minuscole + 10 numeri), il numero totale di permutazioni è:
62^(8) = 218.340.105.584.896 (218 trilioni)
Un metodo basato perlopiù sulla fortuna che non ad un metodo vero e proprio; occorre quindi concentrare l’attacco in modo da ridurre notevolmente il numero di combinazioni ad esempio utilizzando un Attacco Lessicale.
Negli attacchi lessicali, si provano permutazioni di parole comuni o frasi derivanti da liste di password comuni. L’uso di permutazioni in questo contesto implica la generazione di varianti di password comuni che possono portare a brevi tempi di cracking.
La Permutazione
Nel calcolo combinatorio, una permutazione rappresenta la riorganizzazione di tutti i membri (quindi il numero di oggetti è uguale al numero di posti ) di un insieme in qualsiasi ordine o sequenza, nel quale conta l’ordine in cui i membri si dispongono.
Ad esempio, per l’insieme ABC, le possibili permutazioni sarebbero: ABC, ACB, BAC, BCA, CAB e CBA.
Lo script Python allegato di seguito, partendo da una parola (o elenco di parole) effettua tutte le trasliterazioni possibili evitando i risultati ridondanti (nel caso che la parola in input dovesse avere uno o più caratteri duplicati)
ad esempio, per l’insieme ABAB, si otterrebbe: ABAB, ABBA, AABB, BAAB, BABA, BBAA oppure per l’insieme AAAB, si otterrebbe: AAAAB, AAABA, AABAA, ABAAA, BAAAA
# -----------------------------------------------------------------------------
# - Script file name : perm.py
# - Author : Nicola Montemurro
# - DNS administrator: Nicola Montemurro - Tel. xxx, Mobile: xxx
# - Create : 21.07.2025
# - Last Update : 24.07.2025
# - Description :
# - Position : /usr/local/script/python
# - note : NON modificare senza AUTORIZZAZIONE dell'AMMINISTRATORE
# ----------------------------------------------------------------------------
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import itertools
import argparse
import gc
import sys
import os
def do_calculation(str_word, bucket_size, chars):
#Genera tutte le permutation uniche della string (o della sua parte) e le restituisce progressivamente.
#Rilascia le permutation periodicamente dal bucket per evitare troppa memoria accumulata.
str_word = str_word[:chars] # Limita la string alla lunghezza specificata
gc.enable()
permutation = itertools.permutations(str_word)
combination = set() # Utilizziamo un set per evitare duplicazioni
counter = 0
bucket = []
for p in permutation:
str_word = ''.join(p)
if str_word not in combination:
combination.add(str_word)
bucket.append(str_word)
counter += 1
# Rilascia il bucket di permutation ogni bucket_size permutation
if counter >= bucket_size:
for item in bucket:
yield item # Restituisci una permutazione alla volta
bucket.clear() # Pulisce il bucket
counter = 0 # Reset del contatore
#sleep(0.02) # Permette di gestire altre attività (DEBUG)
# destroy objects
del combination, bucket, counter
# freeing memory
gc.collect()
# recreate objects
combination = set()
counter = 0
bucket = []
# Restituisci le restanti permutation se ci sono
for item in bucket:
yield item
def main():
def avaluate_chars(user_input):
# Controllo della lunghezza massima per la word
if args.chars:
if args.chars > len(user_input):
nchars = args.chars
nchars = args.chars
else:
nchars = len(user_input) # Se non viene specificata la lunghezza, utilizza tutta la word
return nchars
def avaluate_lenght(user_input):
# Controllo della lunghezza massima per la word
if args.lenght:
if args.lenght > len(user_input):
wlen = args.lenght
wlen = args.lenght
else:
wlen = len(user_input) # Se non viene specificata la lunghezza, utilizza tutta la word
return wlen
# Impostazione di argparse per gestire gli argomenti
parser = argparse.ArgumentParser(description="Genera tutte le permutazioni di una parola.")
parser.add_argument("-w", "--word", type=str, help="Parola dalla quale generare le permutazioni.")
parser.add_argument("-c", "--chars", type=int, help="Assume solo gli n caratteri della parola da permutare")
parser.add_argument("-l", "--lenght", type=int, help="Limita il numero di caratteri (contando dal fondo) della parola permutata")
parser.add_argument("-f", "--filename", type=str, help="Nome file contenente l'elenco di parole da cui generare le permutazioni.'")
parser.add_argument("-b", "--bucket", type=int, default=1000000, help="Set di permutazioni da generare e rilasciare. (Default: 1000000)")
args = parser.parse_args()
data = None
# Check if filename is provided
if args.filename:
# Ensure filename exists
if not os.path.isfile(args.filename):
print(f"Error: File '{args.filename}' not found or is not a valid file.")
return # Exit gracefully
try:
# Try to open and read the file
with open(args.filename, 'r') as file:
for line in file:
data = line.strip()
max_chars=avaluate_chars(data)
for word in do_calculation(data, args.bucket, max_chars):
max_len=avaluate_lenght(data)
print(word[-max_len:])
#print(word)
except IOError as e:
print(f"Error reading file '{args.filename}': {e}")
return # Exit gracefully
elif args.word:
data = args.word.strip()
max_chars=avaluate_chars(data)
for word in do_calculation(data, args.bucket, max_chars):
max_len=avaluate_lenght(data)
print(word[-max_len:])
#print(word)
# Check if input is from a pipeline
elif not sys.stdin.isatty():
#print("Input is from a pipeline.")
try:
for line in sys.stdin:
data = line.strip()
max_chars=avaluate_chars(data)
#print(f'{data}')
for word in do_calculation(data, args.bucket, max_chars):
max_len=avaluate_lenght(data)
print(word[-max_len:])
#print(word)
except Exception as e:
print(f"Error reading from pipeline: {e}")
return # Exit gracefully
# Check if both input sources are empty
# if data is None:
#print("No input provided. Please specify a filename or pipe input.")
#return # Exit gracefully
if __name__ == '__main__':
main()
In Conclusione
Le permutazioni sono un metodo utilizzato frequentemente durante la generazione delle password, di conseguenza l’utilizzo dello stesso per il password cracking potrebbe rappresentare una soluzione ottimale.
Devifare il login per poter inviare un commento.