Hackflash #1 : Clé privée PKCS8 et formats ASN.1, DER et PEM

La quantité de formats que le profane rencontre en cryptographie a de quoi lui faire tourner la tête. Le sujet peut être d’autant plus déroutant que certains de ces formats semblent équivalents, au sens où ils permettent de véhiculer un même contenu, mais sous des formes différentes.
Tel est notamment le cas des formats ASN.1, DER et PEM, qu’il est possible d’utiliser pour stocker une clé privée générée avec l’algorithme RSA sous trois formes différentes.
Le PEM d'une clé privée
Bien connaître ces formats peut se révéler utile, notamment lors de challenges de sécurité informatique où il arrive d’avoir à forger des certificats et/ou des clés de manière tout à fait artisanale. Dans ce contexte, c’est le format ASN.1 qui peut être mobilisé.
Les brèves explications qui suivent visent à montrer, à travers l’exemple d’une petite clé privée générée avec l’algorithme RSA, comment il est possible de passer de l’un à l’autre de ces formats.
Continuer la lecture de « Hackflash #1 : Clé privée PKCS8 et formats ASN.1, DER et PEM »
Hackflash #1 : Clé privée PKCS8 et formats ASN.1, DER et PEM

Root Me (in progress)

Très amusant, et instructif ! Encore quelques challenges, puis un article…
Une note pour les utilisateurs de l’excellent volatility qui en ont ras-le-bol d’avoir à extraire tous les VAD avec vaddump, pour faire en suite le tri en se référant au résultat généré par vadtree pour ne retenir que les heaps. J’ai indiqué ici sur le site Reverse Engineering de Stack Exchange comment créer un plugin à partir de vadinfo pour faire cela automatiquement. Cela revient donc à produire le fameux plugin heaps, dont il est question dans l’incontournable The Art of Memory Forensics, mais qui n’a jamais existé.
Une petite aide pour ceux qui cherchent à rédiger leur premier outil de forensics, avec l’exemple suivant d’un petit programme Python. Il permet d’extraire d’un dump volumineux tout ce qui pourrait s’apparenter à une image PNG ou JFIF (ie : JPEG).
Le fonctionnement est vraiment basique, puisqu’il faut modifier une constante DUMP_FORMAT dans le code pour indiquer ce qu’il convient d’extraire : PNG ou JFIF. De là, le programme parcourt le dump DUMP_FILE par bloc de BLOCKSIZE octets, dressant la liste des offsets des headers et la liste des offsets des trailers qu’il y trouve. Au terme de parcours, il rapproche ces listes pour décider d’extraire ou non dans DUMP_PATH des données sous forme d’un fichier pouvant constituer une image, la condition étant que la distance entre un header et un trailer ne dépasse pas FILESIZE_MAX octets.
J’aurais sans doute l’occasion de revenir sur ce programme pour en faire un plugin pour Volatility, si jamais il n’en existe pas de tel – ce dont je doute.
import os

# Extraire touts les PNG et JFIF potentiels d'un dump.
# Codé pour Stash of Code (http://www.stashofcode.fr) en octobre 2019.

BLOCKSIZE=1024*1024		# 1MB
FILESIZE_MAX= 1024 * 1024
DUMP_FILE= '../dump'
DUMP_PATH= '../pictures/'
DUMP_FORMAT_PNG=0
DUMP_FORMAT_JFIF=1
DUMP_FORMAT=DUMP_FORMAT_JFIF

extensions = [
	'png',
	'jpeg'
]
headers = [
	b'\x89\x50\x4E\x47',	# En fait 0xFFE0 suivi de 2 octets, puis de cette chaîne
	b'\x4A\x46\x49\x46'
]
trailers = [
	b'\x49\x45\x4E\x44\xAE\x42\x60\x82',
	b'\xFF\xD9'
]
filestat = os.stat (DUMP_FILE)
dump = open (DUMP_FILE, 'rb')
offset = 0
blocksize = BLOCKSIZE
if blocksize > filestat.st_size:
	blocksize = filestat.st_size
chunks = []
nbHeaders = 0
nbTrailers = 0
while offset < filestat.st_size:
	# print (f'{offset:09}-{(offset + blocksize):09}')
	block = dump.read (blocksize)
	start = 0
	while True:
		start = block.find(headers[DUMP_FORMAT], start)
		if start == -1:
			break
		if DUMP_FORMAT == DUMP_FORMAT_PNG:
			# print (f'Header at {(offset + start):09}')
			chunks.append ({'offset':offset + start, 'isHeader':True})
		elif DUMP_FORMAT == DUMP_FORMAT_JFIF:
			# print (f'Header at {(offset + start - 4):09}')
			chunks.append ({'offset': offset + start - 4, 'isHeader': True})
		nbHeaders += 1
		start += len (headers[DUMP_FORMAT])
	start = 0
	while True:
		start = block.find(trailers[DUMP_FORMAT], start)
		if start == -1:
			break
		# print (f'Trailer at {(offset + start):09}')
		chunks.append ({'offset':offset + start + len (trailers[DUMP_FORMAT]) - 1, 'isHeader':False})
		nbTrailers += 1
		start += len (trailers[DUMP_FORMAT])
	offset += blocksize
	if (offset + blocksize) > filestat.st_size:
		blocksize = filestat.st_size - offset
print (f'{nbHeaders} headers and {nbTrailers} trailers found...')
if (nbHeaders != 0) and (nbTrailers != 0):
	chunks.sort(key=lambda chunk : chunk['offset'])
	i = 0
	while True:
		if not chunks[i]['isHeader']:
			i += 1
		elif chunks[i +1]['isHeader']:
			i += 1
		else:
			start = chunks[i]['offset']
			end = chunks[i + 1]['offset']
			if (end - start) < FILESIZE_MAX:
				picture = open (f'{DUMP_PATH}{start:09}-{end:09}.{extensions[DUMP_FORMAT]}', 'wb')
				dump.seek (start)
				data = dump.read (end - start + 1)
				picture.write (data)
				picture.close ()
				print (f'Picture {start:09}-{end:09}.{extensions[DUMP_FORMAT]} dumped in {DUMP_PATH}')
			i += 2
		if i >= (len(chunks) - 1):
			break
dump.close ()
print ('DONE!')
Root Me (in progress)

Un traceroute roots en Python avec Scapy

Scapy est un package de Python bien connu dans le monde du hacking. Il permet d’interagir à bas niveau avec une interface réseau, c’est-à-dire de déterminer les octets qu’elle émet et de récupérer ceux qu’elle reçoit.
Scapy peut donc notamment être utilisé pour forger des trames et/ou paquets sur un réseau. Cela peut permettre de se livrer à des activités que la morale réprouve, comme l’ARP cache poisoning et autres joyeusetés. A l’inverse, comme nous le recommanderons, cela peut permettre de s’adonner à des activités tout à fait respectables, comme le diagnostic.
Scapy, pour sniffer, spoofer et autres
Dans tous les cas, se mettre à Scapy permet de se former au fonctionnement de réseaux en commençant par là où il faut commencer chaque fois qu’on prétend réellement apprendre quelque chose dans quel que domaine, c’est-à-dire à la base. C’est cette finalité pédagogique que poursuit cet article, à l’attention de tous ceux qui n’ont jamais mis le nez dans le réseau. Il présente comment réaliser une version simplifiée d’un outil qui figure inévitablement dans la boite à outils de tout hacker, à savoir traceroute.
Continuer la lecture de « Un traceroute roots en Python avec Scapy »
Un traceroute roots en Python avec Scapy