文章总结: 本文介绍了GoCobaltStrike2.3破解版的情况,并对其功能、免杀能力以及界面进行了评价。文章指出,尽管该版本声称具有强大的免杀能力和代理功能,但实际上其表现并不如预期,特别是在免杀效果和C2特征标记方面存在问题。 综合评分: 45 文章分类: 安全意识,实战经验
GoCobaltStrike 2.3破解版
不知名选手 不知名选手
法克安全
2026年4月28日 18:57 四川
在小说阅读器读本章
去阅读
免杀能力强突破、代理功能替代vshell、全界面汉化 | GoCobaltStrike 2.3发布!
文章看起来感觉挺牛逼对吧,还有web界面。gui界面,免杀能力还提升了就这玩意据说1千多人花了218进他的星球就为了吃这一坨大的。
第一眼看着文章很多人都蠢蠢欲动了吧,结果花了钱进去过后,整个c2的特征估计都被标记烂了不说,自己说的免杀能力强突破结果一言难尽(我自己哪怕用vshell写个c的loder编译出来12kb的exe加上bin文件执行都能静态动态过卡巴的,怎么你这还需要自己重新写个loder吗?很多人不都是奔着免杀效果来的,你这强突破,我是真没看出来哪里突破了)更神奇的是你上线也有问题,而且对cna脚本不太适配,我的妈耶,就这玩意218啊,我把这218拿去买token是不是自己也能搓一个出来了
真的说不下去了,我的评价是:不如vshell,光是我一个人吃了难受,这样可不行,这就放出来给各位品鉴一下咸淡!
破解脚本:
#切勿擅自修改代码,否则无法运行程序,并且造成的后果自寻承担#直接将此脚本放到server目录下,与teamserver-linux-amd64-2.3.1同目录后运行即可#!/usr/bin/env python3import os, sys, subprocess, select, struct, time
EXE = './teamserver-linux-amd64-2.3.1'LICENSE_PATCH_ADDR = 0xb9b580LICENSE_PATCH = bytes.fromhex('b801000000c3')
LIMIT_CHECK_ADDR = 0xae9ec0CODE_CAVE_ADDR = 0xae9d8cALLOW_ADDR = 0xaea0f9FAIL_ADDR = 0xae9ecaLIMIT_VALUE = 9999LICENSE = 'GOCS-ADVANCED-10YEAR-LICENSE-9999CLIENTS'ABOUT_URL = 'https://mp.weixin.qq.com/s/gFNoz9Gv0bPGvmsk1oF-sQ'ABOUT_JS_ADDR = 0xd92060ABOUT_JS_LEN = 3527ABOUT_JS_MARKER = 'Pisces_0721'.encode()ABOUT_JS_MARKER_OFF = 0x87fINDEX_HTML_ADDR = 0xd24cafINDEX_HTML_LEN = 1377INDEX_HTML_MARKER = b'<script type="module" crossorigin src="/static/js/index-CdymiMeI.js"></script>'INDEX_HTML_MARKER_OFF = 414
def rel32(src_next, dst): return struct.pack('<i', dst - src_next)
def jmp_rel32(src, dst): return b'\xE9' + rel32(src + 5, dst)
def jl_rel32(src, dst): return b'\x0F\x8C' + rel32(src + 6, dst)
def build_about_js_patch(): code = ( 'const u=%r;' 'const A={name:"About",setup(){window.location.replace(u);return()=>null}};' 'export{A as default};\n' ) % ABOUT_URL patch = code.encode() if len(patch) > ABOUT_JS_LEN: raise ValueError('about patch is longer than original chunk') pad_len = ABOUT_JS_LEN - len(patch) if pad_len: if pad_len < 4: patch += b' ' * pad_len else: patch += b'/*' + b'A' * (pad_len - 4) + b'*/' assert len(patch) == ABOUT_JS_LEN return patch
def build_index_html_patch(): html = f"""<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" /> <title>管理平台</title> <link rel="icon" href="/favicon.ico?v=1" /> <script>if(location.pathname==="/about/index")location.replace("{ABOUT_URL}")</script> <script type="module" src="/static/js/index-CdymiMeI.js"></script> <link rel="stylesheet" href="/static/css/index-B60k1-56.css"> </head>
<body> <div id="app"> <style>html,body,#app{{width:100%;height:100%;margin:0;display:flex;align-items:center;justify-content:center;overflow:hidden}}.loader,.loader:after,.loader:before{{animation:load-animation 1.8s ease-in-out infinite;animation-fill-mode:both;border-radius:50%;height:2.5em;width:2.5em}}.loader{{animation-delay:-.16s;color:#406eeb;font-size:10px;position:relative;text-indent:-9999em}}.loader:after,.loader:before{{content:"";position:absolute;top:0}}.loader:before{{animation-delay:-.32s;left:-3.5em}}.loader:after{{left:3.5em}}@keyframes load-animation{{0%,80%,to{{box-shadow:0 2.5em 0 -1.3em}}40%{{box-shadow:0 2.5em 0 0}}}}</style> <div class="loader"></div> </div> </body></html>""".encode() if len(html) > INDEX_HTML_LEN: raise ValueError('index html patch is longer than original shell') return html + b' ' * (INDEX_HTML_LEN - len(html))
def patch_index_html(mem, pid): patch = build_index_html_patch() patched_addrs = [] sample = b''
mem.seek(INDEX_HTML_ADDR) old = mem.read(INDEX_HTML_LEN) sample = old[:32] if old.startswith(patch[:96]): patched_addrs.append(INDEX_HTML_ADDR) elif old.startswith(b'<!doctype html>') and INDEX_HTML_MARKER in old: mem.seek(INDEX_HTML_ADDR) mem.write(patch) patched_addrs.append(INDEX_HTML_ADDR)
with open(f'/proc/{pid}/maps', 'r', encoding='utf-8', errors='ignore') as maps: for line in maps: parts = line.split() if len(parts) < 2 or 'r' not in parts[1]: continue start_s, end_s = parts[0].split('-') start, end = int(start_s, 16), int(end_s, 16) size = end - start if size <= 0 or size > 512 * 1024 * 1024: continue try: mem.seek(start) data = mem.read(size) except Exception: continue pos = data.find(INDEX_HTML_MARKER) if pos < 0: continue addr = start + pos - INDEX_HTML_MARKER_OFF if addr < start or addr + INDEX_HTML_LEN > end: continue mem.seek(addr) old = mem.read(INDEX_HTML_LEN) sample = old[:32] if old.startswith(patch[:96]): if addr not in patched_addrs: patched_addrs.append(addr) continue if old.startswith(b'<!doctype html>') and INDEX_HTML_MARKER in old: mem.seek(addr) mem.write(patch) if addr not in patched_addrs: patched_addrs.append(addr)
if patched_addrs: status = f'patched {len(patched_addrs)} copy/copies' return patched_addrs[0], sample, status return None, sample, 'not found'
def patch_about_js(mem, pid): patch = build_about_js_patch()
mem.seek(ABOUT_JS_ADDR) old = mem.read(ABOUT_JS_LEN) if old.startswith(patch[:64]): return ABOUT_JS_ADDR, old[:32], 'already patched' if old.startswith(b'import{') and (ABOUT_JS_MARKER in old or '星落安全团队'.encode() in old): mem.seek(ABOUT_JS_ADDR) mem.write(patch) return ABOUT_JS_ADDR, old[:32], 'patched fixed addr'
with open(f'/proc/{pid}/maps', 'r', encoding='utf-8', errors='ignore') as maps: for line in maps: parts = line.split() if len(parts) < 2 or 'r' not in parts[1]: continue start_s, end_s = parts[0].split('-') start, end = int(start_s, 16), int(end_s, 16) size = end - start if size <= 0 or size > 512 * 1024 * 1024: continue try: mem.seek(start) data = mem.read(size) except Exception: continue pos = data.find(ABOUT_JS_MARKER) if pos < 0: continue addr = start + pos - ABOUT_JS_MARKER_OFF if addr < start or addr + ABOUT_JS_LEN > end: continue mem.seek(addr) old = mem.read(ABOUT_JS_LEN) if old.startswith(b'import{') and ABOUT_JS_MARKER in old: mem.seek(addr) mem.write(patch) return addr, old[:32], 'patched by scan'
return None, old[:32], 'not found'
def patch_mem(pid): with open(f'/proc/{pid}/mem', 'r+b', buffering=0) as mem: mem.seek(LICENSE_PATCH_ADDR) old_lic = mem.read(len(LICENSE_PATCH)) mem.seek(LICENSE_PATCH_ADDR) mem.write(LICENSE_PATCH)
cave = bytearray() cave += b'\x48\x81\xFA' + struct.pack('<I', LIMIT_VALUE) cave += jl_rel32(CODE_CAVE_ADDR + len(cave), ALLOW_ADDR) cave += jmp_rel32(CODE_CAVE_ADDR + len(cave), FAIL_ADDR) cave += b'\x90' * (20 - len(cave)) assert len(cave) <= 20
mem.seek(CODE_CAVE_ADDR) old_cave = mem.read(20) mem.seek(CODE_CAVE_ADDR) mem.write(cave)
tramp = jmp_rel32(LIMIT_CHECK_ADDR, CODE_CAVE_ADDR) + b'\x90' * 5 mem.seek(LIMIT_CHECK_ADDR) old_limit = mem.read(len(tramp)) mem.seek(LIMIT_CHECK_ADDR) mem.write(tramp)
html_addr, old_html, html_status = patch_index_html(mem, pid) about_addr, old_about, about_status = patch_about_js(mem, pid)
print(f'\n[crack] patched main.verifyKeyWithServer @ {LICENSE_PATCH_ADDR:#x}: {old_lic.hex()} -> {LICENSE_PATCH.hex()}', file=sys.stderr, flush=True) print(f'[crack] patched Beacons.Checkin max clients: 99 -> {LIMIT_VALUE}', file=sys.stderr, flush=True) print(f'[crack] trampoline @ {LIMIT_CHECK_ADDR:#x}: {old_limit.hex()} -> {tramp.hex()}', file=sys.stderr, flush=True) print(f'[crack] code cave @ {CODE_CAVE_ADDR:#x}: {old_cave.hex()} -> {cave.hex()}', file=sys.stderr, flush=True) if html_addr is not None: print(f'[crack] patched index shell @ {html_addr:#x}: {html_status}; direct /about/index redirect -> {ABOUT_URL}', file=sys.stderr, flush=True) else: print(f'[crack] WARNING: index shell patch failed: {html_status}; head={old_html.hex()}', file=sys.stderr, flush=True) if about_addr is not None: print(f'[crack] patched /about/index chunk @ {about_addr:#x}: {about_status}; redirect -> {ABOUT_URL}', file=sys.stderr, flush=True) else: print(f'[crack] WARNING: /about/index chunk patch failed: {about_status}; head={old_about.hex()}', file=sys.stderr, flush=True)
def main(): args = [EXE] + (sys.argv[1:] or ['-p','50055','127.0.0.1','pass','default.profile']) p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=0) buf = b'' did_yes = False did_patch = False try: while True: r,_,_ = select.select([p.stdout], [], [], 0.2) if r: chunk = os.read(p.stdout.fileno(), 4096) if not chunk: break sys.stdout.buffer.write(chunk); sys.stdout.flush() buf += chunk if (b'(yes/no)' in buf or '是否同意并继续'.encode() in buf) and not did_yes: p.stdin.write(b'yes\n'); p.stdin.flush(); did_yes=True if b'Please enter your license key' in buf and not did_patch: patch_mem(p.pid) did_patch = True p.stdin.write((LICENSE + '\n').encode()); p.stdin.flush() if p.poll() is not None: break return p.wait() finally: if p.poll() is None: try: p.terminate() except Exception: pass
if __name__ == '__main__': sys.exit(main())
公众号私信发送:GoCobaltStrike 2.3破解版 获取下载地址,自己搭配破解脚本去尝尝咸淡吧!
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:法克安全 《GoCobaltStrike 2.3破解版》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论