Every profile SourcePoint generates is rejected by c2lint on Cobalt Strike
4.13 (June 2026), so none of them can be loaded by a team server on the current
release. I hit this while testing PR #30 and thought it was worth reporting
separately, since two of the four causes are compatibility questions rather
than bugs and the decision on those is yours.
Reproduction
$ ./SourcePoint -Host acme-email.com -Outfile test.profile -Profile 2 -Injector VirtualAllocEx
$ ./c2lint test.profile
[*] Starting c2lint
[-] Error(s) while compiling test.profile
Error: invalid option for <.stage> at line 53
Error: Unknown statement in <.stage> at line 65
[-] Unable to load the Beacon profile
c2lint reports roughly two errors per run, so the failures surface in waves as
each pair is fixed. There are four in total.
The two in PR #30
These are unambiguous on any version, and are fixed there:
smartinject is set in the stage block. It is a post-ex option.
SourcePoint already sets it correctly in post-ex (Struct.go), hardcoded
to "true", so the -SmartInject flag was driving the invalid copy in
stage and never affected the block it was meant to.
sleep_mask is emitted unquoted (set sleep_mask true;) while every
other boolean in the block is quoted. c2lint reports this as
Unknown statement in <.stage>.
The two that are your call
With those fixed, c2lint proceeds further into the block and rejects two more:
Error: invalid option for <.stage> at line 68
rdll_loader
Error: invalid option for <.stage> at line 77
name
I isolated every stage option SourcePoint emits, one per minimal profile, to
confirm which ones 4.13 actually rejects:
| option |
4.13 |
set rdll_loader "PrependLoader" |
rejected |
set rdll_loader "StompLoader" |
rejected |
set name "test.dll" |
rejected |
set checksum "123" |
accepted |
set rich_header "\x00" |
accepted |
set copy_pe_header "false" |
accepted |
set eaf_bypass "false" |
accepted |
set rdll_use_syscalls "false" |
accepted |
set syscall_method "None" |
accepted |
Two things worth noting from that table. rdll_loader is rejected on both
values, so this is not the stomp loader deprecation warning added in an earlier
release, the option is gone. And checksum and rich_header are still
accepted while name is not, so PE cloning still works in 4.13, it just no
longer takes the cloned module's name.
The 4.13 release notes do not mention either removal.
Why I have not sent a patch for these two
name appears in all 30 Peclone_list entries and is arguably the most
visible part of the PE clone. rdll_loader is a documented flag
(-RdllLoader). Dropping either one silently changes behaviour for anyone on
an older team server, and I do not know which versions you want to support, so
this seemed like the wrong thing to decide on your behalf.
If it is useful, a -CSVersion style flag that omits the two options when
targeting 4.13+ would keep older versions working, and I am happy to send that
as a PR if you want it. Equally happy to just drop them if you would rather
move the minimum supported version forward.
Environment
- Cobalt Strike 4.13 (June 2026), licensed,
c2lint from the team server
package
- SourcePoint at current
main
- Go 1.22
Every profile SourcePoint generates is rejected by
c2linton Cobalt Strike4.13 (June 2026), so none of them can be loaded by a team server on the current
release. I hit this while testing PR #30 and thought it was worth reporting
separately, since two of the four causes are compatibility questions rather
than bugs and the decision on those is yours.
Reproduction
c2lintreports roughly two errors per run, so the failures surface in waves aseach pair is fixed. There are four in total.
The two in PR #30
These are unambiguous on any version, and are fixed there:
smartinjectis set in thestageblock. It is apost-exoption.SourcePoint already sets it correctly in
post-ex(Struct.go), hardcodedto
"true", so the-SmartInjectflag was driving the invalid copy instageand never affected the block it was meant to.sleep_maskis emitted unquoted (set sleep_mask true;) while everyother boolean in the block is quoted.
c2lintreports this asUnknown statement in <.stage>.The two that are your call
With those fixed,
c2lintproceeds further into the block and rejects two more:I isolated every stage option SourcePoint emits, one per minimal profile, to
confirm which ones 4.13 actually rejects:
set rdll_loader "PrependLoader"set rdll_loader "StompLoader"set name "test.dll"set checksum "123"set rich_header "\x00"set copy_pe_header "false"set eaf_bypass "false"set rdll_use_syscalls "false"set syscall_method "None"Two things worth noting from that table.
rdll_loaderis rejected on bothvalues, so this is not the stomp loader deprecation warning added in an earlier
release, the option is gone. And
checksumandrich_headerare stillaccepted while
nameis not, so PE cloning still works in 4.13, it just nolonger takes the cloned module's name.
The 4.13 release notes do not mention either removal.
Why I have not sent a patch for these two
nameappears in all 30Peclone_listentries and is arguably the mostvisible part of the PE clone.
rdll_loaderis a documented flag(
-RdllLoader). Dropping either one silently changes behaviour for anyone onan older team server, and I do not know which versions you want to support, so
this seemed like the wrong thing to decide on your behalf.
If it is useful, a
-CSVersionstyle flag that omits the two options whentargeting 4.13+ would keep older versions working, and I am happy to send that
as a PR if you want it. Equally happy to just drop them if you would rather
move the minimum supported version forward.
Environment
c2lintfrom the team serverpackage
main