Hackflash #2 : Lister les segments d’un JPEG

Un grosse astuce en matière de stéganographie consiste à dissimuler des données dans un fichier image. Dans le cas d’un JPEG, il s’agira de jouer avec les segments.
Le flag est dans le JPEG...
La technique de base pour trouver ces données cachées est assez pénible, puisqu’elle consiste à passer en revue le contenu du fichier avec un éditeur hexadécimal tel que l’incontournable HxD.
Fort heureusement, il est possible d’automatiser cela en quelques lignes de Python…
Continuer la lecture de « Hackflash #2 : Lister les segments d’un JPEG »
Hackflash #2 : Lister les segments d’un JPEG

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)

Desire « ONE » : le coding-of d’une BBS-intro sur Amiga

Enfin, la dernière ! Au terme de quelques années de retour dans le passé pour revisiter la programmation du hardware de l’Amiga, voici Desire « ONE », la dernière des productions d’une série dont l’idée était de rendre hommages aux grandes figures de ce que fut la scène. Après avoir successivement salué le mérite des graphistes dans Scoopex « TWO », des coders dans Scoopex « ONE », des crackers dans Scoopex « THREE », c’est donc sur une salutation aux sysops que le rideau tombe définitivement.
Desire "ONE" : Une BBS-intro sur Amiga
Sans doute, il resterait encore bien assez d’aspects du hardware à explorer pour trouver l’occasion de produire des hommages à bien d’autres figures : musiciens, swappers, suppliers, spreaders, editors et qui sais-je encore. Toutefois, il faut rester au diapason du progrès technique, et sans qu’il s’agisse de prétendre en devenir un spécialiste, mais juste savoir un peu de quoi on parle, cela impose actuellement de se former à de sujets denses et divers comme jamais : Cloud, Machine Learning, Ethical Hacking, Ray-Tracing, etc. Le temps étant compté – le développement n’est pas mon métier -, cette mise à l’heure m’apparaît prioritaire.
La production dont il sera question ici est une BBS-intro. Autrement dit, c’est une intro consacrée à la promotion d’un Bulletin Board System (BBS). Elle est le fruit d’une collaboration avec le groupe Desire, qui reste très actif sur plusieurs scènes, notamment la scène Amiga.
Comme toujours : code, data et explications dans tout ce qui suit…
Mise à jour du 15/09/2019 : La BBS-intro a été distribuée lors de la Function 2019 qui s’est tenue à Budapest, et l’archive contenant l’ADF ainsi que le source et les données est donc maintenant proposée au téléchargement.
Continuer la lecture de « Desire « ONE » : le coding-of d’une BBS-intro sur Amiga »
Desire « ONE » : le coding-of d’une BBS-intro sur Amiga

Scoopex « THREE » : Le coding-of d’un menu de trainer sur Amiga

Sur Amiga, le trainer était essentiellement un menu enjolivé par un FX et une musique, qui permettait d’activer des options pour tricher dans un jeu : « Vie illimitées: On/Off », et ainsi de suite. Dans bien des cas, le trainer a pu être le seul moyen de parvenir à profiter totalement d’un jeu sans y passer trop de temps, vu la difficulté. Ne termine pas Shadow of the Beast qui veut…
Dans la continuité d’un programme d’hommages aux différentes figures de la scène, voici Scoopex « THREE », un trainer produit pour le fameux StingRay du glorieux groupe Scoopex. Après Scoopex « TWO » rendant hommage aux graphistes, un hommage aux crackers, donc.
Scoopex THREE : Un trainer pour A500 en 2019
Comme on pourra le constater, l’originalité a pris ici le pas sur la technique. Du moins en apparence, car en matière de programmation du hardware en assembleur sur Amiga, tout devient finalement assez technique rapidement !
Code, data et explications dans tout ce qui suit…
Mise à jour du 08/12/2019 : Le menu a été magnifiquement porté sur Flashtro. C’est ici !
Ce menu n’a toujours pas été utilisé par StingRay, mais comme dans le cas de Scoopex « ONE » j’ai jugé qu’après des mois d’attente, il était nécessaire… de ne plus attendre. A priori, il devrait être utilisé sous peu. On verra bien…
Continuer la lecture de « Scoopex « THREE » : Le coding-of d’un menu de trainer sur Amiga »
Scoopex « THREE » : Le coding-of d’un menu de trainer sur Amiga

Scoopex « ONE » : Le coding-of d’une cracktro AGA sur Amiga

