diff --git a/Arguments/Arguments.go b/Arguments/Arguments.go deleted file mode 100644 index f1e1888..0000000 --- a/Arguments/Arguments.go +++ /dev/null @@ -1,97 +0,0 @@ -package Arguments - -import ( - "flag" - "fmt" - "log" - "os" - "strings" -) - -// ArgumentLength function -func ArgumentLength(versionFlag bool) { - logger := log.New(os.Stderr, "[!] ", 0) - // if no arguments print help menu - if len(os.Args) == 1 { - fmt.Println("Usage of Suprenova.exe:") - flag.PrintDefaults() - os.Exit(0) - // If arguments are more than 2 - } else if len(os.Args) > 2 { - // if versionFlag is enabled - if versionFlag { - logger.Fatal("You cannot use the -version flag in conjunction with other arguments.") - } - } -} - -// ShowVersion function -func ShowVersion(version string, versionFlag bool) { - // if arguments are 2 - if len(os.Args) == 2 { - // if versionFlag is enabled - if versionFlag { - fmt.Printf("[+] Current version: " + version + "\n\n") - os.Exit(0) - } else { - fmt.Println("Usage of Suprenova.exe:") - flag.PrintDefaults() - os.Exit(0) - } - } -} - -// ArgumentEmpty function -func ArgumentEmpty(statement string, option int) { - if statement == "" { - logger := log.New(os.Stderr, "[!] ", 0) - switch option { - case 1: - logger.Fatal("Please provide a path to a file containing raw 64-bit shellcode.") - case 2: - logger.Fatal("Please provide a valid value for the programming language (e.g., C, CSharp, Rust, Nim, Go, Python).") - default: - logger.Fatal("Invalid option specified for ArgumentEmpty function.") - } - } -} - -// ValidateArgument function -func ValidateArgument(argName string, argValue string, validValues []string) string { - if strings.ToLower(argValue) == "golang" { - argValue = "Go" - } - - for _, valid := range validValues { - if strings.EqualFold(strings.ToLower(argValue), strings.ToLower(valid)) { - valid = strings.ToLower(valid) - return valid - } - } - - fmt.Printf("[!] Invalid value '%s' for argument '%s'. Valid values are: %v\n", argValue, argName, validValues) - os.Exit(1) - return "" -} - -// ValidateKeySize function -func ValidateKeySize(key int, encryption string) int { - logger := log.New(os.Stderr, "[!] ", 0) - if key <= 0 { - logger.Fatal("Please provide a valid key value for the size...\n") - } - - if strings.ToLower(encryption) == "aes" || strings.ToLower(encryption) == "b64aes" { - switch key { - case 128, 16: - key = 16 - case 192, 24: - key = 24 - case 256, 32: - key = 32 - default: - logger.Fatal("Provide a valid AES key:\n\nFor AES-128-CBC:\n\n-k 128 or -k 16\n\nFor AES-192-CBC:\n\n-k 192 or -k 24\n\nFor AES-256-CBC:\n\n-k 256 or -k 32\n\n") - } - } - return key -} diff --git a/Converters/Converters.go b/Converters/Converters.go deleted file mode 100644 index dec9462..0000000 --- a/Converters/Converters.go +++ /dev/null @@ -1,140 +0,0 @@ -package Converters - -import ( - "encoding/hex" - "fmt" - "io/ioutil" - "os" - "strings" -) - -// ConvertShellcode2Hex -func ConvertShellcode2Hex(shellcode string, language string) (string, int) { - // Convert raw shellcode to hexadecimal - hexShellcode := hex.EncodeToString([]byte(shellcode)) - - // Split hex shellcode into individual hex values - hexValues := strings.Split(hexShellcode, "") - - var builder strings.Builder - - if language == "python" { - for i := 0; i < len(hexValues); i += 2 { - builder.WriteString("\\x") - builder.WriteString(hexValues[i]) - builder.WriteString(hexValues[i+1]) - } - } else { - // Format and add "0x" in front of each pair of hex characters - for i := 0; i < len(hexValues); i += 2 { - builder.WriteString("0x") - builder.WriteString(hexValues[i]) - builder.WriteString(hexValues[i+1]) - if i < len(hexValues)-2 { - builder.WriteString(", ") - } - } - } - - formattedHexShellcode := builder.String() - - // Calculate shellcode size in bytes - shellcodeSize := len(shellcode) - - return formattedHexShellcode, shellcodeSize -} - -// ConvertShellcode2Template function -func ConvertShellcode2Template(shellcode string, language string, length int, variable string) string { - switch language { - case "c": - template := fmt.Sprintf(`unsigned char %s[] = "%s";`, variable, shellcode) - return template - case "csharp": - template := fmt.Sprintf(`byte[] %s = new byte[%d] {%s};`, variable, length, shellcode) - return template - case "nim": - template := fmt.Sprintf(`var %s: array[%d, byte] = [byte %s]`, variable, length, shellcode) - return template - case "rust": - template := fmt.Sprintf(`let %s: [u8; %d] = [%s];`, variable, length, shellcode) - return template - case "go": - template := fmt.Sprintf(`%s := []byte{%s};`, variable, shellcode) - return template - case "python": - template := fmt.Sprintf(`%s = b"%s"`, variable, shellcode) - return template - case "raw": - return shellcode - default: - fmt.Println("[!] Unsupported programming language:", language) - os.Exit(1) - return "" - } -} - -// ConvertShellcode2String function -func ConvertShellcode2String(shellcodePath string) (string, error) { - // Read the contents of the file into a byte slice - fileContent, err := ioutil.ReadFile(shellcodePath) - if err != nil { - return "", err - } - - // Convert the byte slice to a string - rawShellcode := strings.TrimSpace(string(fileContent)) - - return rawShellcode, nil -} - -// FormatKeysToHex function -func FormatKeysToHex(byteArray []byte) string { - var hexBytes []string - for _, byteVal := range byteArray[:len(byteArray)-1] { - hexBytes = append(hexBytes, fmt.Sprintf("0x%02x", byteVal)) - } - hexBytes = append(hexBytes, fmt.Sprintf("0x%02x", byteArray[len(byteArray)-1])) - - return strings.Join(hexBytes, ", ") -} - -// FormatShellcode function -func FormatShellcode(encryptedShellcode []byte, language string) string { - var formattedShellcode []string - var shellcodeFormatted string - - for _, b := range encryptedShellcode { - if language == "python" { - formattedShellcode = append(formattedShellcode, fmt.Sprintf("\\x%02x", b)) - } else { - formattedShellcode = append(formattedShellcode, fmt.Sprintf("0x%02x", b)) - } - } - - // Combine elements into a single string - if language == "python" { - shellcodeFormatted = strings.Join(formattedShellcode, "") - } else { - shellcodeFormatted = strings.Join(formattedShellcode, ", ") - } - - return shellcodeFormatted -} - -// AddValues2Template function -func AddValues2Template(operatingSystem string, template string) string { - if strings.ToLower(operatingSystem) == "linux" || strings.ToLower(operatingSystem) == "windows" { - template = "#include " + template - } - - return template -} - -// CleanShellcodeString function -func CleanShellcodeString(s string) string { - s = strings.ReplaceAll(s, " ", "") - s = strings.ReplaceAll(s, "0x", "") - s = strings.ReplaceAll(s, ",", "") - return s -} diff --git a/Decryptors/Decryptors.go b/Decryptors/Decryptors.go deleted file mode 100644 index 3c43fb6..0000000 --- a/Decryptors/Decryptors.go +++ /dev/null @@ -1,1513 +0,0 @@ -package Decryptors - -import ( - "Supernova/Output" - "fmt" - "log" - "os" - "strings" -) - -// global variables tamplates -// csharp rot template -var __csharp_rot__ = ` -using System; -using System.Text; -namespace ROTDecryption -{ - class Program - { - static void Main(string[] args) - { - byte[] %s = new byte[%d] {%s}; - int encryptedKey = %d; - byte[] decryptedPayload = DecryptROTPayload(%s, encryptedKey); - string payloadText = Encoding.ASCII.GetString(decryptedPayload); - - // Convert decryptedPayload to a hexadecimal string - StringBuilder hex = new StringBuilder(decryptedPayload.Length * 2); - int totalCount = decryptedPayload.Length; - for (int count = 0; count < totalCount; count++) - { - byte b = decryptedPayload[count]; - - if ((count + 1) == totalCount) // Don't append a comma for the last item - { - hex.AppendFormat("0x{0:x2}", b); - } - else - { - hex.AppendFormat("0x{0:x2}, ", b); - } - } - - Console.WriteLine("ROT Decrypted Payload:\n"); - Console.WriteLine($"byte[] %s = new byte[{%s.Length}] {{ {hex} }};\n\n"); - } - - static byte[] DecryptROTPayload(byte[] encryptedData, int key) - { - byte[] decrypted = new byte[encryptedData.Length]; - for (int i = 0; i < encryptedData.Length; i++) - { - decrypted[i] = (byte)(((uint)(encryptedData[i] - key) & 0xFF)); - } - return decrypted; - } - } -} -` - -// c rot template -var __c_rot__ = ` -#include -#include -#include - -uint8_t* DecryptROTPayload(const uint8_t* encryptedData, size_t dataSize, int key) { - uint8_t* decrypted = (uint8_t*)malloc(dataSize); - if (decrypted == NULL) { - return NULL; - } - - for (size_t i = 0; i < dataSize; i++) { - decrypted[i] = (encryptedData[i] - key) & 0xFF; - } - - return decrypted; -} - -int main() { - uint8_t %s[] = {%s}; - - int encryptedKey = %d; - size_t dataSize = sizeof(%s); - - uint8_t* decryptedPayload = DecryptROTPayload(%s, dataSize, encryptedKey); - - if (decryptedPayload != NULL) { - printf("ROT Decrypted Payload:\n"); - printf("unsigned char %s[] = \""); - - for (size_t i = 0; i < dataSize; i++) { - printf("0x%%02x", decryptedPayload[i]); - if (i < dataSize - 1) { - printf(", "); - } - } - - printf("\";\n"); - - free(decryptedPayload); - } - - return 0; -} -` - -// rust rot template -var __rust_rot__ = ` -fn decrypt_rot_payload(encrypted_data: &[u8], key: i32) -> Vec { - let mut decrypted = Vec::with_capacity(encrypted_data.len()); - - for &byte in encrypted_data { - let decrypted_byte = (byte as i32 - key) as u8; - decrypted.push(decrypted_byte); - } - - decrypted -} - -fn main() { - let %s: [u8; %d] = [%s]; - - let encrypted_key = %d; - - let decrypted_payload = decrypt_rot_payload(&%s, encrypted_key); - - println!("ROT Decrypted Payload:\n"); - print!("let %s[u8; %d] = ["); - - for (i, &byte) in decrypted_payload.iter().enumerate() { - print!("0x{:02x}", byte); - - if i < decrypted_payload.len() - 1 { - print!(", "); - } - } - - println!("];"); -} -` - -// golang rot template -var __go_rot__ = ` -package main - -import ( - "fmt" -) - -func caesarDecrypt(shellcode []byte, key byte) []byte { - decrypted := make([]byte, len(shellcode)) - - for i, char := range shellcode { - decrypted[i] = char - key - } - - return decrypted -} - -func main() { - %s := []byte{%s} - key := byte(%d) - decryptedShellcode := caesarDecrypt(%s, key) - - fmt.Printf("ROT Decrypted Payload:\n\n%s := %%#v\n", decryptedShellcode) -} -` - -// python rot template -var __python_rot__ = ` -def caesar_decrypt(shellcode, key): - decrypted = bytearray(len(shellcode)) - for i in range(len(shellcode)): - decrypted[i] = (shellcode[i] - key) & 0xFF - return decrypted - -def format_shellcode(shellcode): - formatted = "\\x" + "\\x".join([format(byte, '02x') for byte in shellcode]) - return formatted - -def main(): - %s = bytearray(b"%s") - key = %d - decrypted_shellcode = caesar_decrypt(%s, key) - - formatted_shellcode = format_shellcode(decrypted_shellcode) - - print("ROT Decrypted Payload:\n\n") - print("%s = b\"" + formatted_shellcode + "\"") - -if __name__ == "__main__": - main() -` - -// csharp xor template -var __csharp_xor__ = ` -using System; -using System.Text; - -namespace XORDecryption -{ - class Program - { - static byte[] MultiXORDecrypt(byte[] encryptedData, byte[] key) - { - byte[] decrypted = new byte[encryptedData.Length]; - for (int i = 0; i < encryptedData.Length; i++) - { - decrypted[i] = (byte)(encryptedData[i] ^ key[i %% key.Length]); - } - - return decrypted; - } - - static void Main(string[] args) - { - byte[] %s = new byte[%d] {%s}; - - byte[] multiXORKey = new byte[] {%s}; - - byte[] decryptedPayload = MultiXORDecrypt(%s, multiXORKey); - - // Convert decryptedPayload to a hexadecimal string - StringBuilder hex = new StringBuilder(decryptedPayload.Length * 2); - int totalCount = decryptedPayload.Length; - for (int count = 0; count < totalCount; count++) - { - byte b = decryptedPayload[count]; - - if ((count + 1) == totalCount) // Don't append a comma for the last item - { - hex.AppendFormat("0x{0:x2}", b); - } - else - { - hex.AppendFormat("0x{0:x2}, ", b); - } - } - - Console.WriteLine("Multi-XOR Decrypted Payload:\n\n"); - Console.WriteLine($"byte[] %s = new byte[{decryptedPayload.Length}] {{ {hex} }};\n\n"); - } - } -} -` - -// c xor template -var __c_xor__ = ` -#include -#include -#include - -uint8_t* MultiXORDecrypt(const uint8_t* encryptedData, size_t dataSize, const uint8_t* key, size_t keySize) { - uint8_t* decrypted = (uint8_t*)malloc(dataSize); - if (decrypted == NULL) { - return NULL; - } - - for (size_t i = 0; i < dataSize; i++) { - decrypted[i] = encryptedData[i] ^ key[i %% keySize]; - } - - return decrypted; -} - -int main() { - uint8_t %s[] = {%s}; - size_t dataSize = sizeof(%s); - - uint8_t xorKey[] = {%s}; - - uint8_t* decryptedPayload = MultiXORDecrypt(%s, dataSize, xorKey, sizeof(xorKey)); - - if (decryptedPayload != NULL) { - printf("Multi-XOR Decrypted Payload:\n"); - printf("unsigned char %s[] = \""); - - for (size_t i = 0; i < dataSize; i++) { - printf("0x%%02x", decryptedPayload[i]); - if (i < dataSize - 1) { - printf(", "); - } - } - - printf("\";\n"); - - free(decryptedPayload); - } - - return 0; -} -` - -// rust xor template -var __rust_xor__ = ` -fn multi_xor_decrypt(encrypted_data: &[u8], key: &[u8]) -> Vec { - let mut decrypted = vec![0; encrypted_data.len()]; - for (i, byte) in encrypted_data.iter().enumerate() { - decrypted[i] = byte ^ key[i %% key.len()]; - } - decrypted -} - -fn main() { - let %s: [u8; %d] = [%s]; - let xor_key: [u8; %d] = [%s]; - - let decrypted_payload = multi_xor_decrypt(&%s, &xor_key); - - println!("Multi-XOR Decrypted Payload:\n"); - print!("let %s[u8; %d] = ["); - for (i, byte) in decrypted_payload.iter().enumerate() { - print!("0x{:02x}", byte); - if i < decrypted_payload.len() - 1 { - print!(", "); - } - } - println!("];"); -} -` - -// golang xor template -var __go_xor__ = ` -package main - -import ( - "fmt" -) - -func multiXORDecrypt(encryptedData, key []byte) []byte { - decrypted := make([]byte, len(encryptedData)) - for i := 0; i < len(encryptedData); i++ { - decrypted[i] = encryptedData[i] ^ key[i%%len(key)] - } - return decrypted -} - -func main() { - %s := []byte{%s} - - multiXORKey := []byte{%s} - - decryptedPayload := multiXORDecrypt(%s, multiXORKey) - - // Print the decryptedPayload as a Go byte slice initialization - fmt.Println("Multi-XOR Decrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - fmt.Printf("0x%%02x", b) - if i < len(decryptedPayload)-1 { - fmt.Print(", ") - } - } - fmt.Println("};") -} -` - -// python xor template -var __python_xor__ = ` -def multi_xor_decrypt(encrypted_data, key): - decrypted = bytearray(len(encrypted_data)) - for i in range(len(encrypted_data)): - decrypted[i] = encrypted_data[i] ^ key[i %% len(key)] - return decrypted - -def format_shellcode(shellcode): - formatted = "\\x" + "\\x".join([format(byte, '02x') for byte in shellcode]) - return formatted - -def main(): - %s = bytearray(b"%s") - multi_xor_key = bytearray(b"%s") - - decrypted_payload = multi_xor_decrypt(%s, multi_xor_key) - - formatted_shellcode = format_shellcode(decrypted_payload) - - print("Multi-XOR Decrypted Payload:\n\n") - print(f"%s = b\"{formatted_shellcode}\"") - -if __name__ == "__main__": - main() -` - -// csharp rc4 template -var __csharp_rc4__ = ` -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace RC4Dencryption -{ - class Program - { - static byte[] RC4Dencrypt(byte[] data, byte[] key) - { - byte[] encrypted = new byte[data.Length]; - byte[] s = new byte[256]; - - for (int i = 0; i < 256; i++) - { - s[i] = (byte)i; - } - - int j = 0; - for (int i = 0; i < 256; i++) - { - j = (j + s[i] + key[i %% key.Length]) %% 256; - byte temp = s[i]; - s[i] = s[j]; - s[j] = temp; - } - - int x = 0; - int y = 0; - for (int idx = 0; idx < data.Length; idx++) - { - x = (x + 1) %% 256; - y = (y + s[x]) %% 256; - - byte temp = s[x]; - s[x] = s[y]; - s[y] = temp; - - int t = (s[x] + s[y]) %% 256; - encrypted[idx] = (byte)(data[idx] ^ s[t]); - } - - return encrypted; - } - - static byte[] GetKeyFromPassphrase(string passphrase) - { - // Convert the passphrase to bytes using UTF-8 encoding - return Encoding.UTF8.GetBytes(passphrase); - } - - static void Main(string[] args) - { - byte[] %s = new byte[%d] {%s}; - string passphrase = "%s"; - - byte[] key = GetKeyFromPassphrase(passphrase); - byte[] dencryptedPayload = RC4Dencrypt(%s, key); - - // Convert encryptedPayload to a hexadecimal string - StringBuilder hex = new StringBuilder(dencryptedPayload.Length * 2); - int totalCount = dencryptedPayload.Length; - for (int count = 0; count < totalCount; count++) - { - byte b = dencryptedPayload[count]; - - if ((count + 1) == totalCount) // Don't append a comma for the last item - { - hex.AppendFormat("0x{0:x2}", b); - } - else - { - hex.AppendFormat("0x{0:x2}, ", b); - } - } - - Console.WriteLine("RC4 Dencrypted Payload:\n\n"); - Console.WriteLine($"byte[] %s = new byte[{dencryptedPayload.Length}] {{ {hex} }};\n\n"); - } - } -} -` - -// c rc4 template -var __c_rc4__ = ` -#include -#include -#include -#include - -// RC4 algorithm for decryption -void RC4Decrypt(const uint8_t* encryptedData, size_t dataSize, const uint8_t* key, size_t keySize, uint8_t* decryptedData) { - uint8_t s[256]; - for (int i = 0; i < 256; i++) { - s[i] = i; - } - - uint8_t j = 0; - for (int i = 0; i < 256; i++) { - j = (j + s[i] + key[i %% keySize]) %% 256; - // Swap s[i] and s[j] - uint8_t temp = s[i]; - s[i] = s[j]; - s[j] = temp; - } - - int i = 0; - j = 0; - for (size_t k = 0; k < dataSize; k++) { - i = (i + 1) %% 256; - j = (j + s[i]) %% 256; - - // Swap s[i] and s[j] - uint8_t temp = s[i]; - s[i] = s[j]; - s[j] = temp; - - // Calculate the pseudo-random key - uint8_t keyStream = s[(s[i] + s[j]) %% 256]; - - // Decrypt the data - decryptedData[k] = encryptedData[k] ^ keyStream; - } -} - -// Function to convert passphrase to bytes -void PassphraseToBytes(const char* passphrase, uint8_t* key, size_t* keySize) { - size_t passphraseLength = strlen(passphrase); - *keySize = passphraseLength; - - for (size_t i = 0; i < passphraseLength; i++) { - key[i] = (uint8_t)passphrase[i]; - } -} - -int main() { - const char* passphrase = "%s"; // Replace with your passphrase - uint8_t rc4Key[256]; - size_t keySize; - - // Convert passphrase to bytes - PassphraseToBytes(passphrase, rc4Key, &keySize); - - uint8_t %s[] = {%s}; - - size_t dataSize = sizeof(%s); - - uint8_t* decryptedPayload = (uint8_t*)malloc(dataSize); - - if (decryptedPayload == NULL) { - printf("Memory allocation failed.\n"); - return 1; // Return an error code - } - - // Perform RC4 decryption - RC4Decrypt(%s, dataSize, rc4Key, keySize, decryptedPayload); - - printf("RC4 Decrypted Payload:\n\n"); - printf("unsigned char %s[] = \""); - for (size_t i = 0; i < dataSize; i++) { - printf("0x%%02x", decryptedPayload[i]); - if (i < dataSize - 1) { - printf(", "); - } - } - printf("\";\n"); - - // Free the allocated memory - free(decryptedPayload); - - return 0; -} -` - -// rust rc4 template -var __rust_rc4__ = ` -fn rc4_decrypt(encrypted_data: &[u8], key: &[u8]) -> Vec { - let mut s: Vec = (0..=255).collect(); - let mut j: u16 = 0; // Change j to u16 - - for i in 0..=255 { - j = (j + u16::from(s[i]) + u16::from(key[i %% key.len()])) %% 256; // Use u16 for j and casting - s.swap(i as usize, j as usize); - } - - let mut i: u8 = 0; - j = 0; - let mut decrypted_data = Vec::with_capacity(encrypted_data.len()); - - for k in encrypted_data { - i = i.wrapping_add(1); - j = (j + u16::from(s[i as usize])) %% 256; // Use u16 for j and casting - s.swap(i as usize, j as usize); - let key_stream = s[(s[i as usize].wrapping_add(s[j as usize])) as usize]; - decrypted_data.push(k ^ key_stream); - } - - decrypted_data -} - -fn main() { - let passphrase = "%s"; - let rc4_key: Vec = passphrase.bytes().collect(); - - let %s: [u8; %d] = [%s]; - - let decrypted_payload = rc4_decrypt(&%s, &rc4_key); - - println!("RC4 Decrypted Payload:\n\n"); - print!("let %s: [u8; %d] = ["); - for (i, byte) in decrypted_payload.iter().enumerate() { - print!("0x{:02x}", byte); - if i < decrypted_payload.len() - 1 { - print!(", "); - } - } - println!("];"); -} -` - -// golang rc4 template -var __go_rc4__ = ` -package main - -import ( - "crypto/rc4" - "fmt" -) - -func rc4Decrypt(ciphertext, key []byte) ([]byte, error) { - cipher, err := rc4.NewCipher(key) - if err != nil { - return nil, err - } - plaintext := make([]byte, len(ciphertext)) - cipher.XORKeyStream(plaintext, ciphertext) - return plaintext, nil -} - -func main() { - %s := []byte{%s} - passphrase := "%s" - - key := []byte(passphrase) - - decryptedPayload, err := rc4Decrypt(%s, key) - if err != nil { - fmt.Println("Error:", err) - return - } - - // Print the decryptedPayload as a Go byte slice initialization - fmt.Println("RC4 Dencrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - fmt.Printf("0x%%02x", b) - if i < len(decryptedPayload)-1 { - fmt.Print(", ") - } - } - fmt.Println("}") -} -` - -// python rc4 template -var __python_rc4__ = ` -import sys - -def rc4(key, data): - S = list(range(256)) - j = 0 - out = [] - - # Key-scheduling algorithm - for i in range(256): - j = (j + S[i] + key[i %% len(key)]) %% 256 - S[i], S[j] = S[j], S[i] - - # Pseudo-random generation algorithm - i = j = 0 - for byte in data: - i = (i + 1) %% 256 - j = (j + S[i]) %% 256 - S[i], S[j] = S[j], S[i] - out.append(byte ^ S[(S[i] + S[j]) %% 256]) - - return bytes(out) - -def main(): - passphrase = b'%s' - %s = b"%s" - - try: - decrypted_shellcode = rc4(passphrase, %s) - shellcode_hex = ''.join([f'\\x{byte:02x}' for byte in decrypted_shellcode]) - print("RC4 Decrypted Shellcode:\n\n") - print(f'%s = b"{shellcode_hex}"') - except Exception as e: - print(f"Error: {str(e)}") - sys.exit(1) - -if __name__ == "__main__": - main() -` - -// csharp aes template -var __csharp_aes__ = ` -using System; -using System,IO; -using System.Security.Cryptography; -using System.Text; - -namespace AESDecryption -{ - class Program - { - static byte[] AESDecrypt(byte[] encryptedData, byte[] key, byte[] iv) - { - using (Aes aesAlg = Aes.Create()) - { - aesAlg.Key = key; - aesAlg.IV = iv; - - // Create a decryptor to perform the stream transform. - ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); - - // Create the streams used for decryption. - using (MemoryStream msDecrypt = new MemoryStream(encryptedData)) - { - using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) - { - using (MemoryStream msOutput = new MemoryStream()) - { - // Decrypt the data and write it to the output stream. - csDecrypt.CopyTo(msOutput); - return msOutput.ToArray(); - } - } - } - } - } - - static void Main(string[] args) - { - byte[] %s = new byte[%d] {%s}; - byte[] aesKey = new byte[%d] {%s}; - byte[] aesIV = new byte[16] {%s}; - - byte[] decryptedPayload = AESDecrypt(%s, aesKey, aesIV); - - // Convert decryptedPayload to a hexadecimal string - StringBuilder hex = new StringBuilder(decryptedPayload.Length * 2); - int totalCount = decryptedPayload.Length; - for (int count = 0; count < totalCount; count++) - { - byte b = decryptedPayload[count]; - - if ((count + 1) == totalCount) // Don't append a comma for the last item - { - hex.AppendFormat("0x{0:x2}", b); - } - else - { - hex.AppendFormat("0x{0:x2}, ", b); - } - } - - Console.WriteLine("AES Decrypted Payload:\n\n"); - Console.WriteLine($"byte[] %s = new byte[{decryptedPayload.Length}] {{ {hex} }};\n\n"); - } - } -} -` - -// c aes template -var __c_aes__ = ` -#include -#include -#include -#include -#include -#include - -int AESDecrypt(const uint8_t* encryptedData, size_t encryptedDataLength, const uint8_t* key, const uint8_t* iv, uint8_t* decryptedData) { - EVP_CIPHER_CTX* ctx; - int len; - int decryptedLength = 0; - - ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(ctx, EVP_aes_%d_cbc(), NULL, key, iv); - EVP_DecryptUpdate(ctx, decryptedData, &len, encryptedData, encryptedDataLength); - decryptedLength += len; - EVP_DecryptFinal_ex(ctx, decryptedData + len, &len); - decryptedLength += len; - - EVP_CIPHER_CTX_free(ctx); - - return decryptedLength; -} - -int main() { - uint8_t %s[] = {%s}; - size_t shellcodeLength = sizeof(%s); - - uint8_t aesKey[] = {%s}; - - uint8_t aesIV[] = {%s}; - - uint8_t* decryptedPayload = (uint8_t*)malloc(shellcodeLength); - if (decryptedPayload == NULL) { - perror("Memory allocation failed"); - return 1; - } - - int decryptedLength = AESDecrypt(%s, shellcodeLength, aesKey, aesIV, decryptedPayload); - - printf("AES Decrypted Payload:\n\n"); - printf("unsigned char %s[] = \""); - for (size_t i = 0; i < decryptedLength; i++) { - printf("0x%%02x", decryptedPayload[i]); - if (i < decryptedLength - 1) { - printf(", "); - } - } - printf("\";\n"); - - free(decryptedPayload); - - return 0; -} -` - -// rust aes template -var __rust_aes__ = ` -extern crate openssl; - -use openssl::symm::{Cipher, Crypter, Mode}; -use openssl::error::ErrorStack; -use std::io::Write; - -fn aes_decrypt(encrypted_data: &[u8], key: &[u8], iv: &[u8]) -> Result, ErrorStack> { - let cipher = Cipher::aes_%d_cbc(); - let mut decrypter = Crypter::new(cipher, Mode::Decrypt, key, Some(iv))?; - - let mut decrypted_data = vec![0; encrypted_data.len() + cipher.block_size()]; - let mut count = decrypter.update(encrypted_data, &mut decrypted_data)?; - - count += decrypter.finalize(&mut decrypted_data[count..])?; - - decrypted_data.truncate(count); - - Ok(decrypted_data) -} - -fn main() -> Result<(), Box> { - let %s: [u8; %d] = [%s]; - - let aes_key: [u8; %d] = [%s]; - - let aes_iv: [u8; 16] = [%s]; - - match aes_decrypt(&%s, &aes_key, &aes_iv) { - Ok(decrypted_payload) => { - let payload_len = decrypted_payload.len(); - - println!("AES Decrypted Payload:\n"); - print!("let %s: [u8; {}] = [", payload_len); - for (i, byte) in decrypted_payload.iter().enumerate() { - print!("{:#04x}", byte); - if i < payload_len - 1 { - print!(", "); - } - } - println!("];\n"); - } - Err(e) => { - eprintln!("Error: {:?}", e); - } - } - Ok(()) -} -` - -// go aes template -var __go_aes__ = ` -package main - -import ( - "crypto/aes" - "crypto/cipher" - "fmt" -) - -func AESDecrypt(encryptedData []byte, key []byte, iv []byte) []byte { - block, err := aes.NewCipher(key) - if err != nil { - fmt.Println("Error creating AES cipher:", err) - return nil - } - - decrypter := cipher.NewCBCDecrypter(block, iv) - - decrypted := make([]byte, len(encryptedData)) - decrypter.CryptBlocks(decrypted, encryptedData) - - // Remove PKCS7 padding (assuming it was used) - padding := decrypted[len(decrypted)-1] - decrypted = decrypted[:len(decrypted)-int(padding)] - - return decrypted -} - -func main() { - %s := []byte{%s} - - aesKey := []byte{%s} - aesIV := []byte{%s} - - decryptedPayload := AESDecrypt(%s, aesKey, aesIV) - - fmt.Println("AES Decrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - if i == len(decryptedPayload)-1 { - fmt.Printf("0x%%02x", b) - } else { - fmt.Printf("0x%%02x, ", b) - } - } - fmt.Println("}") -} -` - -// python aes template -var __python_aes__ = ` -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -from cryptography.hazmat.primitives import padding - -def decrypt_aes_cbc(key, iv, ciphertext): - cipher = Cipher(algorithms.AES(key), modes.CBC(iv)) - decryptor = cipher.decryptor() - padded_data = decryptor.update(ciphertext) + decryptor.finalize() - unpadder = padding.PKCS7(128).unpadder() - plaintext = unpadder.update(padded_data) + unpadder.finalize() - return plaintext - -def format_shellcode(shellcode): - formatted = "\\x" + "\\x".join([format(byte, '02x') for byte in shellcode]) - return formatted - -def main(): - key = b"%s" - iv = b"%s" - - %s = b"%s" - plaintext = decrypt_aes_cbc(key, iv, %s) - - formatted_shellcode = format_shellcode(plaintext) - - print("AES Decrypted Shellcode:\n\n") - print(f"%s = b\"{formatted_shellcode}\"") - -if __name__ == "__main__": - main() -` - -// golang b64xor template -var __go_b64xor__ = ` -package main - -import ( - "encoding/base64" - "fmt" -) - -func multiXORDecrypt(encryptedData, key []byte) []byte { - decrypted := make([]byte, len(encryptedData)) - for i := 0; i < len(encryptedData); i++ { - decrypted[i] = encryptedData[i] ^ key[i%%len(key)] - } - return decrypted -} - -func main() { - %s := []byte{%s} - - multiXORKey := []byte{%s} - - decryptedShellcodeBase64, _ := base64.StdEncoding.DecodeString(string(%s)) - decryptedPayload := multiXORDecrypt(decryptedShellcodeBase64, multiXORKey) - - // Print the decryptedPayload as a Go byte slice initialization - fmt.Println("B64Multi-XOR Decrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - fmt.Printf("0x%%02x", b) - if i < len(decryptedPayload)-1 { - fmt.Print(", ") - } - } - fmt.Println("}") -} -` - -// golang b64rc4 template -var __go_b64rc4__ = ` -package main - -import ( - "crypto/rc4" - "encoding/base64" - "fmt" -) - -func rc4Decrypt(ciphertext, key []byte) ([]byte, error) { - cipher, err := rc4.NewCipher(key) - if err != nil { - return nil, err - } - plaintext := make([]byte, len(ciphertext)) - cipher.XORKeyStream(plaintext, ciphertext) - return plaintext, nil -} - -func main() { - %s := []byte{%s} - passphrase := "%s" - - key := []byte(passphrase) - - decryptedShellcodeBase64, _ := base64.StdEncoding.DecodeString(string(%s)) - decryptedPayload, err := rc4Decrypt(decryptedShellcodeBase64, key) - if err != nil { - fmt.Println("Error:", err) - return - } - - // Print the decryptedPayload as a Go byte slice initialization - fmt.Println("B64RC4 Dencrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - fmt.Printf("0x%%02x", b) - if i < len(decryptedPayload)-1 { - fmt.Print(", ") - } - } - fmt.Println("}") -} -` - -// go b64aes template -var __go_b64aes__ = ` -package main - -import ( - "crypto/aes" - "crypto/cipher" - "encoding/base64" - "fmt" -) - -func AESDecrypt(encryptedData []byte, key []byte, iv []byte) []byte { - block, err := aes.NewCipher(key) - if err != nil { - fmt.Println("Error creating AES cipher:", err) - return nil - } - - decrypter := cipher.NewCBCDecrypter(block, iv) - - decrypted := make([]byte, len(encryptedData)) - decrypter.CryptBlocks(decrypted, encryptedData) - - // Remove PKCS7 padding (assuming it was used) - padding := decrypted[len(decrypted)-1] - decrypted = decrypted[:len(decrypted)-int(padding)] - - return decrypted -} - -func main() { - %s := []byte{%s} - - aesKey := []byte{%s} - aesIV := []byte{%s} - - decryptedShellcodeBase64, _ := base64.StdEncoding.DecodeString(string(%s)) - decryptedPayload := AESDecrypt(decryptedShellcodeBase64, aesKey, aesIV) - - fmt.Println("AES Decrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - if i == len(decryptedPayload)-1 { - fmt.Printf("0x%%02x", b) - } else { - fmt.Printf("0x%%02x, ", b) - } - } - fmt.Println("}") -} -` - -// go chacha20 -var __go_chacha20__ = ` -package main - -import ( - "golang.org/x/crypto/chacha20poly1305" - "fmt" -) - -func Chacha20Decrypt(data []byte, key []byte) ([]byte) { - aead, err := chacha20poly1305.NewX(key) - - - nonceSize := aead.NonceSize() - - if len(data) < nonceSize { - return nil - } - - // Split nonce and ciphertext. - nonce, ciphertext := data[:nonceSize], data[nonceSize:] - - // Decrypt the message and check it wasn't tampered with. - plaintext, err := aead.Open(nil, nonce, ciphertext, nil) - if err != nil { - if err.Error() == "chacha20poly1305: message authentication failed" { - return nil - } - - return nil - } - - return plaintext -} - - -func main() { - %s := []byte{ %s } - key := []byte { %s } - - decryptedPayload := Chacha20Decrypt(%s, key) - - fmt.Print("CHACHA20 Decrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - if i == len(decryptedPayload)-1 { - fmt.Printf("0x%%02x", b) - } else { - fmt.Printf("0x%%02x, ", b) - } - } - fmt.Println("}") -} -` - -// go b64chacha20 -var __go_b64chacha20__ = ` -package main - -import ( - "golang.org/x/crypto/chacha20poly1305" - "encoding/base64" - - "fmt" -) - -func Chacha20Decrypt(data []byte, key []byte) ([]byte) { - aead, err := chacha20poly1305.NewX(key) - - - nonceSize := aead.NonceSize() - - if len(data) < nonceSize { - return nil - } - - // Split nonce and ciphertext. - nonce, ciphertext := data[:nonceSize], data[nonceSize:] - - // Decrypt the message and check it wasn't tampered with. - plaintext, err := aead.Open(nil, nonce, ciphertext, nil) - if err != nil { - if err.Error() == "chacha20poly1305: message authentication failed" { - return nil - } - - return nil - } - - return plaintext -} - - -func main() { - %s := []byte{ %s } - key := []byte { %s } - - decryptedShellcodeBase64, _ := base64.StdEncoding.DecodeString(string(%s)) - decryptedPayload := Chacha20Decrypt(decryptedShellcodeBase64, key) - - fmt.Print("B64CHACHA20 Decrypted Payload:\n\n") - fmt.Print("%s := []byte{") - for i, b := range decryptedPayload { - if i == len(decryptedPayload)-1 { - fmt.Printf("0x%%02x", b) - } else { - fmt.Printf("0x%%02x, ", b) - } - } - fmt.Println("}") -} -` - -// SaveTemplae2File function -func SaveTamplate2File(filename string, tamplate string, cipher string) { - // Open a file for writing. If the file doesn't exist, it will be created. - file, err := os.Create(filename) - if err != nil { - fmt.Println("Error creating file:", err) - return - } - defer file.Close() // Close the file when the function exits - - // Write the variable value to the file - _, err = fmt.Fprintln(file, tamplate) - if err != nil { - fmt.Println("Error writing to file:", err) - return - } - - cipher = strings.ToUpper(cipher) - fmt.Printf("[+] %s decrytpion function has been saved to %s file\n\n", cipher, filename) -} - -// SetDecryptionFile function -func SetDecryptionFile(extension string) string { - // Set filename according to preferred language - filename := "Program." + extension - - return filename -} - -// DecryptorsTemplates function -func DecryptorsTemplates(language string, cipher string, variable string, key int, payloadSize int, encryptedShellcode string, byteKey []byte, passphrase string, iv []byte) { - - // Set logger for errors - logger := log.New(os.Stderr, "[!] ", 0) - - // Set cipher to lower - cipher = strings.ToLower(cipher) - - switch language { - case "csharp": - extension := "cs" - - // Call function named SetDecryptionFile - foundFilename := SetDecryptionFile(extension) - - switch strings.ToLower(cipher) { - case "rot": - // Config dynamic variable - __csharp_rot__ = fmt.Sprintf(__csharp_rot__, variable, payloadSize, encryptedShellcode, key, variable, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __csharp_rot__, cipher) - case "xor": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __csharp_xor__ = fmt.Sprintf(__csharp_xor__, variable, payloadSize, encryptedShellcode, formattedKey, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __csharp_xor__, cipher) - case "rc4": - // Config dynamic variable - __csharp_rc4__ = fmt.Sprintf(__csharp_rc4__, variable, payloadSize, encryptedShellcode, passphrase, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __csharp_rc4__, cipher) - case "aes": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Call function named KeyDetailsFormatter - formattedIv := Output.KeyDetailsFormatter(iv, language) - - // Config dynamic variable - __csharp_aes__ = fmt.Sprintf(__csharp_aes__, variable, payloadSize, encryptedShellcode, key, formattedKey, formattedIv, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __csharp_aes__, cipher) - default: - fmt.Printf("[!] Guide mode does not support the %s in CSharp language, yet!\n\n", cipher) - } - case "c": - extension := "c" - - // Call function named SetDecryptionFile - foundFilename := SetDecryptionFile(extension) - - switch strings.ToLower(cipher) { - case "rot": - // Config dynamic variable - __c_rot__ = fmt.Sprintf(__c_rot__, variable, encryptedShellcode, key, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __c_rot__, cipher) - case "xor": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __c_xor__ = fmt.Sprintf(__c_xor__, variable, encryptedShellcode, variable, formattedKey, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __c_xor__, cipher) - case "rc4": - // Config dynamic variable - __c_rc4__ = fmt.Sprintf(__c_rc4__, passphrase, variable, encryptedShellcode, variable, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __c_rc4__, cipher) - case "aes": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Call function named KeyDetailsFormatter - formattedIv := Output.KeyDetailsFormatter(iv, language) - - // Call function named DetectNotification - keyNotification := Output.DetectNotification(key) - - // Config dynamic variable - __c_aes__ = fmt.Sprintf(__c_aes__, keyNotification, variable, encryptedShellcode, variable, formattedKey, formattedIv, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __c_aes__, cipher) - default: - fmt.Printf("[!] Guide mode does not support the %s in C language, yet!\n\n", cipher) - } - case "rust": - extension := "rs" - - // Call function named SetDecryptionFile - foundFilename := SetDecryptionFile(extension) - - switch strings.ToLower(cipher) { - case "rot": - // Config dynamic variable - __rust_rot__ = fmt.Sprintf(__rust_rot__, variable, payloadSize, encryptedShellcode, key, variable, variable, payloadSize) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __rust_rot__, cipher) - case "xor": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __rust_xor__ = fmt.Sprintf(__rust_xor__, variable, payloadSize, encryptedShellcode, key, formattedKey, variable, variable, payloadSize) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __rust_xor__, cipher) - case "rc4": - // Config dynamic variable - __rust_rc4__ = fmt.Sprintf(__rust_rc4__, passphrase, variable, payloadSize, encryptedShellcode, variable, variable, payloadSize) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __rust_rc4__, cipher) - case "aes": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Call function named KeyDetailsFormatter - formattedIv := Output.KeyDetailsFormatter(iv, language) - - // Call function named DetectNotification - keyNotification := Output.DetectNotification(key) - - // Config dynamic variable - __rust_aes__ = fmt.Sprintf(__rust_aes__, keyNotification, variable, payloadSize, encryptedShellcode, key, formattedKey, formattedIv, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __rust_aes__, cipher) - default: - fmt.Printf("[!] Guide mode does not support the %s in Rust language, yet!\n\n", cipher) - } - case "nim": - fmt.Printf("[!] Guide mode does not support Nim language, yet!\n\n") - case "go": - extension := "go" - - // Call function named SetDecryptionFile - foundFilename := SetDecryptionFile(extension) - - switch strings.ToLower(cipher) { - case "rot": - // Config dynamic variable - __go_rot__ = fmt.Sprintf(__go_rot__, variable, encryptedShellcode, key, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_rot__, cipher) - case "xor": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __go_xor__ = fmt.Sprintf(__go_xor__, variable, encryptedShellcode, formattedKey, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_xor__, cipher) - case "b64xor": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __go_b64xor__ = fmt.Sprintf(__go_b64xor__, variable, encryptedShellcode, formattedKey, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_b64xor__, cipher) - case "rc4": - // Config dynamic variable - __go_rc4__ = fmt.Sprintf(__go_rc4__, variable, encryptedShellcode, passphrase, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_rc4__, cipher) - case "b64rc4": - // Config dynamic variable - __go_b64rc4__ = fmt.Sprintf(__go_b64rc4__, variable, encryptedShellcode, passphrase, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_b64rc4__, cipher) - case "aes": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Call function named KeyDetailsFormatter - formattedIv := Output.KeyDetailsFormatter(iv, language) - - // Config dynamic variable - __go_aes__ = fmt.Sprintf(__go_aes__, variable, encryptedShellcode, formattedKey, formattedIv, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_aes__, cipher) - case "b64aes": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Call function named KeyDetailsFormatter - formattedIv := Output.KeyDetailsFormatter(iv, language) - - // Config dynamic variable - __go_b64aes__ = fmt.Sprintf(__go_b64aes__, variable, encryptedShellcode, formattedKey, formattedIv, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_b64aes__, cipher) - case "chacha20": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __go_chacha20__ = fmt.Sprintf(__go_chacha20__, variable, encryptedShellcode, formattedKey, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_chacha20__, cipher) - case "b64chacha20": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __go_b64chacha20__ = fmt.Sprintf(__go_b64chacha20__, variable, encryptedShellcode, formattedKey, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __go_b64chacha20__, cipher) - default: - fmt.Printf("[!] Guide mode does not support the %s in Go language, yet!\n\n", cipher) - } - case "python": - extension := "py" - - // Call function named SetDecryptionFile - foundFilename := SetDecryptionFile(extension) - - switch strings.ToLower(cipher) { - case "rot": - // Config dynamic variable - __python_rot__ = fmt.Sprintf(__python_rot__, variable, encryptedShellcode, key, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __python_rot__, cipher) - case "xor": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Config dynamic variable - __python_xor__ = fmt.Sprintf(__python_xor__, variable, encryptedShellcode, formattedKey, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __python_xor__, cipher) - case "rc4": - // Config dynamic variable - __python_rc4__ = fmt.Sprintf(__python_rc4__, passphrase, variable, encryptedShellcode, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __python_rc4__, cipher) - case "aes": - // Call function named KeyDetailsFormatter - formattedKey := Output.KeyDetailsFormatter(byteKey, language) - - // Call function named KeyDetailsFormatter - formattedIv := Output.KeyDetailsFormatter(iv, language) - - // Config dynamic variable - __python_aes__ = fmt.Sprintf(__python_aes__, formattedKey, formattedIv, variable, encryptedShellcode, variable, variable) - - // Call function named SaveTamplate2File - SaveTamplate2File(foundFilename, __python_aes__, cipher) - default: - fmt.Printf("[!] Guide mode does not support the %s in Python language, yet!\n\n", cipher) - } - default: - logger.Fatal("Unsupported programming language") - } -} diff --git a/Packages/Arguments/Arguments.go b/Packages/Arguments/Arguments.go new file mode 100644 index 0000000..22bde72 --- /dev/null +++ b/Packages/Arguments/Arguments.go @@ -0,0 +1,256 @@ +package Arguments + +import ( + "Supernova/Packages/Colors" + "flag" + "fmt" + "log" + "os" + "strings" +) + +// FlagOptions struct represents the options parsed from command line flags +type FlagOptions struct { + OutFile string + InputFile string + Language string + Encryption string + Obfuscation string + Variable string + Debug bool + Key int + Version bool +} + +var ( + version = "2.0" + versionName = "Thunder" + license = "MIT" + authors = [...]string{"@nickvourd", "@Papadope9", "0xvm"} + github = "https://github.com/nickvourd/Supernova" + ascii = ` + +███████╗██╗ ██╗██████╗ ███████╗██████╗ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ +██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗████╗ ██║██╔═══██╗██║ ██║██╔══██╗ +███████╗██║ ██║██████╔╝█████╗ ██████╔╝██╔██╗ ██║██║ ██║██║ ██║███████║ +╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██║ ██║╚██╗ ██╔╝██╔══██║ +███████║╚██████╔╝██║ ███████╗██║ ██║██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ +╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ +` + + text = ` +Supernova v%s - Real fucking shellcode encryptor & obfuscator tool. +Supernova is an open source tool licensed under %s. +Written with <3 by %s, %s and %s. +Please visit %s for more... + +` +) + +// PrintAscii function +func PrintAscii() { + // Initialize RandomColor + randomColor := Colors.RandomColor() + fmt.Print(randomColor(ascii)) + fmt.Printf(text, version, license, authors[0], authors[1], authors[2], github) +} + +// Options function +// Options function parses command line flags and returns FlagOptions +func Options() *FlagOptions { + inputFile := flag.String("input", "", "Path to a raw shellcode") + encryption := flag.String("enc", "", "Shellcode encoding/encryption (i.e., ROT, XOR, RC4, AES, CHACHA20)") + language := flag.String("lang", "", "Programming language to translate the shellcode (i.e., Nim, Rust, C, CSharp, Go, Python, PowerShell, Perl, Ruby, Java, Raw)") + outFile := flag.String("output", "", "Name of the output shellcode file") + variable := flag.String("var", "shellcode", "Name of dynamic variable") + debug := flag.Bool("debug", false, "Enable Debug mode") + key := flag.Int("key", 1, "Key length size for encryption") + version := flag.Bool("version", false, "Show Supernova current version") + obfuscation := flag.String("obf", "", "Shellcode obfuscation (i.e., IPV4, IPV6, MAC, UUID)") + flag.Parse() + + return &FlagOptions{ + OutFile: *outFile, + InputFile: *inputFile, + Language: *language, + Encryption: *encryption, + Variable: *variable, + Debug: *debug, + Key: *key, + Version: *version, + Obfuscation: *obfuscation, + } +} + +// ShowHelp function +func ShowHelp() { + fmt.Println("Usage of Suprenova:") + flag.PrintDefaults() + os.Exit(0) +} + +// ArgumentLength function +func ArgumentLength(versionFlag bool) { + logger := log.New(os.Stderr, "[!] ", 0) + switch len(os.Args) { + case 1: + // if no arguments print help menu + // Call function named ShowHelp + ShowHelp() + case 2: + // if one argument + if versionFlag { + // if version flag exists + fmt.Printf("[+] Current version: " + Colors.BoldRed(version) + "\n\n[+] Version name: " + Colors.BoldRed(versionName) + "\n\n") + os.Exit(0) + } else { + // if version flag not exists + // Call function named ShowHelp + ShowHelp() + } + default: + // if version flag exists + if versionFlag { + logger.Fatal("You cannot use the '-version' flag in conjunction with other arguments.\n\n") + } + } +} + +// ArgumentEmpty function +func ArgumentEmpty(statement string, option int) { + if statement == "" { + logger := log.New(os.Stderr, "[!] ", 0) + switch option { + case 1: + logger.Fatal("The '-input' flag specifying the path to raw shellcode is mandatory.\n\n") + case 2: + logger.Fatal("The '-lang' flag specifying a valid language option is mandatory (e.g., C, CSharp, Rust, Nim, Go, Python, PowerShell, Perl, Ruby, Java, Raw).\n\n") + case 3: + logger.Fatal("The size of the provided raw shellcode is too large!\n\n[!] The '-output' flag specifying the path to output shellcode is mandatory.\n\n") + default: + logger.Fatal("Invalid option specified for ArgumentEmpty function.") + } + } +} + +// ValidateArgument function +func ValidateArgument(argName string, argValue string, validValues []string) string { + // Add aliases for the language command-line names + if strings.ToLower(argValue) == "golang" || strings.ToLower(argValue) == "go-lang" { + argValue = "go" + } + + if strings.ToLower(argValue) == "pwsh" || strings.ToLower(argValue) == "ps1" || strings.ToLower(argValue) == "pshell" { + argValue = "powershell" + } + + if strings.ToLower(argValue) == "rb" { + argValue = "ruby" + } + + if strings.ToLower(argValue) == "py" { + argValue = "python" + } + + if strings.ToLower(argValue) == "pl" { + argValue = "perl" + } + + if strings.ToLower(argValue) == "c#" || strings.ToLower(argValue) == "cs" || strings.ToLower(argValue) == "c-sharp" { + argValue = "csharp" + } + + if strings.ToLower(argValue) == "bin" { + argValue = "raw" + } + + if strings.ToLower(argValue) == "rustlang" || strings.ToLower(argValue) == "rust-lang" || strings.ToLower(argValue) == "rs" { + argValue = "rust" + } + + if strings.ToLower(argValue) == "nimlang" || strings.ToLower(argValue) == "nim-lang" { + argValue = "nim" + } + + for _, valid := range validValues { + if strings.EqualFold(strings.ToLower(argValue), strings.ToLower(valid)) { + valid = strings.ToLower(valid) + return valid + } + } + + fmt.Printf("[!] Invalid value '%s' for argument '%s'. Valid values are: %v\n\n", argValue, argName, validValues) + os.Exit(1) + return "" +} + +// ShellcodeSizeValidation function +func ShellcodeSizeValidation(filename string) bool { + // set starting flag + stagelessFlag := false + logger := log.New(os.Stderr, "[!] ", 0) + // Open the file + file, err := os.Open(filename) + if err != nil { + logger.Fatal(err) + } + defer file.Close() + + // Get the file information + fileInfo, err := file.Stat() + if err != nil { + logger.Fatal(err) + } + + // Get the file size + fileSize := fileInfo.Size() + + // Convert 197 KB to bytes + sizeThresholdKB := 197 + sizeThresholdBytes := int64(sizeThresholdKB) * 1024 + + // Check if the file size is equal or greater than 197KB + if fileSize >= sizeThresholdBytes { + stagelessFlag = true + } else { + stagelessFlag = false + } + + return stagelessFlag +} + +// ValidateKeySize function +func ValidateKeySize(key int, encryption string) int { + logger := log.New(os.Stderr, "[!] ", 0) + + // if key is negative number or zero + if key <= 0 { + logger.Fatal("The provided key value is not valid.\n\n[!] Please provide a valid key value for the size.\n\n") + } + + // if encryption is AES + if strings.ToLower(encryption) == "aes" { + switch key { + case 128, 16: + key = 16 + case 192, 24: + key = 24 + case 256, 32: + key = 32 + default: + logger.Fatal("Provide a valid AES key:\n\n~> For AES-128-CBC: '-key 128' or '-key 16'\n\n~> For AES-192-CBC: '-key 192' or '-key 24'\n\n~> For AES-256-CBC: '-key 256' or '-key 32'\n\n") + } + } + + // if encryption is chacha20 + if strings.ToLower(encryption) == "chacha20" { + switch key { + case 32: + key = 32 + default: + logger.Fatal("Provide a valid Chacha20 key: '-key 32'\n\n") + } + } + + return key +} diff --git a/Packages/Colors/Colors.go b/Packages/Colors/Colors.go new file mode 100644 index 0000000..543a393 --- /dev/null +++ b/Packages/Colors/Colors.go @@ -0,0 +1,31 @@ +package Colors + +import ( + "math/rand" + "time" + + "github.com/fatih/color" +) + +var ( + // Bold Colors + BoldBlue = color.New(color.FgBlue, color.Bold).SprintFunc() + BoldRed = color.New(color.FgRed, color.Bold).SprintFunc() + BoldGreen = color.New(color.FgGreen, color.Bold).SprintFunc() + BoldYellow = color.New(color.FgYellow, color.Bold).SprintFunc() + BoldWhite = color.New(color.FgHiWhite, color.Bold).SprintFunc() + BoldMagneta = color.New(color.FgMagenta, color.Bold).SprintFunc() + BoldCyan = color.New(color.FgCyan, color.Bold).SprintFunc() +) + +// Define a slice containing all available color functions +var allColors = []func(a ...interface{}) string{ + BoldBlue, BoldRed, BoldGreen, BoldYellow, BoldWhite, BoldMagneta, BoldCyan, +} + +// RandomColor function +// RandomColor selects a random color function from the available ones +func RandomColor() func(a ...interface{}) string { + rand.Seed(time.Now().UnixNano()) + return allColors[rand.Intn(len(allColors))] +} diff --git a/Packages/Converters/Converters.go b/Packages/Converters/Converters.go new file mode 100644 index 0000000..675adaf --- /dev/null +++ b/Packages/Converters/Converters.go @@ -0,0 +1,272 @@ +package Converters + +import ( + "encoding/hex" + "fmt" + "os" + "strconv" + "strings" +) + +// UUIDTrimmer function +func UUIDTrimmer(uuidShellcode []string) []string { + // Process each UUID in the slice + for i, uuid := range uuidShellcode { + // Check if this is the last UUID in the slice + if i == len(uuidShellcode)-1 { + // Developer's debug + // fmt.Println("Before:", uuid) + + // Repeat the replacement until there are no more trailing hyphens after characters + for strings.HasSuffix(uuid, "-\"") { + uuid = strings.Replace(uuid, "-\"", "\"", 1) + } + + // Update the last UUID in the slice + uuidShellcode[i] = uuid + + // Developer's debug + //fmt.Println("After:", uuidShellcode[i]) // Print the updated UUID + } + } + + // Check if the last element is only hyphens + lastElement := uuidShellcode[len(uuidShellcode)-1] + //fmt.Println(lastElement) + if lastElement == "\"\"" { + // If yes, remove the last element + uuidShellcode = uuidShellcode[:len(uuidShellcode)-1] + // Developer's debug + //fmt.Println(uuidShellcode[len(uuidShellcode)-1]) + } + + return uuidShellcode +} + +// ConvertShellcodeHex2String function +func ConvertShellcodeHex2String(shellcode []string) string { + // Variable declaration + var formattedShellcode string + + // Join hexadecimal strings into one string with space after every two characters + for _, hexStr := range shellcode { + formattedShellcode += hexStr + " " + } + + return formattedShellcode +} + +// ConvertShellcode2String function +func ConvertShellcode2String(shellcodePath string) (string, error) { + // Read the contents of the file into a byte slice + fileContent, err := os.ReadFile(shellcodePath) + if err != nil { + return "", err + } + + // Convert the byte slice to a string + rawShellcode := strings.TrimSpace(string(fileContent)) + + return rawShellcode, nil +} + +// ConvertShellcode2Hex function +func ConvertShellcode2Hex(shellcode string, language string) (string, int) { + // Convert raw shellcode to hexadecimal + hexShellcode := hex.EncodeToString([]byte(shellcode)) + + // Split hex shellcode into individual hex values + hexValues := strings.Split(hexShellcode, "") + + var builder strings.Builder + + // Format and add "\x" in front of each pair of hex characters + if language == "python" || language == "perl" || language == "c" || language == "ruby" { + for i := 0; i < len(hexValues); i += 2 { + builder.WriteString("\\x") + builder.WriteString(hexValues[i]) + builder.WriteString(hexValues[i+1]) + } + } else if language == "java" { + // Format and add "(byte) 0x" in front of each pair of hex characters + for i := 0; i < len(hexValues); i += 2 { + builder.WriteString("(byte) 0x") + builder.WriteString(hexValues[i]) + builder.WriteString(hexValues[i+1]) + if i < len(hexValues)-2 { + builder.WriteString(", ") + } + } + } else { + // Format and add "0x" in front of each pair of hex characters + for i := 0; i < len(hexValues); i += 2 { + builder.WriteString("0x") + builder.WriteString(hexValues[i]) + builder.WriteString(hexValues[i+1]) + if i < len(hexValues)-2 { + builder.WriteString(", ") + } + } + } + + formattedHexShellcode := builder.String() + + // Calculate shellcode size in bytes + shellcodeSize := len(shellcode) + + return formattedHexShellcode, shellcodeSize +} + +// ConvertShellcode2Template function +func ConvertShellcode2Template(shellcode string, language string, length int, variable string) string { + switch language { + case "c": + template := fmt.Sprintf(`unsigned char %s[] = "%s";`, variable, shellcode) + return template + case "csharp": + template := fmt.Sprintf(`byte[] %s = new byte[%d] {%s};`, variable, length, shellcode) + return template + case "nim": + template := fmt.Sprintf(`var %s: array[%d, byte] = [byte %s]`, variable, length, shellcode) + return template + case "rust": + template := fmt.Sprintf(`let %s: [u8; %d] = [%s];`, variable, length, shellcode) + return template + case "go": + template := fmt.Sprintf(`%s := []byte{%s};`, variable, shellcode) + return template + case "python": + template := fmt.Sprintf(`%s = b"%s"`, variable, shellcode) + return template + case "raw": + return shellcode + case "powershell": + template := fmt.Sprintf(`[Byte[]] $%s = %s`, variable, shellcode) + return template + case "perl": + template := fmt.Sprintf(`my $%s = "%s";`, variable, shellcode) + return template + case "ruby": + template := fmt.Sprintf(`%s = "%s"`, variable, shellcode) + return template + case "java": + template := fmt.Sprintf(`byte %s[] = new byte {%s};`, variable, shellcode) + return template + default: + fmt.Println("[!] Unsupported programming language:", language) + os.Exit(1) + return "" + } +} + +// FormatShellcode function +func FormatShellcode(encryptedShellcode []byte, language string) string { + var formattedShellcode []string + var shellcodeFormatted string + + for _, b := range encryptedShellcode { + if language == "python" || language == "perl" || language == "c" || language == "ruby" { + formattedShellcode = append(formattedShellcode, fmt.Sprintf("\\x%02x", b)) + } else if language == "java" { + formattedShellcode = append(formattedShellcode, fmt.Sprintf("(byte) 0x%02x", b)) + } else { + formattedShellcode = append(formattedShellcode, fmt.Sprintf("0x%02x", b)) + } + } + + // Combine elements into a single string + if language == "python" || language == "perl" || language == "c" || language == "ruby" { + shellcodeFormatted = strings.Join(formattedShellcode, "") + } else { + shellcodeFormatted = strings.Join(formattedShellcode, ", ") + } + + return shellcodeFormatted +} + +// CleanShellcodeString function +func CleanShellcodeString(s string) string { + s = strings.ReplaceAll(s, " ", "") + s = strings.ReplaceAll(s, "0x", "") + s = strings.ReplaceAll(s, ",", "") + return s +} + +// ShellcodeFromByte2String function +// Function to convert byte array to string representation +func ShellcodeFromByte2String(shellcode []byte) string { + var builder strings.Builder + for _, b := range shellcode { + builder.WriteString(fmt.Sprintf("%02x ", b)) + } + return builder.String() +} + +// hexToDecimal function +// Function to convert array of hexadecimal strings to decimal integers +func ShellcodeFromStringHex2Decimal(shellcode []string) []int { + decArray := make([]int, len(shellcode)) + for i, hexStr := range shellcode { + decVal, _ := strconv.ParseInt(hexStr, 16, 64) + decArray[i] = int(decVal) + } + return decArray +} + +// ShellcodeDecimalArray2String function +// Function to convert a array of decimal to strings +func ShellcodeDecimalArray2String(decArray []int) string { + // Create an empty string + str := "" + + // Iterate over each decimal value in the array + for _, dec := range decArray { + // Convert the decimal value to string and append it to the string with a space + str += strconv.Itoa(dec) + " " + } + + // Trim any trailing space and return the resulting string + return strings.TrimSpace(str) +} + +// ConvertObfShellcode2Template function +func ConvertObfShellcode2Template(shellcode string, language string, variable string) string { + switch language { + case "c": + template := fmt.Sprintf(`char *%s[] = {%s};`, variable, shellcode) + return template + case "csharp": + template := fmt.Sprintf(`string[] %s = new string[] {%s};`, variable, shellcode) + return template + case "nim": + template := fmt.Sprintf(`var %s = [%s]`, variable, shellcode) + return template + case "rust": + template := fmt.Sprintf(`let %s = [%s];`, variable, shellcode) + return template + case "go": + template := fmt.Sprintf(`%s := [...]string{%s}`, variable, shellcode) + return template + case "python": + template := fmt.Sprintf(`%s = [%s]`, variable, shellcode) + return template + case "raw": + return shellcode + case "powershell": + template := fmt.Sprintf(`$%s = @(%s)`, variable, shellcode) + return template + case "perl": + template := fmt.Sprintf(`my @%s = (%s);`, variable, shellcode) + return template + case "ruby": + template := fmt.Sprintf(`%s = [%s]`, variable, shellcode) + return template + case "java": + template := fmt.Sprintf(`String[] %s = {%s};`, variable, shellcode) + return template + default: + fmt.Println("[!] Unsupported programming language:", language) + os.Exit(1) + return "" + } +} diff --git a/Encryptors/Encryptors.go b/Packages/Encryptors/Encryptors.go similarity index 54% rename from Encryptors/Encryptors.go rename to Packages/Encryptors/Encryptors.go index cee2e77..463a769 100644 --- a/Encryptors/Encryptors.go +++ b/Packages/Encryptors/Encryptors.go @@ -1,29 +1,23 @@ package Encryptors import ( - "Supernova/Converters" - "Supernova/Output" + "Supernova/Packages/Colors" + "Supernova/Packages/Converters" + "Supernova/Packages/Output" "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" - "encoding/base64" "fmt" "log" "math/big" "os" + "strconv" "strings" "golang.org/x/crypto/chacha20poly1305" ) -// Rc4Context represents the state of the RC4 encryption algorithm. -//type Rc4Context struct { -// i uint32 -// j uint32 -// s [256]uint8 -//} - const ( // chars defines the set of characters used to generate a random key and IV. chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+{}[]" @@ -32,31 +26,6 @@ const ( ivSize = 16 ) -// PKCS7Padding function -func PKCS7Padding(data []byte, blockSize int) []byte { - padding := blockSize - (len(data) % blockSize) - padText := bytes.Repeat([]byte{byte(padding)}, padding) - return append(data, padText...) -} - -// AESEncryption function -func AESEncryption(key []byte, iv []byte, plaintext []byte) ([]byte, error) { - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - // Apply PKCS7 padding to ensure plaintext length is a multiple of the block size - paddedData := PKCS7Padding(plaintext, aes.BlockSize) - ciphertext := make([]byte, len(paddedData)) - - // Create a new CBC mode encrypter - mode := cipher.NewCBCEncrypter(block, iv) - mode.CryptBlocks(ciphertext, paddedData) - - return ciphertext, nil -} - // GenerateRandomBytes function func GenerateRandomBytes(length int) []byte { randomBytes := make([]byte, length) @@ -85,7 +54,8 @@ func GenerateRandomPassphrase(length int) string { return string(passphrase) } -// XOREncryption function performs XOR encryption on input shellcode using a multi xor key. +// XOREncryption function +// Performs XOR encryption on input shellcode using a multi xor key. func XOREncryption(shellcode []byte, key []byte) []byte { encrypted := make([]byte, len(shellcode)) keyLen := len(key) @@ -97,7 +67,45 @@ func XOREncryption(shellcode []byte, key []byte) []byte { return encrypted } -// RC4Encryption function implements the RC4 encryption algorithm +// CaesarEncryption function +// Implements the Caesar encryption algorithm +func CaesarEncryption(shellcode []byte, shift int) []byte { + encrypted := make([]byte, len(shellcode)) + for i, char := range shellcode { + // Apply Caesar cipher encryption + encrypted[i] = byte((int(char) + shift) % 256) + } + return encrypted +} + +// PKCS7Padding function +func PKCS7Padding(data []byte, blockSize int) []byte { + padding := blockSize - (len(data) % blockSize) + padText := bytes.Repeat([]byte{byte(padding)}, padding) + return append(data, padText...) +} + +// AESEncryption function +// Performs AES-CBC encryption +func AESEncryption(key []byte, iv []byte, plaintext []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + // Apply PKCS7 padding to ensure plaintext length is a multiple of the block size + paddedData := PKCS7Padding(plaintext, aes.BlockSize) + ciphertext := make([]byte, len(paddedData)) + + // Create a new CBC mode encrypter + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(ciphertext, paddedData) + + return ciphertext, nil +} + +// RC4Encryption function +// Implements the RC4 encryption algorithm func RC4Encryption(data []byte, key []byte) []byte { var s [256]byte @@ -130,11 +138,6 @@ func RC4Encryption(data []byte, key []byte) []byte { // Encrypt data using given key (32 bytes) // https://github.com/alinz/crypto.go/blob/main/chacha20.go func Chacha20Encryption(data []byte, key []byte) ([]byte, error) { - if len(key) != 32 { - logger := log.New(os.Stderr, "[!] ", 0) - logger.Fatal("Bad key length, expected 32 bytes\n") - } - aead, err := chacha20poly1305.NewX(key) if err != nil { return nil, err @@ -153,20 +156,8 @@ func Chacha20Encryption(data []byte, key []byte) ([]byte, error) { return aead.Seal(nonce, nonce, data, nil), nil } -// CaesarEncryption function implements the Caesar encryption algorithm -func CaesarEncryption(shellcode []byte, shift int) []byte { - encrypted := make([]byte, len(shellcode)) - for i, char := range shellcode { - // Apply Caesar cipher encryption - encrypted[i] = byte((int(char) + shift) % 256) - //encryptedChar := char + byte(shift) - //encrypted[i] = encryptedChar - } - return encrypted -} - // DetectEncryption function -func DetectEncryption(cipher string, shellcode string, key int, language string) (string, int, []byte, string, []byte) { +func DetectEncryption(cipher string, shellcode string, key int, language string) (string, int, []byte) { // Set logger for errors logger := log.New(os.Stderr, "[!] ", 0) @@ -196,36 +187,13 @@ func DetectEncryption(cipher string, shellcode string, key int, language string) // Call function named FormatShellcode shellcodeFormatted := Converters.FormatShellcode(encryptedShellcode, language) - return shellcodeFormatted, len(encryptedShellcode), xorKey, "", nil - case "b64xor": - // Call function named GenerateRandomBytes - xorKey := GenerateRandomBytes(shift) - - // Print generated XOR key - fmt.Printf("[+] Generated XOR key: ") - - // Call function named PrintKeyDetails - Output.PrintKeyDetails(xorKey) - - // Call function named XOREncryption - encryptedShellcode := XOREncryption(shellcodeInBytes, xorKey) - - // Convert encryptedShellcode to Base64 - encryptedShellcodeBase64 := base64.StdEncoding.EncodeToString(encryptedShellcode) - - // Convert Base64 string to []byte - encryptedShellcodeBytes := []byte(encryptedShellcodeBase64) - - // Print length changed notification - fmt.Printf("[+] New Payload size: %d bytes\n\n", len(encryptedShellcodeBytes)) - - // Call function named FormatShellcode - shellcodeFormatted := Converters.FormatShellcode(encryptedShellcodeBytes, language) - - return shellcodeFormatted, len(encryptedShellcode), xorKey, "", nil + return shellcodeFormatted, len(encryptedShellcode), encryptedShellcode case "rot": + // Convert the integer to a string + shiftString := strconv.Itoa(shift) + // Print selected shift key - fmt.Printf("[+] Selected Shift key: %d\n\n", shift) + fmt.Printf("[+] Selected Shift key: %s\n\n", Colors.BoldGreen(shiftString)) // Call function named XOREncryption encryptedShellcode := CaesarEncryption(shellcodeInBytes, shift) @@ -233,7 +201,7 @@ func DetectEncryption(cipher string, shellcode string, key int, language string) // Call function named FormatShellcode shellcodeFormatted := Converters.FormatShellcode(encryptedShellcode, language) - return shellcodeFormatted, len(encryptedShellcode), nil, "", nil + return shellcodeFormatted, len(encryptedShellcode), encryptedShellcode case "aes": // Set key from argument key keySize := key @@ -266,61 +234,16 @@ func DetectEncryption(cipher string, shellcode string, key int, language string) panic(err) } - // Print length changed notification - fmt.Printf("[+] New Payload size: %d bytes\n\n", len(encryptedShellcode)) - - // Call function named FormatShellcode - shellcodeFormatted := Converters.FormatShellcode(encryptedShellcode, language) - - return shellcodeFormatted, len(encryptedShellcode), key, "", iv - case "b64aes": - // Set key from argument key - keySize := key - - // Generate a random 32-byte key and a random 16-byte IV - key := GenerateRandomBytes(keySize) - iv := GenerateRandomBytes(ivSize) - - // Print generated key - fmt.Printf("[+] Generated key (32-byte): ") - - // Call function named PrintKeyDetails - Output.PrintKeyDetails(key) - - // Print generated key - fmt.Printf("[+] Generated IV (16-byte): ") - - // Call function named PrintKeyDetails - Output.PrintKeyDetails(iv) - - // Call function named DetectNotification - keyNotification := Output.DetectNotification(keySize) - - // Print AES--CBC notification - fmt.Printf("[+] Using AES-%d-CBC encryption\n\n", keyNotification) - - // Encrypt the shellcode using AES-256-CBC - encryptedShellcode, err := AESEncryption(key, iv, shellcodeInBytes) - if err != nil { - panic(err) - } + // Convert the integer to a string + lenEncryptedShellcodeString := strconv.Itoa(len(encryptedShellcode)) // Print length changed notification - fmt.Printf("[+] New Payload size: %d bytes\n\n", len(encryptedShellcode)) - - // Convert encryptedShellcode to Base64 - encryptedShellcodeBase64 := base64.StdEncoding.EncodeToString(encryptedShellcode) - - // Convert Base64 string to []byte - encryptedShellcodeBytes := []byte(encryptedShellcodeBase64) - - // Print length changed notification - fmt.Printf("[+] New Payload size: %d bytes\n\n", len(encryptedShellcodeBytes)) + fmt.Printf("[+] New Payload size: %s bytes\n\n", Colors.BoldYellow(lenEncryptedShellcodeString)) // Call function named FormatShellcode - shellcodeFormatted := Converters.FormatShellcode(encryptedShellcodeBytes, language) + shellcodeFormatted := Converters.FormatShellcode(encryptedShellcode, language) - return shellcodeFormatted, len(encryptedShellcode), key, "", iv + return shellcodeFormatted, len(encryptedShellcode), encryptedShellcode case "rc4": // Call function named GenerateRandomPassphrase randomPassphrase := GenerateRandomPassphrase(key) @@ -329,7 +252,7 @@ func DetectEncryption(cipher string, shellcode string, key int, language string) rc4Key := []byte(randomPassphrase) // Print generated passphrase - fmt.Printf("[+] Generated passphrase: %s\n\n", randomPassphrase) + fmt.Printf("[+] Generated passphrase: %s\n\n", Colors.BoldGreen(randomPassphrase)) // Call function named RC4Encryption encryptedShellcode := RC4Encryption(shellcodeInBytes, rc4Key) @@ -337,36 +260,10 @@ func DetectEncryption(cipher string, shellcode string, key int, language string) // Call function named FormatShellcode shellcodeFormatted := Converters.FormatShellcode(encryptedShellcode, language) - return shellcodeFormatted, len(encryptedShellcode), rc4Key, randomPassphrase, nil - case "b64rc4": - // Call function named GenerateRandomPassphrase - randomPassphrase := GenerateRandomPassphrase(key) - - // Convert passphrase to bytes - rc4Key := []byte(randomPassphrase) - - // Print generated passphrase - fmt.Printf("[+] Generated passphrase: %s\n\n", randomPassphrase) - - // Call function named RC4Encryption - encryptedShellcode := RC4Encryption(shellcodeInBytes, rc4Key) - - // Convert encryptedShellcode to Base64 - encryptedShellcodeBase64 := base64.StdEncoding.EncodeToString(encryptedShellcode) - - // Convert Base64 string to []byte - encryptedShellcodeBytes := []byte(encryptedShellcodeBase64) - - // Print length changed notification - fmt.Printf("[+] New Payload size: %d bytes\n\n", len(encryptedShellcodeBytes)) - - // Call function named FormatShellcode - shellcodeFormatted := Converters.FormatShellcode(encryptedShellcodeBytes, language) - - return shellcodeFormatted, len(encryptedShellcode), rc4Key, randomPassphrase, nil + return shellcodeFormatted, len(encryptedShellcode), encryptedShellcode case "chacha20": // Call function named GenerateRandomBytes - chacha20Key := GenerateRandomBytes(32) + chacha20Key := GenerateRandomBytes(key) // Print generated Chacha2 key fmt.Printf("[+] Generated Chacha20 key: ") @@ -377,41 +274,18 @@ func DetectEncryption(cipher string, shellcode string, key int, language string) // Call function named Chacha20Encryption encryptedShellcode, _ := Chacha20Encryption(shellcodeInBytes, chacha20Key) - // Call function named FormatShellcode - shellcodeFormatted := Converters.FormatShellcode(encryptedShellcode, language) - - return shellcodeFormatted, len(encryptedShellcode), chacha20Key, "", nil - case "b64chacha20": - // Call function named GenerateRandomBytes - chacha20Key := GenerateRandomBytes(32) - - // Print generated Chacha2 key - fmt.Printf("[+] Generated Chacha20 key: ") - - // Call function named PrintKeyDetails - Output.PrintKeyDetails(chacha20Key) - - // Call function named Chacha20Encryption - encryptedShellcode, err := Chacha20Encryption(shellcodeInBytes, chacha20Key) - if err != nil { - panic(err) - } - - // Convert encryptedShellcode to Base64 - encryptedShellcodeBase64 := base64.StdEncoding.EncodeToString(encryptedShellcode) - - // Convert Base64 string to []byte - encryptedShellcodeBytes := []byte(encryptedShellcodeBase64) + // Convert the integer to a string + lenEncryptedShellcodeString := strconv.Itoa(len(encryptedShellcode)) // Print length changed notification - fmt.Printf("[+] New Payload size: %d bytes\n\n", len(encryptedShellcodeBytes)) + fmt.Printf("[+] New Payload size: %s bytes\n\n", Colors.BoldYellow(lenEncryptedShellcodeString)) // Call function named FormatShellcode - shellcodeFormatted := Converters.FormatShellcode(encryptedShellcodeBytes, language) + shellcodeFormatted := Converters.FormatShellcode(encryptedShellcode, language) - return shellcodeFormatted, len(encryptedShellcode), chacha20Key, "", nil + return shellcodeFormatted, len(encryptedShellcode), encryptedShellcode default: logger.Fatal("Unsupported encryption cipher") - return "", 0, nil, "", nil + return "", 0, nil } } diff --git a/Packages/Manager/Manager.go b/Packages/Manager/Manager.go new file mode 100644 index 0000000..c1e5134 --- /dev/null +++ b/Packages/Manager/Manager.go @@ -0,0 +1,131 @@ +package Manager + +import ( + "Supernova/Packages/Arguments" + "Supernova/Packages/Converters" + "Supernova/Packages/Encryptors" + "Supernova/Packages/Obfuscators" + "Supernova/Packages/Output" + "fmt" + "strings" +) + +// EncryptionManager function +func EncryptionManager(Key int, Encryption string, Obfuscation string, Debug bool, Variable string, rawShellcode string, foundLanguage string, fileSizeFlag bool) (string, []byte) { + // Call function ValidateKeySize + Key = Arguments.ValidateKeySize(Key, Encryption) + + // Call function named DetectEncryption + encryptedShellcode, encryptedLength, decEncryptedShellcode := Encryptors.DetectEncryption(Encryption, rawShellcode, Key, foundLanguage) + + // Call function named ConvertShellcode2Template + template := Converters.ConvertShellcode2Template(encryptedShellcode, foundLanguage, encryptedLength, Variable) + + // Check if Obfuscation is empty + if Obfuscation == "" { + // Handle the case when Obfuscation is empty + if fileSizeFlag { + // If fileSizeFlag is true + fmt.Printf("[!] The size of the encrypted shellcode exceeds the maximum display limit.\n\n[!] Supernova cannot display it on the screen.\n\n") + } else { + if foundLanguage == "raw" { + // If the foundLanguage is "raw" + fmt.Printf("[!] The encrypted shellcode is displayed in raw format represented as hexadecimal on the terminal.\n\n") + } + // Print the encrypted template + fmt.Printf("[+] The encrypted payload with %s:\n\n%s\n\n", strings.ToUpper(Encryption), template) + } + } else { + // Handle the case when Obfuscation is not empty + if Debug { + // If Debug mode is enabled + if fileSizeFlag { + // If fileSizeFlag is true + fmt.Printf("[!] The size of the encrypted shellcode exceeds the maximum display limit.\n\n[!] Supernova cannot display it on the screen.\n\n") + } else { + if foundLanguage == "raw" { + // If the foundLanguage is "raw" + fmt.Printf("[!] The encrypted shellcode is displayed in raw format represented as hexadecimal on the terminal.\n\n") + } + // Print the encrypted template + fmt.Printf("[+] The encrypted payload with %s:\n\n%s\n\n", strings.ToUpper(Encryption), template) + } + } + } + + return template, decEncryptedShellcode +} + +// OutputManager function +func OutputManager(OutFile string, Language string, template string, Encryption string, Obfuscation string) { + language := strings.ToLower(Language) + // Declare variables + var encryptionFlag bool + + if OutFile != "" { + // Encrytpion option is enable + if Encryption != "" { + // Obfuscation option is enable + if Obfuscation != "" { + // Call function named SaveOutputToFile + err := Output.SaveOutputToFile(template, OutFile, encryptionFlag) + if err != nil { + fmt.Println("[!] Error:", err) + return + } + } else { + if language == "raw" { + // Call function named SaveShellcodeToFile + err := Output.SaveShellcodeToFile(template, OutFile) + if err != nil { + fmt.Println("[!] Error:", err) + return + } + } else { + // Set encryptionFlag true + encryptionFlag = true + + // Call function named SaveOutputToFile + err := Output.SaveOutputToFile(template, OutFile, encryptionFlag) + if err != nil { + fmt.Println("[!] Error:", err) + return + } + } + } + } else { + // Call function named SaveOutputToFile + err := Output.SaveOutputToFile(template, OutFile, encryptionFlag) + if err != nil { + fmt.Println("[!] Error:", err) + return + } + } + } +} + +// ObfuscationManager function +func ObfuscationManager(shellcode []byte, Obfuscation string, Language string, Variable string, fileSizeFlag bool) string { + + // Call function named ShellcodeFromByteString + formattedStringShellcode := Converters.ShellcodeFromByte2String(shellcode) + + // Convert string to array of hexadecimal strings + shellcodeHexArray := strings.Split(formattedStringShellcode, " ") + + // Call function named DetectObfuscation + ObfuscatedShellcode := Obfuscators.DetectObfuscation(Obfuscation, shellcodeHexArray) + + // Call function named ConvertObfShellcode2Template + template := Converters.ConvertObfShellcode2Template(ObfuscatedShellcode, Language, Variable) + + // If fileSizeFlag is true + if fileSizeFlag { + fmt.Printf("[!] The size of the obfuscated shellcode exceeds the maximum display limit.\n\n[!] Supernova cannot display it on the screen.\n\n") + } else { + // Print the obfuscated template + fmt.Printf("[+] The obfuscated payload as %s:\n\n%s\n\n", strings.ToUpper(Obfuscation), template) + } + + return template +} diff --git a/Packages/Obfuscators/Obfuscators.go b/Packages/Obfuscators/Obfuscators.go new file mode 100644 index 0000000..f0e299f --- /dev/null +++ b/Packages/Obfuscators/Obfuscators.go @@ -0,0 +1,449 @@ +package Obfuscators + +import ( + "Supernova/Packages/Colors" + "Supernova/Packages/Converters" + "fmt" + "log" + "math/rand" + "os" + "strings" +) + +// LittleEndian function +func LittleEndian(slice []string) []string { + newSlice := make([]string, len(slice)) + copy(newSlice, slice) + for i := len(newSlice)/2 - 1; i >= 0; i-- { + opp := len(newSlice) - 1 - i + newSlice[i], newSlice[opp] = newSlice[opp], newSlice[i] + } + + return newSlice +} + +// GetSegment function +func GetSegment(segment []string, start, end int) string { + if start >= len(segment) { + return "" + } + + if end > len(segment) { + end = len(segment) + } + + return strings.Join(LittleEndian(segment[start:end]), "") +} + +// GetSegmentNormal function (without LittleEndian) +func GetSegmentNormal(segment []string, start, end int) string { + if start >= len(segment) { + return "" + } + + if end > len(segment) { + end = len(segment) + } + + return strings.Join(segment[start:end], "") +} + +// EnsureSegmentLength function +// EnsureSegmentLength checks if a segment has the desired length and appends random hex if needed +func EnsureSegmentLength(segment string, desiredLength int) (string, int, []string) { + // Declare variables + var randomHexValues []string + totalRandomHexAdded := 0 + + if len(segment) < desiredLength { + // Append random hex values until the segment reaches the desired length + for len(segment) < desiredLength { + randomHex := fmt.Sprintf("%02X", rand.Intn(240)+16) + segment += strings.ToLower(randomHex) + randomHexValues = append(randomHexValues, randomHex) + totalRandomHexAdded++ + } + } + return segment, totalRandomHexAdded, randomHexValues +} + +// UUIDObfuscation function +func UUIDObfuscation(shellcode string) (string, int, []string) { + // Split the shellcode into hex pairs. + hexPairs := strings.Split(shellcode, " ") + + // Initialize a counter for the random hex values + var randomHexCount1, randomHexCount2, randomHexCount3, randomHexCount4, randomHexCount5 int + var randomHexValues1, randomHexValues2, randomHexValues3, randomHexValues4, randomHexValues5 []string + var result []string + var nonEmptyStrings []string + var finalResult string + + // Iterate over the hex pairs in groups of 18. + for i := 0; i < len(hexPairs); i += 18 { + // Determine the end of the current group. + end := i + 18 + if end > len(hexPairs) { + end = len(hexPairs) + } + + // Get the current group of hex pairs. + segment := hexPairs[i:end] + + // Split the segment into five parts to form a UUID. + segment1 := GetSegment(segment, 0, 4) + segment2 := GetSegment(segment, 4, 6) + segment3 := GetSegment(segment, 6, 8) + segment4 := GetSegmentNormal(segment, 8, 10) + segment5 := GetSegmentNormal(segment, 10, 16) + + // Ensure each segment has the desired length + segment1, randomHexCount1, randomHexValues1 = EnsureSegmentLength(segment1, 8) + segment2, randomHexCount2, randomHexValues2 = EnsureSegmentLength(segment2, 4) + segment3, randomHexCount3, randomHexValues3 = EnsureSegmentLength(segment3, 4) + segment4, randomHexCount4, randomHexValues4 = EnsureSegmentLength(segment4, 4) + segment5, randomHexCount5, randomHexValues5 = EnsureSegmentLength(segment5, 12) + + // Append the formatted UUID to the result. + result = append(result, fmt.Sprintf("\"%s-%s-%s-%s-%s\"", segment1, segment2, segment3, segment4, segment5)) + } + + // Sum of counters + TotalCounter := randomHexCount1 + randomHexCount2 + randomHexCount3 + randomHexCount4 + randomHexCount5 + + // Function to filter out empty strings and append non-empty ones + filterAndAppend := func(arr []string) { + for _, s := range arr { + if s != "" { + nonEmptyStrings = append(nonEmptyStrings, s) + } + } + } + + // Apply the filterAndAppend function to each array + filterAndAppend(randomHexValues1) + filterAndAppend(randomHexValues2) + filterAndAppend(randomHexValues3) + filterAndAppend(randomHexValues4) + filterAndAppend(randomHexValues5) + + // Call function named UUIDTrimmer + result = Converters.UUIDTrimmer(result) + + // Join the result array into a single string. + finalResult = strings.Join(result, ", ") + + return finalResult, TotalCounter, nonEmptyStrings +} + +// MacObfuscation function +func MacObfuscation(shellcode string) (string, int, []string) { + // Trim leading and trailing spaces from the shellcode string + shellcode = strings.TrimSpace(shellcode) + + // Split the shellcode string by space separator + split := strings.Split(shellcode, " ") + + // Initialize an empty slice to store the resulting groups + var result []string + + // Initialize a counter for the random hex values + var randomHexCount int + var randomHexValues []string + + // Iterate over the split shellcode with a step of 6 + for i := 0; i < len(split); i += 6 { + // Define the end index for the current group + end := i + 6 + // If the end index exceeds the length of split, set it to the length of split + if end > len(split) { + end = len(split) + } + // Create a group of up to 6 elements + group := split[i:end] + + // If the group has less than 6 elements, generate and append random hex values + if len(group) < 6 { + // Generate and append random hex values to the group + for j := len(group); j < 6; j++ { + randomHex := fmt.Sprintf("%02X", rand.Intn(240)+16) + group = append(group, strings.ToLower(randomHex)) + randomHexValues = append(randomHexValues, randomHex) + randomHexCount++ + } + } + + // Join the elements of the group with "-" separator and wrap each element in quotes + result = append(result, fmt.Sprintf("\"%s-%s-%s-%s-%s-%s\"", group[0], group[1], group[2], group[3], group[4], group[5])) + } + + // Join the resulting groups with ", " separator + output := strings.Join(result, ", ") + + return output, randomHexCount, randomHexValues +} + +// IPv6Obfuscation function +func IPv6Obfuscation(shellcode string) ([]string, int, []string) { + // Remove all spaces + shellcode = strings.ReplaceAll(shellcode, " ", "") + + // Initialize the counter for the random hexadecimal values + randomHexCount := 0 + + // Declare string array + var randomHexValues []string + + // Check if the length of the string is not a multiple of 32 + if len(shellcode)%32 != 0 { + // Calculate the number of characters needed to make it a multiple of 32 + remaining := 32 - (len(shellcode) % 32) + + // Generate random hexadecimal values and append them to the shellcode + for i := 0; i < remaining; i = i + 2 { + randomHex := fmt.Sprintf("%X", rand.Intn(240)+16) + shellcode += strings.ToLower(randomHex) + randomHexValues = append(randomHexValues, randomHex) + randomHexCount++ + } + } + + // Split the string every 32 characters + var parts []string + for i := 0; i < len(shellcode); i += 32 { + // Check if there are enough characters left + if i+32 > len(shellcode) { + parts = append(parts, shellcode[i:]) + break + } + parts = append(parts, shellcode[i:i+32]) + } + + // Add ":" every four characters of 32, exclude the last four + for i, part := range parts { + var newPart string + for j := 0; j < len(part)-4; j += 4 { + newPart += part[j:j+4] + ":" + } + newPart += part[len(part)-4:] + parts[i] = "\"" + newPart + "\"," + } + + return parts, randomHexCount, randomHexValues +} + +// IPv4Obfuscation function +func IPv4Obfuscation(shellcode string) string { + // Arrays to store added numbers and their hexadecimal representations + var addedNumbers []int + var hexRepresentations []string + + // Variables eclaration + var pronous string = "it" + var pronousNum string = "number" + var result string + + // Split the original string into chunks of four digits + chunks := strings.Fields(shellcode) + + // Initialize an empty slice to store the chunkResult + var chunkResult []string + + // Declare variables + var shellcodeProperty string + + // Iterate over the chunks and add them to the chunkResult slice + for i, chunk := range chunks { + chunkResult = append(chunkResult, chunk) + + // Add a dot after every fourth chunk, except for the last chunk + if (i+1)%4 == 0 && i != len(chunks)-1 { + // Join the slice into a string with dots + configResult := strings.Join(chunkResult, ".") + shellcodeProperty += "\"" + configResult + "\", " + chunkResult = chunkResult[:0] // Reset chunkResult slice for the next iteration + } + } + + // Loop until the length of chunkResult is equal to 4 + for len(chunkResult) < 4 { + // Generate a random decimal from 0 to 255 + randomNumber := rand.Intn(256) + + // Convert decimal to hexadecimal + randomHex := fmt.Sprintf("0x%X", randomNumber) + + // Convert the random number to a string + randomString := fmt.Sprintf("%d", randomNumber) + + // Add the random number and its hexadecimal representation to arrays + addedNumbers = append(addedNumbers, randomNumber) + hexRepresentations = append(hexRepresentations, randomHex) + + // Add the random string to the slice + chunkResult = append(chunkResult, randomString) + } + + // Print the message with the count of added numbers and their details + count := len(addedNumbers) + + // if count more than one + if count > 1 { + pronousNum = "numbers" + } + + if count > 0 { + fmt.Printf("[+] Configure payload length evenly for IPv4 obfuscation by adding %d random %s:\n\n", count, pronousNum) + + // Iterate over each element and build the result string + for i, num := range addedNumbers { + hexRep := hexRepresentations[i] + + // Append the formatted string to the result + if i < count-1 { + result += fmt.Sprintf(Colors.BoldRed("%d "), num) + result += fmt.Sprintf("=> byte(%s)", Colors.BoldMagneta(strings.ToLower(hexRep))) + result += ", " + } else { + result += fmt.Sprintf(Colors.BoldRed("%d "), num) + result += fmt.Sprintf("=> byte(%s)", Colors.BoldMagneta(strings.ToLower(hexRep))) + } + } + + fmt.Printf(" " + result + "\n\n") + + // if generated numbers are more than one + if count > 1 { + pronous = "them" + } + + fmt.Printf("[!] Be sure to remove %s during the implementation process!\n\n", pronous) + } + + // Join the last remaining elements into a string with dots + configResult := strings.Join(chunkResult, ".") + + shellcodeProperty += "\"" + configResult + "\"" + + return shellcodeProperty +} + +// DetectObfuscation function +func DetectObfuscation(obfuscation string, shellcode []string) string { + // Set logger for errors + logger := log.New(os.Stderr, "[!] ", 0) + + // Declare variables + var obfuscatedShellcodeString string + var pronousChar string = "byte" + var pronous string = "it" + + switch obfuscation { + case "ipv4": + // Call function named ShellcodeFromStringHex2Decimal + shellcodeDecArray := Converters.ShellcodeFromStringHex2Decimal(shellcode) + + // Call function named ShellcodeDecimalArray2String + shellcodeStr := Converters.ShellcodeDecimalArray2String(shellcodeDecArray) + + // Call function named IPv4Obfuscation + obfuscatedShellcodeString = IPv4Obfuscation(shellcodeStr) + + return obfuscatedShellcodeString + case "ipv6": + // Call function named ConvertShellcodeHex2String + shellcodeStr := Converters.ConvertShellcodeHex2String(shellcode) + + // Call function named IPv6Obfuscation + obfuscatedShellcode, randomHexCount, randomHexValues := IPv6Obfuscation(shellcodeStr) + + // if count more than zero + if randomHexCount > 0 { + // if count more than one + if randomHexCount > 1 { + pronousChar = "bytes" + pronous = "them" + } + + // Call function named CustomPayloadMessage + CustomPayloadMessage(obfuscation, randomHexCount, randomHexValues, pronous, pronousChar) + } + + // Add any part to a string + for _, part := range obfuscatedShellcode { + obfuscatedShellcodeString += part + } + + // Remove comma + obfuscatedShellcodeString = obfuscatedShellcodeString[:len(obfuscatedShellcodeString)-1] + + return obfuscatedShellcodeString + case "mac": + // Call function named ConvertShellcodeHex2String + shellcodeStr := Converters.ConvertShellcodeHex2String(shellcode) + + // Call function named MacObfuscation + obfuscatedShellcodeString, randomHexCount, randomHexValues := MacObfuscation(shellcodeStr) + + // if count more than zero + if randomHexCount > 0 { + // if count more than one + if randomHexCount > 1 { + pronousChar = "bytes" + pronous = "them" + } + + // Call function named CustomPayloadMessage + CustomPayloadMessage(obfuscation, randomHexCount, randomHexValues, pronous, pronousChar) + } + + return obfuscatedShellcodeString + case "uuid": + // Call function named ConvertShellcodeHex2String + shellcodeStr := Converters.ConvertShellcodeHex2String(shellcode) + + //Call function named UUIDObfuscation + obfuscatedShellcodeString, randomHexCount, randomHexValues := UUIDObfuscation(shellcodeStr) + + // if count more than zero + if randomHexCount > 0 { + // if count more than one + if randomHexCount > 1 { + pronousChar = "bytes" + pronous = "them" + } + + // Call function named CustomPayloadMessage + CustomPayloadMessage(obfuscation, randomHexCount, randomHexValues, pronous, pronousChar) + } + + return obfuscatedShellcodeString + default: + logger.Fatal("Unsupported obfuscation technique") + return "" + } +} + +// CustomPayloadMessage function +func CustomPayloadMessage(obfuscation string, randomHexCount int, randomHexValues []string, pronous string, pronousChar string) { + // Declare variables + var hexString string + + fmt.Printf("[+] Configure payload length evenly for %s obfuscation by adding %d random %s:\n\n", obfuscation, randomHexCount, pronousChar) + + // Iterate over each character + for i, char := range randomHexValues { + // Convert the character to lowercase and append it to hexString + hexString += Colors.BoldRed(strings.ToLower(char)) + + // Add a comma and space if it's not the last element + if i < len(randomHexValues)-1 { + hexString += ", " + } + } + + fmt.Printf(" " + hexString + "\n\n") + + fmt.Printf("[!] Be sure to remove %s during the implementation process!\n\n", pronous) + +} diff --git a/Output/Output.go b/Packages/Output/Output.go similarity index 68% rename from Output/Output.go rename to Packages/Output/Output.go index 4b7973b..c18e9e2 100644 --- a/Output/Output.go +++ b/Packages/Output/Output.go @@ -1,46 +1,25 @@ package Output import ( - "Supernova/Converters" - "Supernova/Utils" + "Supernova/Packages/Colors" + "Supernova/Packages/Converters" + "Supernova/Packages/Utils" "encoding/hex" "fmt" "log" "os" + "strconv" ) -// SaveOutputToFile function -func SaveOutputToFile(outputData string, filename string) error { - // Open the file for writing - file, err := os.Create(filename) - if err != nil { - return err - } - defer file.Close() - - // Write the output data to the file - _, err = file.WriteString(outputData) - if err != nil { - return err - } - - // Call function named GetAbsolutePath - absolutePath, err := Utils.GetAbsolutePath(filename) - if err != nil { - fmt.Println("Error:", err) - return err - } - - fmt.Printf("[+] Save encrypted shellcode to " + absolutePath + "\n\n") - return nil -} - // PrintKeyDetails function func PrintKeyDetails(key []byte) { for i, b := range key { decimalValue := int(b) - hexValue := fmt.Sprintf("%02x", b) - fmt.Printf("byte(0x%s) => %d", hexValue, decimalValue) + hexValue := fmt.Sprintf("0x%02x", b) + + // Convert the integer to a string + decimalValueString := strconv.Itoa(decimalValue) + fmt.Printf("byte(%s) => %s", Colors.BoldMagneta(hexValue), Colors.BoldRed(decimalValueString)) if i < len(key)-1 { fmt.Printf(", ") } @@ -49,24 +28,6 @@ func PrintKeyDetails(key []byte) { fmt.Printf("\n\n") } -// KeyDetailsFormatter function -func KeyDetailsFormatter(key []byte, language string) string { - var formattedKey string - for i, b := range key { - if language == "python" { - hexValue := fmt.Sprintf("%02x", b) - formattedKey += "\\x" + hexValue - } else { - hexValue := fmt.Sprintf("%02x", b) - formattedKey += "0x" + hexValue - if i < len(key)-1 { - formattedKey += ", " - } - } - } - return formattedKey -} - // DetectNotification function func DetectNotification(key int) int { logger := log.New(os.Stderr, "[!] ", 0) @@ -85,6 +46,38 @@ func DetectNotification(key int) int { return keyNotification } +// SaveOutputToFile function +func SaveOutputToFile(outputData string, filename string, statement bool) error { + // Open the file for writing + file, err := os.Create(filename) + if err != nil { + return err + } + defer file.Close() + + // Write the output data to the file + _, err = file.WriteString(outputData) + if err != nil { + return err + } + + // Call function named GetAbsolutePath + absolutePath, err := Utils.GetAbsolutePath(filename) + if err != nil { + fmt.Println("[!] Error:", err) + return err + } + + //fmt.Println(statement) + if statement { + fmt.Printf("[+] The encrypted shellcode saved to " + absolutePath + " file.\n\n") + } else { + fmt.Printf("[+] The obfuscated shellcode saved to " + absolutePath + " file.\n\n") + } + + return nil +} + // SaveShellcodeToFile function func SaveShellcodeToFile(shellcode, filename string) error { // Removes Spaces and the "0x" prefix from the string @@ -116,6 +109,6 @@ func SaveShellcodeToFile(shellcode, filename string) error { return err } - fmt.Printf("[+] Save encrypted shellcode file to " + absolutePath + "\n\n") + fmt.Printf("[+] The encrypted shellcode saved to " + absolutePath + " file.\n\n") return nil } diff --git a/Packages/Utils/Utils.go b/Packages/Utils/Utils.go new file mode 100644 index 0000000..705f52e --- /dev/null +++ b/Packages/Utils/Utils.go @@ -0,0 +1,31 @@ +package Utils + +import ( + "log" + "os" + "path/filepath" + "runtime" + "strconv" + "strings" +) + +// CheckGoVersio function +func CheckGoVersion() { + version := runtime.Version() + version = strings.Replace(version, "go1.", "", -1) + verNumb, _ := strconv.ParseFloat(version, 64) + if verNumb < 19.1 { + logger := log.New(os.Stderr, "[!] ", 0) + logger.Fatal("The version of Go is to old, please update to version 1.19.1 or later...\n") + } +} + +// GetAbsolutePath function +func GetAbsolutePath(filename string) (string, error) { + // Get the absolute path of the file + absolutePath, err := filepath.Abs(filename) + if err != nil { + return "", err + } + return absolutePath, nil +} diff --git a/Pictures/AES-128-C.png b/Pictures/AES-128-C.png deleted file mode 100644 index 623d9a8..0000000 Binary files a/Pictures/AES-128-C.png and /dev/null differ diff --git a/Pictures/AES-192-Rust.png b/Pictures/AES-192-Rust.png deleted file mode 100644 index 596f9e0..0000000 Binary files a/Pictures/AES-192-Rust.png and /dev/null differ diff --git a/Pictures/AES-256-Csharp.png b/Pictures/AES-256-Csharp.png deleted file mode 100644 index 5c12fae..0000000 Binary files a/Pictures/AES-256-Csharp.png and /dev/null differ diff --git a/Pictures/AES-Csharp.png b/Pictures/AES-Csharp.png deleted file mode 100644 index 82ba690..0000000 Binary files a/Pictures/AES-Csharp.png and /dev/null differ diff --git a/Pictures/Caesar-Csharp-Debug-Mode.png b/Pictures/Caesar-Csharp-Debug-Mode.png deleted file mode 100644 index a1c1e78..0000000 Binary files a/Pictures/Caesar-Csharp-Debug-Mode.png and /dev/null differ diff --git a/Pictures/Caesar-Rust.png b/Pictures/Caesar-Rust.png deleted file mode 100644 index 9a8c7a6..0000000 Binary files a/Pictures/Caesar-Rust.png and /dev/null differ diff --git a/Pictures/Host-Identifier-Example.png b/Pictures/Host-Identifier-Example.png deleted file mode 100644 index bb06f36..0000000 Binary files a/Pictures/Host-Identifier-Example.png and /dev/null differ diff --git a/Pictures/RC4-C-Output-Option.png b/Pictures/RC4-C-Output-Option.png deleted file mode 100644 index 880d39c..0000000 Binary files a/Pictures/RC4-C-Output-Option.png and /dev/null differ diff --git a/Pictures/RC4-Csharp.png b/Pictures/RC4-Csharp.png deleted file mode 100644 index 07d14ae..0000000 Binary files a/Pictures/RC4-Csharp.png and /dev/null differ diff --git a/Pictures/ROT-Csharp-Guide-Variable-Preview.png b/Pictures/ROT-Csharp-Guide-Variable-Preview.png deleted file mode 100644 index 364d0ad..0000000 Binary files a/Pictures/ROT-Csharp-Guide-Variable-Preview.png and /dev/null differ diff --git a/Pictures/ROT-Csharp-Guide-Variable.png b/Pictures/ROT-Csharp-Guide-Variable.png deleted file mode 100644 index d0f17a3..0000000 Binary files a/Pictures/ROT-Csharp-Guide-Variable.png and /dev/null differ diff --git a/Pictures/supernova_logo.png b/Pictures/Supernova-Logo.png similarity index 100% rename from Pictures/supernova_logo.png rename to Pictures/Supernova-Logo.png diff --git a/Pictures/XOR-Csharp-Variable.png b/Pictures/XOR-Csharp-Variable.png deleted file mode 100644 index 8b0df38..0000000 Binary files a/Pictures/XOR-Csharp-Variable.png and /dev/null differ diff --git a/Pictures/XOR-Nim.png b/Pictures/XOR-Nim.png deleted file mode 100644 index 2963dc6..0000000 Binary files a/Pictures/XOR-Nim.png and /dev/null differ diff --git a/README.md b/README.md index 16cb0cd..0551af2 100644 --- a/README.md +++ b/README.md @@ -1,380 +1,151 @@ # Supernova -Real fucking shellcode encryptor. +Real fucking shellcode encryptor & obfuscator.

