Projects STRLCPY GOAD Commits ee32d016
🤬
  • ■ ■ ■ ■
    Dockerfile
    skipped 8 lines
    9 9   
    10 10  RUN apt-get update -y && \
    11 11   DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
    12  - sshpass
     12 + sshpass lftp rsync openssh-client
    13 13   
    14 14  COPY ./ansible/requirements.yml .
    15 15   
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    README.md
    skipped 169 lines
    170 170  ansible-playbook main.yml
    171 171  ```
    172 172   
     173 +## If you want to discuss about Active Directory and the GOAD project
     174 + 
     175 +- Join us on Discord : https://discord.gg/NYy7rsMf3u
     176 + 
    173 177  ## LAB Content - sevenkingdoms.local / north.sevenkingdoms.local / essos.local
    174 178   
    175 179  ![v2_overview.png](./docs/img/v2_overview.png)
    skipped 26 lines
    202 206   
    203 207  - **elk** a kibana is configured on http://192.168.56.50:5601 to follow the lab events
    204 208  - infos : log encyclopedia : https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/
    205  -- the elk is not installed installed by default due to ressources reasons.
     209 +- the elk is not installed by default due to resources reasons.
    206 210  - to install and start the elk play the following commands :
    207  - 1. uncomment the elk vm in vagrant and provision with `vagrant up elk`
     211 + 1. uncomment the elk vm in vagrant and provision with `vagrant up elk` (do not forget to add a coma on the box before)
    208 212  ```
    209 213  # { :name => "elk", :ip => "192.168.56.50", :box => "bento/ubuntu-18.04", :os => "linux",
    210 214  # :forwarded_port => [
    skipped 2 lines
    213 217  # }
    214 218  ```
    215 219   
    216  - 2. you need `sshpass` for the elk installation
     220 + 2. uncomment the elk part in ansible/hosts file
    217 221  ```
    218  -sudo apt install sshpass
    219  -```
     222 +[elk:vars]
     223 +ansible_connection=ssh
     224 +ansible_ssh_user=vagrant
     225 +ansible_ssh_private_key_file=./.vagrant/machines/elk/virtualbox/private_key
     226 +ansible_ssh_port=22
     227 +host_key_checking = false
    220 228   
    221  - 3. Chocolatey is needed to use elk. To install it run:
     229 +[elk]
     230 +192.168.56.50
    222 231  ```
    223  -ansible-galaxy collection install chocolatey.chocolatey
     232 + 
     233 + 3. install with docker
     234 +```bash
     235 +sudo docker run -ti --rm --network host -h goadansible -v $(pwd):/goad -w /goad/ansible goadansible ansible-playbook elk.yml
    224 236  ```
    225 237   
    226  - 4. play the elk.yml playbook to install and run elk:
     238 + 3. or install on hand :
     239 + 
     240 +- you need `sshpass` for the elk installation
     241 +```bash
     242 +sudo apt install sshpass
     243 +```
     244 +- Chocolatey is needed to use elk. To install it run:
     245 +```bash
     246 +ansible-galaxy collection install chocolatey.chocolatey
    227 247  ```
     248 +- play the elk.yml playbook to install and run elk:
     249 +```bash
    228 250  ansible-playbook elk.yml
    229 251  ```
    230 252   
    skipped 191 lines
    422 444  ansible-playbook main.yml
    423 445  ```
    424 446   
    425  -### Ansible-playbook
    426  - 
    427  -#### Groups domain error
     447 +### Groups domain error
    428 448   
    429 449  - something go wrong with the trust, all the links are not fully establish
    430 450  - wait several minutes and relaunch the playbook
    skipped 4 lines
    435 455  failed: [192.168.56.xx] (item={'key': 'DragonsFriends', 'value': ['sevenkingdoms.local\\tyron.lannister', 'essos.local\\daenerys.targaryen']}) => {"ansible_loop_var": "item", "attempts": 3, "changed": false, "item": {"key": "DragonsFriends", "value": ["north.sevenkingdoms.local\\jon.snow", "sevenkingdoms.local\\tyron.lannister", "essos.local\\daenerys.targaryen"]}, "msg": "Unhandled exception while executing module: Either the target name is incorrect or the server has rejected the client credentials."}
    436 456  ```
    437 457   
    438  -#### Error Add-Warning
     458 +### Error Add-Warning
    439 459   
    440 460  - You got an "Add-Warning" error during the user installation.
    441 461  - Upgrade to community.windows galaxy >= 1.11.0
    skipped 6 lines
    448 468  "msg": "Unhandled exception while executing module: The term 'Add-Warning' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again."}+
    449 469  ```
    450 470   
    451  -#### A parameter cannot be found that matches parameter name 'AcceptLicense'
     471 +### A parameter cannot be found that matches parameter name 'AcceptLicense'
    452 472   
    453 473  - If you got this kind of error you got an ansible.windows version >= 1.11.0
    454 474  - This version add the parameter AcceptLicense but it is accepted only for PowerShellGet module >= 1.6.0 and this one is not embededded in the vms.
    skipped 9 lines
    464 484  }
    465 485  ```
    466 486   
    467  -#### old Ansible version
     487 +### old Ansible version
    468 488   
    469 489  ```bash
    470 490  ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
    skipped 8 lines
    479 499   
    480 500  solution : upgrade Ansible
    481 501   
    482  -##### old ansible.windows version
     502 +#### old ansible.windows version
    483 503  ```bash
    484 504  ERROR! couldn't resolve module/action 'win_powershell'. This often indicates a misspelling, missing collection, or incorrect module path.
    485 505  ```
    skipped 79 lines
  • ■ ■ ■ ■ ■
    Vagrantfile
    skipped 47 lines
    48 48   v.vmx["numvcpus"] = "2"
    49 49   end
    50 50   
     51 + # disable rdp forwarded port inherited from StefanScherer box
     52 + config.vm.network :forwarded_port, guest: 3389, host: 3389, id: "rdp", auto_correct: true, disabled: true
     53 + 
    51 54   # no autoupdate if vagrant-vbguest is installed
    52 55   if Vagrant.has_plugin?("vagrant-vbguest") then
    53 56   config.vbguest.auto_update = false
    skipped 16 lines
    70 73   target.vm.box_version = box[:box_version]
    71 74   end
    72 75   
     76 + # issues/49
     77 + target.vm.synced_folder '.', '/vagrant', disabled: true
     78 + 
    73 79   # IP
    74 80   target.vm.network :private_network, ip: box[:ip]
    75 81   
    skipped 7 lines
    83 89   target.vm.communicator = "ssh"
    84 90   end
    85 91   
    86  - # forwarded port
    87 92   if box.has_key?(:forwarded_port)
     93 + # forwarded port explicit
    88 94   box[:forwarded_port] do |forwarded_port|
    89  - target.vm.network :forwarded_port, guest: forwarded_port[:guest], host: forwarded_port[:host], id: forwarded_port[:id]
     95 + target.vm.network :forwarded_port, guest: forwarded_port[:guest], host: forwarded_port[:host], host_ip: "127.0.0.1", id: forwarded_port[:id]
    90 96   end
    91 97   end
    92 98   
    skipped 4 lines
  • ■ ■ ■ ■ ■ ■
    ansible/ad-trusts.yml
    skipped 8 lines
    9 9  - name: Trusts configuration
    10 10   hosts: dc01,dc03
    11 11   roles:
     12 + - { role: 'settings/disable_nat_adapter' , tags: 'disable_nat_adapter'}
    12 13   - { role: 'dns_conditional_forwarder', tags: 'dns_conditional_forwarder' }
    13 14   - { role: 'trusts', tags: 'trust' }
     15 + - { role: 'settings/enable_nat_adapter', tags: 'enable_nat_adapter'}
    14 16   vars:
    15 17   domain: "{{lab.hosts[dict_key].domain}}"
     18 + domain_username: "{{domain}}\\Administrator"
     19 + domain_password: "{{lab.domains[domain].domain_password}}"
    16 20   remote_forest: "{{lab.domains[domain].trust}}"
    17 21   remote_admin: "Administrator@{{remote_forest}}"
    18 22   remote_admin_password: "{{lab.domains[remote_forest].domain_password}}"
    skipped 3 lines
  • ■ ■ ■ ■ ■ ■
    ansible/hosts
    1 1  [all:vars]
    2 2  ; domain_name : folder inside ad/
    3 3  domain_name=sevenkingdoms.local
     4 +; adapter created by vagrant and vbox
     5 +nat_adapter=Ethernet
     6 +domain_adapter=Ethernet 2
    4 7  ansible_user=vagrant
    5 8  ansible_password=vagrant
    6 9  password=Str0nGPassw0rd123_
    skipped 55 lines
  • ■ ■ ■ ■ ■ ■
    ansible/main.yml
    skipped 27 lines
    28 28  - import_playbook: adcs.yml
    29 29  # set the ACL
    30 30  - import_playbook: ad-acl.yml
     31 + 
     32 +## SERVERS ---------
     33 +### MSSQL + IIS ----------
     34 +# configure servers vulns (done in the midle of ad install to let time before install relations and acl)
     35 +- import_playbook: servers.yml
     36 + 
     37 +## SECURITY -----
    31 38  # --------------------------------------------------------------------
    32 39  # specifics security linked to the scenario are here
    33 40  - import_playbook: security.yml
    skipped 3 lines
  • ■ ■ ■ ■ ■ ■
    ansible/roles/child_domain/tasks/main.yml
    1 1  - name: "Set configure dns to {{dns_domain}}"
    2 2   win_dns_client:
    3  - adapter_names: 'Ethernet 2'
     3 + adapter_names: "{{domain_adapter}}"
    4 4   ipv4_addresses:
    5 5   - "{{dns_domain}}"
    6 6   log_path: C:\dns_log.txt
    skipped 47 lines
    54 54  # ansible_become_pass: "{{password}}"
    55 55  # when: not domain_child_log.stat.exists
    56 56   
    57  -- name: disable interface Ethernet before join domain
    58  - win_shell: netsh interface set interface "Ethernet" disable
     57 +- name: "disable interface {{nat_adapter}} before join domain"
     58 + win_shell: netsh interface set interface "{{nat_adapter}}" disable
    59 59   
    60 60  - name: add child domain to parent domain
    61 61   ansible.windows.win_powershell:
    skipped 51 lines
    113 113   win_reboot:
    114 114   when: child_result.changed
    115 115   
    116  -- name: enable interface Ethernet after domain joined
    117  - win_shell: netsh interface set interface "Ethernet" enable
     116 +- name: "enable interface {{nat_adapter}} after domain joined"
     117 + win_shell: netsh interface set interface "{{nat_adapter}}" enable
    118 118   
    119 119  - name: "Install XactiveDirectory"
    120 120   win_psmodule:
    skipped 3 lines
  • ■ ■ ■ ■ ■ ■
    ansible/roles/domain_controller/tasks/main.yml
     1 +- name: "disable interface {{nat_adapter}} before join domain"
     2 + win_shell: netsh interface set interface "{{nat_adapter}}" disable
     3 + 
    1 4  - name: Ensure that domain exists
    2 5   win_domain:
    3 6   domain_netbios_name : "{{netbios_name}}"
    skipped 21 lines
    25 28   reboot_timeout: 900
    26 29   post_reboot_delay: 100
    27 30   when: check_domain_controller.changed
     31 + 
     32 +- name: "enable interface {{nat_adapter}} after domain joined"
     33 + win_shell: netsh interface set interface "{{nat_adapter}}" enable
    28 34   
    29 35  - name: Check for xDnsServer Powershell module
    30 36   win_psmodule:
    skipped 20 lines
  • ■ ■ ■ ■ ■
    ansible/roles/elk/tasks/main.yml
     1 +- name: "Update cache"
     2 + apt:
     3 + update_cache: true
     4 + cache_valid_time: 86400
     5 + 
    1 6  - name: Add required dependencies.
    2 7   apt:
    3 8   name:
    skipped 88 lines
  • ■ ■ ■ ■ ■ ■
    ansible/roles/logs_windows/defaults/main.yml
    skipped 3 lines
    4 4  sysmon_download_file: Sysmon
    5 5  file_ext: .zip
    6 6  sysmon_config_url: "https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml"
     7 + 
     8 +winlogbeat_service:
     9 + install_path_64: "C:\\Program Files\\Elastic\\winlogbeat"
     10 + install_path_32: "C:\\Program Files (x86)\\Elastic\\winlogbeat"
     11 + version: "7.17.6"
     12 + download: true
  • ■ ■ ■ ■ ■ ■
    ansible/roles/logs_windows/files/uninstall-service-winlogbeat.ps1
     1 +# Delete and stop the service if it already exists.
     2 +if (Get-Service winlogbeat -ErrorAction SilentlyContinue) {
     3 + $service = Get-WmiObject -Class Win32_Service -Filter "name='winlogbeat'"
     4 + $service.StopService()
     5 + Start-Sleep -s 1
     6 + $service.delete()
     7 +}
     8 + 
  • ■ ■ ■ ■ ■ ■
    ansible/roles/logs_windows/handlers/main.yml
     1 +---
     2 +- name: restart-winlogbeat
     3 + win_shell: Restart-Service winlogbeat
  • ■ ■ ■ ■ ■ ■
    ansible/roles/logs_windows/tasks/main.yml
    1  -- name: Ensure chocolatey is installed
    2  - win_chocolatey:
    3  - name:
    4  - - chocolatey
    5  - - chocolatey-core.extension
    6  - state: present
    7  - 
    8 1  - name: Install winlogbeat
    9  - win_chocolatey:
    10  - name: winlogbeat
    11  - state: present
     2 + import_tasks: winlogbeat.yml
    12 3   
    13 4  - name: Set winlogbeat config file
    14 5   win_copy:
    skipped 44 lines
    59 50   failed_when: resultwlb is not defined
    60 51   ignore_errors: yes
    61 52   
     53 +- name: Reboot before launch setup
     54 + win_reboot:
     55 + reboot_timeout: 600
     56 + post_reboot_delay: 100
     57 + when: resultwlb.state is defined and resultwlb.state != 'running'
     58 + 
    62 59  - name: Run winlogbeat setup
    63 60   win_command: "winlogbeat setup -e"
    64 61   args:
    65  - chdir: C:\ProgramData\chocolatey\lib\winlogbeat\tools\
    66  - when: resultwlb.state is not defined or resultwlb.name is not defined
     62 + chdir: "{{ winlogbeat_service.install_path_64 }}\\winlogbeat-{{ winlogbeat_service.version }}-windows-x86_64\\"
     63 + when: resultwlb.state is defined and resultwlb.state != 'running'
    67 64   
    68 65  # RUN winlogbeat
    69 66  - name: check winlogbeat service
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    ansible/roles/logs_windows/tasks/winlogbeat.yml
     1 +---
     2 +# from https://github.com/j91321/ansible-role-winlogbeat
     3 +- name: Create 64-bit install directory
     4 + win_file:
     5 + path: "{{ winlogbeat_service.install_path_64 }}"
     6 + state: directory
     7 + 
     8 +- name: Check if winlogbeat service is installed
     9 + win_service:
     10 + name: winlogbeat
     11 + register: winlogbeat_installed
     12 + 
     13 +- name: Check if winlogbeat is using current version
     14 + win_stat:
     15 + path: "{{ winlogbeat_service.install_path_64 }}\\winlogbeat-{{ winlogbeat_service.version }}-windows-x86_64"
     16 + register: winlogbeat_folder
     17 + 
     18 +- name: Copy winlogbeat uninstall script
     19 + win_copy:
     20 + src: files/uninstall-service-winlogbeat.ps1
     21 + dest: "{{ winlogbeat_service.install_path_64 }}\\uninstall-service-winlogbeat.ps1"
     22 + force: yes
     23 + when: winlogbeat_installed.exists and not winlogbeat_folder.stat.exists
     24 + 
     25 +- name: Uninstall winlogbeat
     26 + win_shell: .\uninstall-service-winlogbeat.ps1
     27 + args:
     28 + chdir: "{{ winlogbeat_service.install_path_64 }}"
     29 + when: winlogbeat_installed.exists and not winlogbeat_folder.stat.exists
     30 + 
     31 +- name: Download winlogbeat
     32 + win_get_url:
     33 + url: "https://artifacts.elastic.co/downloads/beats/winlogbeat/winlogbeat-{{ winlogbeat_service.version }}-windows-x86_64.zip"
     34 + dest: "{{ winlogbeat_service.install_path_64 }}\\winlogbeat.zip"
     35 + when: winlogbeat_service.download and not winlogbeat_folder.stat.exists
     36 + 
     37 +- name: Copy winlogbeat
     38 + win_copy:
     39 + src: "files/winlogbeat-{{ winlogbeat_service.version }}-windows-x86_64.zip"
     40 + dest: "{{ winlogbeat_service.install_path_64 }}\\winlogbeat.zip"
     41 + when: not winlogbeat_service.download and not winlogbeat_folder.stat.exists
     42 + 
     43 +- name: Unzip winlogbeat
     44 + win_unzip:
     45 + src: "{{ winlogbeat_service.install_path_64 }}\\winlogbeat.zip"
     46 + dest: "{{ winlogbeat_service.install_path_64 }}\\"
     47 + delete_archive: yes
     48 + when: not winlogbeat_folder.stat.exists
     49 + 
     50 +- name: Configure winlogbeat
     51 + win_copy:
     52 + src: winlogbeat.yml
     53 + dest: "{{ winlogbeat_service.install_path_64 }}\\winlogbeat-{{ winlogbeat_service.version }}-windows-x86_64\\winlogbeat.yml"
     54 + notify: restart-winlogbeat
     55 + 
     56 +- name: Install winlogbeat
     57 + win_shell: .\install-service-winlogbeat.ps1
     58 + args:
     59 + chdir: "{{ winlogbeat_service.install_path_64 }}\\winlogbeat-{{ winlogbeat_service.version }}-windows-x86_64\\"
     60 + when: not winlogbeat_folder.stat.exists
     61 + notify: restart-winlogbeat
     62 + 
     63 +- name: Remove other winlogbeat installations
     64 + win_shell: |
     65 + $version="{{ winlogbeat_service.version }}"
     66 + Get-ChildItem -Path "{{ winlogbeat_service.install_path_64 }}" | Where-Object {$_.Name -CNotMatch $version} | Remove-Item -Recurse
     67 + when: not winlogbeat_folder.stat.exists
     68 + 
  • ■ ■ ■ ■ ■ ■
    ansible/roles/mssql/tasks/main.yml
    1  -- name: Reboot before install
     1 +- name: Reboot before install (long timeout in case of update)
    2 2   win_reboot:
    3  - reboot_timeout: 600
     3 + reboot_timeout: 1200
    4 4   
    5 5  - name: create a directory for installer download
    6 6   win_file:
    skipped 193 lines
  • ■ ■ ■ ■ ■ ■
    ansible/roles/settings/disable_nat_adapter/tasks/main.yml
     1 +- name: "disable interface {{nat_adapter}}"
     2 + win_shell: netsh interface set interface "{{nat_adapter}}" disable
     3 + 
  • ■ ■ ■ ■ ■ ■
    ansible/roles/settings/enable_nat_adapter/tasks/main.yml
     1 +- name: "enable interface {{nat_adapter}}"
     2 + win_shell: netsh interface set interface "{{nat_adapter}}" enable
     3 + 
  • ■ ■ ■ ■ ■ ■
    ansible/roles/trusts/tasks/main.yml
     1 +- name: "Prepare to trust flush and renew dns"
     2 + win_shell: |
     3 + ipconfig /flushdns
     4 + ipconfig /renew
     5 + 
    1 6  # source : https://social.technet.microsoft.com/wiki/contents/articles/11911.active-directory-powershell-how-to-create-forest-trust.aspx
    2 7  - name: Add trusts between domain
    3 8   ansible.windows.win_powershell:
    skipped 24 lines
    28 33   RemoteForest: "{{remote_forest}}"
    29 34   RemoteAdmin: "{{remote_admin}}"
    30 35   RemoteAdminPassword: "{{remote_admin_password}}"
     36 + vars:
     37 + ansible_become: yes
     38 + ansible_become_method: runas
     39 + ansible_become_user: "{{domain_username}}"
     40 + ansible_become_password: "{{domain_password}}"
    31 41   register:
    32 42   trust_result
    33 43   
    skipped 1 lines
    35 45   win_reboot:
    36 46   test_command: "Get-ADUser -Identity Administrator -Properties *"
    37 47   when: trust_result.changed
     48 + 
     49 + 
     50 +# $localforest=[System.DirectoryServices.ActiveDirectory.Forest]::getCurrentForest()
     51 +# try {
     52 +# $trustPassword = "TrustP@$$w0rd12"
     53 +# $localForest.CreateLocalSideOfTrustRelationship($RemoteForest,"Bidirectional",$trustPassword)
     54 +# $Ansible.Changed = $true
     55 +# } catch [System.DirectoryServices.ActiveDirectory.ActiveDirectoryObjectExistsException] {
     56 +# $Ansible.Changed = $false
     57 + 
     58 +- name: Show trust result
     59 + win_shell: |
     60 + $obj = Get-CimInstance -Class Microsoft_DomainTrustStatus -Namespace root\microsoftactivedirectory
     61 + Write-Output -InputObject $obj
     62 + vars:
     63 + ansible_become: yes
     64 + ansible_become_method: runas
     65 + domain_name: "{{domain}}"
     66 + ansible_become_user: "{{domain_username}}"
     67 + ansible_become_password: "{{domain_password}}"
  • ■ ■ ■ ■ ■ ■
    ansible/roles/vulns/ntlmdowngrade/tasks/main.yml
     1 +# values : https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-security-lan-manager-authentication-level
     2 +# NTLMv1 downgrade attacks are possible with LmCompatibilityLevel 2 and below
     3 +- name: Enable LmCompatibilityLevel
     4 + win_regedit:
     5 + path: HKLM:\System\CurrentControlSet\Control\Lsa
     6 + name: LmCompatibilityLevel
     7 + data: 0x2
     8 + type: dword
     9 + 
  • ■ ■ ■ ■ ■
    ansible/vulnerabilities.yml
    skipped 45 lines
    46 46  - name: "Setup vulnerabilities dc03"
    47 47   hosts: dc03
    48 48   roles:
     49 + - { role: "vulns/ntlmdowngrade", tags: 'openshares'}
    49 50   vars:
    50 51   script_path: "../ad/{{domain_name}}/scripts"
    51 52   
    skipped 6 lines
Please wait...
Page is in error, reload to recover