Comme il en a été question dans un long article sur le coding-of de Scoopex « TWO », Scoopex « ONE » était restée dans les cartons. En effet, au moment de la diffusion de Scoopex « TWO » sur Amiga 500, il s’était avéré que cette cracktro, et celle qui devait la précéder sur Amiga 1200, ne tournaient dans la trame que du fait d’une erreur de configuration de WinUAE. L’émulation n’était pas fidèle, le hardware ne volant pas autant de cycles au MC68000 que dans la réalité.
Dans Scoopex « TWO », le problème fut résolu par downsizing. Restait à trouver une solution pour Scoopex « ONE ». C’est à l’occasion de la programmation d’une BBS-intro à venir pour le groupe Desire qu’elle fut trouvée. Voici donc le détail du coding-of de Scoopex « ONE », une cracktro pour Amiga 1200 :
Scoopex "ONE" : Une cracktro pour A1200 en 2019
Cette cracktro exploite quelques possibilités offertes par le chipset AGA (Advanced Graphics Architecture) : l’affichage en 256 couleurs, et le mode « burst » permettant au hardware de lire les données des bitplanes par paquets de 64 bits. En tant que telle, cette cracktro constitue une bonne introduction à la programmation du hardware de l’Amiga 1200, pour ceux qui souhaitent renouer avec le passé de la plus glorieuse gamme de micro-ordinateurs.
Cette cracktro n’a toujours pas été utilisée par Scoopex, mais j’ai jugé qu’après des mois d’attente, il était nécessaire… de ne plus attendre. A priori, elle devrait être utilisée pour la release d’une version AGA de Hired Guns. On verra bien…
Continuer la lecture de « Scoopex « ONE » : Le coding-of d’une cracktro AGA sur Amiga »
Scoopex « ONE » : Le coding-of d’une cracktro AGA sur Amiga

Déboguer facilement un service Web en PHP et JavaScript

S’il vous en reste, le développement d’un service Web en JavaScript (côté client) et PHP (côté serveur) est une bonne occasion de vous arracher des cheveux. Le débogage est une opération délicate, quand vous ne pouvez pas vous appuyer sur un système tel que Xdebug.
C’est que dans une application Web traditionnelle, un appel de service consiste simplement à appeler un script PHP dont le contenu est retourné par le serveur. Dès lors, toute erreur survenant lors de l’exécution du service s’affiche nécessairement à l’écran.
Il en va tout autrement dans le cas d’une application Web moderne, de type Progressive Web Application. Ici, l’appel de service s’effectue par le truchement d’un objet XMLHttpRequest. Le résultat de l’exécution du script est toujours renvoyé par le serveur, mais il parvient au client via une des propriétés de cet objet.
Dans ces conditions, la callback fournie à l’objet XMLHttpRequest doit analyser ce résultat pour déterminer si une erreur ou non a été rencontrée, et si oui remonter au développeur toutes les informations utiles qu’il voyait s’afficher à l’écran dans le cas d’une application Web traditionnelle : chemin d’accès au script, ligne dans le script où l’erreur est survenue, description de l’erreur, voire plus.
Déboguer facilement un service en JavaScript et PHP
La première chose à faire avant de se lancer dans le développement d’un service Web consiste donc à mettre en place une système de remontée des résultats d’un appel de service efficace. On aurait tort de s’en passer, car il ne faut finalement guère de lignes de code.
Continuer la lecture de « Déboguer facilement un service Web en PHP et JavaScript »
Déboguer facilement un service Web en PHP et JavaScript

Afficher du texte en gros pixels dans une page Web

Pas facile de la jouer rétro avec les technologies du jour ! Afficher un texte en gros pixels comme sur les vieilles bécanes, c’est toute une affaire quand on sait que le moindre texte subit désormais de multiples traitements pour le rendre bien lisible à l’écran. En particulier, ses courbes sont lissées en recourant à l’anti-aliasing.
L’anti-aliasing: voilà l’ennemi. On connaît quelques contournements mis en place pour tenir compte du revival des jeux à gros pixels. Sur ce blog, cet article montre comment désactiver l’anti-aliasing dans le contexte 2D du canvas.
Toutefois, ce contournement ne fonctionne que dans le cas de la copie d’une image et le dessin de formes simples – le rectangle. L’API Canvas ne propose rien pour afficher un texte en gros pixels dans une police donnée, une police de 8×8 pixels à l’ancienne qui plus est.
Dès lors, comment parvenir à produire un pareil résultat ?
La page d'accueil de Pixel Saga: du texte pixelisé généré automatiquement
La solution est très simple. C’est tout simplement celle qui était en vigueur sur les vieux coucous… Explications.
Continuer la lecture de « Afficher du texte en gros pixels dans une page Web »
Afficher du texte en gros pixels dans une page Web

