Full Code of tothi/ad-honeypot-autodeploy for AI

master ec48267abddf cached
34 files
78.7 KB
22.4k tokens
1 symbols
1 requests
Download .txt
Repository: tothi/ad-honeypot-autodeploy
Branch: master
Commit: ec48267abddf
Files: 34
Total size: 78.7 KB

Directory structure:
gitextract_tyoks_c1/

├── README.md
├── ansible/
│   ├── dashboard.json
│   ├── gen_users.py
│   ├── graylog_config.sh
│   ├── hosts
│   ├── id.pub
│   ├── nxlog.conf
│   ├── rdp_public.sh
│   ├── requirements.txt
│   ├── setup-domain.yml
│   └── wordlist.txt
├── init-passwords.sh
├── packer/
│   ├── .ssh/
│   │   ├── id_ed25519
│   │   └── id_ed25519.pub
│   ├── answer_files/
│   │   ├── graylog/
│   │   │   ├── preseed.cfg
│   │   │   └── preseed.cfg~
│   │   ├── win10/
│   │   │   └── Autounattend.xml
│   │   ├── win2012r2/
│   │   │   └── Autounattend.xml
│   │   └── win2016/
│   │       └── Autounattend.xml
│   ├── get-virtio.sh
│   ├── graylog.json
│   ├── packer-build-all.sh
│   ├── private.json
│   ├── scripts/
│   │   ├── bootstrap.ps1
│   │   ├── graylog.sh
│   │   ├── setupcomplete.ps1
│   │   ├── shutdown.ps1
│   │   └── win2012r2-dotnet-fix.ps1
│   ├── win10.json
│   ├── win2012r2.json
│   └── win2016.json
└── terraform/
    ├── main.tf
    ├── network-dhcp-lease.xsl
    └── timer-patch.xsl

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# ad-honeypot-autodeploy

Deploy a small, intentionally insecure, vulnerable Windows Domain
for RDP Honeypot fully automatically.

