Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merging tools repos #9

Merged
merged 6 commits into from
Jul 24, 2023
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/pr_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Test and check coverage pytest
run: |
export PYTHONPATH=$PYTHONPATH:./src:
pytest tests/ -n auto --cov --cov-fail-under=90 --ignore=./tests
pytest tests/ -n auto --cov --cov-fail-under=1

do-flake8:
name: Do flake8
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
find . -name '*requirements.txt' | while read file; do pip install -r "$file"; done
- name: Lint with mypy
run: |
mypy .
mypy ./src/powerpwn/machinepwn/

do-isort:
name: Do isort
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,7 @@ cov.xml
.output

# MacOS files
.DS_Store
.DS_Store

tokens.json
*.zip
3 changes: 2 additions & 1 deletion .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ line_length=150
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
use_parentheses=True
profile=black
36 changes: 36 additions & 0 deletions docs/powerdoor/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Backdoor Flow

[![stars](https://img.shields.io/github/stars/mbrg?icon=github&style=social)](https://github.com/mbrg)
[![twitter](https://img.shields.io/twitter/follow/mbrg0?icon=twitter&style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=mbrg0)
[![email me](https://img.shields.io/badge/michael.bargury-owasp.org-red?logo=Gmail)](mailto:michael.bargury@owasp.org)

Backdoor Flow is a demo showing how to maintain persistency on Power Platform by installing an automation factory that creates, executes and deletes arbitrary commands.

<a href="https://powerautomate.microsoft.com/en-us/robotic-process-automation/"><img src="https://docs.microsoft.com/en-us/power-pages/media/overview/power-platform.png" alt="Power Pwn" width="500" height="250" /></a>

Disclaimer: these materials are presented from an attacker’s perspective with the goal of raising awareness to the risks of underestimating the security impact of No Code/Low Code. No Code/Low Code is awesome.

## Usage
**As a python package**

```python
from powerpwn.powerdoor.backdoor_flow import BackdoorFlow
from powerpwn.powerdoor.samples.forward_email_backdoor_flow import SAMPLE_FLOW
POST_URL = ""
factory = BackdoorFlow(post_url=POST_URL)

flow = factory.create_flow(
environment_id=SAMPLE_FLOW["environment"],
flow_display_name=SAMPLE_FLOW["flowDisplayName"],
flow_definition=SAMPLE_FLOW["flowDefinition"],
flow_state=SAMPLE_FLOW["flowState"],
connection_references=EXAMPLE["connectionReferences"]
)

factory.delete_flow(environment_id=SAMPLE_FLOW["environment"], flow_id=flow["name"])
```

**From powerpwn cli**
* Run `powerpwn exec --help` to get all available commands.
* To create flow run `powerpwn exec create-flow -e {environment-id} -webhook-url {url to installed factory} -i {full path to input}`
* You can find an example to input file in samples/sample_backdoor_flow_cli_input.json
49 changes: 49 additions & 0 deletions docs/powerdump/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# powerdump


powerdump is a tool for exploring information in Microsoft PowerPlatform from a Red Team perspective. In short, this is what it does:
* Generates access tokens to fetch available resources in Microsoft PowerApps.
* Use HTTP calls in Python to dump all available information in the Micsrofot PowerPlatform to local directory.
* Generates access tokens to perform advanced actions on discovered resources.
* Provide a basic GUI to present collected resources and data.

powerpwn uses `browsepy` Python library and is only compatible with Python 3.6-3.8 (development is done with Python 3.8).

### Installation
**Using a version from GitHub**

Clone the repository and run:

```
pip install .
```

### Installation for development
Clone the repository and setup a virtual environment in your IDE. Install python packages by running:

```
python init_repo.py

```
To activate the virtual environment (.venv) run:
```
.\.venv\Scripts\activate (Windows)

./.venv/bin/activate (Linux)

```

### Using powerpwn
**Explore using cli**
* Run `powerpwn dump --tenant {tenantId} --cache-path {path}` to collect data from tenantId and store it in path. The default cache-path is `.cache` .
* For more options run `powerpwn dump --help`
* On first run, a device flow will initiate to acquire an access token.
* This may take a while depends on the tenant size. Once collect is done, you can find collected resources and data under `path` directory
* Access tokens to powerapps and apihub are cached in tokens.json file.
* To run a local server for gui, run dump command with `-g` or `--gui`.

**Using Gui**
* Run `powerpwn gui --cache-path {path}`, with same cache-path of `dump` command. The default cache-path is `.cache` .
* On http://127.0.0.1:5000/ you can find an application with all collected resources
* For connections, Playground will generate the connections swagger, that allow you to run these connections and perform actions on the platform. To authenticate, use the generated apihub access token generated in the previous step.
* On http://127.0.0.1:8080/ you can find a simple file browser with all resources and data dump.
44 changes: 44 additions & 0 deletions init_repo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
import subprocess # nosec
import sys


def log(message: str):
print(f"[init_repo] {message}")


def check_python_version():
version_info = sys.version_info
if version_info.major != 3:
return False
if version_info.minor < 6 or version_info.minor > 8:
return False

return True


if check_python_version():
log("Setting python path")
# set pythonpath
sys.path.append("./src")

log("Creating virtual environment")
subprocess.run("python -m venv .venv") # nosec

log("Installing python packages")
py_path = os.path.join(".venv", "Scripts", "python")

if not sys.platform.startswith("win"):
py_path = os.path.join(".venv", "bin", "python")

subprocess.run(f"{py_path} -m pip install --upgrade pip", shell=True) # nosec

# install packages
subprocess.run(f"{py_path} -m pip install -r requirements.txt", shell=True) # nosec

log("Python packages installed successfully")

log("DONE!")

else:
log("Supported python versions are 3.6-3.8")
6 changes: 5 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ Power Pwn is a demo showing how to repurpose Microsoft-trusted executables, serv

Disclaimer: these materials are presented from an attacker’s perspective with the goal of raising awareness to the risks of underestimating the security impact of No Code/Low Code. No Code/Low Code is awesome.

# TODO: organize powerpwn toolset docs
# TODO: organize powerpwn toolset docs

[LCNC Malware](docs/machinepwn/machine_pwn.md)
[PowerDump](docs/powerdump/readme.md)
[PowerDoor](docs/powerdoor/readme.md)
25 changes: 25 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pydantic[email]==1.10.7
pydantic==1.10.7
swagger-ui-py==22.7.13
Flask==2.2.2
requests~=2.28.1
msal~=1.20.0
responses~=0.23.1
pytest~=7.2.2
pytest-cov~=3.0.0
pytest-xdist~=2.5.0
prance~=0.22.11.4.0
openapi~=1.1.0
openapi-spec-validator~=0.5.6
jsf~=0.7.1
pillow~=10.0.0
scandir~=1.10.0
backports.shutil-get-terminal-size~=1.0.0
browsepy~=0.5.6
art
flake8~=4.0.1
black~=22.3.0
types-requests==2.31.0.1
bandit~=1.7.2
mypy~=0.931
isort~=5.10.1
43 changes: 43 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
[metadata]
name = powerpwn
author = Michael Bargury
version = 0.1

[options]
install_requires =
pydantic[email] ==1.10.7
pydantic ==1.10.7
swagger-ui-py ==22.7.13
Flask ==2.2.2
requests >=2.6.0
msal >=1.20.0
responses >=0.23.1
pytest >=7.2.2
prance >=0.22.11.4.0
openapi >=1.1.0
openapi-spec-validator >=0.5.6
jsf >=0.7.1
pillow >=10.0.0
scandir >=1.10.0
backports.shutil-get-terminal-size >=1.0.0
browsepy >=0.5.6
art

packages = find:
package_dir =
= src

[options.packages.find]
where = src

[options.package_data]
powerpwn = modules/gui/templates/*.html

python_requires = >=3.6,<=3.8.10

scripts = src/powerpwn/cli.py

[options.entry_points]
console_scripts =
powerpwn = powerpwn.cli:main

[mypy]
plugins = pydantic.mypy

Expand Down
4 changes: 4 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from setuptools import setup

if __name__ == "__main__":
setup()
Loading
Loading