Web Components : un élément <TR> personnalisé (2/2)

Cet article est le second, et donc le dernier, d’un série de deux consacrés à la réalisation d’un élément <tr> personnalisé exploitant des technologies de la famille Web Components.
Dans le premier article, il s’agissait de passer en revue l’intégralité du code requis pour créer un élément <tr> personnalisé <param-number> permettant d’ajouter un spinner précédé d’un libellé dans un tableau, comme ici :
Un élément personnalisé
Ce spinner est lié à une propriété quelconque que le développeur pointe à l’élément personnalisé en fournissant un chemin d’accès, comme par exemple shader.particle.start.delay. Ainsi, une fois qu’il a rajouté un élément <param-number> dans la page Web, le développeur n’a plus qu’à réagir aux modifications de la propriété via son getter. Le chemin est réévalué à chaque accès, si bien que le développeur peut toujours changer l’objet sur lequel il débouche.
Dans ce second article, il s’agit de revenir sur certains choix techniques qui ont présidé à l’écriture du code de l’élément personnalisé. En particulier, on s’interroge sur les avantages et les inconvénients d’une personnalisation d’un élément HTML existant tel que <tr>. Il s’agit aussi de pointer quelques enjeux des technologies de la famille Web Components pour l’avenir, notamment le recours aux classes en JavaScript et la prise de distance avec les éléments HTML standards.
Continuer la lecture de « Web Components : un élément <TR> personnalisé (2/2) »
Web Components : un élément <TR> personnalisé (2/2)

Web Components : un élément <TR> personnalisé (1/2)

Web Components est un ensemble de technologies apparues dans le cadre de HTML5 : custom elements, templates et shadow DOM – les imports HTML aussi, mais ils ne sont toujours pas standardisés. D’après Can I use… (ici, ici et ), ces technologies sont désormais assez largement adoptées dans leurs dernières versions – la v1. En particulier, Firefox gère parfaitement cela depuis l’automone dernier – la version 63.
Pour faire court, cet ensemble permet de créer un élément ou une variante d’élément HTML dans une page Web, et de faire exécuter du code JavaScript au moment où le navigateur cherche à l’interpréter, ce qui permet d’injecter dans la page Web ce que vous voulez. Par exemple, on peut écrire… :
<param-number name="Delay" property="g.shaderUI.delay" step="1" iseditable="true" buttonclassname="uiButton" numberclassname="uiNumber" layout="middle"></param-number>
…et récupérer une référence sur cet élément au moment où le navigateur cherche quoi en faire. Ici, il serait possible d’afficher un champ de saisie entouré de deux boutons, l’un pour décrémenter et l’autre pour incrémenter la valeur figurant dans le champ :
Un élément personnalisé
On comprend qu’il serait alors facile d’utiliser un tel composant à volonté, comme par exemple ici :
Une page Web utilisant généreusement des éléments personnalisés
Mais il pourrait tout autant s’agir d’effectuer une requête asynchrone à une base de données – une bonne occasion d’utiliser une promise -, afin de récupérer des informations sur un client et de les afficher quand elles sont disponibles, sans bloquer l’affichage du reste de la page – soyons progressifs.
Le sujet des Web Components est bien documenté sur MDN, et la spécification HTML qui doit servir de référence est pour sa part assez claire. Pourquoi en parler alors ?
Il faut en parler, car le sujet reste assez nouveau, et car la pratique montre que le développeur peut être confronté à des choix assez cornéliens. L’exemple pris ici est celui de la création d’un élément custom pour rajouter des lignes à un tableau. Ce sujet s’impose de lui-même dès que l’on commence à manipuler les Web Components, car la première idée qu’on y voit est de factoriser des éléments redondants, à ce titre souvent affichés dans un tableau.
Cet article est le premier d’un série de deux. Il s’agit de présenter l’intégralité du code requis pour faire fonctionner l’élément <param-number> évoqué. Dans le second article, plusieurs choix techniques et perspectives des technologies utilisées feront l’objet d’une discussion.
Continuer la lecture de « Web Components : un élément <TR> personnalisé (1/2) »
Web Components : un élément <TR> personnalisé (1/2)