Runs on self-hosted virtualization using [libvirt](https://libvirt.org)
with [QEMU](https://www.qemu.org/)/[KVM](https://www.linux-kvm.org/page/Main_Page) (but it can be customized easily for cloud-based solutions).

Used for painlessly set up a small Windows Domain from scratch
automatically (without user interaction) for the purpose of RDP Honeypot
testing.

Features a Domain Controller, a Desktop Computer and a configured
Graylog server for logging the actions of the bad guys.

## Automatic deployment phases

1. [Packer](https://www.packer.io/): download the necessary install media and setup the
automated base virtual machine images unattended.

2. [Terraform](https://www.terraform.io/): provision the libvirt virtualization infrastructure
(network + virtual machines) using the packer-prepared
virtual machine images.

3. [Ansible](https://www.ansible.com/): Configure the infrastructure (DC, Desktop, Graylog)
automatically, without user interaction.

After going through the Packer+Terraform+Ansible pipeline,
the configured Windows Domain should be up and running, you could
attach the RDP service of the Desktop to the public internet, and
let's monitor the events through the Graylog.

## Features

Features of the running system are:

* a Windows Server 2016 as a Domain Controller
* a Windows 10 Desktop (version 21H2) as a Domain Computer
* a [Graylog](https://www.graylog.org/) 3.3 (Open Source edition) running as a Log Collector on [Ubuntu](https://ubuntu.com/) 18.04 LTS
* Using [VirtIO](https://wiki.libvirt.org/page/Virtio) drivers for best performance
* Enabled RDP and WinRM Services
* Populated Windows Active Directory with random users
* [Sysmon](https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon) (from [Windows Sysinternals](https://docs.microsoft.com/en-us/sysinternals/)) installed and running on Domain Computers
* [NXLog](https://nxlog.co/) Collector running a Domain Computers and forwarding logs to Graylog
* Configured Graylog GeoIP lookup table and pipeline for IP addresses (useful for showing a map of invalid RDP login attempts)
* Graylog World Map of RDP attacks
* an extra [Kali](https://www.kali.org/) VM attached to the Windows subnet for playing with attack techniques

## Host System Requirements

Virtualization needs some power of your host system:

* ~100 GB disk space for the base images and the sparse images of the guest computers.
* at least 4 x 4 GB memory for the guest machines
(may run with less than 16 GB because of overcommitment)
* installed up-to-date libvirt with QEMU/KVM (official current packages in Ubuntu 18.04 LTS should work)
* Python 3 (preferably with venv) for Ansible

Tested on Ubuntu 18.04 LTS host.

## Installation and Usage

First, clone the repo:

```
git clone https://github.com/tothi/ad-honeypot-autodeploy
cd ad-honeypot-autodeploy
```

Before starting with Packer, set up the intial passwords (watch for complexity requirements):

```
./init_passwords.sh
```

### Packer

Now build the initial images.

```
cd packer
```

Windows Server 2016 and Ubuntu installation media should be downloaded
by the Packer script. VirtIO needs to be downloaded by the attached
get-virtio.sh script:

```
./get-virtio.sh
```

Windows 10 should be downloaded manually by getting a temporary
download link and save it to the ISO folder. The download link
could be obtained from [here](https://www.microsoft.com/hu-hu/software-download/windows10ISO). Select the English (International), 64-bit version and
save the ISO to `ISO/Win10_21H2_EnglishInternational_x64.iso`.

For mapping IP locations on a World Map in Graylog, the MaxMind GeoIP
database is needed. Unfortunately due to licensing terms it cannot
be redistributed, so you have to download it manually (after registering)
from the [MaxMind site](https://www.maxmind.com). The free GeoLite2 version should work, get the
"GeoLite2 City" Database in MMDB format (download the GZIP and untar)
and put it at `resources/GeoLite2-City.mmdb`.

If you do not have Packer, get the latest version from the packer.io site
([download the pre-compiled binary](https://www.packer.io/downloads.html))
or try to [add the Hashicorp repository](https://learn.hashicorp.com/tutorials/terraform/install-cli) to your packaging system (useful for Terrafrom also).

If you are rebuilding the images, do not forget to clean up previous
builds:

```
rm -fr output_*
```

If you want to re-download the images, remove packer_cache:

```
rm -fr packer_cache
```

After these preparing steps, run the Packer builds in parallel:

```
./packer-build-all.sh
```

![Packer in action](./packer.png)

The images should be ready in a reasonable time (~20-30 mins depending
on your host hardware power).

### Terraform

Now the infrastructure can be deployed using Terraform.

Get Terraform (>=0.13) if you do not have it (look at the install methods
at Packer, above).

[Terraform provider for libvirt](https://github.com/dmacvicar/terraform-provider-libvirt)
should be automatically downloaded from the [Terraform Registry](https://registry.terraform.io/)
during the apply phase.

Enter Terraform folder:

```
cd ../terraform
```

Initialize the working directory (only needed for first time use):
```
terraform init
```

Build and launch the infrastructure ("apply the changes"):
```
terraform apply
```

Note, that if the user running `terraform apply` is not root, sudo privileges for running `/usr/sbin/iptables`
is needed (without password).

![Terraform in action](./terraform.png)

After a short time (~2-3 mins),
the network and virtual machines are up and running. If there are any failures, `terraform destroy` might not be enough,
manual undefining resources may be necessary.

> WARNING: You should take care of protecting your private
> network. The terraform config (main.tf) provided here just contains
> a custom firewall rule for my own testing environment
> (blocking 192.168.0.0/16 destination traffic from the
> 192.168.3.0/24 honeypot network).

Next is the configuration phase.

### Ansible

Get into the ansible folder:

```
cd ../ansible
```

Recommended installation method is installing the latest Ansible
with some required additional dependencies in a Python venv virtualized
environment:
```
python3 -m venv venv
. ./venv/bin/activate
pip3 install -r requirements.txt
```

For later use just activate the venv by
```
. ./venv/bin/activate
```

And just `deactivate` if it is not needed anymore in your
current session.

You should put an SSH public key with filename `id.pub` (use `ssh-keygen`) into the ansible
folder for accessing the Ubuntu Graylog machine with the ubuntu user
(ansible will add it to `~ubuntu/.ssh/authorized_keys`).

The `wordlist.txt` file contains some (intentionally weak) passwords
for the populated domain users which can be customized.

Run the configuration phase:

```
ansible-playbook -i hosts setup-domain.yml -v
```

![Ansible in action](./ansible.png)

After 20-25 mins everything is ready.

## The deployed system

| hostname  | ip address    | operating system          | role                      |
| --------- | ------------- | ------------------------- | ------------------------- |
| dc1       | 192.168.3.100 | Windows Server 2016       | Domain Controller         |
| desktop12 | 192.168.3.112 | Windows 10 (version 2004) | Domain Member Workstation |
| graylog   | 192.168.3.191 | Ubuntu 18.04 LTS          | Graylog Server            |
| kali      | 192.168.3.192 | Kali Rolling (2022.3)     | Offensive Operations      |

According to the libvirt network configuration (NAT), the hosts can access
the public internet (if your host system allows it).

Accessing the hosts is possible through the host system.
Practically using an SSH socks tunnel and proxychains for RDP or WinRM
access is very comfortable.

For example, if your libvirt host IP is 192.168.0.10,
create a socks tunnel listening on `localhost:5000` by
```
ssh 192.168.0.10 -D5000 -NTv
```

And access the Windows 10 desktop (using an appropriate `/etc/proxychains.conf`
configured for the :5000 tunnel):
```
proxychains xfreerdp /v:192.168.3.112 /u:administrator
```

Or, access the Graylog web interface listening on :9000 locally on
the Graylog Ubuntu server by SSH ProxyJump and custom forward tunnel:
```
ssh -J 192.168.0.10 ubuntu@192.168.3.191 -NTv -L9000:127.0.0.1:9000
```

Then open URL `http://localhost:9000` and you reach the Graylog web
interface.

For activating the RDP honeypot, just allow public access
to 192.168.3.112:3389 (for example with some port forwarding
configuration on your router and iptables rules on the host
machine; my helper script is [rdp_public.sh](ansible/rdp_public.sh))
and keep watching the Graylog. ;)



================================================
FILE: ansible/dashboard.json
================================================
{
  "v": 1,
  "id": "2397d589-a1fd-4ad8-b271-e72f44b4611f",
  "rev": 1,
  "name": "RDP Attack Dashboard",
  "summary": "Monitoring Dashboard for RDP Attacks",
  "description": "",
  "vendor": "an0n",
  "url": "",
  "parameters": [],
  "entities": [
    {
      "v": "1",
      "type": {
        "name": "dashboard",
        "version": "2"
      },
      "id": "e42b37b9-3e53-4e0e-ab66-064d57feacab",
      "data": {
        "summary": {
          "@type": "string",
          "@value": "Monitor RDP Attacks"
        },
        "search": {
          "queries": [
            {
              "id": "703206bc-2209-44c6-9027-148d841210ba",
              "timerange": {
                "type": "relative",
                "range": 300
              },
              "query": {
                "type": "elasticsearch",
                "query_string": ""
              },
              "search_types": [
                {
                  "query": {
                    "type": "elasticsearch",
                    "query_string": "EventID: 4625"
                  },
                  "name": "chart",
                  "timerange": {
                    "type": "relative",
                    "range": 0
                  },
                  "streams": [],
                  "series": [
                    {
                      "type": "count",
                      "id": "Message Count",
                      "field": null
                    }
                  ],
                  "filter": null,
                  "rollup": true,
                  "row_groups": [],
                  "type": "pivot",
                  "id": "30b34c81-72ee-411e-a9e6-8bfc6d13fdce",
                  "column_groups": [],
                  "sort": []
                },
                {
                  "query": {
                    "type": "elasticsearch",
                    "query_string": "EventID: 4625"
                  },
                  "name": "chart",
                  "timerange": {
                    "type": "relative",
                    "range": 0
                  },
                  "streams": [],
                  "series": [
                    {
                      "type": "count",
                      "id": "count()",
                      "field": null
                    }
                  ],
                  "filter": null,
                  "rollup": true,
                  "row_groups": [
                    {
                      "type": "values",
                      "field": "IpAddress_geo_city",
                      "limit": 15
                    }
                  ],
                  "type": "pivot",
                  "id": "56cd0b71-feac-4765-9750-7fc3f20486c2",
                  "column_groups": [],
                  "sort": []
                },
                {
                  "query": {
                    "type": "elasticsearch",
                    "query_string": "EventID: 4625"
                  },
                  "name": "chart",
                  "timerange": {
                    "type": "relative",
                    "range": 0
                  },
                  "streams": [],
                  "series": [
                    {
                      "type": "count",
                      "id": "count()",
                      "field": null
                    }
                  ],
                  "filter": null,
                  "rollup": true,
                  "row_groups": [
                    {
                      "type": "values",
                      "field": "IpAddress_geo_location",
                      "limit": 15
                    }
                  ],
                  "type": "pivot",
                  "id": "1f393b80-ef25-40d4-b04d-0d4a9d8156f1",
                  "column_groups": [],
                  "sort": []
                },
                {
                  "query": {
                    "type": "elasticsearch",
                    "query_string": "EventID: 4624 AND LogonType: 10"
                  },
                  "name": "chart",
                  "timerange": {
                    "type": "relative",
                    "range": 0
                  },
                  "streams": [],
                  "series": [
                    {
                      "type": "count",
                      "id": "Message Count",
                      "field": null
                    }
                  ],
                  "filter": null,
                  "rollup": true,
                  "row_groups": [],
                  "type": "pivot",
                  "id": "3963de17-64fb-4178-8aec-11b4951cbb2e",
                  "column_groups": [],
                  "sort": []
                }
              ]
            }
          ],
          "parameters": [],
          "requires": {},
          "owner": "admin",
          "created_at": "2020-10-05T23:20:44.620Z"
        },
        "created_at": "2020-10-05T22:34:45.717Z",
        "requires": {},
        "state": {
          "703206bc-2209-44c6-9027-148d841210ba": {
            "selected_fields": null,
            "static_message_list_id": null,
            "titles": {
              "widget": {
                "3c978baf-6e85-431a-b4c1-6d82c3ddddc4": "RDP Attack Origin World Map",
                "4db2a07e-8b77-4716-b659-029e2750dbf8": "Failed Login Attempts",
                "c1e773ab-706a-4935-9c9c-7e23c02e6820": "RDP Attack Origin",
                "496f078b-9707-47c2-8829-094b35d61004": "Successful RDP Logins"
              }
            },
            "widgets": [
              {
                "id": "3c978baf-6e85-431a-b4c1-6d82c3ddddc4",
                "type": "aggregation",
                "filter": null,
                "timerange": {
                  "type": "relative",
                  "range": 0
                },
                "query": {
                  "type": "elasticsearch",
                  "query_string": "EventID: 4625"
                },
                "streams": [],
                "config": {
                  "visualization": "map",
                  "event_annotation": false,
                  "row_pivots": [
                    {
                      "field": "IpAddress_geo_location",
                      "type": "values",
                      "config": {
                        "limit": 15
                      }
                    }
                  ],
                  "series": [
                    {
                      "config": {
                        "name": null
                      },
                      "function": "count()"
                    }
                  ],
                  "rollup": true,
                  "column_pivots": [],
                  "visualization_config": {
                    "viewport": {
                      "zoom": 1,
                      "center_x": 51.83577752045248,
                      "center_y": 23.203125000000004
                    }
                  },
                  "formatting_settings": null,
                  "sort": []
                }
              },
              {
                "id": "4db2a07e-8b77-4716-b659-029e2750dbf8",
                "type": "aggregation",
                "filter": null,
                "timerange": {
                  "type": "relative",
                  "range": 0
                },
                "query": {
                  "type": "elasticsearch",
                  "query_string": "EventID: 4625"
                },
                "streams": [],
                "config": {
                  "visualization": "numeric",
                  "event_annotation": false,
                  "row_pivots": [],
                  "series": [
                    {
                      "config": {
                        "name": "Message Count"
                      },
                      "function": "count()"
                    }
                  ],
                  "rollup": true,
                  "column_pivots": [],
                  "visualization_config": null,
                  "formatting_settings": null,
                  "sort": []
                }
              },
              {
                "id": "496f078b-9707-47c2-8829-094b35d61004",
                "type": "aggregation",
                "filter": null,
                "timerange": {
                  "type": "relative",
                  "range": 0
                },
                "query": {
                  "type": "elasticsearch",
                  "query_string": "EventID: 4624 AND LogonType: 10"
                },
                "streams": [],
                "config": {
                  "visualization": "numeric",
                  "event_annotation": false,
                  "row_pivots": [],
                  "series": [
                    {
                      "config": {
                        "name": "Message Count"
                      },
                      "function": "count()"
                    }
                  ],
                  "rollup": true,
                  "column_pivots": [],
                  "visualization_config": null,
                  "formatting_settings": null,
                  "sort": []
                }
              },
              {
                "id": "c1e773ab-706a-4935-9c9c-7e23c02e6820",
                "type": "aggregation",
                "filter": null,
                "timerange": {
                  "type": "relative",
                  "range": 0
                },
                "query": {
                  "type": "elasticsearch",
                  "query_string": "EventID: 4625"
                },
                "streams": [],
                "config": {
                  "visualization": "table",
                  "event_annotation": false,
                  "row_pivots": [
                    {
                      "field": "IpAddress_geo_city",
                      "type": "values",
                      "config": {
                        "limit": 15
                      }
                    }
                  ],
                  "series": [
                    {
                      "config": {
                        "name": null
                      },
                      "function": "count()"
                    }
                  ],
                  "rollup": true,
                  "column_pivots": [],
                  "visualization_config": null,
                  "formatting_settings": null,
                  "sort": []
                }
              }
            ],
            "widget_mapping": {
              "4db2a07e-8b77-4716-b659-029e2750dbf8": [
                "30b34c81-72ee-411e-a9e6-8bfc6d13fdce"
              ],
              "496f078b-9707-47c2-8829-094b35d61004": [
                "3963de17-64fb-4178-8aec-11b4951cbb2e"
              ],
              "c1e773ab-706a-4935-9c9c-7e23c02e6820": [
                "56cd0b71-feac-4765-9750-7fc3f20486c2"
              ],
              "3c978baf-6e85-431a-b4c1-6d82c3ddddc4": [
                "1f393b80-ef25-40d4-b04d-0d4a9d8156f1"
              ]
            },
            "positions": {
              "4db2a07e-8b77-4716-b659-029e2750dbf8": {
                "col": 9,
                "row": 1,
                "height": 2,
                "width": 2
              },
              "c1e773ab-706a-4935-9c9c-7e23c02e6820": {
                "col": 7,
                "row": 1,
                "height": 4,
                "width": 2
              },
              "3c978baf-6e85-431a-b4c1-6d82c3ddddc4": {
                "col": 1,
                "row": 1,
                "height": 4,
                "width": 6
              },
              "496f078b-9707-47c2-8829-094b35d61004": {
                "col": 9,
                "row": 3,
                "height": 2,
                "width": 2
              }
            },
            "formatting": {
              "highlighting": []
            },
            "display_mode_settings": {
              "positions": {}
            }
          }
        },
        "properties": [],
        "owner": "admin",
        "title": {
          "@type": "string",
          "@value": "RDP Attacks"
        },
        "type": "DASHBOARD",
        "description": {
          "@type": "string",
          "@value": "Basic Monitoring Dashboard"
        }
      },
      "constraints": [
        {
          "type": "server-version",
          "version": ">=3.3.6+92fb41e"
        }
      ]
    }
  ]
}

================================================
FILE: ansible/gen_users.py
================================================
#!/usr/bin/env python3
#
# generate fake users for ad:
#  * importable by ansible win_domain_user module users.yml var file (slow)
#  * ps1 script format (fast)
#

from faker import Factory
import random

NUM_OF_USERS = 1000
OUT_YML = "users.yml"
OUT_PS1 = "users.ps1"
OU = "Staff"

fake = Factory.create('en-GB')

group_chance = {"Domain Admins": 0.05, "RDP All": 0.8}

wordlist = list(map(lambda x: x.rstrip(), open("wordlist.txt", "r").readlines()))

def grouplist():
  res = []
  for g in group_chance:
    if random.random() < group_chance[g]:
      res.append(g)
  return res

yml = open(OUT_YML, "w")
ps1 = open(OUT_PS1, "w")

ps1.write('$d = (Get-ADDomain).DistinguishedName\r\n')
ps1.write('If (Get-ADOrganizationalUnit -Filter "distinguishedName -eq \'OU={},$d\'") {{ Remove-ADOrganizationalUnit -Identity "OU={},$d" -Confirm:$False }}\r\n'.format(OU, OU))
ps1.write('New-ADOrganizationalUnit -Name "{}" -Path $d -ProtectedFromAccidentalDeletion $false\r\n'.format(OU))
yml.write("users:\n")
groupdb = {}
samdb = []
for i in range(NUM_OF_USERS):
  fn = fake.first_name()
  ln = fake.last_name()
  pw = random.choice(wordlist)
  samname_base = "{}.{}".format(fn.lower(), ln.lower())
  samname = samname_base
  idx = 0
  while samname in samdb:
    idx += 1
    samname = "{}.{}".format(samname_base, idx)
  samdb.append(samname)
  if idx > 0:
    cn = "{} {} {}".format(fn, ln, idx)
  else:
    cn = "{} {}".format(fn, ln)
  yml.write("  - name: {}\n".format(samname))
  yml.write("    firstname: {}\n".format(fn))
  yml.write("    surname: {}\n".format(ln))
  yml.write("    password: {}\n".format(pw))
  yml.write("    state: present\n")
  yml.write("    groups:\n")
  ps1.write('New-ADUser -Enabled $true -AccountPassword (ConvertTo-SecureString -AsPlainText "{}" -Force) -Name "{}" -GivenName "{}" -Surname "{}" -SamAccountName "{}" -Path "OU={},$d"\r\n'.format(pw, cn, fn, ln, samname, OU))
  for g in grouplist():
    yml.write("      - {}\n".format(g))
    if g not in groupdb:
      groupdb[g] = []
    groupdb[g].append(samname)
for g in groupdb:
  ps1.write('If (-Not (Get-ADGroup -Filter "Name -eq \'{}\'")) {{ New-ADGroup -Name "{}" -GroupScope Global }}'.format(g, g))
  ps1.write('Add-ADGroupMember -Identity "{}" -Members "{}"\r\n'.format(g, '","'.join(groupdb[g])))

yml.close()
ps1.close()


================================================
FILE: ansible/graylog_config.sh
================================================
#!/bin/bash
#
# create Graylog lookup table (using previously created adapter + caches) by API calls
#

USER="$1"
PASS="$2"

ADAPTER=`/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' http://${USER}:${PASS}@127.0.0.1:9000/api/system/lookup/adapters | /usr/bin/jq '.data_adapters[] | select(.name=="geoip")' | /usr/bin/jq -r '.id'`
CACHE=`/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' http://${USER}:${PASS}@127.0.0.1:9000/api/system/lookup/caches | /usr/bin/jq '.caches[] | select(.name=="geoip")' | /usr/bin/jq -r '.id'`

/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/lookup/tables" -X POST --data "{\"title\":\"GeoIP\",\"description\":\"GeoIP Lookup Table\",\"name\":\"geoip\",\"cache_id\":\"${CACHE}\",\"data_adapter_id\":\"${ADAPTER}\",\"content_pack\":null,\"default_single_value\":\"\",\"default_single_value_type\":\"NULL\",\"default_multi_value\":\"\",\"default_multi_value_type\":\"NULL\"}}"

/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/pipelines/rule" -X POST --data '{"title":"GeoIP lookup: IpAddress","description":"","source":"rule \"GeoIP lookup: IpAddress\"\nwhen\n  has_field(\"IpAddress\")\nthen\nlet geo = lookup(\"geoip\", to_string($message.IpAddress));\nset_field(\"IpAddress_geo_location\", geo[\"coordinates\"]);\nset_field(\"IpAddress_geo_country\", geo[\"country\"].iso_code);\nset_field(\"IpAddress_geo_city\", geo[\"city\"].names.en);\nend\n"}'

/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/pipelines/pipeline" -X POST --data '{"title":"GeoIP lookup","description":"","source":"pipeline \"GeoIP lookup\"\nstage 0 match either\nrule \"GeoIP lookup: IpAddress\"\nend","stages":[{"stage":0,"match_all":false,"rules":["GeoIP lookup: IpAddress"]}]}'

/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/pipelines/pipeline"

PIPELINE=`/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/pipelines/pipeline" | /usr/bin/jq '.[] | select(.title=="GeoIP lookup")' | /usr/bin/jq -r '.id'`
STREAM="000000000000000000000001"

/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/pipelines/connections/to_stream" -X POST --data "{\"stream_id\":\"${STREAM}\",\"pipeline_ids\":[\"${PIPELINE}\"]}"

/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/content_packs" -X POST -d @/home/ubuntu/dashboard.json

/usr/bin/curl -s -H 'Content-Type: application/json' -H 'X-Requested-By: cli' "http://${USER}:${PASS}@127.0.0.1:9000/api/system/content_packs/2397d589-a1fd-4ad8-b271-e72f44b4611f/1/installations" -X POST -d '{"parameters": {}, "comment": ""}'


================================================
FILE: ansible/hosts
================================================
[domain]
dc1 ansible_host=192.168.3.100 ansible_user=Administrator ansible_password='{{ domain_admin_password }}'
desktop12 ansible_host=192.168.3.112 ansible_user=Administrator ansible_password='{{ default_password }}'

[domain:vars]
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_port=5985
dns_name=ecorp.local
default_password=
domain_admin_password=
dsrm_password=

[monitor]
graylog ansible_host=192.168.3.191 ansible_connection=ssh ansible_user=ubuntu ansible_ssh_private_key_file=../packer/.ssh/id_ed25519

[monitor:vars]
ubuntu_password=
graylog_admin=admin
graylog_pwd=


================================================
FILE: ansible/id.pub
================================================


================================================
FILE: ansible/nxlog.conf
================================================
define ROOT C:\Program Files (x86)\nxlog
Moduledir %ROOT%\modules

<Extension _gelf>
    Module      xm_gelf
</Extension>

<Input eventlog>
    Module      im_msvistalog
    <QueryXML>
        <QueryList>
            <Query Id='0'>
                <Select Path='Application'>*</Select>
                <Select Path='Security'>*[System/Level&lt;4]</Select>
                <Select Path='System'>*</Select>
                <Select Path="Microsoft-Windows-Sysmon/Operational">*</Select>
                <Select Path="Microsoft-Windows-PowerShell/Operational">*</Select>
            </Query>
        </QueryList>
    </QueryXML>
</Input>

<Output graylog>
    Module      om_udp
    Host        192.168.3.191
    Port        12201
    OutputType  GELF
</Output>

<Route eventlog_to_graylog>
    Path eventlog => graylog
</Route>


================================================
FILE: ansible/rdp_public.sh
================================================
#!/bin/bash
#

help () {
  echo "$0 [on/off]"
}

if [ $# -ne 1 ]; then
  help
  exit 0
fi

if [ "$1" == "on" ]; then
  iptables -I FORWARD -p tcp -d 192.168.3.112 --dport 3389 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
  iptables -t nat -A PREROUTING -p tcp -i br0 --dport 14999 -j DNAT --to-destination 192.168.3.112:3389
  echo "Public RDP access enabled"
  exit 0
elif [ "$1" == "off" ]; then
  iptables -D FORWARD -p tcp -d 192.168.3.112 --dport 3389 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
  iptables -t nat -D PREROUTING -p tcp -i br0 --dport 14999 -j DNAT --to-destination 192.168.3.112:3389
  echo "Public RDP access disabled"
  exit 0
fi

help
exit 0


================================================
FILE: ansible/requirements.txt
================================================
wheel
ansible
pywinrm
faker


================================================
FILE: ansible/setup-domain.yml
================================================
- name: Configure DC1
  hosts: dc1
  gather_facts: false
#  vars_files:
#    - users.yml
  tasks:
    - name: Using the default admin password
      set_fact: ansible_password='{{ default_password }}'

    - name: Waiting for WinRM...
      wait_for_connection:

    - name: Install AD Features
      win_feature:
        name: AD-Domain-Services
        include_management_tools: yes
        include_sub_features: yes
        state: present
      register: ad_features

    - name: Set Hostname
      win_hostname:
        name: '{{ inventory_hostname }}'
      register: dc_hostname

    - name: Reboot Server
      win_reboot:
        msg: "Installing AD. Rebooting..."
        pre_reboot_delay: 15
      when: ad_features.reboot_required or dc_hostname.reboot_required

    - name: Install Domain
      win_domain:
        dns_domain_name: '{{ dns_name }}'
        safe_mode_password: '{{ dsrm_password }}'
      register: ad

    - name: Reboot Server
      win_reboot:
        msg: "Installing AD. Rebooting..."
        pre_reboot_delay: 15
      when: ad.reboot_required

    - name: Waiting for Active Directory Web Services...
      win_wait_for:
        port: 9389

    - name: Weaken Security Policy
      win_shell: Set-ADDefaultDomainPasswordPolicy -Identity {{ dns_name }} -ComplexityEnabled 0 -LockoutThreshold 0
      retries: 10
      delay: 30
      register: result
      until: result.rc == 0

    - name: Change Administrator password in domain
      win_domain_user:
        name: Administrator
        state: present
        password: '{{ domain_admin_password }}'

    - name: Using the new domain Administrator password
      set_fact: ansible_password='{{ domain_admin_password }}'

    - name: Generate ADUser PS script
      command: ./gen_users.py
      delegate_to: 127.0.0.1

    - name: Populate domain users
      script: users.ps1

#    - name: Populate domain users
#      win_domain_user:
#        name: '{{ item.name }}'
#        state: present
#        password: '{{ item.password }}'
#        groups: '{{ item.groups }}'
#      with_items: '{{ users }}'
#      async: 600
#      poll: 0
#      register: create_users
#
#    - name: Check users
#      async_status:
#        jid: "{{ create_users.ansible_job_id }}"
#      register: job_result
#      until: job_result.finished
#      retries: 30

- name: Configure Graylog
  hosts: graylog
  gather_facts: false
  tasks:
    - name: Write new host keys to known hosts
      shell: '/usr/bin/ssh-keygen -R {{ ansible_host }}; /usr/bin/ssh-keyscan -H {{ ansible_host }} | /bin/grep -v "^#" >> ~/.ssh/known_hosts'
      delegate_to: 127.0.0.1

    - name: Configure GELF UDP Collection
      uri:
        url: http://127.0.0.1:9000/api/system/inputs
        method: POST
        user: "{{ graylog_admin }}"
        password: "{{ graylog_pwd }}"
        body: '{"title":"nxlog_udp","type":"org.graylog2.inputs.gelf.udp.GELFUDPInput","configuration":{"bind_address":"0.0.0.0","port":12201,"recv_buffer_size":262144,"override_source":null,"decompress_size_limit":8388608},"global":true}'
        force_basic_auth: yes
        status_code: 201
        body_format: json
        headers:
          X-Requested-By: cli

    - name: Add Graylog Adapter for GeoIP Lookup
      uri:
        url: http://127.0.0.1:9000/api/system/lookup/adapters
        method: POST
        user: "{{ graylog_admin }}"
        password: "{{ graylog_pwd }}"
        body: '{"title":"GeoIP","description":"GeoIP Adapter","name":"geoip","custom_error_ttl_enabled":false,"custom_error_ttl":null,"custom_error_ttl_unit":null,"content_pack":null,"config":{"type":"maxmind_geoip","type":"maxmind_geoip","path":"/etc/graylog/server/GeoLite2-City.mmdb","database_type":"MAXMIND_CITY","check_interval":1,"check_interval_unit":"HOURS"}}'
        force_basic_auth: yes
        status_code: 200
        body_format: json
        headers:
          X-Requested-By: cli

    - name: Add Graylog Cache for GeoIP Lookup
      uri:
        url: http://127.0.0.1:9000/api/system/lookup/caches
        method: POST
        user: "{{ graylog_admin }}"
        password: "{{ graylog_pwd }}"
        body: '{"config":{"type":"guava_cache","type":"guava_cache","max_size":1000,"expire_after_access":1,"expire_after_access_unit":"HOURS","expire_after_write":0,"expire_after_write_unit":null},"title":"GeoIP","description":"GeoIP Cache","name":"geoip","content_pack":null}'
        force_basic_auth: yes
        status_code: 200
        body_format: json
        headers:
          X-Requested-By: cli

    - name: Copy dashboard.json
      copy:
        src: dashboard.json
        dest: '/home/ubuntu/dashboard.json'

    - name: More Configuration for Graylog...
      script: graylog_config.sh '{{ graylog_admin }}' '{{ graylog_pwd }}'

    - name: Disable SSH Password Auth
      shell: "echo {{ ubuntu_password }} | /usr/bin/sudo -S /bin/sh -c '/bin/sed -i \"/PasswordAuthentication/cPasswordAuthentication no\" -i /etc/ssh/sshd_config; /bin/systemctl reload sshd'"

    - name: Add extra SSH key
      lineinfile:
        path: /home/ubuntu/.ssh/authorized_keys
        insertafter: EOF
        line: "{{ lookup('file', 'id.pub') }}"
      
- name: Join Desktops
  hosts: domain
  gather_facts: true
  tasks:
    - name: Sync NTP Time
      win_command: w32tm /resync

    - name: Join Desktops
      win_domain_membership:
        dns_domain_name: '{{ dns_name }}'
        hostname: '{{ inventory_hostname }}'
        domain_admin_user: Administrator@{{dns_name}}
        domain_admin_password: '{{ domain_admin_password }}'
        state: domain
      register: domain_state

    - name: Reboot Server
      win_reboot:
        msg: 'Joined Domain. Rebooting...'
      when: domain_state.reboot_required

- name: Install Softwares on Domain
  hosts: domain
  gather_facts: false
  tasks:
    - name: Install Firefox
      win_chocolatey:
        name: firefox
        state: present

    - name: Install NXLog Collector
      win_chocolatey:
        name: nxlog
        state: present

    - name: Install Sysmon
      win_chocolatey:
        name: sysmon
        ignore_checksums: true
        state: present

- name: Configure Logging
  hosts: domain
  gather_facts: false
  tasks:
    - name: Configure NXLog
      win_copy:
        src: nxlog.conf
        dest: 'c:\Program Files (x86)\nxlog\conf\nxlog.conf'

    - name: Fetch Sysmon config
      win_get_url:
        url: https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml
        dest: 'c:\windows\sysmonconfig-export.xml'

    - name: Launch Sysmon Service
      win_command: 'c:\ProgramData\chocolatey\bin\Sysmon64.exe -accepteula -i c:\windows\sysmonconfig-export.xml'

    - name: Restart NXLog
      win_service:
        name: nxlog
        state: restarted


================================================
FILE: ansible/wordlist.txt
================================================
Summer2020
Spring2020
Spring2019
Winter2019
Autumn2019
Password123


================================================
FILE: init-passwords.sh
================================================
#!/bin/bash
#

echo "[*] Setting initial passwords."

echo -n "[?] Enter default Windows local Administrator password: "
read -s adminpass
echo

echo -n "[?] Enter Windows Domain Admin password for user ECORP\\Administrator: "
read -s domainadminpass
echo

echo -n "[?] Enter DSRM password for Windows Domain: "
read -s dsrmpass
echo

echo -n "[?] Enter password for sudo user 'ubuntu' on Ubuntu (Graylog) system: "
read -s ubuntupass
echo

echo -n "[?] Enter Graylog password for root user 'admin': "
read -s graylogpass
echo

echo -n "[?] Enter password for sudo user 'kali' on Kali system: "
read -s kalipass
echo

echo "[*] Setting Windows local Administrator password, Ubuntu user password and Kali password in packer/private.json"
adminpass_esc=$(printf '%s\n' "${adminpass}" | sed -e 's/[\/&]/\\&/g')
ubuntupass_esc=$(printf '%s\n' "${ubuntupass}" | sed -e 's/[\/&]/\\&/g')
kalipass_esc=$(printf '%s\n' "${kalipass}" | sed -e 's/[\/&]/\\&/g')
sed -i packer/private.json -e "s/\"administrator_password\": \".*\"/\"administrator_password\": \"${adminpass_esc}\"/" \
                           -e "s/\"ubuntu_password\": \".*\"/\"ubuntu_password\": \"${ubuntupass_esc}\"/" \
                           -e "s/\"kali_password\": \".*\"/\"kali_password\": \"${kalipass_esc}\"/"

p1=`echo -n "${adminpass}Password" | iconv -tutf-16le | base64 -w0`
p2=`echo -n "${adminpass}AdministratorPassword" | iconv -tutf-16le | base64 -w0`
for w in win2016 win10 win2012r2; do
  a="packer/answer_files/${w}/Autounattend.xml"
  echo "[*] Setting Windows local Administrator password in ${a} for UserAccounts and AutoLogon"
  sed -i "$a" -e "/<Password>/,/<\/Password>/ s/<Value>.*<\/Value>/<Value>${p1}<\/Value>/" \
              -e "/<AdministratorPassword>/,/<\/AdministratorPassword>/ s/<Value>.*<\/Value>/<Value>${p2}<\/Value>/"
done

echo "[*] Creating SSH key for Ubuntu (Graylog) and Kali access..."
rm -fr packer/.ssh
mkdir packer/.ssh
ssh-keygen -t ed25519 -f packer/.ssh/id_ed25519 -N "" -C supervisor@infra
SSH_PUBKEY=`cat packer/.ssh/id_ed25519.pub | tr -d '\n'`

echo "[*] Setting Ubuntu password and SSH key in packer/answer_files/graylog/preseed.cfg"
ubuntupasscrypt=`mkpasswd -m sha-512 -S $(pwgen -ns 16 1) ${ubuntupass}`
sed -i packer/answer_files/graylog/preseed.cfg -e "s#d-i passwd/user-password-crypted password .*#d-i passwd/user-password-crypted password ${ubuntupasscrypt}#" \
                                               -e "s#echo ssh-ed25519 AAA.* supervisor@infra#echo ${SSH_PUBKEY}#"

echo "[*] Setting Graylog password in packer/scripts/graylog.sh"
graylogsha2=`echo -n "${graylogpass}" | sha256sum | cut -d' ' -f1`
sed -i packer/scripts/graylog.sh -e "s/GRAYLOG_SHA2=\".*\"/GRAYLOG_SHA2=\"${graylogsha2}\"/"

echo "[*] Setting Kali password and SSH key in packer/answer_files/kali/preseed.cfg"
kalipasscrypt=`mkpasswd -m sha-512 -S $(pwgen -ns 16 1) ${kalipass}`
sed -i packer/answer_files/kali/preseed.cfg -e "s#d-i passwd/user-password-crypted password .*#d-i passwd/user-password-crypted password ${kalipasscrypt}#" \
                                            -e "s#echo ssh-ed25519 AAA.* supervisor@infra#echo ${SSH_PUBKEY}#"

echo "[*] Updating passwords in ansible/hosts"
domainadminpass_esc=$(printf '%s\n' "${domainadminpass}" | sed -e 's/[\/&]/\\&/g')
dsrmpass_esc=$(printf '%s\n' "${dsrmpass}" | sed -e 's/[\/&]/\\&/g')
graylogpass_esc=$(printf '%s\n' "${graylogpass}" | sed -e 's/[\/&]/\\&/g')
sed -i ansible/hosts -e "s/^default_password=.*/default_password=\"${adminpass_esc}\"/" \
                     -e "s/^domain_admin_password=.*/domain_admin_password=\"${domainadminpass_esc}\"/" \
                     -e "s/^dsrm_password=.*/dsrm_password=\"${dsrmpass_esc}\"/" \
                     -e "s/^ubuntu_password=.*/ubuntu_password=\"${ubuntupass_esc}\"/" \
                     -e "s/^graylog_pwd=.*/graylog_pwd=\"${graylogpass_esc}\"/"

echo "[+] Done. Deploy with packer+terraform+ansible."


================================================
FILE: packer/.ssh/id_ed25519
================================================
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCGBoPvk7BWDdlq9umPbz3LbaDEV8egoPlg++gzywglxwAAAJhCYCqIQmAq
iAAAAAtzc2gtZWQyNTUxOQAAACCGBoPvk7BWDdlq9umPbz3LbaDEV8egoPlg++gzywglxw
AAAEA7owk2wVvt21vApPlle6zQ8IaQpi/LiTh2aab5jFiwh4YGg++TsFYN2Wr26Y9vPctt
oMRXx6Cg+WD76DPLCCXHAAAAEnVidW50dUBwYWNrZXItaG9zdAECAw==
-----END OPENSSH PRIVATE KEY-----


================================================
FILE: packer/.ssh/id_ed25519.pub
================================================
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIYGg++TsFYN2Wr26Y9vPcttoMRXx6Cg+WD76DPLCCXH ubuntu@packer-host


================================================
FILE: packer/answer_files/graylog/preseed.cfg
================================================
#d-i debconf/priority string critical
#d-i auto-install/enable boolean true

# localization
d-i debian-installer/locale string en_US

# keyboard
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/xkb-keymap select us

# use dhcp network configuration
d-i netcfg/choose_interface select auto

# user setup
d-i passwd/user-fullname string ubuntu
d-i passwd/username string ubuntu

# mkpasswd -m sha-512 -S $(pwgen -ns 16 1) mypassword
d-i passwd/user-password-crypted password $6$r7ItP8TFvsgaLKsa$MvlIgvX/wpjITq/74dPLebOfoS9CoEA9NWuFPKfVonmZKiPQGYI6f6wflHPgOEBGGRAHRDd9vDM7Ox9TbPrOh1

# clock & timezone
d-i clock-setup/utc boolean true
d-i time/zone string Europe/Budapest

# auto-partition, all files in one partition
d-i partman-auto/method string regular
d-i partman-auto/choose_recipe select atomic
d-i partman/choose_partition select finish
d-i partman/confirm_nooverwrite boolean true
d-i partman/confirm boolean true

# packages
d-i pkgsel/include string openssh-server
d-i pkgsel/upgrade select full-upgrade
d-i pkgsel/update-policy select none

# reboot at the end
d-i finish-install/reboot_in_progress note

d-i preseed/late_command string \
in-target sh -c "mkdir -m 700 /home/ubuntu/.ssh ; echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIYGg++TsFYN2Wr26Y9vPcttoMRXx6Cg+WD76DPLCCXH ubuntu@packer-host > /home/ubuntu/.ssh/authorized_keys; chmod 600 /home/ubuntu/.ssh/authorized_keys; chown -R ubuntu:ubuntu /home/ubuntu/.ssh"


================================================
FILE: packer/answer_files/graylog/preseed.cfg~
================================================
#d-i debconf/priority string critical
#d-i auto-install/enable boolean true

# localization
d-i debian-installer/locale string en_US

# keyboard
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/xkb-keymap select us

# use dhcp network configuration
d-i netcfg/choose_interface select auto

# user setup
d-i passwd/user-fullname string ubuntu
d-i passwd/username string ubuntu

# mkpasswd -m sha-512 -S $(pwgen -ns 16 1) mypassword
d-i passwd/user-password-crypted password $6$WwICQQbv2lPNRZLh$4oivwzgiU/ydX4NcljluqtJfRKmJO.ktaj/fDCiv.bcqzxeQiEfDwcK8mKMteNHKzYtapG6znOhNTFpDIeuFI.

# clock & timezone
d-i clock-setup/utc boolean true
d-i time/zone string Europe/Budapest

# auto-partition, all files in one partition
d-i partman-auto/method string regular
d-i partman-auto/choose_recipe select atomic
d-i partman/choose_partition select finish
d-i partman/confirm_nooverwrite boolean true
d-i partman/confirm boolean true

# packages
d-i pkgsel/include string openssh-server
d-i pkgsel/upgrade select full-upgrade
d-i pkgsel/update-policy select none

# reboot at the end
d-i finish-install/reboot_in_progress note

d-i preseed/late_command string \
in-target sh -c "mkdir -m 700 /home/ubuntu/.ssh ; echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMR2FQi9N1SCsnrwpAuyiGo4e/rpZ665q28wu3QPvXBh istvan@archive01-host > /home/ubuntu/.ssh/authorized_keys; chmod 600 /home/ubuntu/.ssh/authorized_keys; chown -R ubuntu:ubuntu /home/ubuntu/.ssh"


================================================
FILE: packer/answer_files/win10/Autounattend.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>en-US</UILanguage>
            </SetupUILanguage>
            <InputLocale>0409:00000409</InputLocale>
            <SystemLocale>en-GB</SystemLocale>
            <UILanguage>en-GB</UILanguage>
            <UserLocale>en-GB</UserLocale>
        </component>
        <component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DriverPaths>
                <PathAndCredentials wcm:action="add" wcm:keyValue="1">
                    <Path>a:\</Path>
                </PathAndCredentials>
            </DriverPaths>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Size>350</Size>
                            <Type>Primary</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>2</Order>
                            <Extend>true</Extend>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Active>true</Active>
                            <Extend>false</Extend>
                            <Format>NTFS</Format>
                            <Label>Boot</Label>
                            <Order>1</Order>
                            <PartitionID>1</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Active>false</Active>
                            <Extend>false</Extend>
                            <Format>NTFS</Format>
                            <Label>OS</Label>
                            <Letter>C</Letter>
                            <Order>2</Order>
                            <PartitionID>2</PartitionID>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <DiskID>0</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
                            <Value>Windows 10 Pro</Value>
                        </MetaData>
                    </InstallFrom>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>2</PartitionID>
                    </InstallTo>
                    <InstallToAvailablePartition>false</InstallToAvailablePartition>
                    <WillShowUI>OnError</WillShowUI>
                </OSImage>
            </ImageInstall>
            <UserData>
                <ProductKey>
                    <Key>VK7JG-NPHTM-C97JM-9MPGT-3V66T</Key>
                    <WillShowUI>OnError</WillShowUI>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
            </UserData>
        </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <AutoLogon>
                <Password>
                    <Value>UABhAHMAcwB3AG8AcgBkAA==</Value>
                    <PlainText>false</PlainText>
                </Password>
                <Enabled>true</Enabled>
                <LogonCount>1</LogonCount>
                <Username>administrator</Username>
            </AutoLogon>
            <FirstLogonCommands>
                <SynchronousCommand wcm:action="add">
                    <CommandLine>reg add &quot;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon&quot; /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine>
                    <Description>Disable AutoLogon (LogonCount issue fix)</Description>
                    <Order>1</Order>
                </SynchronousCommand>
                <SynchronousCommand wcm:action="add">
                    <Order>2</Order>
                    <Description>Bootstrap Script</Description>
                    <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ep bypass a:\bootstrap.ps1</CommandLine>
                </SynchronousCommand>
            </FirstLogonCommands>
            <OOBE>
                <HideEULAPage>true</HideEULAPage>
                <HideLocalAccountScreen>true</HideLocalAccountScreen>
                <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
                <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
                <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
                <ProtectYourPC>3</ProtectYourPC>
            </OOBE>
            <UserAccounts>
                <AdministratorPassword>
                    <Value>QQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcgBQAGEAcwBzAHcAbwByAGQA</Value>
                    <PlainText>false</PlainText>
                </AdministratorPassword>
            </UserAccounts>
            <TimeZone>Central Europe Standard Time</TimeZone>
        </component>
        <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <InputLocale>0409:00000409</InputLocale>
            <UserLocale>en-GB</UserLocale>
            <UILanguage>en-GB</UILanguage>
            <SystemLocale>en-GB</SystemLocale>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim://vboxsvr/_shared/win10_rw/install.wim#Windows 10 Pro" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>


================================================
FILE: packer/answer_files/win2012r2/Autounattend.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Size>350</Size>
                            <Type>Primary</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Extend>true</Extend>
                            <Order>2</Order>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Active>true</Active>
                            <Extend>false</Extend>
                            <Format>NTFS</Format>
                            <Label>Boot</Label>
                            <Order>1</Order>
                            <PartitionID>1</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Active>false</Active>
                            <Extend>false</Extend>
                            <Format>NTFS</Format>
                            <Label>OS</Label>
                            <Letter>C</Letter>
                            <Order>2</Order>
                            <PartitionID>2</PartitionID>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <DiskID>0</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
                            <Value>Windows Server 2012 R2 SERVERSTANDARD</Value>
                        </MetaData>
                    </InstallFrom>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>2</PartitionID>
                    </InstallTo>
                    <InstallToAvailablePartition>false</InstallToAvailablePartition>
                    <WillShowUI>OnError</WillShowUI>
                </OSImage>
            </ImageInstall>
            <UserData>
                <ProductKey>
                    <WillShowUI>OnError</WillShowUI>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
            </UserData>
        </component>
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>en-US</UILanguage>
            </SetupUILanguage>
            <InputLocale>en-US</InputLocale>
            <SystemLocale>en-US</SystemLocale>
            <UILanguage>en-US</UILanguage>
            <UserLocale>en-US</UserLocale>
        </component>
        <component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DriverPaths>
                <PathAndCredentials wcm:action="add" wcm:keyValue="1">
                    <Path>a:\</Path>
                </PathAndCredentials>
            </DriverPaths>
        </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <UserAccounts>
                <AdministratorPassword>
                    <Value>QQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcgBQAGEAcwBzAHcAbwByAGQA</Value>
                    <PlainText>false</PlainText>
                </AdministratorPassword>
            </UserAccounts>
            <AutoLogon>
                <Password>
                    <Value>UABhAHMAcwB3AG8AcgBkAA==</Value>
                    <PlainText>false</PlainText>
                </Password>
                <Enabled>true</Enabled>
                <Username>administrator</Username>
                <LogonCount>1</LogonCount>
            </AutoLogon>
            <FirstLogonCommands>
                <SynchronousCommand wcm:action="add">
                    <Order>2</Order>
                    <Description>Bootstrap Script</Description>
                    <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ep bypass a:\bootstrap.ps1</CommandLine>
                </SynchronousCommand>
                <SynchronousCommand wcm:action="add">
                    <CommandLine>reg add &quot;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon&quot; /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine>
                    <Description>Disable AutoLogon (LogonCount issue fix)</Description>
                    <Order>1</Order>
                </SynchronousCommand>
            </FirstLogonCommands>
            <TimeZone>Central Europe Standard Time</TimeZone>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim://vboxsvr/shared/win2012r2_rw/install.wim#Windows Server 2012 R2 SERVERSTANDARD" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>


================================================
FILE: packer/answer_files/win2016/Autounattend.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>en-US</UILanguage>
            </SetupUILanguage>
            <InputLocale>en-US</InputLocale>
            <SystemLocale>en-US</SystemLocale>
            <UILanguage>en-US</UILanguage>
            <UserLocale>en-US</UserLocale>
        </component>
        <component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DriverPaths>
                <PathAndCredentials wcm:action="add" wcm:keyValue="1">
                    <Path>a:\</Path>
                </PathAndCredentials>
            </DriverPaths>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Size>350</Size>
                            <Type>Primary</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>2</Order>
                            <Extend>true</Extend>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Active>true</Active>
                            <Label>Boot</Label>
                            <Order>1</Order>
                            <PartitionID>1</PartitionID>
                            <Format>NTFS</Format>
                            <Extend>false</Extend>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Active>false</Active>
                            <Extend>false</Extend>
                            <Format>NTFS</Format>
                            <Label>OS</Label>
                            <Letter>C</Letter>
                            <Order>2</Order>
                            <PartitionID>2</PartitionID>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <DiskID>0</DiskID>
                    <WillWipeDisk>true</WillWipeDisk>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
                            <Value>Windows Server 2016 SERVERSTANDARD</Value>
                        </MetaData>
                    </InstallFrom>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>2</PartitionID>
                    </InstallTo>
                    <InstallToAvailablePartition>false</InstallToAvailablePartition>
                    <WillShowUI>OnError</WillShowUI>
                </OSImage>
            </ImageInstall>
            <UserData>
                <ProductKey>
                    <WillShowUI>OnError</WillShowUI>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
            </UserData>
        </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <AutoLogon>
                <Password>
                    <Value>UABhAHMAcwB3AG8AcgBkAA==</Value>
                    <PlainText>false</PlainText>
                </Password>
                <Enabled>true</Enabled>
                <LogonCount>1</LogonCount>
                <Username>administrator</Username>
            </AutoLogon>
            <FirstLogonCommands>
                <SynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Description>Disable AutoLogon (LogonCount issue fix)</Description>
                    <CommandLine>reg add &quot;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon&quot; /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine>
                </SynchronousCommand>
                <SynchronousCommand wcm:action="add">
                    <Order>2</Order>
                    <Description>Bootstrap Script</Description>
                    <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ep bypass a:\bootstrap.ps1</CommandLine>
                </SynchronousCommand>
            </FirstLogonCommands>
            <UserAccounts>
                <AdministratorPassword>
                    <Value>QQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcgBQAGEAcwBzAHcAbwByAGQA</Value>
                    <PlainText>false</PlainText>
                </AdministratorPassword>
            </UserAccounts>
            <TimeZone>Central Europe Standard Time</TimeZone>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim://vboxsvr/shared/win2016_rw/install.wim#Windows Server 2016 SERVERSTANDARD" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>


================================================
FILE: packer/get-virtio.sh
================================================
#!/bin/bash
#

echo "[*] Cleaning up & init virtio folder..."
rm -fr virtio
mkdir virtio
if ! cd virtio; then
    echo "[!] Problem creating virtio folder"
    exit 0
fi

echo "[*] Downloading stable virtio-win.iso..."
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

echo "[*] Extracting iso..."
mkdir virtio-win
7z x -ovirtio-win virtio-win.iso

echo "[*] Arranging drivers..."
shopt -s nullglob
for winver in w10 w8.1 2k16; do
  mkdir -p ${winver}/core
  mkdir -p ${winver}/extra
  for driver in NetKVM viostor; do
    for f in virtio-win/${driver}/${winver}/amd64/*.{inf,cat,sys,dll}; do
      mv $f ${winver}/core
    done
  done
  for driver in Balloon viorng vioserial qxldod; do
    for f in virtio-win/${driver}/${winver}/amd64/*.{inf,cat,sys,dll}; do
      mv $f ${winver}/extra
    done
  done
done
shopt -u nullglob

echo "[*] Cleaning up..."
rm -fr virtio-win



================================================
FILE: packer/graylog.json
================================================
{
  "builders": [
    {
      "type": "qemu",
      "name": "qemu-graylog",
      "iso_url": "http://cdimage.ubuntu.com/releases/18.04/release/ubuntu-18.04.6-server-amd64.iso",
      "iso_checksum": "sha256:f5cbb8104348f0097a8e513b10173a07dbc6684595e331cb06f93f385d0aecf6",
      "output_directory": "output_graylog",
      "disk_size": "20480M",
      "format": "qcow2",
      "accelerator": "kvm",
      "cpus": "2",
      "memory": "4096",
      "vm_name": "graylog",
      "net_device": "virtio-net",
      "disk_interface": "virtio",
      "http_directory": "answer_files/graylog",
      "communicator": "ssh",
      "ssh_username": "ubuntu",
      "ssh_private_key_file": ".ssh/id_ed25519",
      "ssh_timeout": "20m",
      "headless": true,
      "boot_wait": "10s",
      "boot_command": [
        "<esc><wait>", "<esc><wait>", "<enter><wait>",
        "/install/vmlinuz<wait>", " initrd=/install/initrd.gz",
        " auto-install/enable=true",
        " debconf/priority=critical",
        " preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg<wait>",
        " -- <wait>",
        "<enter><wait>"
      ],
      "shutdown_command": "echo '{{user `ubuntu_password`}}' | sudo -S shutdown -P now"
    }
  ],
  "provisioners": [
    {
      "type": "file",
      "source": "resources/GeoLite2-City.mmdb",
      "destination": "GeoLite2-City.mmdb"
    },
    {
      "type": "shell",
      "script": "scripts/graylog.sh",
      "execute_command": "echo '{{user `ubuntu_password`}}' | sudo -S bash {{.Path}}"
    }
  ]
}


================================================
FILE: packer/packer-build-all.sh
================================================
#!/bin/bash
#

echo "[*] Running packers..."
packer build -timestamp-ui -var-file private.json win2016.json &
packer build -timestamp-ui -var-file private.json win10.json &
packer build -timestamp-ui -var-file private.json graylog.json &
packer build -timestamp-ui -var-file private.json kali.json &

wait

echo "[+] All of the builds have been completed."


================================================
FILE: packer/private.json
================================================
{
  "administrator_password": "",
  "ubuntu_password": "",
  "kali_password": ""
}


================================================
FILE: packer/scripts/bootstrap.ps1
================================================
# bootstrap script for win2012r2 and win2016 packer image

New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Network\NewNetworkWindowOff" -Force
Write-Output "[*] New Network Window Popup -> OFF"

$ifaceinfo = Get-NetConnectionProfile
Set-NetConnectionProfile -InterfaceIndex $ifaceinfo.InterfaceIndex -NetworkCategory Private 
Write-Output "[*] NetConnectionProfile -> Private"

Set-WSManQuickConfig -Force
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true
Write-Output "[!] INSECURE!!! WARNING!!! AllowUnencrypted WSMan over HTTP"


================================================
FILE: packer/scripts/graylog.sh
================================================
#!/bin/bash
#

echo "=== Setup Graylog ==="

GRAYLOG_TIMEZONE="Europe/Budapest"
GRAYLOG_SHA2="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" # Gr@yl0g_Rul3z
DEBIAN_FRONTEND=noninteractive

echo "[*] Upgrade base"
apt-get install -y software-properties-common
add-apt-repository universe
apt-get update && apt-get upgrade
apt-get install -y apt-transport-https openjdk-8-jre-headless uuid-runtime pwgen gnupg libterm-readline-gnu-perl curl jq

echo "[*] Installing MongoDB"
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list
apt-get update
apt-get install -y mongodb-org

echo "[*] Enabling mongodb"
systemctl daemon-reload
systemctl enable mongod.service
systemctl restart mongod.service
systemctl --type=service --state=active | grep mongod

echo "[*] Installing Elasticsearch"
wget -q https://artifacts.elastic.co/GPG-KEY-elasticsearch -O myKey
apt-key add myKey
rm myKey
echo "deb https://artifacts.elastic.co/packages/oss-6.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-6.x.list
apt-get update && apt-get install -y elasticsearch-oss

echo "[*] Configuring Elasticsearch"
sed -i /etc/elasticsearch/elasticsearch.yml \
  -e '/cluster\.name:/c\cluster.name: graylog' \
  -e '$ a action.auto_create_index: false'

echo "[*] Enabling Elasticsearch"
systemctl daemon-reload
systemctl enable elasticsearch.service
systemctl restart elasticsearch.service
systemctl --type=service --state=active | grep elasticsearch

echo "[*] Installing Graylog"
wget https://packages.graylog2.org/repo/packages/graylog-3.3-repository_latest.deb
dpkg -i graylog-3.3-repository_latest.deb
rm graylog-3.3-repository_latest.deb
apt-get update && apt-get install -y graylog-server graylog-enterprise-plugins graylog-integrations-plugins graylog-enterprise-integrations-plugins

echo "[*] Installing Slack plugin"
wget https://github.com/graylog-labs/graylog-plugin-slack/releases/download/3.1.0/graylog-plugin-slack-3.1.0.deb
dpkg -i graylog-plugin-slack-3.1.0.deb
rm graylog-plugin-slack-3.1.0.deb

echo "[*] Configuring Graylog"
SECRET=`pwgen -N 1 -s 96`
sed -i /etc/graylog/server/server.conf \
  -e "/^password_secret/c\\password_secret = ${SECRET}" \
  -e "/^root_password_sha2/c\\root_password_sha2 = ${GRAYLOG_SHA2}" \
  -e "/root_timezone/c\\root_timezone = ${GRAYLOG_TIMEZONE}"

echo "[*] Enabling Graylog"
systemctl daemon-reload
systemctl enable graylog-server.service
systemctl start graylog-server.service
systemctl --type=service --state=active | grep graylog

echo "[*] Copying GeoLite2-City.mmdb to /etc/graylog/server/"
cp ~ubuntu/GeoLite2-City.mmdb /etc/graylog/server/

echo "=== Setup Graylog Done ==="


================================================
FILE: packer/scripts/setupcomplete.ps1
================================================
Write-Output "[*] Installing extra VirtIO drivers..."

<# this was fixed in new VirtIO release, no need to install custom cert
$driverFile = "c:\windows\temp\extra\balloon.sys"
$certFile = "c:\windows\temp\extra\redhat.cer"
$exportType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert
$cert = (Get-AuthenticodeSignature $driverFile).SignerCertificate;
[System.IO.File]::WriteAllBytes($certFile, $cert.Export($exportType));
Import-Certificate -FilePath $certFile -CertStoreLocation Cert:\LocalMachine\TrustedPublisher
#>

pnputil -i -a c:\windows\temp\extra\balloon.inf
pnputil -i -a c:\windows\temp\extra\qxldod.inf
pnputil -i -a c:\windows\temp\extra\viorng.inf
pnputil -i -a c:\windows\temp\extra\vioser.inf

Write-Output "[*] Disabling Auto-Hibernate..."
powercfg -hibernate OFF

Write-Output "[*] Enabling Windows Time Service"
Set-Service -Name w32time -StartupType Automatic
sc.exe triggerinfo w32time delete

Write-Output "[*] Checking for Windows 10..."
If ([Environment]::OSVersion.Version -ge (new-object 'Version' 10,0)) {
  Write-Output "[+] Validated Windows 10"
  Write-Output "[*] Disabling Windows AutoUpdate"
  New-Item HKLM:\SOFTWARE\Policies\Microsoft\Windows -Name WindowsUpdate
  New-Item HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name AU
  New-ItemProperty HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name NoAutoUpdate -Value 1
  Write-Output "[*] Disabling Windows Defender"
  Set-MpPreference -DisableIntrusionPreventionSystem $true `
                   -DisableIOAVProtection $true `
                   -DisableRealtimeMonitoring $true `
                   -DisableScriptScanning $true `
                   -EnableControlledFolderAccess Disabled `
                   -EnableNetworkProtection AuditMode `
                   -Force -MAPSReporting Disabled `
                   -SubmitSamplesConsent NeverSend
} Else {
  Write-Output "[!] Older Windows detected"
}

Write-Output "[*] Allowing incoming WinRM on Any Profile in Firewall..."
New-NetFirewallRule -DisplayName "Allow WinRM" -Direction Inbound -LocalPort 5985 -Protocol TCP -Action Allow -Profile Any

Write-Output "[*] Enabling RDP..."
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"

Write-Output "[+] Setup complete. Cleaning up files..."
Remove-Item -Recurse -Force -Path c:/windows/temp/extra


================================================
FILE: packer/scripts/shutdown.ps1
================================================
Set-Item WSMan:\localhost\Service\AllowUnencrypted $false
Write-Output "[+] Disabled Unencrypted WSMan over HTTP"

shutdown /s /t 5 /f /d p:4:1 /c "Packer Shutdown"


================================================
FILE: packer/scripts/win2012r2-dotnet-fix.ps1
================================================
Write-Host "[*] Fixing CPU spiking caused by .NET Runtime Optimization Service"
Get-ChildItem $env:SystemRoot/Microsoft.net/NGen.exe -recurse | %{ & $_ executeQueuedItems }


================================================
FILE: packer/win10.json
================================================
{
  "builders": [
    {
      "type": "qemu",
      "name": "qemu-win10",
      "iso_url": "ISO/Win10_21H2_EnglishInternational_x64.iso",
      "iso_checksum": "sha256:06fd4a512c5f3e8d16f77ca909c4f20110329b8cdd5ad101e2afc0d58b06d416",
      "output_directory": "output_win10",
      "disk_size": "40960M",
      "format": "qcow2",
      "accelerator": "kvm",
      "cpus": "2",
      "memory": "4096",
      "vm_name": "win10",
      "net_device": "virtio-net",
      "disk_interface": "virtio",
      "floppy_files": [ "answer_files/win10/Autounattend.xml", "virtio/w10/core/*", "scripts/bootstrap.ps1" ],
      "communicator": "winrm",
      "winrm_username": "administrator",
      "winrm_password": "{{user `administrator_password`}}",
      "winrm_use_ntlm": true,
      "shutdown_command": "powershell -ep bypass c:\\windows\\temp\\shutdown.ps1",
      "headless": true
    }
  ],
  "provisioners": [
    {
      "type": "file",
      "source": "scripts/shutdown.ps1",
      "destination": "c:/windows/temp/shutdown.ps1"
    },
    {
      "type": "file",
      "source": "virtio/w10/extra",
      "destination": "c:/windows/temp/"
    },
    {
      "type": "powershell",
      "script": "scripts/setupcomplete.ps1"
    }
  ]
}


================================================
FILE: packer/win2012r2.json
================================================
{
  "builders": [
    {
      "type": "qemu",
      "name": "qemu-win2012r2",
      "iso_url": "http://download.microsoft.com/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.17050.WINBLUE_REFRESH.140317-1640_X64FRE_SERVER_EVAL_EN-US-IR3_SSS_X64FREE_EN-US_DV9.ISO",
      "iso_checksum": "sha256:6612b5b1f53e845aacdf96e974bb119a3d9b4dcb5b82e65804ab7e534dc7b4d5",
      "output_directory": "output_win2012r2",
      "disk_size": "40960M",
      "format": "qcow2",
      "accelerator": "kvm",
      "cpus": "2",
      "memory": "4096",
      "vm_name": "win2012r2",
      "net_device": "virtio-net",
      "disk_interface": "virtio",
      "floppy_files": [ "answer_files/win2012r2/Autounattend.xml", "virtio/w8.1/core/*", "scripts/bootstrap.ps1" ],
      "communicator": "winrm",
      "winrm_username": "administrator",
      "winrm_password": "{{user `administrator_password`}}",
      "winrm_use_ntlm": true,
      "shutdown_command": "powershell -ep bypass c:\\windows\\temp\\shutdown.ps1",
      "headless": true
    }
  ],
  "provisioners": [
    {
      "type": "file",
      "source": "scripts/shutdown.ps1",
      "destination": "c:/windows/temp/shutdown.ps1"
    },
    {
      "type": "file",
      "source": "virtio/w8.1/extra",
      "destination": "c:/windows/temp/"
    },
    {
      "type": "powershell",
      "script": "scripts/setupcomplete.ps1"
    },
    {
      "type": "powershell",
      "script": "scripts/win2012r2-dotnet-fix.ps1"
    }
  ]
}


================================================
FILE: packer/win2016.json
================================================
{
  "builders": [
    {
      "type": "qemu",
      "name": "qemu-win2016",
      "iso_url": "https://software-download.microsoft.com/download/pr/Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO",
      "iso_checksum": "sha256:1ce702a578a3cb1ac3d14873980838590f06d5b7101c5daaccbac9d73f1fb50f",
      "output_directory": "output_win2016",
      "disk_size": "40960M",
      "format": "qcow2",
      "accelerator": "kvm",
      "cpus": "2",
      "memory": "4096",
      "vm_name": "win2016",
      "net_device": "virtio-net",
      "disk_interface": "virtio",
      "floppy_files": [ "answer_files/win2016/Autounattend.xml", "virtio/2k16/core/*", "scripts/bootstrap.ps1" ],
      "communicator": "winrm",
      "winrm_username": "administrator",
      "winrm_password": "{{user `administrator_password`}}",
      "winrm_use_ntlm": true,
      "shutdown_command": "powershell -ep bypass c:\\windows\\temp\\shutdown.ps1",
      "headless": true
    }
  ],
  "provisioners": [
    {
      "type": "file",
      "source": "scripts/shutdown.ps1",
      "destination": "c:/windows/temp/shutdown.ps1"
    },
    {
      "type": "file",
      "source": "virtio/2k16/extra",
      "destination": "c:/windows/temp/"
    },
    {
      "type": "powershell",
      "script": "scripts/setupcomplete.ps1"
    }
  ]
}


================================================
FILE: terraform/main.tf
================================================
provider "libvirt" {
  uri = "qemu:///system"
}

locals {
  mac_dc1       = "50:73:0F:31:81:E1"
  mac_desktop12 = "50:73:0F:31:81:E2"
  mac_graylog   = "50:73:0F:31:81:F1"
  mac_kali      = "50:73:0F:31:81:F2"
}

resource "libvirt_network" "honeypot" {
  name      = "honeypot"
  mode      = "nat"
  bridge    = "honeybr0"
  addresses = ["192.168.3.0/24"]
  dhcp {
    enabled = true
  }
  dns {
    enabled = true
    forwarders {
      address = "192.168.3.100"
      domain = "local"
    }
  }

  xml {
    xslt = file("network-dhcp-lease.xsl")
  }

  provisioner "local-exec" {
    command = "/usr/bin/sudo /usr/sbin/iptables -I FORWARD -j DROP -i honeybr0 -d 192.168.0.0/16; /usr/bin/sudo /usr/sbin/iptables -I FORWARD -j ACCEPT -i honeybr0 -o honeybr0"
  }
  provisioner "local-exec" {
    command = "/usr/bin/sudo /usr/sbin/iptables -D FORWARD -j DROP -i honeybr0 -d 192.168.0.0/16; /usr/bin/sudo /usr/sbin/iptables -D FORWARD -j ACCEPT -i honeybr0 -o honeybr0"
    when    = destroy
  }
}

resource "libvirt_pool" "honeypot" {
  name = "honeypot-pool"
  type = "dir"
  path = "/mnt/archive01/vm/honeypot-pool"
}

resource "libvirt_volume" "dc1-vol" {
  pool   = libvirt_pool.honeypot.name
  name   = "dc1-vol"
  source = "../packer/output_win2016/win2016"
}

resource "libvirt_volume" "desktop12-vol" {
  pool   = libvirt_pool.honeypot.name
  name   = "desktop12-vol"
  source = "../packer/output_win10/win10"
}

resource "libvirt_volume" "graylog-vol" {
  pool   = libvirt_pool.honeypot.name
  name   = "graylog-vol"
  source = "../packer/output_graylog/graylog"
}

resource "libvirt_volume" "kali-vol" {
  pool   = libvirt_pool.honeypot.name
  name   = "kali-vol"
  source = "../packer/output_kali/kali"
}

resource "libvirt_domain" "dc1-dom" {
  provider = libvirt
  name     = "h-dc1"
  memory   = "4096"
  vcpu     = 4

  disk {
    volume_id = libvirt_volume.dc1-vol.id
  }

  network_interface {
    network_id     = libvirt_network.honeypot.id
    hostname       = "dc1"
    mac            = local.mac_dc1
  }

  xml {
    xslt = file("timer-patch.xsl")
  }
}

resource "libvirt_domain" "desktop12-dom" {
  provider = libvirt
  name     = "h-desktop12"
  memory   = "4096"
  vcpu     = 4

  disk {
    volume_id = libvirt_volume.desktop12-vol.id
  }

  network_interface {
    network_id     = libvirt_network.honeypot.id
    hostname       = "desktop12"
    mac            = local.mac_desktop12
  }

  xml {
    xslt = file("timer-patch.xsl")
  }
}

resource "libvirt_domain" "graylog-dom" {
  provider = libvirt
  name     = "h-graylog"
  memory   = "4096"
  vcpu     = 4

  disk {
    volume_id = libvirt_volume.graylog-vol.id
  }

  network_interface {
    network_id     = libvirt_network.honeypot.id
    hostname       = "graylog"
    mac            = local.mac_graylog
  }

  xml {
    xslt = file("timer-patch.xsl")
  }
}

resource "libvirt_domain" "kali-dom" {
  provider = libvirt
  name     = "h-kali"
  memory   = "4096"
  vcpu     = 4

  disk {
    volume_id = libvirt_volume.kali-vol.id
  }

  network_interface {
    network_id     = libvirt_network.honeypot.id
    hostname       = "kali"
    mac            = local.mac_kali
  }

  xml {
    xslt = file("timer-patch.xsl")
  }
}

terraform {
  required_version = ">= 0.13"
  required_providers {
    libvirt = {
      source  = "dmacvicar/libvirt"
      version = "0.6.14"
    }
  }
}


================================================
FILE: terraform/network-dhcp-lease.xsl
================================================
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="/network/ip/dhcp">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:copy-of select="node()"/>
      <host mac='50:73:0F:31:81:E1' ip='192.168.3.100'/>
      <host mac='50:73:0F:31:81:E2' ip='192.168.3.112'/>
      <host mac='50:73:0F:31:81:F1' ip='192.168.3.191'/>
      <host mac='50:73:0F:31:81:F2' ip='192.168.3.192'/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>


================================================
FILE: terraform/timer-patch.xsl
================================================
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="/domain/clock">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:copy-of select="node()"/>
      <timer name='hpet' present='yes'/>
      <timer name='hypervclock' present='yes'/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
Download .txt
gitextract_tyoks_c1/

├── README.md
├── ansible/
│   ├── dashboard.json
│   ├── gen_users.py
│   ├── graylog_config.sh
│   ├── hosts
│   ├── id.pub
│   ├── nxlog.conf
│   ├── rdp_public.sh
│   ├── requirements.txt
│   ├── setup-domain.yml
│   └── wordlist.txt
├── init-passwords.sh
├── packer/
│   ├── .ssh/
│   │   ├── id_ed25519
│   │   └── id_ed25519.pub
│   ├── answer_files/
│   │   ├── graylog/
│   │   │   ├── preseed.cfg
│   │   │   └── preseed.cfg~
│   │   ├── win10/
│   │   │   └── Autounattend.xml
│   │   ├── win2012r2/
│   │   │   └── Autounattend.xml
│   │   └── win2016/
│   │       └── Autounattend.xml
│   ├── get-virtio.sh
│   ├── graylog.json
│   ├── packer-build-all.sh
│   ├── private.json
│   ├── scripts/
│   │   ├── bootstrap.ps1
│   │   ├── graylog.sh
│   │   ├── setupcomplete.ps1
│   │   ├── shutdown.ps1
│   │   └── win2012r2-dotnet-fix.ps1
│   ├── win10.json
│   ├── win2012r2.json
│   └── win2016.json
└── terraform/
    ├── main.tf
    ├── network-dhcp-lease.xsl
    └── timer-patch.xsl
Download .txt
SYMBOL INDEX (1 symbols across 1 files)

FILE: ansible/gen_users.py
  function grouplist (line 22) | def grouplist():
Condensed preview — 34 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (88K chars).
[
  {
    "path": "README.md",
    "chars": 8823,
    "preview": "# ad-honeypot-autodeploy\n\nDeploy a small, intentionally insecure, vulnerable Windows Domain\nfor RDP Honeypot fully autom"
  },
  {
    "path": "ansible/dashboard.json",
    "chars": 12516,
    "preview": "{\n  \"v\": 1,\n  \"id\": \"2397d589-a1fd-4ad8-b271-e72f44b4611f\",\n  \"rev\": 1,\n  \"name\": \"RDP Attack Dashboard\",\n  \"summary\": \""
  },
  {
    "path": "ansible/gen_users.py",
    "chars": 2316,
    "preview": "#!/usr/bin/env python3\n#\n# generate fake users for ad:\n#  * importable by ansible win_domain_user module users.yml var f"
  },
  {
    "path": "ansible/graylog_config.sh",
    "chars": 3072,
    "preview": "#!/bin/bash\n#\n# create Graylog lookup table (using previously created adapter + caches) by API calls\n#\n\nUSER=\"$1\"\nPASS=\""
  },
  {
    "path": "ansible/hosts",
    "chars": 594,
    "preview": "[domain]\ndc1 ansible_host=192.168.3.100 ansible_user=Administrator ansible_password='{{ domain_admin_password }}'\ndeskto"
  },
  {
    "path": "ansible/id.pub",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ansible/nxlog.conf",
    "chars": 857,
    "preview": "define ROOT C:\\Program Files (x86)\\nxlog\r\nModuledir %ROOT%\\modules\r\n\r\n<Extension _gelf>\r\n    Module      xm_gelf\r\n</Exte"
  },
  {
    "path": "ansible/rdp_public.sh",
    "chars": 679,
    "preview": "#!/bin/bash\n#\n\nhelp () {\n  echo \"$0 [on/off]\"\n}\n\nif [ $# -ne 1 ]; then\n  help\n  exit 0\nfi\n\nif [ \"$1\" == \"on\" ]; then\n  i"
  },
  {
    "path": "ansible/requirements.txt",
    "chars": 28,
    "preview": "wheel\nansible\npywinrm\nfaker\n"
  },
  {
    "path": "ansible/setup-domain.yml",
    "chars": 6807,
    "preview": "- name: Configure DC1\n  hosts: dc1\n  gather_facts: false\n#  vars_files:\n#    - users.yml\n  tasks:\n    - name: Using the "
  },
  {
    "path": "ansible/wordlist.txt",
    "chars": 67,
    "preview": "Summer2020\nSpring2020\nSpring2019\nWinter2019\nAutumn2019\nPassword123\n"
  },
  {
    "path": "init-passwords.sh",
    "chars": 3933,
    "preview": "#!/bin/bash\n#\n\necho \"[*] Setting initial passwords.\"\n\necho -n \"[?] Enter default Windows local Administrator password: \""
  },
  {
    "path": "packer/.ssh/id_ed25519",
    "chars": 411,
    "preview": "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\nQyNTUxOQAAACC"
  },
  {
    "path": "packer/.ssh/id_ed25519.pub",
    "chars": 100,
    "preview": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIYGg++TsFYN2Wr26Y9vPcttoMRXx6Cg+WD76DPLCCXH ubuntu@packer-host\n"
  },
  {
    "path": "packer/answer_files/graylog/preseed.cfg",
    "chars": 1449,
    "preview": "#d-i debconf/priority string critical\n#d-i auto-install/enable boolean true\n\n# localization\nd-i debian-installer/locale "
  },
  {
    "path": "packer/answer_files/graylog/preseed.cfg~",
    "chars": 1452,
    "preview": "#d-i debconf/priority string critical\n#d-i auto-install/enable boolean true\n\n# localization\nd-i debian-installer/locale "
  },
  {
    "path": "packer/answer_files/win10/Autounattend.xml",
    "chars": 7218,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<unattend xmlns=\"urn:schemas-microsoft-com:unattend\">\r\n    <settings pass=\"windo"
  },
  {
    "path": "packer/answer_files/win2012r2/Autounattend.xml",
    "chars": 6261,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<unattend xmlns=\"urn:schemas-microsoft-com:unattend\">\r\n    <settings pass=\"windo"
  },
  {
    "path": "packer/answer_files/win2016/Autounattend.xml",
    "chars": 6253,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<unattend xmlns=\"urn:schemas-microsoft-com:unattend\">\r\n    <settings pass=\"windo"
  },
  {
    "path": "packer/get-virtio.sh",
    "chars": 925,
    "preview": "#!/bin/bash\n#\n\necho \"[*] Cleaning up & init virtio folder...\"\nrm -fr virtio\nmkdir virtio\nif ! cd virtio; then\n    echo \""
  },
  {
    "path": "packer/graylog.json",
    "chars": 1536,
    "preview": "{\n  \"builders\": [\n    {\n      \"type\": \"qemu\",\n      \"name\": \"qemu-graylog\",\n      \"iso_url\": \"http://cdimage.ubuntu.com/"
  },
  {
    "path": "packer/packer-build-all.sh",
    "chars": 357,
    "preview": "#!/bin/bash\n#\n\necho \"[*] Running packers...\"\npacker build -timestamp-ui -var-file private.json win2016.json &\npacker bui"
  },
  {
    "path": "packer/private.json",
    "chars": 83,
    "preview": "{\n  \"administrator_password\": \"\",\n  \"ubuntu_password\": \"\",\n  \"kali_password\": \"\"\n}\n"
  },
  {
    "path": "packer/scripts/bootstrap.ps1",
    "chars": 545,
    "preview": "# bootstrap script for win2012r2 and win2016 packer image\n\nNew-Item -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Networ"
  },
  {
    "path": "packer/scripts/graylog.sh",
    "chars": 2831,
    "preview": "#!/bin/bash\n#\n\necho \"=== Setup Graylog ===\"\n\nGRAYLOG_TIMEZONE=\"Europe/Budapest\"\nGRAYLOG_SHA2=\"e3b0c44298fc1c149afbf4c899"
  },
  {
    "path": "packer/scripts/setupcomplete.ps1",
    "chars": 2457,
    "preview": "Write-Output \"[*] Installing extra VirtIO drivers...\"\n\n<# this was fixed in new VirtIO release, no need to install custo"
  },
  {
    "path": "packer/scripts/shutdown.ps1",
    "chars": 165,
    "preview": "Set-Item WSMan:\\localhost\\Service\\AllowUnencrypted $false\nWrite-Output \"[+] Disabled Unencrypted WSMan over HTTP\"\n\nshutd"
  },
  {
    "path": "packer/scripts/win2012r2-dotnet-fix.ps1",
    "chars": 173,
    "preview": "Write-Host \"[*] Fixing CPU spiking caused by .NET Runtime Optimization Service\"\nGet-ChildItem $env:SystemRoot/Microsoft."
  },
  {
    "path": "packer/win10.json",
    "chars": 1235,
    "preview": "{\n  \"builders\": [\n    {\n      \"type\": \"qemu\",\n      \"name\": \"qemu-win10\",\n      \"iso_url\": \"ISO/Win10_21H2_EnglishIntern"
  },
  {
    "path": "packer/win2012r2.json",
    "chars": 1477,
    "preview": "{\n  \"builders\": [\n    {\n      \"type\": \"qemu\",\n      \"name\": \"qemu-win2012r2\",\n      \"iso_url\": \"http://download.microsof"
  },
  {
    "path": "packer/win2016.json",
    "chars": 1313,
    "preview": "{\n  \"builders\": [\n    {\n      \"type\": \"qemu\",\n      \"name\": \"qemu-win2016\",\n      \"iso_url\": \"https://software-download."
  },
  {
    "path": "terraform/main.tf",
    "chars": 3367,
    "preview": "provider \"libvirt\" {\n  uri = \"qemu:///system\"\n}\n\nlocals {\n  mac_dc1       = \"50:73:0F:31:81:E1\"\n  mac_desktop12 = \"50:73"
  },
  {
    "path": "terraform/network-dhcp-lease.xsl",
    "chars": 720,
    "preview": "<?xml version=\"1.0\" ?>\n<xsl:stylesheet version=\"1.0\"\n                xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n "
  },
  {
    "path": "terraform/timer-patch.xsl",
    "chars": 577,
    "preview": "<?xml version=\"1.0\" ?>\n<xsl:stylesheet version=\"1.0\"\n                xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n "
  }
]

About this extraction

This page contains the full source code of the tothi/ad-honeypot-autodeploy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 34 files (78.7 KB), approximately 22.4k tokens, and a symbol index with 1 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!