计算HASH,使用windows命令行
| certutil -hashfile cobaltstrike.jar SHA256
|
验证HASH官方地址
| https://verify.cobaltstrike.com/
|
CS 4.3相关
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| package common;
public class Authorization { protected int watermark = 0; protected String validto = ""; protected String error = null; protected boolean valid = false;
public Authorization() { this.watermark = ; this.validto = "forever"; this.error = null; this.valid = true; try { MudgeSanity.systemDetail("valid to", "perpetual"); MudgeSanity.systemDetail("id", getWatermark()); SleevedResource.Setup(hex2bytes("3a4425490f389aeec312bdd758ad2b99")); }catch (Exception ex2) { MudgeSanity.logException("auth file parsing", ex2, false); } }
private byte[] hex2bytes(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; }
public boolean isPerpetual() { return "forever".equals(this.validto); }
public boolean isValid() { return this.valid; }
public String getError() { return this.error; }
public String getWatermark() { return this.watermark + ""; }
public long getExpirationDate() { return CommonUtils.parseDate(this.validto, "yyyyMMdd"); }
public boolean isExpired() { return System.currentTimeMillis() > this.getExpirationDate() + CommonUtils.days(1); }
public String whenExpires() { long var1 = (this.getExpirationDate() + CommonUtils.days(1) - System.currentTimeMillis()) / CommonUtils.days(1); if (var1 == 1L) { return "1 day (" + CommonUtils.formatDateAny("MMMMM d, YYYY", this.getExpirationDate()) + ")"; } else { return var1 <= 0L ? "TODAY (" + CommonUtils.formatDateAny("MMMMM d, YYYY", this.getExpirationDate()) + ")" : var1 + " days (" + CommonUtils.formatDateAny("MMMMM d, YYYY", this.getExpirationDate()) + ")"; } }
public boolean isAlmostExpired() { long var1 = System.currentTimeMillis() + CommonUtils.days(30); return var1 > this.getExpirationDate(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| package beacon;
import common.CommonUtils; import java.io.ByteArrayOutputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set;
public class BeaconData { public static final int MODE_HTTP = 0; public static final int MODE_DNS = 1; public static final int MODE_DNS_TXT = 2; public static final int MODE_DNS6 = 3; protected Map queues = new HashMap(); protected Map modes = new HashMap(); protected Set tasked = new HashSet(); protected boolean shouldPad = false; protected long when = 0L;
protected List getQueue(String var1) { synchronized(this) { if (this.queues.containsKey(var1)) { return (List)this.queues.get(var1); } else { LinkedList var3 = new LinkedList(); this.queues.put(var1, var3); return var3; } } }
public boolean isNewSession(String var1) { synchronized(this) { return !this.tasked.contains(var1); } }
public void virgin(String var1) { synchronized(this) { this.tasked.remove(var1); } }
public void shouldPad(boolean var1) { this.shouldPad = false; this.when = System.currentTimeMillis() + 1800000L; }
public void task(String var1, byte[] var2) { synchronized(this) { List var4 = this.getQueue(var1); if (this.shouldPad && System.currentTimeMillis() > this.when) { CommandBuilder var5 = new CommandBuilder(); var5.setCommand(3); var5.addString(var2); var4.add(var5.build()); } else { var4.add(var2); }
this.tasked.add(var1); } }
public void seen(String var1) { synchronized(this) { this.tasked.add(var1); } }
public void clear(String var1) { synchronized(this) { List var3 = this.getQueue(var1); var3.clear(); this.tasked.add(var1); } }
public int getMode(String var1) { synchronized(this) { String var3 = (String)this.modes.get(var1); if ("dns-txt".equals(var3)) { return 2; } else if ("dns6".equals(var3)) { return 3; } else { return "dns".equals(var3) ? 1 : 2; } } }
public void mode(String var1, String var2) { synchronized(this) { this.modes.put(var1, var2); } }
public boolean hasTask(String var1) { synchronized(this) { List var3 = this.getQueue(var1); return var3.size() > 0; } }
public byte[] dump(String var1, int var2) { synchronized(this) { int var4 = 0; List var5 = this.getQueue(var1); if (var5.size() == 0) { return new byte[0]; } else { ByteArrayOutputStream var6 = new ByteArrayOutputStream(8192); Iterator var7 = var5.iterator();
while(var7.hasNext()) { byte[] var8 = (byte[])((byte[])var7.next()); if (var4 + var8.length < var2) { var6.write(var8, 0, var8.length); var7.remove(); var4 += var8.length; } else { if (var8.length < var2) { CommonUtils.print_warn("Chunking tasks for " + var1 + "! " + var8.length + " + " + var4 + " past threshold. " + var5.size() + " task(s) on hold until next checkin."); break; }
CommonUtils.print_error("Woah! Task " + var8.length + " for " + var1 + " is beyond our limit. Dropping it"); var7.remove(); } }
return var6.toByteArray(); } } } }
|
搞完这些,就可以白嫖了。
beacon/Tasks 定义命令编号 beacon/Job 定义beacon端返回模块执行结果编号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| package beacon;
public class Tasks { public static final int COMMAND_SPAWN = 1; public static final int COMMAND_SHELL = 2; public static final int COMMAND_DIE = 3; public static final int COMMAND_SLEEP = 4; public static final int COMMAND_CD = 5; public static final int COMMAND_KEYLOG_START = 6; public static final int COMMAND_KEYLOG_STOP = 7; public static final int COMMAND_INJECT_PID = 9; public static final int COMMAND_INJECT_PING = 18; public static final int COMMAND_UPLOAD = 10; public static final int COMMAND_SPAWN_PROC_X86 = 13; public static final int COMMAND_JOB_REGISTER = 40; public static final int COMMAND_INJECTX64_PID = 43; public static final int COMMAND_SPAWNX64 = 44; public static final int COMMAND_LSOCKET_BIND = 50; public static final int COMMAND_LSOCKET_CLOSE = 51; public static final int COMMAND_JOB_REGISTER_IMPERSONATE = 62; public static final int COMMAND_SPAWN_POWERSHELLX86 = 63; public static final int COMMAND_SPAWN_POWERSHELLX64 = 64; public static final int COMMAND_INJECT_POWERSHELLX86_PID = 65; public static final int COMMAND_INJECT_POWERSHELLX64_PID = 66; public static final int COMMAND_UPLOAD_CONTINUE = 67; public static final int COMMAND_PIPE_OPEN_EXPLICIT = 68; public static final int COMMAND_SPAWN_PROC_X64 = 69; public static final int COMMAND_JOB_SPAWN_X86 = 70; public static final int COMMAND_JOB_SPAWN_X64 = 71; public static final int COMMAND_SETENV = 72; public static final int COMMAND_FILE_COPY = 73; public static final int COMMAND_FILE_MOVE = 74; public static final int COMMAND_PPID = 75; public static final int COMMAND_RUN_UNDER_PID = 76; public static final int COMMAND_GETPRIVS = 77; public static final int COMMAND_EXECUTE_JOB = 78; public static final int COMMAND_PSH_HOST_TCP = 79; public static final int COMMAND_DLL_LOAD = 80; public static final int COMMAND_REG_QUERY = 81; public static final int COMMAND_LSOCKET_TCPPIVOT = 82; public static final int COMMAND_ARGUE_ADD = 83; public static final int COMMAND_ARGUE_REMOVE = 84; public static final int COMMAND_ARGUE_LIST = 85; public static final int COMMAND_TCP_CONNECT = 86; public static final int COMMAND_JOB_SPAWN_TOKEN_X86 = 87; public static final int COMMAND_JOB_SPAWN_TOKEN_X64 = 88; public static final int COMMAND_SPAWN_TOKEN_X86 = 89; public static final int COMMAND_SPAWN_TOKEN_X64 = 90; public static final int COMMAND_INJECTX64_PING = 91; public static final int COMMAND_BLOCKDLLS = 92; public static final int COMMAND_SPAWNAS_X86 = 93; public static final int COMMAND_SPAWNAS_X64 = 94; public static final int COMMAND_INLINE_EXECUTE = 95; public static final int COMMAND_RUN_INJECT_X86 = 96; public static final int COMMAND_RUN_INJECT_X64 = 97; public static final int COMMAND_SPAWNU_X86 = 98; public static final int COMMAND_SPAWNU_X64 = 99; public static final int COMMAND_INLINE_EXECUTE_OBJECT = 100; public static final int COMMAND_JOB_REGISTER_MSGMODE = 101; public static final int COMMAND_LSOCKET_BIND_LOCALHOST = 102; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package beacon;
import common.CommonUtils; import common.ReflectiveDLL; import common.SleevedResource; import pe.PostExObfuscator;
public abstract class Job { public static final int CALLBACK_OUTPUT = 0; public static final int CALLBACK_KEYSTROKES = 1; public static final int CALLBACK_FILE = 2; public static final int CALLBACK_SCREENSHOT = 3; public static final int CALLBACK_CLOSE = 4; public static final int CALLBACK_READ = 5; public static final int CALLBACK_CONNECT = 6; public static final int CALLBACK_PING = 7; public static final int CALLBACK_FILE_WRITE = 8; public static final int CALLBACK_FILE_CLOSE = 9; public static final int CALLBACK_PIPE_OPEN = 10; public static final int CALLBACK_PIPE_CLOSE = 11; public static final int CALLBACK_PIPE_READ = 12; public static final int CALLBACK_POST_ERROR = 13; public static final int CALLBACK_PIPE_PING = 14; public static final int CALLBACK_TOKEN_STOLEN = 15; public static final int CALLBACK_TOKEN_GETUID = 16; public static final int CALLBACK_PROCESS_LIST = 17; public static final int CALLBACK_POST_REPLAY_ERROR = 18; public static final int CALLBACK_PWD = 19; public static final int CALLBACK_JOBS = 20; public static final int CALLBACK_HASHDUMP = 21; public static final int CALLBACK_PENDING = 22; public static final int CALLBACK_ACCEPT = 23; public static final int CALLBACK_NETVIEW = 24; public static final int CALLBACK_PORTSCAN = 25; public static final int CALLBACK_DEAD = 26; public static final int CALLBACK_SSH_STATUS = 27; public static final int CALLBACK_CHUNK_ALLOCATE = 28; public static final int CALLBACK_CHUNK_SEND = 29; public static final int CALLBACK_OUTPUT_OEM = 30; public static final int CALLBACK_ERROR = 31; public static final int CALLBACK_OUTPUT_UTF8 = 32; }
|
package beacon 与beacon相关DLL只在客户端保存即可,与beacon执行命令的结果会在服务器存储以及通过广播发给所有用户/也可以指定某个用户。需要二次开发时注意让DLL的执行结果支持返回给指定用户。
关于Beacon端二开,在看了Majority师傅的CS二开浅析视频后,注意到以下几点。
静态A.B.U:
- 加密
- 混淆:导入表、字符串、花指令
- 隐写:图片、音频
动态A.B.U:
- 敏感API调用走syscall,参考地狱之门的实现
- 内存加载(DarkLoadLibrary)
- 内存申请从RWX改成RW -> RX
- ACE(AlternativeShellcodeExec)
- 三端分离(加载器、安装器、核心控制端)
- 其他的执行方式
- 禁止AMSI
- 禁止ETW
推荐用Native(C++、go等)写后渗透模块,比较通用,C#需要对环境进行适配,不是很通用。