Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 94 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,94 @@
** Make sure to pip install ansible, apt has an older copy **

# Instructions
* Start with Parrot HTB Edition
* Install Ansible (python3 -m pip install ansible)
* Clone and enter the repo (git clone)
* ansible-galaxy install -r requirements.yml
* Make sure we have a sudo token (sudo whoami)
* ansible-playbook main.yml

# Off-Video Changes
* Mate-Terminal Colors, I show how to configure it here (https://www.youtube.com/watch?v=2y68gluYTcc). I just did the steps in that video on my old VM to backup the color scheme, then copied it to this repo.
* Evil-Winrm/Certipy/SharpCollection/CME/Impacket, will make a video for these soon
* Updated BurpSuite Activation. Later versions of ansible would hang if a shell script started a process that didn't die. Put a timeout on the java process
# Parrot OS 7.2 HTB Edition - Build Automation Playbook

This repository contains an updated and modernized Ansible playbook (originally designed by Ippsec) to automate the configuration and customization of a **Parrot OS 7.2 HTB Edition** virtual machine or local install.

It configures a complete, high-productivity ethical hacking and development environment with custom terminal styling, browser extensions, global proxy configurations, logging rules, VSCode plugins, and modern security tools.

---

## What's Configured?

### 1. Terminal Customization
- **Shell (`.bashrc`):**
- Forces terminal session encoding to `UTF-8` globally (resolving Python/Ansible encoding errors).
- Custom multi-line prompt that parses active network interfaces, IP addresses, and Hack The Box VPN connection status dynamically.
- Adds helpful shortcuts (like `_` as an alias for `sudo` and `_i` for `sudo -i`).
- Pre-configures search `PATH` to include `~/go/bin` and `~/.local/bin`.
- **MATE Terminal Profile:** Restores Ippsec's custom "Video" profile (large high-contrast fonts, custom palette) for visibility and streaming.
- **Tmux:** Custom status bar styles, vi-mode window navigation, clipboard integration (`xclip`), and join/send pane shortcuts.

### 2. VSCode Configuration
- Native installation of Visual Studio Code (`code`) using Microsoft's official signing keys and repositories.
- Automatic, idempotent installation of security and programming extensions:
- **Snyk Security** (vulnerability scanner)
- **Python** (IntelliSense and debugging)
- **Go** (Golang syntax and utilities)
- **C/C++** (native compilation tools support)
- **PHP Tools** (PHP language support)
- **GitHub Copilot** (AI assistance)
- **Code Spell Checker**
- **YAML** (Ansible playbook syntax highlighting)

### 3. Browser & Proxy Setup (Burp Suite & Firefox)
- **Burp Suite:**
- Automated headless JRE/Java launch to generate the Burp CA certificate dynamically.
- Registers the CA certificate in the system trust store (`update-ca-certificates`) so system CLI tools trust Burp traffic.
- Copies and applies the default custom dark-themed community config, setting SOCKS configurations, layout styles, and optimal hotkeys.
- **Firefox:**
- Configures system-wide Firefox Enterprise policies.
- Automatically installs and locks trusted Burp Suite CA certificates.
- Auto-installs critical pentesting and utility extensions:
- **FoxyProxy Standard** (quick proxy switcher)
- **Hack-Tools** (payload cheat sheet and generator)
- **Cookie-Editor** (cookie inspector/editor)
- **Wappalyzer** (web technology detector)
- **Dark Reader** (forced dark modes)

### 4. Hacking & Development Tools
- **Pipx Packages (Python CLI):**
- `impacket` (latest Git version)
- `netexec` (successor to CME, installed via pipx to avoid package conflicts)
- `certipy-ad` (Active Directory Certificate Services tool)
- `bloodhound-ce` (Python collector for BloodHound Community Edition)
- **Go Installed Binaries:**
- `kerbrute` (Active Directory Kerberos brute-forcing tool)
- **Ruby Gems:**
- `evil-winrm` (interactive WinRM shell) along with essential WinRM and parsing library dependencies.
- **Standalone Binaries:**
- `chisel` (TCP/UDP tunnels over HTTP, Linux & Windows amd64 binaries in `/opt/chisel`)
- `PEASS-ng` (`linpeas.sh` and `winPEASx64.exe` binaries in `/opt/peas`)
- `chainsaw` (rapid event log analysis tool in `/opt/chainsaw`)
- `BloodHound Legacy GUI` (standalone client extractor in `/opt/BloodHound-Legacy`)
- **BloodHound Community Edition (CE):**
- Configures localized docker-compose servers in `/opt/bloodhound/server`.
- Runs BloodHound CE via Docker, binds the interface port to `8088`, and logs the initial generated admin password to `/opt/bloodhound/server/initial-password.txt`.

### 5. System & Logging Configuration
- Configures passwordless `sudo` rights (`NOPASSWD`) for the invoking user.
- Installs and enables `rsyslog` and `ufw` firewall rules (logging TCP SYN packets in the input chain).
- Installs `auditd` and sets up optimized audit rules.
- Installs **Laurel v0.7.3** (JSON logging plugin for auditd) ensuring modern glibc compatibility with Parrot OS 7.2.

---

## Instructions

To build and customize your environment in one command, simply run the bootstrap script:

1. Clone and enter the repository:
```bash
git clone https://github.com/yokesh-kumar-M/parrot-build.git
cd parrot-build
```

2. Make the bootstrap script executable:
```bash
chmod +x setup.sh
```

3. Run the bootstrap runner:
```bash
./setup.sh
```

The script will automatically refresh your sudo credentials, configure your terminal to use UTF-8, install base compilers and package dependencies (including `Ansible`), and run the custom playbook.
41 changes: 32 additions & 9 deletions main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,43 @@
- name: "Customizing Parrot"
hosts: localhost
connection: local
gather_facts: true

pre_tasks:
- name: "Get login user or sudo user"
set_fact:
real_user: "{{ ansible_env.SUDO_USER | default(ansible_env.USER) | default(ansible_user_id) }}"

- name: "Fallback if real_user is root"
shell: "logname || echo $LOGNAME || whoami"
register: logname_output
when: real_user == 'root'
changed_when: false
failed_when: false

- name: "Set real_user from logname if needed"
set_fact:
real_user: "{{ logname_output.stdout | default('root') }}"
when: real_user == 'root' and logname_output.stdout is defined and logname_output.stdout != ""

- name: "Get passwd database information for real_user"
getent:
database: passwd
key: "{{ real_user }}"
register: passwd_info
failed_when: false

- name: "Set home directory fact"
set_fact:
real_user_home: "{{ getent_passwd[real_user][4] if (getent_passwd is defined and real_user in getent_passwd) else ansible_env.HOME }}"

roles:
- role: "roles/install-tools"
- role: "roles/configure-tmux"
- role: "roles/customize-terminal"
- role: "roles/customize-browser"
- role: "roles/configure-logging"
- role: "roles/configure-system"
- role: gantsign.visual-studio-code
users:
- username: "{{ ansible_user_id }}"
visual_studio_code_extensions:
- streetsidesoftware.code-spell-checker
- ms-python.python
- DEVSENSE.phptools-vscode
- GitHub.copilot
- snyk-security.snyk-vulnerability-scanner
- role: "roles/customize-vscode"


1 change: 0 additions & 1 deletion requirements.yml

This file was deleted.

13 changes: 7 additions & 6 deletions roles/configure-logging/tasks/auditd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@
become: true
become_method: sudo

- name: "Downloading https://github.com/threathunters-io/laurel/releases/download/v0.5.2/laurel-v0.5.2-x86_64-glibc.tar.gz"
- name: "Downloading https://github.com/threathunters-io/laurel/releases/download/v0.7.3/laurel-0.7.3-x86_64-glibc.tar.gz"
get_url:
url: https://github.com/threathunters-io/laurel/releases/download/v0.5.2/laurel-v0.5.2-x86_64-glibc.tar.gz
dest: /tmp/laurel-v0.5.2-x86_64-glibc.tar.gz
url: https://github.com/threathunters-io/laurel/releases/download/v0.7.3/laurel-0.7.3-x86_64-glibc.tar.gz
dest: /tmp/laurel-0.7.3-x86_64-glibc.tar.gz
mode: 0640

- name: "Extract /tmp/laurel-v0.5.2-x86_64-glibc.tar.gz"
- name: "Extract /tmp/laurel-0.7.3-x86_64-glibc.tar.gz"
unarchive:
src: /tmp/laurel-v0.5.2-x86_64-glibc.tar.gz
src: /tmp/laurel-0.7.3-x86_64-glibc.tar.gz
dest: /tmp/laurel/
owner: root
group: root
Expand All @@ -78,7 +78,8 @@
become_method: sudo

- name: "Running install -m755 laurel /usr/local/sbin/laurel"
command: "install -m755 laurel /usr/local/sbin/laurel"
shell: |
find . -type f -name laurel -exec install -m755 {} /usr/local/sbin/laurel \;
args:
chdir: /tmp/laurel/
become: true
Expand Down
6 changes: 3 additions & 3 deletions roles/configure-system/tasks/configure-sudoers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
lineinfile:
dest: /etc/sudoers
insertbefore: EOF
regexp: "{{ ansible_user_id }} ALL="
regexp: "{{ real_user }} ALL="
line: "{{ item }}"
validate: visudo -cf %s
when: ansible_user_id != 'root'
when: real_user != 'root'
with_items:
- "{{ ansible_user_id }}\tALL=(ALL) NOPASSWD:ALL"
- "{{ real_user }}\tALL=(ALL) NOPASSWD:ALL"
6 changes: 5 additions & 1 deletion roles/configure-tmux/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
- name: "Copying Tmux Config"
copy:
src: "{{ role_path }}/files/.tmux.conf"
dest: "{{ ansible_env.HOME }}"
dest: "{{ real_user_home }}/.tmux.conf"
owner: "{{ real_user }}"
group: "{{ real_user }}"
mode: '0644'
become: true


45 changes: 40 additions & 5 deletions roles/customize-browser/files/getburpcert.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
#!/bin/bash
burp=$(find / -name burp*.jar 2>/dev/null | tail -1)
/bin/bash -c "timeout 45 /usr/share/burpsuite/jre/bin/java -Djava.awt.headless=true -jar $burp < <(echo y) &"
sleep 30
curl http://localhost:8080/cert -o /tmp/cacert.der
exit
# ==============================================================================
# Retriever script to headlessly launch Burp Suite and download its CA Certificate
# ==============================================================================

# Search for the Burp Suite jar in a localized, standard path (much faster than root find)
burp=$(find /usr/share/burpsuite -name "burpsuite*.jar" -o -name "burp*.jar" 2>/dev/null | head -n 1)

if [ -z "$burp" ]; then
# Fallback search if not in standard directory
burp=$(find /usr/share/ -name "burpsuite*.jar" -o -name "burp*.jar" 2>/dev/null | head -n 1)
fi

# Locate the appropriate Java binary (bundled JRE vs system-wide fallback)
java_bin="/usr/share/burpsuite/jre/bin/java"
if [ ! -f "$java_bin" ]; then
java_bin=$(which java)
fi

if [ -n "$burp" ] && [ -n "$java_bin" ]; then
echo "[*] Found Burp Suite Jar: $burp"
echo "[*] Using Java binary: $java_bin"

# Start Burp headlessly in background. It automatically listens on port 8080
timeout 45 "$java_bin" -Djava.awt.headless=true -jar "$burp" --headless < <(echo y) &

# Loop and check if the port is open and we can download the certificate
echo "[*] Waiting for Burp Suite web server to start up..."
for i in {1..15}; do
if curl -s http://localhost:8080/cert -o /tmp/cacert.der; then
echo "[+] Successfully downloaded Burp Suite CA Certificate!"
exit 0
fi
sleep 2
done

echo "[-] Error: Failed to retrieve Burp Suite CA Certificate (Timeout)."
exit 1
else
echo "[-] Error: Could not locate Burp Suite or Java."
exit 1
fi
69 changes: 63 additions & 6 deletions roles/customize-browser/tasks/burp.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,75 @@
- name: "Check if BurpSuiteCA.der exists"
- name: "Check if BurpSuiteCA.crt exists"
stat:
path: /usr/local/share/ca-certificates/BurpSuiteCA.der
path: /usr/local/share/ca-certificates/BurpSuiteCA.crt
register: burp_cert

- name: "Create Java userPrefs directory for Burp"
ansible.builtin.file:
path: "{{ real_user_home }}/.java/.userPrefs/burp"
state: directory
owner: "{{ real_user }}"
group: "{{ real_user }}"
mode: '0755'
recurse: yes
become: true
when: burp_cert.stat.exists == False

- name: "Create Burp Java preferences file to accept EULA"
ansible.builtin.copy:
dest: "{{ real_user_home }}/.java/.userPrefs/burp/prefs.xml"
content: |
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE map SYSTEM "http://java.sun.com/dtd/preferences.dtd">
<map MAP_XML_VERSION="1.0">
<entry key="eula" value="20"/>
<entry key="eula.community" value="20"/>
<entry key="eula.professional" value="20"/>
<entry key="eulacommunity" value="20"/>
<entry key="eulafree" value="20"/>
<entry key="eulapro" value="20"/>
</map>
owner: "{{ real_user }}"
group: "{{ real_user }}"
mode: '0644'
become: true
when: burp_cert.stat.exists == False

- name: "Copying Burp Script"
copy:
src: files/getburpcert.sh
dest: /tmp/getburpcert.sh
mode: 0744
mode: 0755
when: burp_cert.stat.exists == False

- name: "Executing bash script to Download CA Certificate"
shell:
/tmp/getburpcert.sh
become: true
become_user: "{{ real_user }}"
when: burp_cert.stat.exists == False

- name: "Convert DER Certificate to PEM format"
ansible.builtin.command:
cmd: openssl x509 -inform der -in /tmp/cacert.der -out /tmp/BurpSuiteCA.crt
when: burp_cert.stat.exists == False

- name: "Copying CA Certificate to /usr/local/share/ca-certificates"
copy:
src: /tmp/cacert.der
dest: /usr/local/share/ca-certificates/BurpSuiteCA.der
src: /tmp/BurpSuiteCA.crt
dest: /usr/local/share/ca-certificates/BurpSuiteCA.crt
owner: root
group: root
mode: 0644
become: true
become_method: sudo
when: burp_cert.stat.exists == False

- name: "Update CA Certificates"
ansible.builtin.command: update-ca-certificates
become: true
become_method: sudo
when: burp_cert.stat.exists == False

- name: Create directory for Burp Suite extras
ansible.builtin.file:
path: "{{ burpsuite_extras_dir }}"
Expand All @@ -44,8 +88,21 @@
become_method: sudo
loop: "{{ lookup('dict', burpsuite_extras_jars) }}"

- name: Create .BurpSuite directory
ansible.builtin.file:
path: "{{ real_user_home }}/.BurpSuite"
state: directory
owner: "{{ real_user }}"
group: "{{ real_user }}"
mode: '0755'
become: true

- name: Copy BurpSuite Community Config
template:
src: "templates/UserConfigCommunity.json.j2"
dest: "/home/{{ ansible_user_id }}/.BurpSuite/UserConfigCommunity.json"
dest: "{{ real_user_home }}/.BurpSuite/UserConfigCommunity.json"
owner: "{{ real_user }}"
group: "{{ real_user }}"
mode: '0644'
become: true

Loading