From 021555b724f32b9885e6b49b2ea7c6ce31901bff Mon Sep 17 00:00:00 2001 From: m0rv4i <20513519+m0rv4i@users.noreply.github.com> Date: Wed, 29 Jul 2020 14:17:27 +0100 Subject: [PATCH] Update scripts & README Pull out common stuff in scripts Install-for-Docker.sh script to not have to clone PoshC2 Change default comms values in template for ease of use Automatically determine latest tag version Add project switch warning that needs restart Update install scripts and posh-update to take args allowing git branch to be specified and PoshC2 install dir Install script determines if has already been cloned to a none-default location Docker scripts allow you to specify a tag to use Update PoshC2.psm1 Windows Docker Script Install script updates exisiting repo if being re-run Add docker stop server script Update README --- Install-for-Docker.sh | 141 +++++++++------- Install.sh | 86 ++++++++-- LICENSE | 2 +- README.md | 190 ++++++++++++---------- poshc2/__init__.py | 7 +- poshc2/server/Config.py | 8 +- resources/config-template.yml | 4 +- resources/modules/SharpSocks.ps1 | 68 ++++---- resources/scripts/PoshC2.psm1 | 120 ++------------ resources/scripts/_posh-common | 37 +++++ resources/scripts/fpc | 19 +-- resources/scripts/posh | 4 +- resources/scripts/posh-config | 13 +- resources/scripts/posh-cookie-decrypter | 4 +- resources/scripts/posh-docker | 35 +++- resources/scripts/posh-docker-build | 7 +- resources/scripts/posh-docker-debug | 28 +++- resources/scripts/posh-docker-server | 39 +++-- resources/scripts/posh-docker-service | 26 --- resources/scripts/posh-docker-stop-server | 13 ++ resources/scripts/posh-log | 13 +- resources/scripts/posh-project | 44 +++-- resources/scripts/posh-server | 17 +- resources/scripts/posh-service | 13 +- resources/scripts/posh-update | 35 +++- resources/scripts/poshc2-docker.service | 10 -- 26 files changed, 539 insertions(+), 444 deletions(-) create mode 100644 resources/scripts/_posh-common delete mode 100755 resources/scripts/posh-docker-service create mode 100644 resources/scripts/posh-docker-stop-server delete mode 100644 resources/scripts/poshc2-docker.service diff --git a/Install-for-Docker.sh b/Install-for-Docker.sh index b403621a..5379e525 100755 --- a/Install-for-Docker.sh +++ b/Install-for-Docker.sh @@ -10,73 +10,98 @@ echo """ |____| \____/____ >___| / \______ /\_______ \\\\ \/ \/ \/ \/ ================= www.PoshC2.co.uk ================""" + echo "" echo "" -echo "[+] Installing PoshC2" -echo "" + if [[ $(id -u) -ne 0 ]]; then - echo -e "You must run this installer as root.\nQuitting!"; + echo -e "[-] You must run this installer as root.\nQuitting!"; exit 1; fi -if [[ ! -z "$1" ]]; then - POSH_DIR="$1" - echo "PoshC2 is not being installed to /opt/PoshC2." - echo "Don't forget to set the POSHC2_DIR environment variable so that the commands use the correct directory." -elif [[ ! -z "${POSHC2_DIR}" ]]; then - POSH_DIR="${POSHC2_DIR}" -else - POSH_DIR="/opt/PoshC2" +command -v curl >/dev/null 2>&1 +if [ "$?" != "0" ]; then + command -v apt >/dev/null 2>&1 + + if [ "$?" == "0" ]; then + echo "[+] Performing apt-get update" + apt-get update + echo "" + echo "[+] Installing curl for downloading scripts" + apt-get install -y curl + else + echo "[-] Curl not found and apt not found in order to install it, please install curl on your system and try again." + exit 1 + fi fi -# Update apt -echo "[+] Performing apt-get update" -apt-get update +# A POSIX variable +OPTIND=1 # Reset in case getopts has been used previously in the shell. -# Check if /opt/ exists, else create folder opt -if [ ! -d /opt/ ]; then - echo "" - echo "[+] Creating folder in /opt/" - mkdir /opt/ -fi +# Initialize our own variables: +GIT_BRANCH="master" -if [[ ! -d "$POSH_DIR" ]]; then - # Git cloning PoshC2 +show_help(){ + echo "*** PoshC2 Install script for Docker ***" + echo "Usage:" + echo "./Install.sh -b " echo "" - echo "[+] Installing git & cloning PoshC2 into $POSH_DIR" - apt-get install -y git - git clone https://github.com/nettitude/PoshC2 "$POSH_DIR" -fi + echo "Default is the master branch" +} +while getopts "h?b:" opt; do + case "$opt" in + h|\?) + show_help + exit 0 + ;; + b) GIT_BRANCH="$OPTARG" + ;; + esac +done + +echo "[+] Installing PoshC2 for Docker" +echo "" echo "" -echo "[+] Symlinking useful scripts to /usr/bin" -ln -s "$POSH_DIR/resources/scripts/fpc" /usr/bin/fpc -ln -s "$POSH_DIR/resources/scripts/posh-docker" /usr/bin/posh -ln -s "$POSH_DIR/resources/scripts/posh-docker-server" /usr/bin/posh-server -ln -s "$POSH_DIR/resources/scripts/posh-config" /usr/bin/posh-config -ln -s "$POSH_DIR/resources/scripts/posh-log" /usr/bin/posh-log -ln -s "$POSH_DIR/resources/scripts/posh-docker-service" /usr/bin/posh-service -ln -s "$POSH_DIR/resources/scripts/posh-stop-service" /usr/bin/posh-stop-service -ln -s "$POSH_DIR/resources/scripts/posh-update" /usr/bin/posh-update -ln -s "$POSH_DIR/resources/scripts/posh-cookie-decrypter" /usr/bin/posh-cookie-decryptor -ln -s "$POSH_DIR/resources/scripts/posh-project" /usr/bin/posh-project -ln -s "$POSH_DIR/resources/scripts/posh-docker-build" /usr/bin/posh-docker-build -ln -s "$POSH_DIR/resources/scripts/posh-docker-clean" /usr/bin/posh-docker-clean -ln -s "$POSH_DIR/resources/scripts/posh-docker-debug" /usr/bin/posh-docker-debug -chmod +x "$POSH_DIR/resources/scripts/fpc" -chmod +x "$POSH_DIR/resources/scripts/posh-docker" -chmod +x "$POSH_DIR/resources/scripts/posh-docker-server" -chmod +x "$POSH_DIR/resources/scripts/posh-config" -chmod +x "$POSH_DIR/resources/scripts/posh-log" -chmod +x "$POSH_DIR/resources/scripts/posh-docker-service" -chmod +x "$POSH_DIR/resources/scripts/posh-stop-service" -chmod +x "$POSH_DIR/resources/scripts/posh-update" -chmod +x "$POSH_DIR/resources/scripts/posh-cookie-decrypter" -chmod +x "$POSH_DIR/resources/scripts/posh-project" -chmod +x "$POSH_DIR/resources/scripts/posh-docker-build" -chmod +x "$POSH_DIR/resources/scripts/posh-docker-clean" -chmod +x "$POSH_DIR/resources/scripts/posh-docker-debug" +echo "[+] Installing scripts to /usr/bin" +rm -f /usr/bin/_posh-common +rm -f /usr/bin/fpc +rm -f /usr/bin/posh +rm -f /usr/bin/posh-server +rm -f /usr/bin/posh-config +rm -f /usr/bin/posh-log +rm -f /usr/bin/posh-service +rm -f /usr/bin/posh-stop-service +rm -f /usr/bin/posh-project +rm -f /usr/bin/posh-docker-clean +rm -f /usr/bin/posh-stop-server +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/_posh-common -o /usr/bin/_posh-common >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/fpc -o /usr/bin/fpc >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-docker -o /usr/bin/posh >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-docker-server -o /usr/bin/posh-server >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-config -o /usr/bin/posh-config >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-log -o /usr/bin/posh-log >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-service -o /usr/bin/posh-service >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-stop-service -o /usr/bin/posh-stop-service >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-project -o /usr/bin/posh-project >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-docker-clean -o /usr/bin/posh-docker-clean >/dev/null +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/posh-docker-stop-server -o /usr/bin/posh-stop-server >/dev/null +chmod +x /usr/bin/fpc +chmod +x /usr/bin/posh +chmod +x /usr/bin/posh-server +chmod +x /usr/bin/posh-config +chmod +x /usr/bin/posh-log +chmod +x /usr/bin/posh-service +chmod +x /usr/bin/posh-stop-service +chmod +x /usr/bin/posh-project +chmod +x /usr/bin/posh-docker-clean +chmod +x /usr/bin/posh-stop-server + +mkdir -p "/var/poshc2" +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/config-template.yml -o "/var/poshc2/config-template.yml" >/dev/null + +curl https://raw.githubusercontent.com/nettitude/PoshC2/$GIT_BRANCH/resources/scripts/poshc2.service -o /lib/systemd/system/poshc2.service >/dev/null echo "" echo "[+] Setup complete" @@ -89,16 +114,18 @@ echo """ \/ \/ \/ \/ ================= www.PoshC2.co.uk ================""" echo "" -echo "Edit the config file - run: " -echo "# posh-config" +echo "Create a new project with: " +echo "# posh-project -n " echo "" -echo "Then build the Docker image:" -echo "# posh-docker-build" +echo "Then edit the config file - run: " +echo "# posh-config" echo "" echo "Then run:" echo "# posh-server <-- This will run the C2 server, which communicates with Implants and receives task output" +echo "# posh-stop-server <-- This will stop the server container" echo "# posh <-- This will run the ImplantHandler, used to issue commands to the server and implants" echo "" echo "Other options:" echo "posh-service <-- This will run the C2 server as a service instead of in the foreground" +echo "posh-stop-service <-- This will stop the service" echo "posh-log <-- This will view the C2 log if the server is already running" \ No newline at end of file diff --git a/Install.sh b/Install.sh index d5c0d560..94bfe01e 100755 --- a/Install.sh +++ b/Install.sh @@ -12,24 +12,56 @@ echo """ ================= www.PoshC2.co.uk ================""" echo "" echo "" -echo "[+] Installing PoshC2" -echo "" if [[ $(id -u) -ne 0 ]]; then - echo -e "You must run this installer as root.\nQuitting!"; + echo -e "[-] You must run this installer as root.\nQuitting!"; exit 1; fi -if [[ ! -z "$1" ]]; then - POSH_DIR="$1" - echo "PoshC2 is not being installed to /opt/PoshC2." - echo "Don't forget to set the POSHC2_DIR environment variable so that the commands use the correct directory." -elif [[ ! -z "${POSHC2_DIR}" ]]; then - POSH_DIR="${POSHC2_DIR}" -else - POSH_DIR="/opt/PoshC2" +command -v apt >/dev/null 2>&1 + +if [ "$?" != "0" ]; then + echo "[-] This install script must be run on a Debian based system with apt installed." + echo "[-] Look at PoshC2's Docker support for running PoshC2 on none-Debian based systems." + exit 1 +fi + +# A POSIX variable +OPTIND=1 # Reset in case getopts has been used previously in the shell. + +# Initialize our own variables: +GIT_BRANCH="master" +POSH_DIR="/opt/PoshC2" +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +if [ -f "$SCRIPT_DIR/poshc2/server/C2Server.py" ]; then + POSH_DIR="$SCRIPT_DIR" fi +show_help(){ + echo "*** PoshC2 Install script ***" + echo "Usage:" + echo "./Install.sh -b -p " + echo "" + echo "Defaults are master branch to /opt/PoshC2" +} + +while getopts ":h:?:b:p:" opt; do + case "$opt" in + h|\?) + show_help + exit 0 + ;; + b) GIT_BRANCH="$OPTARG" + ;; + p) POSH_DIR="$OPTARG" + ;; + esac +done + +echo "[+] Installing PoshC2 in \"$POSH_DIR\" for branch \"$GIT_BRANCH\"" +echo "" + # Update apt echo "[+] Performing apt-get update" apt-get update @@ -46,7 +78,13 @@ if [[ ! -d "$POSH_DIR" ]]; then echo "" echo "[+] Installing git & cloning PoshC2 into $POSH_DIR" apt-get install -y git - git clone https://github.com/nettitude/PoshC2 "$POSH_DIR" + git clone -b "$GIT_BRANCH" https://github.com/nettitude/PoshC2 "$POSH_DIR" +else + echo "[*] PoshC2 directory already exists, updating..." + pushd "$POSH_DIR" + git fetch + git stash + git reset --hard origin/"$GIT_BRANCH" fi # Install requirements for PoshC2 @@ -80,6 +118,18 @@ python3 -m pipenv --three install >/dev/null echo "" echo "[+] Symlinking useful scripts to /usr/bin" +rm -f /usr/bin/_posh-common +rm -f /usr/bin/fpc +rm -f /usr/bin/posh +rm -f /usr/bin/posh-server +rm -f /usr/bin/posh-config +rm -f /usr/bin/posh-log +rm -f /usr/bin/posh-service +rm -f /usr/bin/posh-stop-service +rm -f /usr/bin/posh-update +rm -f /usr/bin/posh-cookie-decryptor +rm -f /usr/bin/posh-project +ln -s "$POSH_DIR/resources/scripts/_posh-common" /usr/bin/_posh-common ln -s "$POSH_DIR/resources/scripts/fpc" /usr/bin/fpc ln -s "$POSH_DIR/resources/scripts/posh" /usr/bin/posh ln -s "$POSH_DIR/resources/scripts/posh-server" /usr/bin/posh-server @@ -101,14 +151,16 @@ chmod +x "$POSH_DIR/resources/scripts/posh-update" chmod +x "$POSH_DIR/resources/scripts/posh-cookie-decrypter" chmod +x "$POSH_DIR/resources/scripts/posh-project" +mkdir -p "/var/poshc2/" +cp "$POSH_DIR/resources/config-template.yml" "/var/poshc2/config-template.yml" + echo "[+] Adding service files" cp "$POSH_DIR/resources/scripts/poshc2.service" /lib/systemd/system/poshc2.service -cp "$POSH_DIR/resources/scripts/poshc2-docker.service" /lib/systemd/system/poshc2-docker.service # Install requirements of dotnet core for SharpSocks echo "" echo "[+] Adding microsoft debian repository & subsequent" -curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - +curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - >/dev/null echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/dotnetdev.list apt-get update apt-get install -y dotnet-runtime-2.2 dotnet-hostfxr-2.2 dotnet-host libssl1.1 @@ -130,7 +182,10 @@ echo """ \/ \/ \/ \/ ================= www.PoshC2.co.uk ================""" echo "" -echo "Edit the config file - run: " +echo "Create a new project with: " +echo "# posh-project -n " +echo "" +echo "Then edit the config file - run: " echo "# posh-config" echo "" echo "Then run:" @@ -139,4 +194,5 @@ echo "# posh <-- This will run the ImplantHandler, used to issue commands to the echo "" echo "Other options:" echo "posh-service <-- This will run the C2 server as a service instead of in the foreground" +echo "posh-stop-service <-- This will stop the service" echo "posh-log <-- This will view the C2 log if the server is already running" diff --git a/LICENSE b/LICENSE index 6663e447..8213e467 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2018, Nettitude +Copyright (c) 2020, Nettitude All rights reserved. diff --git a/README.md b/README.md index c6ef19a8..6c18a2a6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![PoshC2 Logo](https://raw.githubusercontent.com/nettitude/PoshC2/master/resources/images/PoshC2Logo.png) +![Docker Image CI](https://github.com/nettitude/PoshC2/workflows/Docker%20Image%20CI/badge.svg?branch=master) + PoshC2 is a proxy aware C2 framework used to aid penetration testers with red teaming, post-exploitation and lateral movement. PoshC2 is primarily written in Python3 and follows a modular format to enable users to add their own modules and tools, allowing an extendible and flexible C2 framework. Out-of-the-box PoshC2 comes PowerShell/C# and Python3 implants with payloads written in PowerShell v2 and v4, C++ and C# source code, a variety of executables, DLLs and raw shellcode in addition to a Python3 payload. These enable C2 functionality on a wide range of devices and operating systems, including Windows, *nix and OSX. @@ -11,13 +13,14 @@ Other notable features of PoshC2 include: * A large number of payloads generated out-of-the-box which are frequently updated and maintained to bypass common Anti-Virus products. * Auto-generated Apache Rewrite rules for use in a C2 proxy, protecting your C2 infrastructure and maintaining good operational security. * A modular format allowing users to create or edit C#, PowerShell or Python3 modules which can be run in-memory by the Implants. -* Notifications on receiving a successful Implant, such as via text message or Pushover. +* Notifications on receiving a successful Implant via Pushover. * A comprehensive and maintained contextual help and an intelligent prompt with contextual auto-completion, history and suggestions. * Fully encrypted communications, protecting the confidentiality and integrity of the C2 traffic even when communicating over HTTP. * Client/Server format allowing multiple team members to utilise a single C2 server. * Extensive logging. Every action and response is timestamped and stored in a database with all relevant information such as user, host, implant number etc. In addition to this the C2 server output is directly logged to a separate file. * PowerShell-less implants that do not use System.Management.Automation.dll using C# or Python. -* A free and open-source SOCKS Proxy by integrating with SharpSocks +* A free and open-source SOCKS Proxy using [SharpSocks](https://github.com/nettitude/SharpSocks) +* HTTP(S) and SMB named-pipe comms for implants combined with Implant Daisy-chaining for reaching networks that do not have access to the internet ## Documentation @@ -27,157 +30,170 @@ Find us on #Slack - [poshc2.slack.com](poshc2.slack.com) (to request an invite s ## Install -### Kali hosts +You can install PoshC2 directly or use the Docker images, instructions for both are below. -Automatic install for Python3 using curl & bash: +### Direct install on Kali hosts -From an elevated prompt: +Python3 install script: -```bash -curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh | bash +``` +*** PoshC2 Install script *** +Usage: +./Install.sh -b -p + +Defaults are master branch to /opt/PoshC2 ``` -Manual install: +Elevated privileges are required as the install script performs `apt` updates and installations. ```bash -wget https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh -chmod +x ./Install.sh -./Install.sh +curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh | sudo bash ``` - -You can manually set the PoshC2 installation directory by passing it as an argument to the Install.sh script, or by setting the `POSHC2_DIR` environment variable. The default is **/opt/PoshC2**. +You can manually set the PoshC2 installation directory by passing it to the Install.sh script as the `-p` argument. The default is **/opt/PoshC2**: ``` -curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh | bash -s "/root/PoshC2" +curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install.sh | sudo bash -s -- -p /root/PoshC2 ``` -Elevated privileges are required as the install script performs `apt` updates and installations. +### Cutting Edge Features + +We want to keep the `master` branch stable to ensure that users are able to rely on it when required and for this reason changes can often be feature-complete but not yet present on `master` as they have not been tested completely and signed-off yet. + +If you want to look at upcoming features in PoshC2 you can check out the `dev` branch, or any individual feature branches branched off of `dev`. + +As features **are** tested before they are merged into `dev` this branch should still be fairly stable and operators can opt in to using this branch or a particular feature branch for their engagement. +This does trade stablity for new features however so do it at your own discretion. + +To use `dev` or a feature branch pass the branch name to the Install.sh script as the `-b` argument: + +```bash +curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/dev/Install.sh | sudo bash -s -- -b dev +``` + +Note the URL includes the branch name also (here `dev` instead of `master`). -### Installing for Docker +## Installing for Docker You can also run PoshC2 using Docker, this allows more stable and running and enables PoshC2 to easily run on other operating systems. -To start with, install Docker on the host and then add the PoshC2 installation and project directories to the Docker as shared directories. By default on Kali these are **/opt/PoshC2** and **/opt/PoshC2_Project**. +The Docker install does not clone PoshC2 as the PoshC2 images on Docker Hub are used, so only a minimal install of some dependencies and scripts are performed. -#### Kali based hosts +To start with, install Docker on the host and then add the PoshC2 projects directory to Docker as a shared directory if required for your OS. By default this is **/var/poshc2** on *nix. -Automatic PoshC2 install for Python3 using curl & bash +### Kali based hosts + +Python3 install script: + +``` +*** PoshC2 Install script for Docker *** +Usage: +./Install.sh -b + +Default is the master branch +``` + +Elevated privileges are required as the install script performs `apt` updates and installations. ```bash -curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install-for-Docker.sh | bash +curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install-for-Docker.sh | sudo bash ``` -Manual install: +To use the `dev` or feature branches with Docker curl down the `Install-for-Docker.sh` on the appropriate branch and pass the branch name as an argument: ```bash -wget https://raw.githubusercontent.com/nettitude/PoshC2/master/Install-for-Docker.sh -chmod +x ./Install-for-Docker.sh -./Install-for-Docker.sh +curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/BRANCHNAME/Install-for-Docker.sh | sudo bash -s -- -b BRANCHNAME ``` -#### Other OSs +### Other OSs On other *nix flavours and MacOS, copy the posh-docker\* commands to your path. On Windows, import the PoshC2.psm1 PowerShell module. -See the Docker section below on running PoshC2 using Docker. - ## Running PoshC2 -1. Edit the config file by running `posh-config` to open it in $EDITOR. If this variable is not set then it defaults to vim, or you can use --nano to open it in nano. -2. Run the server using `posh-server` -3. Others can view the log using `posh-log` -4. Interact with the implants using the handler, run by using `posh` +Create a new project: -Note that if your C2 server is going to bind to a privileged port, such as 443, then the C2 server and Implant Handler need to be run as elevated process (such as as root or via sudo) in order to be able to bind to this port. +```bash +posh-project -n +``` -### Running as a service (*nix) +Projects can be switched to or listed using this script: -Running as a service provides multiple benefits such as being able to log to service logs, viewing with journalctl and automatically starting on reboot. +```bash +[*] Usage: posh-project -n +[*] Usage: posh-project -s +[*] Usage: posh-project -l (lists projects) +[*] Usage: posh-project -d +[*] Usage: posh-project -c (shows current project) -1. Start the service from an elevated prompt +``` + +Edit the configuration for your project: ```bash -posh-service +posh-config ``` -2. View the log: +Launch the PoshC2 server: -``` -posh-log +```bash +posh-server ``` -Note that re-running `posh-service` will restart the posh-service. -Running `posh-service` will automatically start to display the log, but Ctrl-C will not stop the service only quit the log in this case -`posh-log` can be used to re-view the log at any point. -`posh-stop-service` can be used to stop the service. +Alternatively start it as a service: -### Running in Docker +```bash +posh-service +``` -PoshC2 supports running in Docker containers for consistency and cross-platform support. +Separately, run the ImplantHandler for interacting with implants: -**See the Install section above for setting up Docker & PoshC2** +```bash +posh -u +``` -You can build the Docker image after installing by issuing this command: +See https://poshc2.readthedocs.io/en/latest/ for full documentation on PoshC2. -``` -posh-docker-build -``` +### Specifying a Docker tag -Once this has completed, run Posh as usual. -All project content is stored in the project directory on the host. +If you are using Docker you can specify the Docker image tag to run with the `-t` option to `posh-server` and `posh`. -You can clean the Docker containers and images on the host using the following command: +E.g. + +```bash +posh-server -t latest -``` -posh-docker-clean ``` ## Updating PoshC2 Installations -You can update your PoshC2 installation using the following command: +When using a git cloned version of PoshC2 you can update your PoshC2 installation using the following command: ``` posh-update ``` -This command will save the changes you have made to your configuration file, then reset the PoshC2 installation to the latest master branch before re-applying those changes. - -If applying the changes fails, a message will be printed in order to allow the user to manually merge in the changes. - -## Using older versions - -You can use an older version of PoshC2 by referencing the appropriate tag. You can list the tags for the repository by issuing: +This script allows you to specify an alternative branch. -### Linux Install Python2 - stable but unmaintained - -Automatic install for Python2 using curl & bash - -```bash -curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/python2/Install.sh | bash ``` +*** PoshC2 Update Script *** +Usage: +posh-update -b -### Other tags - -```bash -git tag --list +Default is the master branch ``` -or viewing them online. -Then you can use the install one-liner but replace the branch name with the tag: +This command will reset the PoshC2 installation to the latest master branch. -```bash -curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2//Install.sh | bash -``` +## Using older versions -For example: +You can use an older version of PoshC2 by referencing the appropriate tag. Note this only works if you have cloned down the repository. +You can list the tags for the repository by issuing: ```bash -curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/v4.8/Install.sh | bash +git tag --list ``` -### Offline - If you have a local clone of PoshC2 you can change the version that is in use while offline by just checking out the version you want to use: ```bash @@ -190,16 +206,10 @@ For example: git reset --hard v4.8 ``` -However note that this will overwrite any local changes to files, such as Config.py and you may have to re-run the install script for that version or re-setup the environment appropriately. - -## Issues / FAQs - -If you are experiencing any issues that aren't solved by reading the documentation at https://poshc2.readthedocs.io, please check the open issues tracking page within GitHub. If this page doesn't have what you're looking for please open a new issue or issue a pull request. - -If you are looking for tips and tricks on PoshC2 usage and optimisation, you are welcome to join the slack channel below. +However note that this will overwrite any local changes to files, such as changes to the configuration files, and you may have to re-run the install script for that version or re-setup the environment appropriately. ## License / Terms of Use This software should only be used for **authorised** testing activity and not for malicious use. -By downloading this software you are accepting the terms of use and the licensing agreement. +By downloading this software you are accepting the terms of use and the licensing agreement. \ No newline at end of file diff --git a/poshc2/__init__.py b/poshc2/__init__.py index f9a8335a..ddd0effb 100644 --- a/poshc2/__init__.py +++ b/poshc2/__init__.py @@ -1,8 +1,11 @@ #! /usr/bin/env python3 -import sys +import sys, subprocess -VERSION = "v6.0" +try: + VERSION = subprocess.check_output(["git", "describe", "--match", "v[0-9]*", "--abbrev=0", "--tags", "HEAD"]).decode().strip() +except: + VERSION = "Zip" def run(): if sys.argv[1] == '--client': diff --git a/poshc2/server/Config.py b/poshc2/server/Config.py index da13b2f2..737eef5d 100644 --- a/poshc2/server/Config.py +++ b/poshc2/server/Config.py @@ -2,7 +2,9 @@ from poshc2.server.UrlConfig import UrlConfig from poshc2.Utils import string_to_array -if not os.path.exists(os.path.expanduser("~/.poshc2/CURRENT_PROJECT")): +POSH_PROJECTS_DIR = "/var/poshc2/" + +if not os.path.exists(f"{POSH_PROJECTS_DIR}CURRENT_PROJECT"): print("PoshC2 current project file does not exist, please run posh-project") sys.exit(1) @@ -12,10 +14,10 @@ if not PoshInstallDirectory.endswith("/"): PoshInstallDirectory = PoshInstallDirectory + "/" -with open(os.path.expanduser("~/.poshc2/CURRENT_PROJECT"), 'r') as current_project_file: +with open(f"{POSH_PROJECTS_DIR}CURRENT_PROJECT", 'r') as current_project_file: current_project = current_project_file.read().strip() -PoshProjectDirectory = os.path.expanduser(f"~/.poshc2/{current_project}") +PoshProjectDirectory = f"{POSH_PROJECTS_DIR}{current_project}" if not PoshProjectDirectory.endswith("/"): PoshProjectDirectory = PoshProjectDirectory + "/" diff --git a/resources/config-template.yml b/resources/config-template.yml index edcca545..8e01cd2f 100644 --- a/resources/config-template.yml +++ b/resources/config-template.yml @@ -11,8 +11,8 @@ DatabaseType: SQLite # or Postgres PostgresConnectionString: "dbname='poshc2_project_x' port='5432' user='admin' host='192.168.111.111' password='XXXXXXX'" # Only used if Postgres in use # Payload Comms -PayloadCommsHost: "https://127.0.0.1:443,https://127.0.0.1" # "https://www.domainfront.com:443,https://www.direct.com" -DomainFrontHeader: "127.0.0.1,127.0.0.1" # "axpejfaaec.cloudfront.net,www.direct.com" +PayloadCommsHost: "https://127.0.0.1" # "https://www.domainfront.com:443,https://www.direct.com" +DomainFrontHeader: "" # "axpejfaaec.cloudfront.net,www.direct.com" Referrer: "" # optional ServerHeader: "Apache" UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" # This should be updated to match the environment, this is Chrome on 2020-03-2 diff --git a/resources/modules/SharpSocks.ps1 b/resources/modules/SharpSocks.ps1 index 8847ec5a..0538f6b8 100644 --- a/resources/modules/SharpSocks.ps1 +++ b/resources/modules/SharpSocks.ps1 @@ -4,7 +4,7 @@ $Global:Socks = $null $Global:BoolStart = $null $iLogOutput = $null $Comms = $null -function SharpSocks +function SharpSocks { <# .Synopsis @@ -12,27 +12,27 @@ function SharpSocks Tunnellable HTTP/HTTPS socks4a proxy written in C# and deployable via PowerShell - SharpSocks 2017 Nettitude - Rob Maslen @rbmaslen + SharpSocks 2020 Nettitude + Rob Maslen @rbmaslen .DESCRIPTION - PS C:\> Usage: SharpSocks -Uri + PS C:\> Usage: SharpSocks -Uri .EXAMPLE - Start the Implant(Client) specifying the web server (http://127.0.0.1:8081), the encryption keys and channel id. Also specify a list of URLs to use when making HTTP Request. Set the beacon time to 0.5 seconds + Start the Implant(Client) specifying the web server (http://127.0.0.1:8081), the encryption keys and channel id. Also specify a list of URLs to use when making HTTP Request. Set the beacon time to 0.5 seconds PS C:\> SharpSocks -Client -Uri http://127.0.0.1:8081 -Key PTDWISSNRCThqmpWEzXFZ1nSusz10u0qZ0n0UjH66rs= -Channel 7f404221-9f30-470b-b05d-e1a922be3ff6 -URLs "site/review/access.php","upload/data/images" -Beacon 500 .EXAMPLE Same as above using different list of URLs PS C:\> SharpSocks -Client -Uri http://127.0.0.1:8081 -Key PTDWISSNRCThqmpWEzXFZ1nSusz10u0qZ0n0UjH66rs= -Channel 7f404221-9f30-470b-b05d-e1a922be3ff6 -URLs "Upload","Push","Res" -Beacon 500 .EXAMPLE - Sames as above but connect out via an authenticated proxy server + Sames as above but connect out via an authenticated proxy server PS C:\> SharpSocks -Client -Uri http://127.0.0.1:8081 -ProxyUser bob -ProxyPass pass -ProxyDomain dom -ProxyUrl http://10.150.10.1:8080 -Key PTDWISSNRCThqmpWEzXFZ1nSusz10u0qZ0n0UjH66rs= -Channel 7f404221-9f30-470b-b05d-e1a922be3ff6 -URLs "Upload","Push","Res" -Beacon 500 #> param( - [Parameter(Mandatory=$True)][string]$Uri, - [Parameter(Mandatory=$False)]$URLs="Upload", - [Parameter(Mandatory=$False)][switch]$Server, - [Parameter(Mandatory=$False)][switch]$Client, - [Parameter(Mandatory=$False)][int]$SocksPort=43334, + [Parameter(Mandatory=$True)][string]$Uri, + [Parameter(Mandatory=$False)]$URLs="Upload", + [Parameter(Mandatory=$False)][switch]$Server, + [Parameter(Mandatory=$False)][switch]$Client, + [Parameter(Mandatory=$False)][int]$SocksPort=43334, [Parameter(Mandatory=$False)][string]$Channel, [Parameter(Mandatory=$False)][string]$IPAddress="0.0.0.0", [Parameter(Mandatory=$False)][string]$DomainFrontURL, @@ -52,7 +52,7 @@ function SharpSocks echo "[-] Loading Assemblies" if ($psversiontable.CLRVersion.Major -lt 3) { echo "Not running on CLRVersion 4 or above. Try 'migrate' to use unmanaged powershell" - } + } else { if (($SocksClientLoaded -ne "TRUE") -and ($Client.IsPresent)) { $Script:SocksClientLoaded = "TRUE" @@ -63,17 +63,17 @@ function SharpSocks $gzipStream = New-Object System.IO.Compression.GzipStream $gzdll, ([IO.Compression.CompressionMode]::Decompress) try { $buffer = New-Object byte[](32000); - while ($true) + while ($true) { $read = $gzipStream.Read($buffer, 0, 32000) - if ($read -le 0) + if ($read -le 0) { break; } $output.Write($buffer, 0, $read) } } - finally + finally { Write-Verbose "Closing streams and newly decompressed file" $gzipStream.Close(); @@ -98,7 +98,7 @@ function SharpSocks $Key = Create-AesKey } - $secureStringPwd = $Key | ConvertTo-SecureString -AsPlainText -Force + $secureStringPwd = $Key | ConvertTo-SecureString -AsPlainText -Force #If there is no channel set if (!$Channel) { @@ -107,17 +107,17 @@ function SharpSocks # Proxy Config if ($ProxyURL) { - $Proxy = New-Object System.Net.WebProxy($ProxyURL,$True); + $Proxy = New-Object System.Net.WebProxy($ProxyURL,$True); if ($ProxyUser -and $ProxyPassword) { $creds = new-object System.Net.NetworkCredential $creds.UserName = $ProxyUser $creds.Domain = $ProxyDomain - $creds.SecurePassword = ConvertTo-SecureString $ProxyPassword -AsPlainText -Force; + $creds.SecurePassword = ConvertTo-SecureString $ProxyPassword -AsPlainText -Force; $Proxy.Credentials = $Creds; - } else { + } else { $Proxy.UseDefaultCredentials = $True; - } + } } else { $Proxy = [System.Net.WebRequest]::GetSystemWebProxy() $Proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials @@ -137,7 +137,7 @@ function SharpSocks $Script:Socks = [SocksProxy.Classes.Integration.PoshCreateProxy]::CreateSocksController($Uri, $Channel, $DomainFrontURL, $UserAgent, $secureStringPwd, $NewURLs, $Cookie1, $Cookie2, $Proxy, $Beacon, $Comms, $InsecureSSL); $Script:BoolStart = $Socks.Start() if ($BoolStart) { - echo "" + echo "" echo "[+] SharpSocks client Started!" echo "" echo "URLs:" @@ -150,7 +150,7 @@ function SharpSocks echo "Cookies: $Cookie1 $Cookie2" echo "User-Agent: $UserAgent" echo "" - echo "" + echo "" echo "[-] Run StopSocks to stop the client!" echo "" } @@ -167,18 +167,18 @@ function StopSocks { $Script:Socks.HARDStop() $Script:BoolStart = $Socks.Stop() $Script:BoolStart = $Socks.HARDStop() - echo "" + echo "" echo "[-] SharpSocks stopped!" echo "" } else { - echo "" + echo "" echo "[-] SharpSocks not running!" echo "" } } # creates a randon AES symetric encryption key -function Create-AesManagedObject +function Create-AesManagedObject { param ( @@ -193,37 +193,37 @@ function Create-AesManagedObject $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros $aesManaged.BlockSize = 128 $aesManaged.KeySize = 256 - if ($IV) + if ($IV) { - if ($IV.getType().Name -eq 'String') + if ($IV.getType().Name -eq 'String') {$aesManaged.IV = [System.Convert]::FromBase64String($IV)} - else + else {$aesManaged.IV = $IV} } - if ($key) + if ($key) { - if ($key.getType().Name -eq 'String') + if ($key.getType().Name -eq 'String') {$aesManaged.Key = [System.Convert]::FromBase64String($key)} - else + else {$aesManaged.Key = $key} } $aesManaged } # creates a randon AES symetric encryption key -function Create-AesKey() +function Create-AesKey() { $aesManaged = Create-AesManagedObject $aesManaged.GenerateKey() [System.Convert]::ToBase64String($aesManaged.Key) } -function Get-RandomChamnnel +function Get-RandomChamnnel { param ([int]$Length) $set = 'abcdefghijklmnopqrstuvwxyz0123456789'.ToCharArray() $result = '' - for ($x = 0; $x -lt $Length; $x++) + for ($x = 0; $x -lt $Length; $x++) { $result += $set | Get-Random } diff --git a/resources/scripts/PoshC2.psm1 b/resources/scripts/PoshC2.psm1 index 105db376..0cb0868f 100644 --- a/resources/scripts/PoshC2.psm1 +++ b/resources/scripts/PoshC2.psm1 @@ -1,4 +1,5 @@ +PoshC2DockerImage="m0rv4i/poshc2" Function Build-PoshC2DockerImage { <# @@ -21,7 +22,7 @@ Function Build-PoshC2DockerImage { .PARAMETER NoCache - A switch which specifices that the image should be built without using any cached layers in Docker. + A switch which specifices that the image should be built without using any cached layers in Docker. .EXAMPLE @@ -35,15 +36,15 @@ Function Build-PoshC2DockerImage { ) Write-Verbose "[+] Ensure .sh files use LF instead of CRLF" - Get-ChildItem -Path $PoshC2Dir -File -Recurse | Where-Object {$_.Extension -eq '.sh'} | ForEach-Object { + Get-ChildItem -Path $PoshC2Dir -File -Recurse | Where-Object {$_.Extension -eq '.sh'} | ForEach-Object { $Content = Get-Content -Raw -Path $_.FullName $Content -Replace "`r`n","`n" | Set-Content -Path $_.FullName -NoNewline -Force } If($NoCache) { - docker build -t nettitude/poshc2 $PoshC2Dir --no-cache + docker build -t $PoshC2DockerImage $PoshC2Dir --no-cache } Else { - docker build -t nettitude/poshc2 $PoshC2Dir + docker build -t $PoshC2DockerImage $PoshC2Dir } } @@ -71,7 +72,7 @@ Function Clean-PoshC2DockerState { .EXAMPLE - Clean-PoshC2DockerState + Clean-PoshC2DockerState #> [CmdletBinding()] Param( @@ -89,11 +90,11 @@ Function Clean-PoshC2DockerState { $confirmation = Read-Host "Would you like to do a clean? y/N" if ($confirmation -eq 'y' -or $confirmation -eq 'Y') { - docker system prune -f + docker system prune -f } } -Function Invoke-PoshC2DockerServer { +Function Start-PoshC2Server { <# .SYNOPSIS @@ -116,17 +117,13 @@ Function Invoke-PoshC2DockerServer { The local path that is/will be used as the Project Directory for PoshC2. - .PARAMETER DockerPoshC2ProjectDir - - The docker path that is/will be used as the Project Directory for PoshC2. - .PARAMETER PoshC2Port The Port that the PoshC2 server binds to, defaults to 443. .EXAMPLE - Invoke-PoshC2DockerServer -PoshC2Dir "C:\PoshC2" -LocalPoshC2ProjectDir "C:\PoshC2_Project" -DockerPoshC2ProjectDir "/opt/PoshC2_Project" + Start-PoshC2DockerServer -PoshC2Dir "C:\PoshC2" -LocalPoshC2ProjectDir "C:\PoshC2_Project" #> [CmdletBinding()] Param( @@ -134,16 +131,14 @@ Function Invoke-PoshC2DockerServer { [string]$PoshC2Dir, [Parameter(Mandatory=$true)] [string]$LocalPoshC2ProjectDir, - [Parameter(Mandatory=$true)] - [string]$DockerPoshC2ProjectDir, [int]$PoshC2Port = 443 - + ) - docker run -ti --rm -p $("$PoshC2Port" + ":" + "$PoshC2Port") -v $("$LocalPoshC2ProjectDir" + ":" + "$DockerPoshC2ProjectDir") -v $("$PoshC2Dir" + ":" + "/opt/PoshC2") nettitude/poshc2 /usr/bin/posh-server + docker run --rm -p $("$PoshC2Port:$PoshC2Port") -v $("$LocalPoshC2ProjectDir:/var/poshc2") $PoshC2DockerImage /usr/bin/posh-server } -Function Invoke-PoshC2DockerHandler { +Function Start-PoshC2DockerHandler { <# .SYNOPSIS @@ -166,17 +161,13 @@ Function Invoke-PoshC2DockerHandler { The local path that is/will be used as the Project Directory for PoshC2. - .PARAMETER DockerPoshC2ProjectDir - - The docker path that is/will be used as the Project Directory for PoshC2. - .PARAMETER User The user to login as in the ImplantHandler.x .EXAMPLE - Invoke-PoshC2DockerHandler -PoshC2Dir "C:\PoshC2" -PoshC2ProjectDir "C:\PoshC2_Project" -User CrashOverride + Start-PoshC2DockerHandler -PoshC2Dir "C:\PoshC2" -PoshC2ProjectDir "C:\PoshC2_Project" -User CrashOverride #> [CmdletBinding()] Param( @@ -184,92 +175,13 @@ Function Invoke-PoshC2DockerHandler { [string]$PoshC2Dir, [Parameter(Mandatory=$true)] [string]$LocalPoshC2ProjectDir, - [Parameter(Mandatory=$true)] - [string]$DockerPoshC2ProjectDir, [string]$User = "" ) - docker run -ti --rm -v $("$LocalPoshC2ProjectDir" + ":" + "$DockerPoshC2ProjectDir") -v $("$PoshC2Dir" + ":" + "/opt/PoshC2") nettitude/poshc2 /usr/bin/posh -u "$User" -} - -Function Update-PoshC2 { - <# - .SYNOPSIS - - Updates the PoshC2 installation. - - Author: @m0rv4i - License: BSD 3-Clause - Required Dependencies: None - Optional Dependencies: None - - .DESCRIPTION - - Updates the PoshC2 installation. - - .PARAMETER PoshC2Dir - - Specifies the path to the PoshC2 installation which will be built. - - .EXAMPLE - - Update-PoshC2 -PoshC2Dir "C:\PoshC2" - #> - [CmdletBinding()] - Param( - [Parameter(Mandatory=$true)] - [string]$PoshC2Dir - ) - - Write-Output """ - __________ .__. _________ ________ - \_______ \____ _____| |__ \_ ___ \ \_____ \\ - | ___/ _ \/ ___/ | \ / \ \/ / ____/ - | | ( <_> )___ \| Y \ \ \____/ \\ - |____| \____/____ >___| / \______ /\_______ \\ - \/ \/ \/ \/ - ================= www.PoshC2.co.uk ================""" - - Write-Output "" - Write-Output "[+] Updating PoshC2" - Write-Output "" - - Push-Location "$PoshC2Dir" - - Write-Output "" - Write-Output "[+] Saving changes to Config.py" - Write-Output "" - git diff Config.py >> $env:Temp\PoshC2_Config_Diff.git - - Write-Output "" - Write-Output "[+] Updating Posh Installation to latest master" - git fetch - git reset --hard origin/master - - Write-Output "" - Write-Output "[+] Creating docker image" - posh-docker-build - - Write-Output "" - Write-Output "[+] Re-applying Config file changes" - git apply $env:Temp\PoshC2_Config_Diff.git - - If($?) { - Remote-Item $env:Temp\PoshC2_Config_Diff.git - } - Else { - Write-Output "[-] Re-applying Config file changes failed, please merge manually from /tmp/PoshC2_Config_Diff.git" - } - - Pop-Location - - Write-Output "" - Write-Output "[+] Update complete" - Write-Output "" + docker run -ti --rm -v $("$LocalPoshC2ProjectDir:/var/poshc2") $PoshC2DockerImage /usr/bin/posh -u "$User" } Export-ModuleMember -Function Build-PoshC2DockerImage -Alias posh-docker-build Export-ModuleMember -Function Clean-PoshC2DockerState -Alias posh-docker-clean -Export-ModuleMember -Function Invoke-PoshC2DockerServer -Alias posh-docker-server -Export-ModuleMember -Function Invoke-PoshC2DockerHandler -Alias posh-docker -Export-ModuleMember -Function Update-PoshC2 -Alias posh-update +Export-ModuleMember -Function Start-PoshC2DockerServer -Alias posh-server +Export-ModuleMember -Function Start-PoshC2DockerHandler -Alias posh \ No newline at end of file diff --git a/resources/scripts/_posh-common b/resources/scripts/_posh-common new file mode 100644 index 00000000..c82f6ade --- /dev/null +++ b/resources/scripts/_posh-common @@ -0,0 +1,37 @@ +#!/bin/bash + +get_posh_projects_dir(){ + POSH_PROJECTS_DIR="/var/poshc2" +} + +get_docker_posh_projects_dir(){ + DOCKER_POSH_PROJECTS_DIR="/var/poshc2" +} + +get_posh_dir() { + SCRIPT_LOCATION=`readlink -f -n $0` + POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" +} + +get_posh_project(){ + get_posh_projects_dir + POSH_PROJECT=`cat $POSH_PROJECTS_DIR/CURRENT_PROJECT 2>/dev/null` + if [ -z "$POSH_PROJECT" ]; then + echo "No PoshC2 project set, please run posh-project" + exit 1 + fi +} + +get_posh_project_dir(){ + get_posh_projects_dir + get_posh_project + POSH_PROJECT_DIR="$POSH_PROJECTS_DIR/$POSH_PROJECT" + if [ ! -d "$POSH_PROJECT_DIR" ]; then + echo "No PoshC2 project directory, please run posh-project" + exit 1 + fi +} + +get_docker_image_name(){ + DOCKER_IMAGE_NAME="m0rv4i/poshc2" +} \ No newline at end of file diff --git a/resources/scripts/fpc b/resources/scripts/fpc index c5f5e3d8..8125fe2b 100755 --- a/resources/scripts/fpc +++ b/resources/scripts/fpc @@ -8,20 +8,9 @@ function ctrl_c() { exit } -SCRIPT_LOCATION=`readlink -f -n $0` -POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" - -POSH_PROJECT=`cat $HOME/.poshc2/CURRENT_PROJECT 2>/dev/null` -if [ -z "$POSH_PROJECT" ]; then - echo "No PoshC2 project set, please run posh-project" - exit 1 -fi - -POSH_PROJECT_DIR="$HOME/.poshc2/$POSH_PROJECT" -if [ ! -d "$POSH_PROJECT_DIR" ]; then - echo "No PoshC2 project directory, please run posh-project" - exit 1 -fi +source /usr/bin/_posh-common +get_posh_dir +get_posh_project_dir DATABASE_TYPE=`cat $POSH_PROJECT_DIR/config.yml | grep "DatabaseType: " | cut -d "\"" -f 2` DATABASE_STRING=`cat $POSH_PROJECT_DIR/config.yml | grep "PostgresConnectionString: " | cut -d "\"" -f 2` @@ -29,8 +18,6 @@ DATABASE_STRING=`cat $POSH_PROJECT_DIR/config.yml | grep "PostgresConnectionStri pushd "$POSH_DIR" >/dev/null if [ "$?" -eq "0" ]; then - python3 -m pipenv run python3 "resources/scripts/fpc.py" -p "$POSH_PROJECT_DIR" -d "$DATABASE_TYPE" -pg "$DATABASE_STRING" $@ popd > /dev/null - fi diff --git a/resources/scripts/posh b/resources/scripts/posh index ad62dcf2..d46c85f9 100755 --- a/resources/scripts/posh +++ b/resources/scripts/posh @@ -8,8 +8,8 @@ function ctrl_c() { exit } -SCRIPT_LOCATION=`readlink -f -n $0` -POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" +source /usr/bin/_posh-common +get_posh_dir pushd "$POSH_DIR" >/dev/null diff --git a/resources/scripts/posh-config b/resources/scripts/posh-config index 2e16e6ca..27160acf 100755 --- a/resources/scripts/posh-config +++ b/resources/scripts/posh-config @@ -1,16 +1,7 @@ #!/bin/bash -POSH_PROJECT=`cat $HOME/.poshc2/CURRENT_PROJECT 2>/dev/null` -if [ -z "$POSH_PROJECT" ]; then - echo "No PoshC2 project set, please run posh-project" - exit 1 -fi - -POSH_PROJECT_DIR="$HOME/.poshc2/$POSH_PROJECT" -if [ ! -d "$POSH_PROJECT_DIR" ]; then - echo "No PoshC2 project directory, please run posh-project" - exit 1 -fi +source /usr/bin/_posh-common +get_posh_project_dir if [[ "$EDITOR" != "" ]]; then sudo $EDITOR "$POSH_PROJECT_DIR/config.yml" diff --git a/resources/scripts/posh-cookie-decrypter b/resources/scripts/posh-cookie-decrypter index 5f691479..cc6548b6 100755 --- a/resources/scripts/posh-cookie-decrypter +++ b/resources/scripts/posh-cookie-decrypter @@ -8,8 +8,8 @@ function ctrl_c() { exit } -SCRIPT_LOCATION=`readlink -f -n $0` -POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" +source /usr/bin/_posh-common +get_posh_dir pushd $POSH_DIR >/dev/null if [ "$?" -eq "0" ]; then diff --git a/resources/scripts/posh-docker b/resources/scripts/posh-docker index 47bd074e..f4079885 100755 --- a/resources/scripts/posh-docker +++ b/resources/scripts/posh-docker @@ -1,3 +1,36 @@ #!/bin/bash -sudo -E docker run -ti --rm -v "$HOME/.poshc2:/root/.poshc2" m0rv4i/poshc2 /usr/bin/posh "$@" +source /usr/bin/_posh-common +get_posh_projects_dir +get_docker_posh_projects_dir +get_docker_image_name + +show_help(){ + echo "*** PoshC2 Docker Implant Handler ***" + echo "Usage:" + echo "posh -t -u " + echo "" + echo "Default Docker tag is master" +} + +DOCKER_TAG="master" +USER="" + +while getopts "h?t:u:" opt; do + case "$opt" in + h|\?) + show_help + exit 0 + ;; + t) DOCKER_TAG="$OPTARG" + ;; + u) USER="$OPTARG" + ;; + esac +done + +if [ ! -z "$USER" ]; then + sudo -E docker run -ti -l posh-client --rm -v "$POSH_PROJECTS_DIR:$DOCKER_POSH_PROJECTS_DIR" "$DOCKER_IMAGE_NAME":"$DOCKER_TAG" /usr/bin/posh -u "$USER" +else + sudo -E docker run -ti -l posh-client --rm -v "$POSH_PROJECTS_DIR:$DOCKER_POSH_PROJECTS_DIR" "$DOCKER_IMAGE_NAME":"$DOCKER_TAG" /usr/bin/posh +fi diff --git a/resources/scripts/posh-docker-build b/resources/scripts/posh-docker-build index 9778bc4d..2edc1ebb 100755 --- a/resources/scripts/posh-docker-build +++ b/resources/scripts/posh-docker-build @@ -8,14 +8,15 @@ function ctrl_c() { exit } -SCRIPT_LOCATION=`readlink -f -n $0` -POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" +source /usr/bin/_posh-common +get_posh_dir +get_docker_image_name pushd "$POSH_DIR" >/dev/null if [ "$?" -eq "0" ]; then posh-docker-clean - sudo -E docker build -t m0rv4i/poshc2 . "$@" + sudo -E docker build -t "$DOCKER_IMAGE_NAME" . "$@" popd > /dev/null fi diff --git a/resources/scripts/posh-docker-debug b/resources/scripts/posh-docker-debug index 21add354..c73ef745 100755 --- a/resources/scripts/posh-docker-debug +++ b/resources/scripts/posh-docker-debug @@ -1,4 +1,30 @@ #!/bin/bash -sudo -E docker run -ti --rm -v "$HOME/.poshc2:/root/.poshc2" m0rv4i/poshc2 /bin/bash +source /usr/bin/_posh-common +get_posh_projects_dir +get_docker_posh_projects_dir +get_docker_image_name + +show_help(){ + echo "*** PoshC2 Docker Debug ***" + echo "Usage:" + echo "posh-docker-debug -t " + echo "" + echo "Default Docker tag is master" +} + +DOCKER_TAG="master" + +while getopts "h?t:" opt; do + case "$opt" in + h|\?) + show_help + exit 0 + ;; + t) DOCKER_TAG="$OPTARG" + ;; + esac +done + +sudo -E docker run -ti --rm -v "$POSH_PROJECTS_DIR:$DOCKER_POSH_PROJECTS_DIR" "$DOCKER_IMAGE_NAME":"$DOCKER_TAG" /bin/bash diff --git a/resources/scripts/posh-docker-server b/resources/scripts/posh-docker-server index 6ba8e05e..d263bb56 100755 --- a/resources/scripts/posh-docker-server +++ b/resources/scripts/posh-docker-server @@ -1,18 +1,33 @@ #!/bin/bash -POSH_PROJECT=`cat $HOME/.poshc2/CURRENT_PROJECT 2>/dev/null` -if [ -z "${POSH_PROJECT}" ]; then - echo "No PoshC2 project set, please run posh-project" - exit 1 -fi - -POSH_PROJECT_DIR="$HOME/.poshc2/$POSH_PROJECT" -if [ ! -d "$POSH_PROJECT_DIR" ]; then - echo "No PoshC2 project directory, please run posh-project" - exit 1 -fi +source /usr/bin/_posh-common +get_posh_project_dir +get_posh_projects_dir +get_docker_posh_projects_dir +get_docker_image_name POSHC2_PORT=`cat $POSH_PROJECT_DIR/config.yml | grep "BindPort: " | grep -o -e "[0-9]\+"` -sudo -E docker run -ti --rm -p "$POSHC2_PORT:$POSHC2_PORT" -v "$HOME/.poshc2:/root/.poshc2" m0rv4i/poshc2 /usr/bin/posh-server +show_help(){ + echo "*** PoshC2 Docker Server ***" + echo "Usage:" + echo "posh-server -t " + echo "" + echo "Default is master" +} + +DOCKER_TAG="master" + +while getopts "h?t:" opt; do + case "$opt" in + h|\?) + show_help + exit 0 + ;; + t) DOCKER_TAG="$OPTARG" + ;; + esac +done + +sudo -E docker run --rm -l posh-server -p "$POSHC2_PORT:$POSHC2_PORT" -v "$POSH_PROJECTS_DIR:$DOCKER_POSH_PROJECTS_DIR" "$DOCKER_IMAGE_NAME":"$DOCKER_TAG" /usr/bin/posh-server diff --git a/resources/scripts/posh-docker-service b/resources/scripts/posh-docker-service deleted file mode 100755 index 5cd47e45..00000000 --- a/resources/scripts/posh-docker-service +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -POSH_PROJECT=`cat $HOME/.poshc2/CURRENT_PROJECT 2>/dev/null` -if [ -z "$POSH_PROJECT" ]; then - echo "No PoshC2 project set, please run posh-project" - exit 1 -fi - -POSH_PROJECT_DIR="$HOME/.poshc2/$POSH_PROJECT" -if [ ! -d "$POSH_PROJECT_DIR" ]; then - echo "No PoshC2 project directory, please run posh-project" - exit 1 -fi - -sudo systemctl enable poshc2-docker.service >/dev/null -sudo systemctl restart poshc2-docker.service >/dev/null - -while [[ $x -le 10 ]]; do - if [ -f "$POSH_PROJECT_DIR/poshc2_server.log" ]; then - break; - fi - sleep 1s - x=$(( $x + 1 )) -done - -/usr/bin/posh-log \ No newline at end of file diff --git a/resources/scripts/posh-docker-stop-server b/resources/scripts/posh-docker-stop-server new file mode 100644 index 00000000..684a2114 --- /dev/null +++ b/resources/scripts/posh-docker-stop-server @@ -0,0 +1,13 @@ +#!/bin/bash + +source /usr/bin/_posh-common +get_docker_image_name + +echo "[*] Stopping the PoshC2 server Docker container..." +CONTAINER=`sudo docker ps -q -f label=posh-server -f ancestor=$DOCKER_IMAGE_NAME` +if [ ! -z "$CONTAINER" ]; then + sudo docker stop "$CONTAINER" >/dev/null + echo "[+] Done" +else + echo "[*] No running PoshC2 server containers found" +fi \ No newline at end of file diff --git a/resources/scripts/posh-log b/resources/scripts/posh-log index 3a23409b..508092eb 100755 --- a/resources/scripts/posh-log +++ b/resources/scripts/posh-log @@ -1,16 +1,7 @@ #!/bin/bash -POSH_PROJECT=`cat $HOME/.poshc2/CURRENT_PROJECT 2>/dev/null` -if [ -z "$POSH_PROJECT" ]; then - echo "No PoshC2 project set, please run posh-project" - exit 1 -fi - -POSH_PROJECT_DIR="$HOME/.poshc2/$POSH_PROJECT" -if [ ! -d "$POSH_PROJECT_DIR" ]; then - echo "No PoshC2 project directory, please run posh-project" - exit 1 -fi +source /usr/bin/_posh-common +get_posh_project_dir tail -n 5000 -f "$POSH_PROJECT_DIR/poshc2_server.log" 2>/dev/null\ || ( echo -e "\e[31m[!] Could not open logfile: "$POSH_PROJECT_DIR/poshc2_server.log"\e[0m") diff --git a/resources/scripts/posh-project b/resources/scripts/posh-project index ed136768..d05ffe33 100755 --- a/resources/scripts/posh-project +++ b/resources/scripts/posh-project @@ -8,8 +8,8 @@ function ctrl_c() { exit } -SCRIPT_LOCATION=`readlink -f -n $0` -POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" +source /usr/bin/_posh-common +get_posh_projects_dir if [ "$1" == "-n" ]; then @@ -18,28 +18,28 @@ if [ "$1" == "-n" ]; then exit 1 fi - if [ -d "$HOME/.poshc2/$2" ]; then - echo "[-] Project directory already exists: $HOME/.poshc2/$2" + if [ -d "$POSH_PROJECTS_DIR/$2" ]; then + echo "[-] Project directory already exists: $POSH_PROJECTS_DIR/$2" exit 1 fi - mkdir -p "$HOME/.poshc2/$2" - echo "$2" > "$HOME/.poshc2/CURRENT_PROJECT" - cp "${POSH_DIR}resources/config-template.yml" "$HOME/.poshc2/$2/config.yml" + sudo mkdir -p "$POSH_PROJECTS_DIR/$2" + echo "$2" | sudo tee "$POSH_PROJECTS_DIR/CURRENT_PROJECT" >/dev/null + sudo cp "$POSH_PROJECTS_DIR/config-template.yml" "$POSH_PROJECTS_DIR/$2/config.yml" echo "[+] Created Project: $2" echo "[*] Now run posh-config to set your configuration" elif [ "$1" == "-s" ]; then - if [ -z "$2"]; then + if [ -z "$2" ]; then echo "[*] Usage: posh-project -s " exit 1 fi - if [ ! -d "$HOME/.poshc2/$2" ]; then - echo "[-] Project directory does not exist: $HOME/.poshc2/$2" + if [ ! -d "$POSH_PROJECTS_DIR/$2" ]; then + echo "[-] Project directory does not exist: $POSH_PROJECTS_DIR/$2" exit 1 fi - echo "$2" > $HOME/.poshc2/CURRENT_PROJECT + echo "$2" | sudo tee $POSH_PROJECTS_DIR/CURRENT_PROJECT >/dev/null echo "[+] Switched to: $2" echo "[*] Restart the PoshC2 C2 server & ImplantHandler to use the new project." @@ -53,8 +53,30 @@ elif [ "$1" == "-l" ]; then echo "[*] Listing PoshC2 Projects in $POSH_PROJECTS_DIR" command ls -dl /var/poshc2/*/ 2>/dev/null | cut -d '/' -f 4 +elif [ "$1" == "-c" ]; then + + if [ ! -f "$POSH_PROJECTS_DIR/CURRENT_PROJECT" ]; then + echo "[-] No current project selected." + exit 1 + fi + + echo "[*] Current project: " + cat "$POSH_PROJECTS_DIR/CURRENT_PROJECT" + +elif [ "$1" == "-d" ]; then + + read -p "Are you sure you want to delete the project $2? y/N " -n 1 -r + echo # (optional) move to a new line + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "[*] Removal aborted" + else + sudo rm -rf "$POSH_PROJECTS_DIR/$2" + echo "[+] Project removed" + fi else echo "[*] Usage: posh-project -n " echo "[*] Usage: posh-project -s " echo "[*] Usage: posh-project -l (lists projects)" + echo "[*] Usage: posh-project -d " + echo "[*] Usage: posh-project -c (shows current project)" fi diff --git a/resources/scripts/posh-server b/resources/scripts/posh-server index 451b9d93..bbd5e743 100755 --- a/resources/scripts/posh-server +++ b/resources/scripts/posh-server @@ -8,20 +8,9 @@ function ctrl_c() { exit } -SCRIPT_LOCATION=`readlink -f -n $0` -POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" - -POSH_PROJECT=`cat $HOME/.poshc2/CURRENT_PROJECT 2>/dev/null` -if [ -z "$POSH_PROJECT" ]; then - echo "No PoshC2 project set, please run posh-project" - exit 1 -fi - -POSH_PROJECT_DIR="$HOME/.poshc2/$POSH_PROJECT" -if [ ! -d "$POSH_PROJECT_DIR" ]; then - echo "No PoshC2 project directory, please run posh-project" - exit 1 -fi +source /usr/bin/_posh-common +get_posh_dir +get_posh_project_dir pushd $POSH_DIR >/dev/null if [ "$?" -eq "0" ]; then diff --git a/resources/scripts/posh-service b/resources/scripts/posh-service index 283e6b5f..6ca06d1a 100755 --- a/resources/scripts/posh-service +++ b/resources/scripts/posh-service @@ -1,16 +1,7 @@ #!/bin/bash -POSH_PROJECT=`cat $HOME/.poshc2/CURRENT_PROJECT 2>/dev/null` -if [ -z "$POSH_PROJECT" ]; then - echo "No PoshC2 project set, please run posh-project" - exit 1 -fi - -POSH_PROJECT_DIR="$HOME/.poshc2/$POSH_PROJECT" -if [ ! -d "$POSH_PROJECT_DIR" ]; then - echo "No PoshC2 project directory, please run posh-project" - exit 1 -fi +source /usr/bin/_posh-common +get_posh_project_dir sudo systemctl enable poshc2.service >/dev/null sudo systemctl restart poshc2.service >/dev/null diff --git a/resources/scripts/posh-update b/resources/scripts/posh-update index 58436a46..ce0754d3 100755 --- a/resources/scripts/posh-update +++ b/resources/scripts/posh-update @@ -8,8 +8,33 @@ function ctrl_c() { exit } -SCRIPT_LOCATION=`readlink -f -n $0` -POSH_DIR="`dirname $SCRIPT_LOCATION`/../../" +# A POSIX variable +OPTIND=1 # Reset in case getopts has been used previously in the shell. + +# Initialize our own variables: +GIT_BRANCH="master" + +show_help(){ + echo "*** PoshC2 Update Script ***" + echo "Usage:" + echo "posh-update -b " + echo "" + echo "Default is the master branch" +} + +while getopts "h?b:" opt; do + case "$opt" in + h|\?) + show_help + exit 0 + ;; + b) GIT_BRANCH="$OPTARG" + ;; + esac +done + +source /usr/bin/_posh-common +get_posh_dir pushd $POSH_DIR >/dev/null @@ -34,13 +59,13 @@ if [ "$?" -eq "0" ]; then fi echo "" - echo "[+] Updating Posh Installation to latest master" + echo "[+] Updating Posh Installation to latest $GIT_BRANCH" git fetch - git reset --hard origin/master + git reset --hard origin/"$GIT_BRANCH" echo "" echo "[+] Running Install script" - ./Install.sh + ./Install.sh -b "$GIT_BRANCH" -p "$POSH_DIR" echo "" echo "[+] Update complete" diff --git a/resources/scripts/poshc2-docker.service b/resources/scripts/poshc2-docker.service deleted file mode 100644 index 65e923ab..00000000 --- a/resources/scripts/poshc2-docker.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=PoshC2 Dockerised Server - -[Service] -Type=simple -User=root -ExecStart=/usr/bin/posh-docker-server - -[Install] -WantedBy=default.target \ No newline at end of file