Skip to content

Commit

Permalink
🆕 Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kernel-sanders committed Apr 5, 2024
0 parents commit 948f705
Show file tree
Hide file tree
Showing 12 changed files with 2,283 additions and 0 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
# This workflow requires a GALAXY_API_KEY secret present in the GitHub
# repository or organization.
#
# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy
# See: https://github.com/ansible/galaxy/issues/46

name: Release
'on':
push:
tags:
- '*'

defaults:
run:
working-directory: 'ludus_ansible_role'

jobs:

release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Check out the codebase.
uses: actions/checkout@v4
with:
path: 'ludus_ansible_role'

- name: Set up Python 3.
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Install Ansible.
run: pip3 install ansible-core

- name: Trigger a new import on Galaxy.
run: >-
ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }}
$(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2)
49 changes: 49 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
### Ansible ###
*.retry

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud

### VisualStudioCode ###
.vscode

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Ansible Role: Commando VM ([Ludus](https://ludus.cloud))

An Ansible Role that sets up [Commando VM](https://github.com/mandiant/commando-vm) on Windows >= 10 hosts.

Uses code from [privacy.sexy](https://privacy.sexy) to disable Defender and Tamper Protection.

## Requirements

- Windows >= 10
- at least 60 GB of disk space (80+ recommended)
- at least 2GB RAM (4+ recommended)

## Role Variables

# Disable the red/green dynamic Ludus wallpaper in favor of the static Commando VM wallpaper
ludus_commandovm_use_commandovm_wallpaper: true
# Use the -noPassword option if the user is set for auto-login (default: true)
ludus_commandovm_nopassword: true
# Provide the user's password if the user is not set for auto-login
ludus_commandovm_password:

## Dependencies

- community.windows

## Troubleshooting

See [Troubleshooting](https://github.com/mandiant/commando-vm/blob/main/Docs/Troubleshooting.md)

## Known issues

After the first reboot the commando process may reboot again before ansible can remove the Run key that starts the install and it will fail in the background. This has no impact on the install.

## Example Playbook

```yaml
- hosts: commandovm_hosts
roles:
- badsectorlabs.ludus_commandovm
```
## Example Ludus Range Config
```yaml
ludus:
- vm_name: "{{ range_id }}-commando"
hostname: "{{ range_id }}-COMMANDO"
template: win11-22h2-x64-enterprise-template
vlan: 99
ip_last_octet: 4
ram_gb: 8
cpus: 4
windows:
install_additional_tools: false
roles:
- badsectorlabs.ludus_commandovm
```
## License
GPLv3
## Author Information
This role was created by [Bad Sector Labs](https://github.com/badsectorlabs), for [Ludus](https://ludus.cloud/).
4 changes: 4 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
ludus_commandovm_use_commandovm_wallpaper: true
ludus_commandovm_nopassword: true
ludus_commandovm_password:
1,028 changes: 1,028 additions & 0 deletions files/disable_defender.bat

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions files/disable_updates.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Start-Transcript -path C:\ludus\disable-updates-log.txt -append
$ErrorActionPreference = "SilentlyContinue"

# Stop the service and disable it
Stop-Service -Name wuauserv
Set-Service -Name wuauserv -StartupType Disabled

# Notify before download
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "AUOptions" -Value 2 -Type DWord -Force

# Turn the whole thing off
Set-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate" -Name "DisableWindowsUpdateAccess" -Value 0 -Type DWord -Force
Set-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoUpdate" -Value 1 -Type DWord -Force

# Disable the update prompt scheduled tasks
try {
Get-ScheduledTask -TaskPath "\Microsoft\Windows\UpdateOrchestrator\USO_UxBroker_Display" -ErrorAction SilentlyContinue | Disable-ScheduledTask
} catch {
Write-Host "No task \Microsoft\Windows\UpdateOrchestrator\USO_UxBroker_Display"
}
try {
Get-ScheduledTask -TaskPath "\Microsoft\Windows\UpdateOrchestrator\MusUx_UpdateInterval" -ErrorAction SilentlyContinue | Disable-ScheduledTask
} catch {
Write-Host "No task \Microsoft\Windows\UpdateOrchestrator\MusUx_UpdateInterval"
}
try {
Get-ScheduledTask -TaskPath "\Microsoft\Windows\WindowsUpdate\sih" -ErrorAction SilentlyContinue | Disable-ScheduledTask
} catch {
Write-Host "No task \Microsoft\Windows\WindowsUpdate\sih"
}
12 changes: 12 additions & 0 deletions ludus-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ludus:
- vm_name: "{{ range_id }}-commando"
hostname: "{{ range_id }}-COMMANDO"
template: win11-22h2-x64-enterprise-template
vlan: 99
ip_last_octet: 4
ram_gb: 8
cpus: 4
windows:
install_additional_tools: false
roles:
- badsectorlabs.ludus_commandovm
22 changes: 22 additions & 0 deletions meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
dependencies: []

galaxy_info:
role_name: ludus_commandovm
author: badsectorlabs
description: An Ansible Role that sets up Commando VM on Windows >= 10 hosts
company: Bad Sector Labs
license: GPLv3
min_ansible_version: "2.10"
platforms:
- name: Windows
versions:
- "2019"
- "2022"
galaxy_tags:
- hacking
- offsec
- commando

collections:
- community.windows
98 changes: 98 additions & 0 deletions tasks/download_file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
## General purpose caching downloader for Ludus

## Example windows usage:
# - name: General purpose caching downloader example
# ansible.builtin.include_tasks:
# file: download_file.yml
# vars:
# ludus_download_file_name: adkwinpesetup.exe
# ludus_download_file_url: https://download.microsoft.com/download/0/1/C/01CC78AA-B53B-4884-B7EA-74F2878AA79F/adk/adksetup.exe
# ludus_download_file_host_path: "C:\\ludus\\sccm"

## Example Linux usage:
# - name: General purpose caching downloader example (Linux)
# ansible.builtin.include_tasks:
# file: download_file.yml
# vars:
# ludus_download_file_name: elastic-agent-8.13.1-linux-x86_64.tar.gz
# ludus_download_file_url: https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent-8.13.1-linux-x86_64.tar.gz
# ludus_download_file_host_path: /opt/elastic
# # Only use checksums for files that do not update!
# ludus_download_file_checksum: "sha512:a91a09124eacfdce9cb8d6876ae2896ad0f0682ca8e112ccf2ec5660f3ec4db96b230869f5dc5011136a15d2882a58b71e45775843f31c282ee8c8db9524a27f"
# # Set to always download and ignore cache
# ludus_download_file_force_download: true

####################################
# You should not modify this file! #
####################################

- name: Get file if needed
run_once: true
block:
- name: "Create directory on Ludus host if it doesn't exist: {{ ludus_install_path }}/resources/{{ role_name }}"
ansible.builtin.file:
path: "{{ ludus_install_path }}/resources/{{ role_name }}"
state: directory
recurse: true
delegate_to: localhost

- name: Check if file exists on Ludus host
ansible.builtin.stat:
path: "{{ ludus_install_path }}/resources/{{ role_name }}/{{ ludus_download_file_name }}"
checksum_algorithm: "{{ ludus_download_file_checksum.split(':')[0] if ludus_download_file_checksum is defined else 'sha1' }}"
delegate_to: localhost
register: file_check

- name: Chceck file checksum if file exists
ansible.builtin.set_fact:
existing_file_checksum_correct: "{{ file_check.stat.checksum == ludus_download_file_checksum.split(':')[1] }}"
when: file_check.stat.exists and ludus_download_file_checksum is defined

- name: Downloading file to Ludus host
ansible.builtin.get_url:
url: "{{ ludus_download_file_url }}"
dest: "{{ ludus_install_path }}/resources/{{ role_name }}/{{ ludus_download_file_name }}"
checksum: "{{ ludus_download_file_checksum | default(omit) }}"
mode: "660"
delegate_to: localhost
when: |
(ludus_download_file_force_download is defined and ludus_download_file_force_download)
or not file_check.stat.exists
or (existing_file_checksum_correct is defined and not existing_file_checksum_correct)
- name: Create directory on VM if it doesn't exist (Windows)
ansible.windows.win_file:
path: "{{ ludus_download_file_host_path }}"
state: directory
when: ansible_os_family == "Windows"

- name: Check if file exists on VM (Windows)
ansible.windows.win_stat:
path: "{{ ludus_download_file_host_path }}\\{{ ludus_download_file_name }}"
register: file_host_check_windows
when: ansible_os_family == "Windows"

- name: Copy file to windows VM (Windows)
ansible.windows.win_copy:
src: "{{ ludus_install_path }}/resources/{{ role_name }}/{{ ludus_download_file_name }}"
dest: "{{ ludus_download_file_host_path }}\\{{ ludus_download_file_name }}"
when: ansible_os_family == "Windows" and not file_host_check_windows.stat.exists

- name: Create directory on VM if it doesn't exist (Linux/macOS)
ansible.builtin.file:
path: "{{ ludus_download_file_host_path }}"
state: directory
mode: "0755"
when: not ansible_os_family == "Windows"

- name: Check if file exists on VM (Linux/macOS)
ansible.builtin.stat:
path: "{{ ludus_download_file_host_path }}/{{ ludus_download_file_name }}"
register: file_host_check_linux
when: not ansible_os_family == "Windows"

- name: Copy file to windows VM (Linux/macOS)
ansible.builtin.copy:
src: "{{ ludus_install_path }}/resources/{{ role_name }}/{{ ludus_download_file_name }}"
dest: "{{ ludus_download_file_host_path }}/{{ ludus_download_file_name }}"
when: not ansible_os_family == "Windows" and not file_host_check_linux.stat.exists
Loading

0 comments on commit 948f705

Please sign in to comment.