--- - name: Scan hosts: tower #- localhost become: true gather_facts: false vars: # vaultwarden_url: "https://vault.jingoh.fr" bw_requested_password_id: 34fe88a0-e9f0-42d1-9433-f75787327f4e bw_client_secret: "{{ lookup('env', 'bw_client_secret') }}" bw_client_password: "{{ lookup('env', 'bw_client_password') }}" bw_client_id: "{{ lookup('env', 'bw_client_id') }}" # password_monitoring_alert: "{{ lookup('env', 'password') }}" # user_monitoring_alert: "{{ lookup('env', 'username') }}" gitea_token: "{{ lookup('env', 'gitea_token') }}" user_mail: "{{ lookup('env', 'mail') }}" user: "{{ lookup('env', 'username') }}" target_network: "{{ lookup('env', 'target_network') }}" target_port: "{{ lookup('env', 'target_port') }}" # user: sgratias # user_mail: stephane.gratiasquiquandon@gmail.com # token: !vault | # $ANSIBLE_VAULT;1.2;AES256;prod # 30383538646164373137616166636632353964373362323735626239656337306139616265323138 # 3834383331316466653565323632616163353964643637660a363262383461363234363738613034 # 64383132373061653337313365333734646635396635313133613861303730303163383764653664 # 6537633761353939330a356236623265383931643530316430303938303735306536343163323163 # 62636236346362663036343765363830383738623563613161373637383239623134376163653662 # 3565333032326133326232326633386332633639373862313463 #TODO target in list # 163.172.0.0/24 # 163.172.80.0/28 # target_network: 147.135.120.20/30 # target_port: 20-80 # 163.172.0.0/20 # 163.172.16.0/20 # 163.172.31.0/20 # 163.172.48.0/20 # 163.172.63.254/20 # ansible_user: stephane # ansible_password: stephane # ansible_become_password: stephane # username: jingohalert # password: !vault | # $ANSIBLE_VAULT;1.2;AES256;prod # 66346630333538386564396632636161316239326530653037666465616165393135666532643264 # 3037363865363531636635306535663736353734333733340a363639636638396662616538343335 # 65366439343135636634393832636436353764303066653530346232323164376265313039373630 # 3863613961373430340a303866363962353262623030373061616134303366336237346631383539 # 3130 # # apt-get install sshpass # # # # @author Stéphane Gratias (2021). # # roles: # - { role: geerlingguy.pip, tags: pip } tasks: #! SECRETS - name: Install Bitwarden CLI ansible.builtin.command: cmd: "{{ item }}" delegate_to: localhost loop: - apk add --no-cache nodejs npm - npm install -g @bitwarden/cli - ansible.builtin.command: cmd: bw logout delegate_to: localhost ignore_errors: true become: false - name: bitwarden token session ansible.builtin.shell: "{{ item }}" environment: BW_CLIENTID: "{{ bw_client_id }}" BW_CLIENTSECRET: "{{ bw_client_secret }}" BW_PASSWORD: "{{ bw_client_password }}" loop: - bw config server {{ vaultwarden_url }} - bw login --apikey - bw unlock --passwordenv BW_PASSWORD --raw delegate_to: localhost register: bw_session_result become: false - name: Get secret from Bitwarden command: argv: - bw - get - password - "{{ bw_requested_password_id }}" - --session - "{{ bw_session_result.results[-1].stdout | trim }}" delegate_to: localhost register: gitea_token_result no_log: true changed_when: false become: false # - name: Return all secrets from a path # ansible.builtin.debug: # msg: "{{ gitea_token_result.stdout }}" # delegate_to: localhost - ansible.builtin.set_fact: gitea_token : "{{ gitea_token_result.stdout | trim }}" no_log: true delegate_to: localhost become: false #! SECRETS # - ansible.builtin.apt: # name: masscan # update_cache: true - ansible.builtin.git: repo: https://{{ user }}:{{ gitea_token }}@gitea.jingoh.fr/{{ user }}/scan.git dest: "{{ playbook_dir }}/scan" single_branch: yes force: true delegate_to: localhost become: false #TODO auto select interface + router mac - ansible.builtin.command: cmd: "masscan {{ target_network }} -p{{ target_port }} --router-mac 00-81-c4-f6-e9-17 --interface enp0s20" #cmd: "/opt/homebrew/bin/masscan {{ target_network }} -p{{ target_port }}" become: true register: scan_output # when: target_port is not list # pause - debug: msg: "{{ item.split('/')[0].split(' ')[-1]|int }}" loop: "{{ scan_output.stdout_lines }}" - community.crypto.get_certificate: host: "{{ item.split('on')[-1].strip() }}" #port: 443 port: "{{ item.split('/')[0].split(' ')[-1]|int }}" asn1_base64: true delegate_to: localhost become: false run_once: true loop: "{{ scan_output.stdout_lines }}" ignore_errors: true register: cert tags: test - ansible.builtin.command: "nc -v -w 1 {{ item.split('on')[-1].strip() }} {{ item.split('/')[0].split(' ')[-1]|int }}" register: nc_port ignore_errors: true loop: "{{ scan_output.stdout_lines }}" - debug: # msg: "{{ item.subject.CN }}" msg: "{{ item }}" loop: "{{ nc_port.results }}" # # - "{{ cert.not_after }}" # # - "{{ ansible_date_time.iso8601_basic }}" # tags: test # delegate_to: localhost - ansible.builtin.set_fact: nc_port_list: "{{ nc_port_list|default([]) + [item.stderr_lines + item.stdout_lines]}}" loop: "{{ nc_port.results }}" #! remove run once when network range > 24 #! take time, can be better - ansible.builtin.file: path: "{{ playbook_dir }}/scan/https/{{ item.invocation.module_args.host.split('.')[0] }}/{{ item.invocation.module_args.host.split('.')[1] }}/" state: directory loop: "{{ cert.results }}" # run_once: true when: item.invocation is defined #! take time, can be better - ansible.builtin.lineinfile: path: "{{ playbook_dir }}/scan/https/{{ item.invocation.module_args.host.split('.')[0] }}/{{ item.invocation.module_args.host.split('.')[1] }}/{{ item.invocation.module_args.host.split('.')[2] }}.csv" line: "IP,PORT,SERVICE,CN,ISSUER COUNTRY,ISSUER ORGA" insertbefore: BOF create: yes loop: "{{ cert.results }}" # loop_control: # index_var: my_idx delegate_to: localhost become: false #run_once: true when: - item.invocation is defined # - cert.results[my_idx].invocation.module_args.host.split('.')[2] != cert.results[my_idx+1].invocation.module_args.host.split('.')[2] - ansible.builtin.lineinfile: path: "{{ playbook_dir }}/scan/https/{{ item.invocation.module_args.host.split('.')[0] }}/{{ item.invocation.module_args.host.split('.')[1] }}/{{ item.invocation.module_args.host.split('.')[2] }}.csv" line: "{{ item.invocation.module_args.host }},{{ item.invocation.module_args.port }},{{ nc_port_list[my_idx] | join (' ') |default('no service ??') }}, {{ item.subject.CN | default('no CN') }},{{ item.issuer.C | default('no issuer Country') }},{{ item.issuer.O| default('no issuer Orga') }}" create: yes state: present loop: "{{ cert.results }}" loop_control: index_var: my_idx delegate_to: localhost become: false when: item.invocation is defined - ansible.builtin.shell: | git config user.email "{{ user_mail }}" git config user.name "{{ user }}" git add . git commit -m "Push scan with access token" git push https://{{ user }}:{{ gitea_token}}@gitea.jingoh.fr/{{ user }}/scan.git args: chdir: "{{ playbook_dir }}/scan/" run_once: true delegate_to: localhost become: false - community.docker.docker_container_exec: container: scan command: gowitness scan single --url "https://{{ item.subject.CN }}" --write-db chdir: /data loop: "{{ cert.results }}" when: - item.subject.CN is defined - "'*' not in item.subject.CN" - community.docker.docker_container_exec: container: scan command: gowitness scan single --url "http://{{ item.invocation.module_args.host }}:{{ item.invocation.module_args.port }}" --write-db chdir: /data loop: "{{ cert.results }}" when: - item.subject.CN is not defined - screenshot_all|default(false) is true # gowitness scan single --url "https://nuage.monassa.fr" --write-db # - debug: # msg: "{{ host_interfaces }}" - name: NTFY when docker compose changed uri: url: "http://alert/scaleway" method: POST # user: "{{ username }}" # password: "{{ password }}" headers: Title: "SCAN {{ target_port }}" ta: "file_folder" body: "{{ target_network }}" status_code: 200 delegate_to: localhost become: false - name: logout bw ansible.builtin.command: cmd: bw logout delegate_to: localhost become: false