{"id":13845770,"url":"https://github.com/sensepost/dwn","last_synced_at":"2025-04-13T09:51:09.928Z","repository":{"id":49960540,"uuid":"314914778","full_name":"sensepost/dwn","owner":"sensepost","description":"d(ockerp)wn - a docker pwn tool manager","archived":false,"fork":false,"pushed_at":"2021-06-08T16:38:47.000Z","size":161,"stargazers_count":155,"open_issues_count":6,"forks_count":22,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-27T01:12:21.219Z","etag":null,"topics":["docker","framework","manager","pentest","tool"],"latest_commit_sha":null,"homepage":"https://sensepost.com/blog/2021/dwn-a-docker-pwn-tool-manager-experiment/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sensepost.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-21T22:26:45.000Z","updated_at":"2024-10-22T13:22:35.000Z","dependencies_parsed_at":"2022-09-07T01:11:14.183Z","dependency_job_id":null,"html_url":"https://github.com/sensepost/dwn","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sensepost%2Fdwn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sensepost%2Fdwn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sensepost%2Fdwn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sensepost%2Fdwn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sensepost","download_url":"https://codeload.github.com/sensepost/dwn/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248695300,"owners_count":21146952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","framework","manager","pentest","tool"],"created_at":"2024-08-04T17:03:35.647Z","updated_at":"2025-04-13T09:51:09.909Z","avatar_url":"https://github.com/sensepost.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cbr\u003e\n    🥽 dwn\n  \u003cbr\u003e\n  \u003cbr\u003e\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003ed(ockerp)wn - a docker attack tool manager\u003c/h4\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://twitter.com/leonjza\"\u003e\u003cimg src=\"https://img.shields.io/badge/twitter-%40leonjza-blue.svg\" alt=\"@leonjza\" height=\"18\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.python.org/pypi/dwn\"\u003e\u003cimg src=\"https://badge.fury.io/py/dwn.svg\" alt=\"PyPI version\" height=\"18\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cbr\u003e\n\n## introduction\n\n`dwn` is a \"docker-compose for hackers\". Using a simple YAML \"plan\" format similar to `docker-compose`, image names, versions and volume / port mappings are defined to setup a tool for use.\n\n## features\n\nWith `dwn` you can:\n\n- Configure common pentest tools for use in a docker container\n- Have context aware volume mounts\n- Dynamically modify port bindings without container restarts\n- And more!\n\n## installation\n\nSimply run `pip3 install dwn`.\n\n## usage\n\n`dwn` is actually really simple. The primary concept is that of \"plans\" where information about a tool (such as name, version, mounts and binds) are defined. There are a few [built-in plans](plans/) already available, but you can also roll your own. Without arguments, just running `dwn` would look like this.\n\n```text\n❯ dwn\nUsage: dwn [OPTIONS] COMMAND [ARGS]...\n\n       __\n   ___/ /    _____\n  / _  / |/|/ / _ \\\n  \\_,_/|__,__/_//_/\n    docker pwn tool manager\n    by @leonjza / @sensepost\n\nOptions:\n  --debug  enable debug logging\n  --help   Show this message and exit.\n\nCommands:\n  check    Check plans and Docker environment\n  network  Work with networks\n  plans    Work with plans\n  run      Run a plan\n  show     Show running plans\n  stop     Stop a plan\n```\n\nTo list the available plans, run `dwn plans show`.\n\n```text\n❯ dwn plans show\n                                    dwn plans\n┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n┃ name             ┃ path                                  ┃\n┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n│ sqlmap           │ /tools/dwn/plans/sqlmap.yml           │\n│ wpscan           │ /tools/dwn/plans/wpscan.yml           │\n│ gowitness-report │ /tools/dwn/plans/gowitness-report.yml │\n│ msfconsole       │ /tools/dwn/plans/msfconsole.yml       │\n│ gowitness        │ /tools/dwn/plans/gowitness.yml        │\n│ nginx            │ /tools/dwn/plans/nginx.yml            │\n│ cme              │ /tools/dwn/plans/cme.yml              │\n│ netcat-reverse   │ /tools/dwn/plans/netcat-reverse.yml   │\n│ semgrep-sec      │ /tools/dwn/plans/semgrep-sec.yml      │\n│ semgrep-ci       │ ~/.dwn/plans/semgrep-ci.yml           │\n│ neo4j            │ ~/.dwn/plans/neo4j.yml                │\n└──────────────────┴───────────────────────────────────────┘\n                                     11 plans\n```\n\nTo run a plan such as `gowitness` screenshotting \u003chttps://google.com\u003e, run `dwn run gowitness --disable-db single https://www.google.com`. This plan will exit when done, so you don’t have to `dwn stop gowitness`.\n\n```text\n❯ dwn run gowitness --disable-db single https://www.google.com\n(i) found plan for gowitness\n(i) volume: ~/scratch -\u003e /data\n(i) streaming container logs\n08 Feb 2021 10:46:18 INF preflight result statuscode=200 title=Google url=https://www.google.com\n❯\n❯ ls screenshots\nhttps-www.google.com.png\n```\n\nA plan such as `netcat-reverse` however will stay alive. You can connect to the plans TTY after it is started to interact with any shells you may receive. Example usage would be:\n\n```text\n❯ dwn run netcat-reverse\n(i) found plan for netcat-reverse\n(i) port: 4444\u003c-4444\n(i) container booted! attach \u0026 detach commands are:\n(i) attach: docker attach dwn_wghz_netcat-reverse\n(i) detach: ctrl + p, ctrl + q\n```\n\nAttaching to the plan (and executing `nc -e` somewhere else)\n\n```text\n❯ docker attach dwn_wghz_netcat-reverse\nconnect to [::ffff:172.19.0.2]:4444 from dwn_wghz_netcat-reverse_net_4444_4444.dwn:46318 ([::ffff:172.19.0.3]:46318)\n\nenv | grep -i shell\nSHELL=/bin/zsh\n\nread escape sequence\n```\n\nYou can get a running plan report too\n\n```text\n❯ dwn show\n                                running plan report\n┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┓\n┃ plan           ┃ container(s)                          ┃ port(s)    ┃ volume(s) ┃\n┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━┩\n│ netcat-reverse │ dwn_wghz_netcat-reverse_net_4444_4444 │ 4444\u003c-4444 │           │\n│                │ dwn_wghz_netcat-reverse               │            │           │\n└────────────────┴───────────────────────────────────────┴────────────┴───────────┘\n```\n\nAnd finally, stop a plan.\n\n```text\n❯ dwn stop netcat-reverse -y\n(i) stopping 2 containers for plan netcat-reverse\n```\n\n## networking\n\n`dwn` lets you dynamically map ports to plans without any container restarts. Networking commands live under the `dwn network` subcommand. Taking the [nginx](plans/nginx.yml) plan as an example, we can add a port mapping dynamically. First, start the `nginx` plan.\n\n```text\n❯ dwn run nginx\n(i) found plan for nginx\n(i) volume: ~/scratch -\u003e /usr/share/nginx/html\n(i) port: 80\u003c-8888\n(i) container dwn_wghz_nginx started for plan nginx, detaching\n```\n\nNext, test the communication with cURL\n\n```text\n❯ curl localhost:8888/poo.txt\nhaha, you touched it!\n\n❯ curl localhost:9000/poo.txt\ncurl: (7) Failed to connect to localhost port 9000: Connection refused\n```\n\nPort 9000 is not open, so let's add a new port binding and test connectivity\n\n```text\n❯ dwn network add nginx -i 80 -o 9000\n(i) port binding for 9000-\u003enginx:80 created\n❯\n❯ curl localhost:9000/poo.txt\nhaha, you touched it!\n```\n\n## updating plans\n\nThe `dwn plans pull` command can be used to update the `images` defined in plans. To only update a single plan, add the plan name after `pull`. Eg: `dwn plans pull nginx`.\n\n## writing plans\n\nA `dwn plans new` command exists to quickly scaffold a new plan. While only a few options are needed to get a plan up and running, all of the options that exist in the Python Docker SDK for the [run](https://docker-py.readthedocs.io/en/stable/containers.html#docker.models.containers.ContainerCollection.run) call are valid tags that can be used.\n\n## license\n\n`dwn` is licensed under a [GNU General Public v3 License](https://www.gnu.org/licenses/gpl-3.0.en.html). Permissions beyond the scope of this license may be available at \u003chttp://sensepost.com/contact/\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsensepost%2Fdwn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsensepost%2Fdwn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsensepost%2Fdwn/lists"}