YARA Detection Rule: CobaltStrike_Resources_Bind64_Bin_v2_5_through_v4_x
Repository: Neo23x0/signature-base
Detects: Cobalt Strike's resources/bind64.bin signature for versions v2.5 to v4.x
Author: gssincla@google.com
Reference: https://cloud.google.com/blog/products/identity-security/making-cobalt-strike-harder-for-threat-actors-to-abuse

Pattern signatures:
/*
		48 31 C0       xor     rax, rax
		AC             lodsb
		41 C1 C9 0D    ror     r9d, 0Dh
		41 01 C1       add     r9d, eax
		38 E0          cmp     al, ah
		75 F1          jnz     short loc_[PII_REDACTED]0007D
		4C 03 4C 24 08 add     r9, [rsp+40h+var_38]
		45 39 D1       cmp     r9d, r10d
		75 D8          jnz     short loc_[PII_REDACTED]0006E
		58             pop     rax
		44 8B 40 24    mov     r8d, [rax+24h]
		49 01 D0       add     r8, rdx
		66 41 8B 0C 48 mov     cx, [r8+rcx*2]
		44 8B 40 1C    mov     r8d, [rax+1Ch]
		49 01 D0       add     r8, rdx
		41 8B 04 88    mov     eax, [r8+rcx*4]
		48 01 D0       add     rax, rdx
	*/

	$apiLocator = {
			48 [2]
			AC
			41 [2] 0D
			41 [2]
			38 ??
			75 ??
			4C [4]
			45 [2]
			75 ??
			5?
			44 [2] 24
			49 [2]
			66 [4]
			44 [2] 1C
			49 [2]
			41 [3]
			48 
		}


  // the signature for reverse64 and bind really differ slightly, here we are using the inclusion of additional calls
  // found in bind64 to differentate between this and 

Detection condition:
$apiLocator and $calls

Full rule:
rule CobaltStrike_Resources_Bind64_Bin_v2_5_through_v4_x
{
	meta:
		description = "Cobalt Strike's resources/bind64.bin signature for versions v2.5 to v4.x"
		hash =  "5dd136f5674f66363ea6463fd315e06690d6cb10e3cc516f2d378df63382955d"
		author = "gssincla@google.com"
		reference = "https://cloud.google.com/blog/products/identity-security/making-cobalt-strike-harder-for-threat-actors-to-abuse"
		date = "2022-11-18"
		
		id = "a01e7bc3-40e9-5f87-8fd6-926972be273b"
	strings:
	/*
		48 31 C0       xor     rax, rax
		AC             lodsb
		41 C1 C9 0D    ror     r9d, 0Dh
		41 01 C1       add     r9d, eax
		38 E0          cmp     al, ah
		75 F1          jnz     short loc_[PII_REDACTED]0007D
		4C 03 4C 24 08 add     r9, [rsp+40h+var_38]
		45 39 D1       cmp     r9d, r10d
		75 D8          jnz     short loc_[PII_REDACTED]0006E
		58             pop     rax
		44 8B 40 24    mov     r8d, [rax+24h]
		49 01 D0       add     r8, rdx
		66 41 8B 0C 48 mov     cx, [r8+rcx*2]
		44 8B 40 1C    mov     r8d, [rax+1Ch]
		49 01 D0       add     r8, rdx
		41 8B 04 88    mov     eax, [r8+rcx*4]
		48 01 D0       add     rax, rdx
	*/

	$apiLocator = {
			48 [2]
			AC
			41 [2] 0D
			41 [2]
			38 ??
			75 ??
			4C [4]
			45 [2]
			75 ??
			5?
			44 [2] 24
			49 [2]
			66 [4]
			44 [2] 1C
			49 [2]
			41 [3]
			48 
		}


  // the signature for reverse64 and bind really differ slightly, here we are using the inclusion of additional calls
  // found in bind64 to differentate between this and reverse64
  // Note that we can reasonably assume that the constants being passed to the call rbp will be just that, constant,
  // since we are triggering on the API hasher. If that hasher is unchanged, then the hashes we look for should be
  // unchanged. This means we can use these values as anchors in our signature.
	/*
		41 BA C2 DB 37 67 mov     r10d, bind
		FF D5             call    rbp
		48 31 D2          xor     rdx, rdx
		48 89 F9          mov     rcx, rdi
		41 BA B7 E9 38 FF mov     r10d, listen
		FF D5