- +

+ Static Badge + Static Badge

+ GitHub Repo stars + GitHub forks + GitHub watchers

## Description -Supernova is an open-source Golang tool that empowers users to securely encrypt their raw shellcodes. -Additionally, it offers automatic conversion of the encrypted shellcode into formats compatible with various programming languages, including: -- C -- C# -- Rust -- Nim -- Golang (Community request by [@_atsika](https://twitter.com/_atsika)) -- Python - -It supports a variety of different ciphers, including: -- ROT -- XOR -- RC4 -- AES (AES-128-CBC, AES-192-CBC, AES-256-CBC) +Supernova is an open-source tool that empowers users to securely encrypt and/or obfuscate their raw shellcode. -Moreover, this tool generates the decrypted function using the chosen cipher and language, while also supplying instructions on how to utilize it effectively. +Supernova supports various features beyond those typically found in a common shellcode encryptor tool. Please refer to the Features section for more information. -Supernova is written in Golang, a cross-platform language, enabling its use on both Windows and Linux systems. - -## Version - -### 1.1.0 +For command-line usage and examples, please refer to our [Wiki](https://github.com/nickvourd/Supernova/wiki). -## License - -This tool is licensed under the [![License: MIT](https://img.shields.io/badge/MIT-License-yellow.svg)](LICENSE). - -## Acknowledgement +> If you find any bugs, don’t hesitate to [report them](https://github.com/nickvourd/Supernova/issues). Your feedback is valuable in improving the quality of this project! -Special thanks to my brothers [@S1ckB0y1337](https://twitter.com/S1ckB0y1337) and [@IAMCOMPROMISED](https://twitter.com/IAMCOMPROMISED), who provided invaluable assistance during the beta testing phase of the tool. - -Grateful acknowledgment to [@y2qaq](https://twitter.com/y2qaq) for his valuable contributions. - -This tool was inspired during the malware development courses of [MALDEV Academy](https://maldevacademy.com). +## Disclaimer -Supernova was created with :heart: by [@nickvourd](https://twitter.com/nickvourd), [@0xvm](https://twitter.com/0xvm) and [@Papadope9](https://twitter.com/Papadope9). +The authors and contributors of this project are not liable for any illegal use of the tool. It is intended for educational purposes only. Users are responsible for ensuring lawful usage. ## Table of Contents + - [Supernova](#supernova) - [Description](#description) - - [Version](#version) - - [License](#license) - - [Acknowledgement](#acknowledgement) + - [Disclaimer](#disclaimer) - [Table of Contents](#table-of-contents) + - [Acknowledgement](#acknowledgement) + - [Features](#features) - [Installation](#installation) - - [Background](#background) - - [Command Line Usage](#command-line-usage) - - [About Dynamic Variable Name](#about-dynamic-variable-name) - - [Dynamic Variable Name Example](#dynamic-variable-name-example) - - [About Guide](#about-guide) - - [Guide Example](#guide-example) - - [About Debug](#about-debug) - - [Debug Example](#debug-example) - - [About Output File](#about-output-file) - - [Output File Example](#output-file-example) - - [Encryptions](#encryptions) - - [ROT Encryption](#rot-encryption) - - [XOR Encryption](#xor-encryption) - - [RC4 Encryption](#rc4-encryption) - - [AES Encryption](#aes-encryption) - - [AES-128-CBC](#aes-128-cbc) - - [AES-192-CBC](#aes-192-cbc) - - [AES-256-CBC](#aes-256-cbc) + - [Usage](#usage) - [References](#references) -## Installation - -To install Supernova, run the following command, or use the [compiled binary](https://github.com/nickvourd/Supernova/releases): -``` -go build Supernova.go -``` - -:information_source: Supernova works without the necessity of installing any additional dependencies. - -## Background - -### Command Line Usage - -``` -███████╗██╗ ██╗██████╗ ███████╗██████╗ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ -██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗████╗ ██║██╔═══██╗██║ ██║██╔══██╗ -███████╗██║ ██║██████╔╝█████╗ ██████╔╝██╔██╗ ██║██║ ██║██║ ██║███████║ -╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██║ ██║╚██╗ ██╔╝██╔══██║ -███████║╚██████╔╝██║ ███████╗██║ ██║██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ -╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ - -Supernova v1.1.0 - Real fucking shellcode encryptor. -Supernova is an open source tool licensed under MIT. -Written with <3 by @nickvourd, @0xvm and @Papadope9... -Please visit https://github.com/nickvourd/Supernova for more... - -Usage of Supernova.exe: - -d Enable Debug mode - -enc string - Shellcode encoding/encryption (i.e., ROT, XOR, RC4, AES) - -guide - Enable guide mode - -i string - Path to the raw 64-bit shellcode - -k int - Key lenght size for encryption (default 1) - -lang string - Programming language to translate the shellcode (i.e., Nim, Rust, C, CSharp, Go, Python) - -o string - Name of the output file - -v string - Name of dynamic variable (default "shellcode") - -version - Show Supernova current version -``` - -### About Dynamic Variable Name - -Dynamic variable name is employed to insert the desired variable name for the shellcode payload and the exported decryption function. This approach imparts dynamism to the output code by incorporating variables, thereby enhancing the code's copy-and-paste utility. - -Use dynamic variable name with `-v` switch and provide your preferred value. - -The default value of dynamic variable name is `shellcode`. - -#### Dynamic Variable Name Example - -Here is a simple example demonstrating how the dynamic variable name operates. - -An attacker uses XOR encryption and utilizes the C# language option in conjunction with the variable setting as value `nickvourd`: - -``` -.\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc xor -lang csharp -k 2 -v nickvourd -``` - -Outcome: - -![Variable-Example](/Pictures/XOR-Csharp-Variable.png) - -### About Guide - - This section provides information about the `-guide` option, which is designed to work in conjunction with the `-lang` and `-enc` options. It proves to be particularly valuable when users are unfamiliar with the decryption functionality or wish to experiment with different languages. The three primary actions encompass: - - - Decryption functionality - - Set key/passphrase in main - - Call function in main - - Additionally, when used in conjunction with the `-v` flag and a value (default `shellcode`), it can make the output's code dynamic by incorporating variables, thereby enhancing the code's copy-and-paste utility. - - Last but not least, `-guide` saves the decryption function to a file named Program with the specific file extension of the chosen language. - -⚠️ Guide mode does not support the Nim language at this stage of the release. - - #### Guide Example - - Here is a simple example demonstrating how the guide mode operates. - - An attacker uses ROT encryption and utilizes the C# language option in conjunction with the guide mode and variable setting: - - ``` - .\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc rot -lang csharp -k 2 -guide -v buffer - ``` - - Outcome: - -![Guide-Example](/Pictures/ROT-Csharp-Guide-Variable.png) - -Decryption file preview example: - -![Guide-Preview-File](/Pictures/ROT-Csharp-Guide-Variable-Preview.png) - -### About Debug - -The debug mode is useful if you want to observe the original payload in a selected programming language. To activate this functionality, you need to include the `-d` option. - -#### Debug Example - -Here is a simple example illustrating the functioning of the debug option. - -An adversary uses ROT encryption and utilizes the C# language option in conjunction with the debug option: - -``` -.\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc rot -lang csharp -k 2 -d -``` - -Outcome: - -![Debug-Example](/Pictures/Caesar-Csharp-Debug-Mode.png) - -### About Output File - -The output option is indicated by the `-o` switch, followed by the desired value, allowing you to save the encrypted payload into a file. - -#### Output File Example - -Here is a simple example illustrating the functioning of the output option. - -An attacker uses RC4 encryption and utilizes the C language option in conjunction with the output option and a desired filename: - -``` -.\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc rc4 -lang c -k 3 -o shellcode.bin -``` - -Outcome: - -![Output-Example](/Pictures/RC4-C-Output-Option.png) - -## Encryptions +## Acknowledgement -### ROT Encryption +Special thanks to my brothers [@S1ckB0y1337](https://twitter.com/S1ckB0y1337) and [@IAMCOMPROMISED](https://twitter.com/IAMCOMPROMISED), who provided invaluable assistance during the beta testing phase of the tool. -The ROT cipher, also known as the rotation cipher, is a family of simple substitution ciphers in which the letters of the alphabet are shifted by a fixed number of positions. The term "ROT" is often followed by a number that indicates the amount of rotation applied to the letters. Each variant of the ROT cipher corresponds to a specific shift value. +Grateful acknowledgment to [@y2qaq](https://twitter.com/y2qaq) for his valuable contributions. -Each letter in the plaintext message is replaced with the letter that appears a certain number of positions ahead in the alphabet, based on the key. The shifting is performed circularly, wrapping around from "Z" to "A". +Special thanks to my friend [@MikeAngelowtt](https://twitter.com/MikeAngelowtt) for all our evening discussions during the development process. -As an example, using the Swift key 13: +Special thanks to my friend [Efstratios Chatzoglou](https://www.linkedin.com/in/efstratios-chatzoglou-b2b09616b/) and his tool named [Pandora](https://github.com/efchatz/pandora), which inspired me to improve the beauty of this `README.md` file. -``` -"A" becomes "N" -"B" becomes "O" -... -"N" becomes "A" -"O" becomes "B" -... -"Z" becomes "M" -``` +This tool was inspired during the malware development courses of [MALDEV Academy](https://maldevacademy.com). -To employ Supernova with the ROT cipher, you must select a key that signifies the shift key, a preferred programming language, and provide a raw shellcode: +Supernova was created with :heart: by [@nickvourd](https://twitter.com/nickvourd), [@Papadope9](https://twitter.com/Papadope9) and [@0xvm](https://twitter.com/0xvm). -In the provided example, the preferred language is Rust, and the chosen Swift key is 7: +## Features -``` -.\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc rot -lang rust -k 7 -``` +Supernova offers automatic conversion of the encrypted shellcode into formats compatible with various programming languages, including: +- C +- C# +- Rust +- Nim +- Golang (Community request by [@_atsika](https://twitter.com/_atsika)) +- Python +- Perl +- PowerShell +- Java +- Ruby +- Raw (Implemented by [@y2qaq](https://twitter.com/y2qaq)) -Outcome: +Supports a variety of different ciphers, including: +- ROT +- XOR +- RC4 +- AES (AES-128-CBC, AES-192-CBC, AES-256-CBC) +- Chacha20 (Implemented by [@y2qaq](https://twitter.com/y2qaq)) -![ROT-Example](/Pictures/Caesar-Rust.png) +Supports various obfuscation techniques, which make the malicious shellcode appear as if it were: +- IPv4 +- IPv6 +- MAC +- UUID (Supported by [@S1ckB0y1337](https://twitter.com/S1ckB0y1337) & [@MikeAngelowtt](https://twitter.com/MikeAngelowtt)) -### XOR Encryption +Supernova is written in Golang, a cross-platform language, enabling its use on both Windows and Linux systems. -The XOR cipher, also known as the exclusive OR cipher, is a basic encryption technique that operates by applying the XOR (exclusive OR) operation between each bit of the plaintext and a corresponding bit of a secret key. This results in ciphertext that appears random and can only be decrypted by performing the XOR operation again with the same secret key. +## Installation -The XOR operation is performed between each bit of the plaintext message and the corresponding bit of the key. If the bits are the same (both 0 or both 1), the result is 0; if the bits are different, the result is 1. +You can use the [precompiled binaries](https://github.com/nickvourd/Supernova/releases), or you can manually install Supernova by following the next steps: -For example, given a key of "10110": +1) Clone the repository by executing the following command: ``` -Plaintext "01001" XOR Key "10110" = Ciphertext "11111" +git clone https://github.com/nickvourd/Supernova.git ``` -To employ Supernova with the XOR cipher, you must select a key that generates random XOR byte keys, a preferred programming language, and provide a raw shellcode: - -In the given illustration, the preferred programming language is Nim, and the selected key is 4. This key will be utilized to generate four-byte sequences for encryption purposes: +2) Once the repository is cloned, navigate into the Supernova directory: ``` -.\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc xor -lang nim -k 4 +cd Supernova ``` -Outcome: - -![XOR-Example](/Pictures/XOR-Nim.png) - -### RC4 Encryption - -The RC4 cipher, also known as the Rivest Cipher 4 or ARC4, is a symmetric stream cipher that was designed by Ron Rivest in 1987. It gained popularity due to its simplicity and efficiency in generating a pseudorandom stream of bits, which can be used for encryption and decryption. The RC4 cipher was initially a trade secret, but it later became widely known and used in various applications. - -The RC4 algorithm starts by initializing two arrays, S (state) and T (temporary). The key is used to initialize these arrays based on a process called key scheduling. The key can be of variable length, which influences the strength of the cipher. - -The PRGA (Pseudorandom Generation Algorithm) generates a pseudorandom stream of bytes that are used to encrypt or decrypt the plaintext. The PRGA operates as follows: - -- The arrays S and T are mixed based on the key to create the initial state. -- For each byte of the output stream, the values in arrays S and T are further mixed and used to generate a pseudorandom byte. -- This pseudorandom byte is XORed with the plaintext byte to produce the ciphertext byte (or vice versa for decryption). - -The pseudorandom stream generated by the PRGA is called the keystream. This keystream is combined with the plaintext using the XOR operation to produce the ciphertext. - -To employ Supernova with the RC4 cipher, you must select a key that generates a random Passphrase, a preferred programming language, and provide a raw shellcode. Additionally, the numerical value provided in the "key" argument specifies the desired length of the generated random passphrase: - -In the given illustration, the preferred programming language is CSharp, and the selected key is 9: +3) Install the third-party dependencies: ``` -.\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc rc4 -lang csharp -k 9 +go mod download ``` -Outcome: - -![RC4-Example](/Pictures/RC4-Csharp.png) - -### AES Encryption - -The Advanced Encryption Standard (AES) is a widely adopted symmetric encryption algorithm that provides strong security for various applications. It was established as a standard encryption algorithm by the U.S. National Institute of Standards and Technology (NIST) in 2001, following a competition to find a replacement for the aging Data Encryption Standard (DES). AES is known for its efficiency and robust security features, making it a cornerstone of modern cryptography. - -#### AES-128-CBC -**AES-128** in the name refers to the key length used in the algorithm. AES-128 employs a 128-bit encryption key, resulting in 2^128 possible key combinations. This makes it computationally infeasible for attackers to brute-force the key and decrypt the encrypted data without the proper key. - -- **Key Setup**: Before you can encrypt or decrypt data using AES-128-CBC, you need to establish a secret key of 128 bits (16 bytes). This key is known only to the sender and receiver and is used for both encryption and decryption. -Padding: If the plaintext data is not a multiple of 128 bits (16 bytes), it needs to be padded to the nearest multiple. -Common padding schemes include PKCS7 padding. - -- **Initialization Vector (IV)**: An IV is a random value that is used to initialize the encryption process. The IV should be different for each message encrypted with the same key. It is typically 128 bits (16 bytes) long. -Dividing Data into Blocks: The plaintext data is divided into blocks, each 128 bits in length. - -- **Cipher Block Chaining (CBC)**: AES-128-CBC uses CBC mode to encrypt each block of data. In CBC mode, the ciphertext of one block is XORed with the plaintext of the next block before encryption. The IV is XORed with the first block of plaintext before encryption. This chaining effect ensures that identical blocks of plaintext do not result in identical blocks of ciphertext. - -- **Encryption**: Each block of plaintext is encrypted using the AES encryption algorithm with the 128-bit secret key. - -To employ Supernova with the AES-128-CBC cipher, you must select a preferred programming language, provide a raw shellcode and a key with value `128` or `16`. Additionally, the generated key is a random 16-byte value, and the generated IV is a random 16-byte value. - -In the given illustration, the preferred programming language is C: +4) Build Supernova with the following command: ``` -.\Supernova.exe -i C:\Users\nickvourd\Desktop\shellcode.bin -enc aes -k 128 -lang c +go build Supernova ``` -Outcome: - -![AES-128-C](/Pictures/AES-128-C.png) - -#### AES-192-CBC - -**AES-192** in the name refers to the key length used in the algorithm. AES-192 employs a 192-bit encryption key, resulting in 2^192 possible key combinations. This significantly increases the complexity compared to AES-128, making it computationally infeasible for attackers to brute-force the key and decrypt the encrypted data without the proper key. - -- **Key Setup**: You need to establish a secret key of 192 bits (24 bytes). This key is known only to the sender and receiver and is used for both encryption and decryption. - -- **Padding**: If the plaintext data is not a multiple of 128 bits (16 bytes), it should be padded to the nearest multiple, typically using a padding scheme like PKCS7. +## Usage -- **Initialization Vector (IV)**: An IV is a random value that initializes the encryption process. The IV should be different for each message encrypted with the same key. In AES-192-CBC, it is typically 128 bits (16 bytes) long. +:information_source: Please refer to the [Supernova Wiki](https://github.com/nickvourd/Supernova/wiki) for detailed usage instructions and examples of commands. -- **Dividing Data into Blocks**: The plaintext data is divided into blocks, each 128 bits in length. - -- **Cipher Block Chaining (CBC)**: AES-192-CBC uses CBC mode. In this mode, the ciphertext of one block is XORed with the plaintext of the next block before encryption. The IV is XORed with the first block of plaintext before encryption, ensuring that identical blocks of plaintext do not result in identical blocks of ciphertext. - -- **Encryption**: Each block of plaintext is encrypted using the AES encryption algorithm with the 192-bit secret key. - -To employ Supernova with the AES-192-CBC cipher, you must select a preferred programming language, provide a raw shellcode and a key with value `192` or `24`. Additionally, the generated key is a random 24-byte value, and the generated IV is a random 16-byte value. - -In the given illustration, the preferred programming language is Rust: - -``` -.\Supernova.exe -i C:\Users\nickvourd\Desktop\shellcode.bin -enc aes -k 192 -lang rust ``` -Outcome: - -![AES-192-Rust](/Pictures/AES-192-Rust.png) - -#### AES-256-CBC - -The **AES-256** in the name refers to the key length used in the algorithm. AES-256 employs a 256-bit encryption key, which means there are 2^256 possible key combinations, making it incredibly difficult and time-consuming for attackers to brute-force the key and decrypt the encrypted data without the proper key. - -- **Key Setup**: To use AES-256-CBC, you need a secret key of 256 bits (32 bytes). This key is kept secret and is used for both encryption and decryption. - -- **Padding**: If the plaintext data is not a multiple of 128 bits (16 bytes), it should be padded to the nearest multiple, typically using a padding scheme like PKCS7. - -- **Initialization Vector (IV)**: An IV is a random value that initializes the encryption process. The IV should be different for each message encrypted with the same key. In AES-256-CBC, it is typically 128 bits (16 bytes) long. - -- **Dividing Data into Blocks**: The plaintext data is divided into blocks, each 128 bits in length. - -- **Cipher Block Chaining (CBC)**: AES-256-CBC uses CBC mode, just like the other AES modes. In this mode, the ciphertext of one block is XORed with the plaintext of the next block before encryption. The IV is XORed with the first block of plaintext before encryption, ensuring that identical blocks of plaintext do not result in identical blocks of ciphertext. - -- **Encryption**: Each block of plaintext is encrypted using the AES encryption algorithm with the 256-bit secret key. - -To employ Supernova with the AES-256-CBC cipher, you must select a preferred programming language, provide a raw shellcode and a key with value `256` or `32`. Additionally, the generated key is a random 32-byte value, and the generated IV is a random 16-byte value. +███████╗██╗ ██╗██████╗ ███████╗██████╗ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ +██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗████╗ ██║██╔═══██╗██║ ██║██╔══██╗ +███████╗██║ ██║██████╔╝█████╗ ██████╔╝██╔██╗ ██║██║ ██║██║ ██║███████║ +╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██║ ██║╚██╗ ██╔╝██╔══██║ +███████║╚██████╔╝██║ ███████╗██║ ██║██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ +╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ -In the given illustration, the preferred programming language is Csharp: +Supernova v2.0 - Real fucking shellcode encryptor & obfuscator tool. +Supernova is an open source tool licensed under MIT. +Written with <3 by @nickvourd, @Papadope9 and 0xvm. +Please visit https://github.com/nickvourd/Supernova for more... +Usage of Suprenova: + -debug + Enable Debug mode + -enc string + Shellcode encoding/encryption (i.e., ROT, XOR, RC4, AES, CHACHA20) + -input string + Path to a raw shellcode + -key int + Key length size for encryption (default 1) + -lang string + Programming language to translate the shellcode (i.e., Nim, Rust, C, CSharp, Go, Python, PowerShell, Perl, Ruby, Java, Raw) + -obf string + Shellcode obfuscation (i.e., IPV4, IPV6, MAC, UUID) + -output string + Name of the output shellcode file + -var string + Name of dynamic variable (default "shellcode") + -version + Show Supernova current version ``` -.\Supernova.exe -i C:\Users\User\Desktop\shellcode.bin -enc aes -k 256 -lang csharp -``` - -Outcome: - -![AES-256-Csharp](/Pictures/AES-256-Csharp.png) ## References @@ -382,11 +153,10 @@ Outcome: - [XOR Cipher Wikipedia](https://en.wikipedia.org/wiki/XOR_cipher) - [RC4 Cipher Wikipedia](https://en.wikipedia.org/wiki/RC4) - [AES Cipher Wikipedia](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) +- [ChaCha20-Poly1305 Wikipedia](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) - [Block cipher mode of operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) -- [Nim (programming language)](https://en.wikipedia.org/wiki/Nim_(programming_language)) -- [Rust (programming language)](https://en.wikipedia.org/wiki/Rust_(programming_language)) -- [C Sharp (programming language)](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) -- [C (programming language)](https://en.wikipedia.org/wiki/C_(programming_language)) - [Sector7 Institute](https://institute.sektor7.net/) - [MalDev Academy](https://maldevacademy.com/) -- [OSEP-Code-Snippets](https://github.com/chvancooten/OSEP-Code-Snippets) +- [OSEP-Code-Snippets GitHub by Chvancooten](https://github.com/chvancooten/OSEP-Code-Snippets) +- [From the Front Lines | Hive Ransomware Deploys Novel IPfuscation Technique To Avoid Detection by SentinelOne](https://www.sentinelone.com/blog/hive-ransomware-deploys-novel-ipfuscation-technique/) +- [Shellcode Obfuscation by Bordergate](https://www.bordergate.co.uk/shellcode-obfuscation/) diff --git a/Supernova.go b/Supernova.go index 31ea54e..7f833f3 100644 --- a/Supernova.go +++ b/Supernova.go @@ -1,183 +1,158 @@ package main import ( - "Supernova/Arguments" - "Supernova/Converters" - "Supernova/Decryptors" - "Supernova/Encryptors" - "Supernova/Output" - "Supernova/Utils" - "flag" + "Supernova/Packages/Arguments" + "Supernova/Packages/Colors" + "Supernova/Packages/Converters" + "Supernova/Packages/Manager" + "Supernova/Packages/Utils" "fmt" "log" "os" + "strconv" "strings" + "time" ) -// Structure -type FlagOptions struct { - outFile string - inputFile string - language string - encryption string - obfuscation string - variable string - key int - debug bool - guide bool - version bool -} - -// global variables -var ( - __version__ = "1.1.0" - __license__ = "MIT" - __author__ = "@nickvourd" - __github__ = "https://github.com/nickvourd/Supernova" - __coauthors__ = [2]string{"@Papadope9", "@0xvm"} -) - -var __ascii__ = ` - -███████╗██╗ ██╗██████╗ ███████╗██████╗ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ -██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗████╗ ██║██╔═══██╗██║ ██║██╔══██╗ -███████╗██║ ██║██████╔╝█████╗ ██████╔╝██╔██╗ ██║██║ ██║██║ ██║███████║ -╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██║ ██║╚██╗ ██╔╝██╔══██║ -███████║╚██████╔╝██║ ███████╗██║ ██║██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ -╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ - -Supernova v%s - Real fucking shellcode encryptor. -Supernova is an open source tool licensed under %s. -Written with <3 by %s, %s and %s... -Please visit %s for more... - -` - -// Options function -func Options() *FlagOptions { - inputFile := flag.String("i", "", "Path to the raw 64-bit shellcode") - encryption := flag.String("enc", "", "Shellcode encoding/encryption (i.e., ROT, XOR, RC4, AES, CHACHA20, B64XOR, B64RC4, B64AES, B64CHACHA20)") - language := flag.String("lang", "", "Programming language to translate the shellcode (i.e., Nim, Rust, C, CSharp, Go, Python, RAW)") - outFile := flag.String("o", "", "Name of the output file") - variable := flag.String("v", "shellcode", "Name of dynamic variable") - debug := flag.Bool("d", false, "Enable Debug mode") - key := flag.Int("k", 1, "Key lenght size for encryption") - version := flag.Bool("version", false, "Show Supernova current version") - guide := flag.Bool("guide", false, "Enable guide mode") - // obfuscation := flag.String("obf", "", "Shellcode obfuscation (i.e., IPv4, IPv6, MAC, UUID)") - flag.Parse() - - return &FlagOptions{outFile: *outFile, inputFile: *inputFile, language: *language, encryption: *encryption, variable: *variable, debug: *debug, key: *key, version: *version, guide: *guide} -} - // main function func main() { - // Print ascii - fmt.Printf(__ascii__, __version__, __license__, __author__, __coauthors__[1], __coauthors__[0], __github__) + // Declare variables + var template string + var encryptedShellcode []byte + var shellcode []byte - // Check GO version of the current system - Utils.Version() + // Call function named PrintAscii + Arguments.PrintAscii() - // Retrieve command-line options using the Options function - options := Options() + // Call function named CheckGoVersion + Utils.CheckGoVersion() - // Check Arguments Length - Arguments.ArgumentLength(options.version) + // Parsing command line flags + options := Arguments.Options() - // Check Version of tool - Arguments.ShowVersion(__version__, options.version) + // Call function named ArgumentLength + Arguments.ArgumentLength(options.Version) // Call function named ArgumentEmpty - Arguments.ArgumentEmpty(options.inputFile, 1) + Arguments.ArgumentEmpty(options.InputFile, 1) - // Call function name ConvertShellcode2String - rawShellcode, err := Converters.ConvertShellcode2String(options.inputFile) - if err != nil { - fmt.Println("[!] Error:", err) - return + // Call function named ShellcodeSizeValidation + fileSizeFlag := Arguments.ShellcodeSizeValidation(options.InputFile) + + // If fileSizeFlag is true + if fileSizeFlag { + // Call function named ArgumentEmpty + Arguments.ArgumentEmpty(options.OutFile, 3) } // Call function named ArgumentEmpty - Arguments.ArgumentEmpty(options.language, 2) + Arguments.ArgumentEmpty(options.Language, 2) - // Check for valid values of language argument - foundLanguage := Arguments.ValidateArgument("lang", options.language, []string{"Nim", "Rust", "C", "CSharp", "Go", "Python", "RAW"}) + // Call function ValidateArgument + foundLanguage := Arguments.ValidateArgument("lang", options.Language, []string{"Nim", "Rust", "C", "CSharp", "Go", "Python", "PowerShell", "Perl", "Ruby", "Java", "Raw"}) - // Check if the encryption or obfuscation option is not used - if options.encryption == "" { - // && options.obfuscation == "" + if options.Encryption == "" && options.Obfuscation == "" { logger := log.New(os.Stderr, "[!] ", 0) - logger.Fatal("Please choose the encryption option to proceed!\n") - // logger.Fatal("Please choose either the encryption option or the obfuscation option to proceed!\n") + logger.Fatal("Please choose either the Encryption option (-enc) or the Obfuscation option (-obf) to proceed, or select both.\n\n") } - // Check if encryption and obfuscation are used together - // if options.encryption != "" && options.obfuscation != "" { - // logger := log.New(os.Stderr, "[!] ", 0) - // logger.Fatal("You cannot choose both the encryption and obfuscation options; please select only one!\n") - //} + // if Encryption option is enable + if options.Encryption != "" { + // Call function named ValidateArgument + Arguments.ValidateArgument("enc", options.Encryption, []string{"ROT", "XOR", "RC4", "AES", "CHACHA20"}) + } + + // Obfuscation option is enable + if options.Obfuscation != "" { + // Call function named ValidateArgument + Arguments.ValidateArgument("obf", options.Obfuscation, []string{"IPV4", "IPV6", "MAC", "UUID"}) + } + + // Call function name ConvertShellcode2String + rawShellcode, err := Converters.ConvertShellcode2String(options.InputFile) + if err != nil { + fmt.Println("[!] Error:", err) + return + } // Call function named ConvertShellcode2Hex convertedShellcode, payloadLength := Converters.ConvertShellcode2Hex(rawShellcode, foundLanguage) - // Print payload size and chosen language - fmt.Printf("[+] Payload size: %d bytes\n\n[+] Converted payload to %s language\n\n", payloadLength, foundLanguage) + // Convert the integer to a string + payloadLengthString := strconv.Itoa(payloadLength) - if options.debug { - // Call function named ConvertShellcode2Template - template := Converters.ConvertShellcode2Template(convertedShellcode, foundLanguage, payloadLength, options.variable) + // Print payload size and chosen language + fmt.Printf("[+] Payload size: %s bytes\n\n[+] Converted payload to %s language\n\n", Colors.BoldCyan(payloadLengthString), strings.ToUpper(foundLanguage)) + + // if Debug true + if options.Debug { + switch fileSizeFlag { + case true: + fmt.Printf("[!] The size of the original shellcode exceeds the maximum display limit.\n\n[!] Supernova cannot display it on the screen.\n\n") + default: + // if language is raw + if foundLanguage == "raw" { + fmt.Printf("[!] The original shellcode is displayed in raw format represented as hexadecimal on the terminal.\n\n") + } + // Call function named ConvertShellcode2Template + template := Converters.ConvertShellcode2Template(convertedShellcode, foundLanguage, payloadLength, options.Variable) - // Print original template - fmt.Printf("[+] The original payload:\n\n%s\n\n", template) + // Print original template + fmt.Printf("[+] The original payload:\n\n%s\n\n", template) + } } // Encryption option is enable - if options.encryption != "" { - // Call function named ValidateArgument - Arguments.ValidateArgument("enc", options.encryption, []string{ - "XOR", "RC4", "AES", "ROT", "CHACHA20", - "B64XOR", "B64RC4", "B64AES", "B64CHACHA20", - }) + if options.Encryption != "" { + // Record the start time + encryptionStartTime := time.Now() - // Call function ValidateKeySize - options.key = Arguments.ValidateKeySize(options.key, options.encryption) + // Call function named EncryptionManager + template, encryptedShellcode = Manager.EncryptionManager(options.Key, options.Encryption, options.Obfuscation, options.Debug, options.Variable, rawShellcode, foundLanguage, fileSizeFlag) - // Call function named DetectEncryption - encryptedShellcode, encryptedLength, key, passphrase, iv := Encryptors.DetectEncryption(options.encryption, rawShellcode, options.key, foundLanguage) + // Record the end time + encryptionEndTime := time.Now() - // Call function named ConvertShellcode2Template - template := Converters.ConvertShellcode2Template(encryptedShellcode, foundLanguage, encryptedLength, options.variable) + // Calculate the duration + encryptionDuration := encryptionEndTime.Sub(encryptionStartTime) - // Print encrypted template - fmt.Printf("[+] The encrypted payload with %s:\n\n%s\n\n", strings.ToUpper(options.encryption), template) + fmt.Printf("[+] Payload encryption with %s completed successfully! (Completed in %s)\n\n", strings.ToUpper(options.Encryption), encryptionDuration) + } + + // Obfuscation option is enables + if options.Obfuscation != "" { + // Record the start time + encryptionStartTime := time.Now() - // Guide option is enable - if options.guide { - Decryptors.DecryptorsTemplates(foundLanguage, options.encryption, options.variable, options.key, encryptedLength, encryptedShellcode, key, passphrase, iv) + // if fileSizeFlag is enabled + if fileSizeFlag { + fmt.Printf("[!] Please be patient as Supernova processes your request.\n\n") } - // Outfile option is enable - if options.outFile != "" { - language := strings.ToLower(options.language) - if language == "raw" { - err := Output.SaveShellcodeToFile(template, options.outFile) - if err != nil { - fmt.Println("Error:", err) - return - } - } else { - err := Output.SaveOutputToFile(template, options.outFile) - if err != nil { - fmt.Println("Error:", err) - return - } - } + // Encryption option is enable + if options.Encryption != "" { + // Set as shellcode the encryptedShellcode (byte) + shellcode = encryptedShellcode + + // Call function named ObfuscationManager + template = Manager.ObfuscationManager(shellcode, strings.ToLower(options.Obfuscation), foundLanguage, options.Variable, fileSizeFlag) + } else { + // Convert raw shellcode to bytes + shellcode = []byte(rawShellcode) + + // Call function named ObfuscationManager + template = Manager.ObfuscationManager(shellcode, strings.ToLower(options.Obfuscation), foundLanguage, options.Variable, fileSizeFlag) } + + // Record the end time + encryptionEndTime := time.Now() + + // Calculate the duration + encryptionDuration := encryptionEndTime.Sub(encryptionStartTime) + + fmt.Printf("[+] Payload obfuscation as %s completed successfully! (Completed in %s)\n\n", strings.ToUpper(options.Obfuscation), encryptionDuration) } - // Obfuscation option is enable - // if options.obfuscation != "" { - // Call function named ValidateArgument - // Arguments.ValidateArgument("obf", options.obfuscation, []string{"IPv4", "IPv6", "MAC", "UUID"}) - // } + // Call function named OutputManager + Manager.OutputManager(options.OutFile, foundLanguage, template, options.Encryption, options.Obfuscation) } diff --git a/ToDO.md b/ToDO.md new file mode 100644 index 0000000..e5b5581 --- /dev/null +++ b/ToDO.md @@ -0,0 +1,3 @@ +## To Do List + +- Create and write Supernova Wiki \ No newline at end of file diff --git a/Utils/Utils.go b/Utils/Utils.go deleted file mode 100644 index 0f745f1..0000000 --- a/Utils/Utils.go +++ /dev/null @@ -1,51 +0,0 @@ -package Utils - -import ( - "log" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" -) - -// Version function -func Version() { - Version := runtime.Version() - Version = strings.Replace(Version, "go1.", "", -1) - VerNumb, _ := strconv.ParseFloat(Version, 64) - if VerNumb >= 19.1 { - } else { - logger := log.New(os.Stderr, "[!] ", 0) - logger.Fatal("The version of Go is to old, please update to version 1.19.1 or later...\n") - } -} - -// GetAbsolutePath function -func GetAbsolutePath(filename string) (string, error) { - // Get the absolute path of the file - absolutePath, err := filepath.Abs(filename) - if err != nil { - return "", err - } - return absolutePath, nil -} - -// HostIdentifier function -func HostIdentifier() string { - // Get OS of host machine - osName := runtime.GOOS - var operatingSystem string - - switch osName { - case "windows": - operatingSystem = "Windows" - case "linux": - operatingSystem = "Linux" - default: - logger := log.New(os.Stderr, "[!] ", 0) - logger.Fatal("Unsupported Operating System...\n") - } - - return operatingSystem -} diff --git a/go.mod b/go.mod index 3e99f50..5ee1b86 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,12 @@ module Supernova go 1.20 require ( - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/sys v0.16.0 // indirect + github.com/fatih/color v1.16.0 + golang.org/x/crypto v0.21.0 +) + +require ( + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/sys v0.18.0 // indirect ) diff --git a/go.sum b/go.sum index 75b3631..75184c7 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,13 @@ -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=