penkit 0.0.1.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/TERMS +73 -0
- data/bin/penkit +5 -0
- data/config/wordpress.yml +33 -0
- data/lib/penkit.rb +4 -0
- data/lib/penkit/cli.rb +1 -0
- data/lib/penkit/cli/penkit.rb +96 -0
- data/lib/penkit/docker.rb +85 -0
- data/lib/penkit/docker_compose.rb +37 -0
- data/lib/penkit/version.rb +3 -0
- metadata +85 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 1f4a19d70fab6445e950cf902d1521ec8a45ccdb
|
|
4
|
+
data.tar.gz: a445066995b1e562e06f7901fc3965369017569c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d9e52c147e9abec5a100613f2c1e1d472736fefb1a585ba37b2f2c050ed69689463cc002ab59bc6705102b31465c6a78c3eeef31b5c30688b22056084811eab4
|
|
7
|
+
data.tar.gz: d7de7a08b54d0ada8b5d8c7ff06200688c2ca337a7e0da2c63b164886b57c1df0616c660ad9f84ab8b35be32f573a1133ef42037743eded6681534142e3683f3
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 penkit
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/TERMS
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
penkit Terms of Service
|
|
2
|
+
|
|
3
|
+
Terms of Service will be referred to as 'TOS.'
|
|
4
|
+
The website, software, and source code will collectively be referred to as 'penkit.'
|
|
5
|
+
|
|
6
|
+
1. Acceptance of Terms:
|
|
7
|
+
|
|
8
|
+
penkit may update the TOS at any time and without prior notice by posting a new version at http://penkit.io. The information on this site, any penkit software, and your use of it is subject to the most recent version of the TOS posted.
|
|
9
|
+
|
|
10
|
+
2. Indemnity:
|
|
11
|
+
|
|
12
|
+
You agree to indemnify and hold penkit and its subsidiaries, affiliates, officers,
|
|
13
|
+
agents, employees, partners and licensors harmless from any claim or demand including
|
|
14
|
+
but not limited to your use of of penkit, your connection to penkit, your violation of
|
|
15
|
+
the penkit TOS, or your violation of any rights of another.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
3. Modifications to penkit:
|
|
19
|
+
|
|
20
|
+
You acknowledge that penkit and its maintainers may establish general practices and
|
|
21
|
+
limits concerning use of penkit. You further acknowledge that penkit reserves the
|
|
22
|
+
right to modify these general practices and limits from time to time. penkit reserves
|
|
23
|
+
the right at any time and from time to time to modify or discontinue, temporarily or
|
|
24
|
+
permanently, the penkit service (or any part thereof) with or without notice. You
|
|
25
|
+
agree that penkit shall not be liable to you or to any third party for any
|
|
26
|
+
modification, suspension or discontinuance of penkit.
|
|
27
|
+
|
|
28
|
+
4. Termination:
|
|
29
|
+
|
|
30
|
+
You agree that penkit and its maintainers may terminate your access to penkit for
|
|
31
|
+
violations of the TOS and/or requests by authorized law enforcement or other
|
|
32
|
+
government agencies.
|
|
33
|
+
|
|
34
|
+
5. Links:
|
|
35
|
+
|
|
36
|
+
The penkit may provide, or third parties may provide, links to other World Wide Web
|
|
37
|
+
sites or resources. Because penkit has no control over such sites and resources, you
|
|
38
|
+
acknowledge and agree that penkit is not responsible for the availability of such
|
|
39
|
+
external sites or resources, and does not endorse and is not responsible or liable for
|
|
40
|
+
any Content, advertising, products or other materials on or available from such sites
|
|
41
|
+
or resources. You further acknowledge and agree that penkit shall not be responsible
|
|
42
|
+
or liable, directly or indirectly, for any damage or loss caused or alleged to be
|
|
43
|
+
caused by or in connection with use of or reliance on any such Content, goods or
|
|
44
|
+
services available on or through any such site or resource.
|
|
45
|
+
|
|
46
|
+
6. Distribution, modification, and repackaging:
|
|
47
|
+
|
|
48
|
+
You may distribute, modify, or repackage penkit in accordance with the MIT license.
|
|
49
|
+
If you choose to redistribute penkit, we would be very grateful if you credited
|
|
50
|
+
our project and spread the word.
|
|
51
|
+
|
|
52
|
+
7. Permitted and Prohibited Uses:
|
|
53
|
+
|
|
54
|
+
You may use penkit for the sole purpose of learning about computer security on
|
|
55
|
+
computers or other electronic devices you own.
|
|
56
|
+
|
|
57
|
+
You may not use penkit to test, exploit, attack or in any way interact with computers
|
|
58
|
+
or electronic devices that you do not own.
|
|
59
|
+
|
|
60
|
+
You may not use 'penkit' or any of the affiliated penkit branding without explicit permission from the maintainers.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
8. Limitation of Liability:
|
|
64
|
+
|
|
65
|
+
You expressly understand and agree that penkit and its subsidiaries, affiliates,
|
|
66
|
+
officers, employees, agents, partners and licensors shall not be liable to you for any
|
|
67
|
+
direct, indirect, incidental, special, consequential or exemplary damages, including,
|
|
68
|
+
but not limited to, damages for loss of profits, goodwill, use, data or other
|
|
69
|
+
intangible losses (even if penkit has been advised of the possibility of such
|
|
70
|
+
damages), resulting from the use or the inability to use the penkit service.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
By visiting our site or using our product, you agree to the TOS. Any violation of the terms listed above prohibits you from using penkit.
|
data/bin/penkit
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
version: "2.0"
|
|
2
|
+
services:
|
|
3
|
+
wordpress:
|
|
4
|
+
image: ${DOCKER_IMAGE}
|
|
5
|
+
container_name: ${DOCKER_NAME}
|
|
6
|
+
depends_on:
|
|
7
|
+
- mysql
|
|
8
|
+
environment:
|
|
9
|
+
WP_DB_HOST: ${DOCKER_NAME}_mysql
|
|
10
|
+
WP_DB_PORT: 3306
|
|
11
|
+
WP_DB_USER: wpuser
|
|
12
|
+
WP_DB_PASS: password
|
|
13
|
+
WP_DB_NAME: wpdb
|
|
14
|
+
labels:
|
|
15
|
+
penkit: "true"
|
|
16
|
+
networks:
|
|
17
|
+
penkit:
|
|
18
|
+
|
|
19
|
+
mysql:
|
|
20
|
+
image: penkit/mysql:latest
|
|
21
|
+
container_name: ${DOCKER_NAME}_mysql
|
|
22
|
+
environment:
|
|
23
|
+
MYSQL_USER: wpuser
|
|
24
|
+
MYSQL_PASSWORD: password
|
|
25
|
+
MYSQL_DATABASE: wpdb
|
|
26
|
+
labels:
|
|
27
|
+
penkit: "true"
|
|
28
|
+
networks:
|
|
29
|
+
penkit:
|
|
30
|
+
|
|
31
|
+
networks:
|
|
32
|
+
penkit:
|
|
33
|
+
external: true
|
data/lib/penkit.rb
ADDED
data/lib/penkit/cli.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "penkit/cli/penkit"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require "thor"
|
|
2
|
+
|
|
3
|
+
module Penkit
|
|
4
|
+
class CLI < Thor
|
|
5
|
+
desc "ps", "List penkit docker containers"
|
|
6
|
+
def ps
|
|
7
|
+
docker.ps
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
desc "rm [CONTAINER...]", "Remove penkit docker containers"
|
|
11
|
+
def rm(*containers)
|
|
12
|
+
if containers.any?
|
|
13
|
+
docker.rm(*containers)
|
|
14
|
+
else
|
|
15
|
+
rm_all
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "start [OPTIONS] IMAGE", "Start a penkit docker image"
|
|
20
|
+
option :name, desc: "Override name and hostname of container"
|
|
21
|
+
def start(image)
|
|
22
|
+
if docker_compose.has_config?(image)
|
|
23
|
+
opts = options.dup
|
|
24
|
+
opts[:name] ||= docker.unique_name(image)
|
|
25
|
+
docker_compose.up(image, opts)
|
|
26
|
+
else
|
|
27
|
+
docker.start(image, options.dup)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc "stop [CONTAINER...]", "Stop penkit docker containers"
|
|
32
|
+
def stop(*containers)
|
|
33
|
+
if containers.any?
|
|
34
|
+
docker.stop(*containers)
|
|
35
|
+
else
|
|
36
|
+
stop_all
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Tools
|
|
41
|
+
|
|
42
|
+
desc "curl [ARGS...]", "Run curl on the penkit docker network"
|
|
43
|
+
def curl(*args)
|
|
44
|
+
docker.run("cli:curl", *args)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
desc "metasploit [ARGS...]", "Run metasploit on the penkit docker network"
|
|
48
|
+
def metasploit(*args)
|
|
49
|
+
docker.run("cli:metasploit", *args)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
desc "sqlmap [ARGS...]", "Run sqlmap on the penkit docker network"
|
|
53
|
+
def sqlmap(*args)
|
|
54
|
+
docker.run("cli:sqlmap", *args)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc "wpscan [ARGS...]", "Run wpscan on the penkit docker network"
|
|
58
|
+
def wpscan(*args)
|
|
59
|
+
docker.run("cli:wpscan", *args)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def docker
|
|
65
|
+
@docker ||= Penkit::Docker.new
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def docker_compose
|
|
69
|
+
@docker_compose ||= Penkit::DockerCompose.new
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def stop_all
|
|
73
|
+
containers = docker.find_running_containers
|
|
74
|
+
docker.stop(*containers) if stop_all?(containers)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def stop_all?(containers)
|
|
78
|
+
return false if containers.size == 0
|
|
79
|
+
message = "Are you sure you want to stop %d %s? [y/N]"
|
|
80
|
+
word = containers.size > 1 ? "containers" : "container"
|
|
81
|
+
ask(message % [containers.size, word]) == "y"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def rm_all
|
|
85
|
+
containers = docker.find_all_containers
|
|
86
|
+
docker.rm(*containers) if rm_all?(containers)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def rm_all?(containers)
|
|
90
|
+
return false if containers.size == 0
|
|
91
|
+
message = "Are you sure you want to remove %d %s? [y/N]"
|
|
92
|
+
word = containers.size > 1 ? "containers" : "container"
|
|
93
|
+
ask(message % [containers.size, word]) == "y"
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Penkit
|
|
2
|
+
class Docker
|
|
3
|
+
IMAGE_REGEX = /^([^\s\/:]+)(:[^\s\/:]+)?$/
|
|
4
|
+
NETWORK = "penkit".freeze
|
|
5
|
+
REPOSITORY = "penkit".freeze
|
|
6
|
+
|
|
7
|
+
def create_network!
|
|
8
|
+
system("docker", "network", "create", *network_options, out: File::NULL) unless network_exists?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def find_all_containers
|
|
12
|
+
IO.popen(["docker", "ps", "-aq", *filter_options]).readlines.map(&:strip)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def find_running_containers
|
|
16
|
+
IO.popen(["docker", "ps", "-q", *filter_options]).readlines.map(&:strip)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def image_name(image)
|
|
20
|
+
image[IMAGE_REGEX, 1]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def image_url(image)
|
|
24
|
+
"#{REPOSITORY}/#{image}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ps
|
|
28
|
+
exec("docker", "ps", *filter_options)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def rm(*containers)
|
|
32
|
+
exec("docker", "rm", "--force", *containers)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def run(image, *args)
|
|
36
|
+
create_network!
|
|
37
|
+
exec("docker", "run", "--rm", "-it", *run_options, image_url(image), *args)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def start(image, options={})
|
|
41
|
+
create_network!
|
|
42
|
+
options[:name] ||= unique_name(image)
|
|
43
|
+
puts "Starting container #{options[:name]}"
|
|
44
|
+
exec("docker", "run", "--detach", *run_options(options), image_url(image))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def stop(*containers)
|
|
48
|
+
exec("docker", "stop", *containers)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def unique_name(name)
|
|
52
|
+
name = image_name(name)
|
|
53
|
+
name_list = find_container_names
|
|
54
|
+
100.times do |i|
|
|
55
|
+
return name unless name_list.include? name
|
|
56
|
+
name = [name[/^(.*\D)\d*$/, 1], i + 1].join
|
|
57
|
+
end
|
|
58
|
+
name
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def find_container_names
|
|
64
|
+
IO.popen(["docker", "ps", "-a", "--format", "{{.Names}}", *filter_options]).readlines.map(&:strip)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def network_exists?
|
|
68
|
+
system("docker", "network", "inspect", NETWORK, out: File::NULL, err: File::NULL)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def network_options
|
|
72
|
+
%w(--driver bridge) << NETWORK
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def filter_options
|
|
76
|
+
%w(--filter label=penkit)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def run_options(options={})
|
|
80
|
+
args = %w(--label penkit=true --network penkit)
|
|
81
|
+
args += ["--name", options[:name], "--hostname", options[:name]] if options[:name]
|
|
82
|
+
args
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Penkit
|
|
2
|
+
class DockerCompose
|
|
3
|
+
def has_config?(image)
|
|
4
|
+
File.exist?(config_file(image))
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def up(image, options = {})
|
|
8
|
+
docker.create_network!
|
|
9
|
+
env = compose_env(image, options)
|
|
10
|
+
|
|
11
|
+
# TODO: find out why exec bombs here (see Penkit::Docker#find_all_containers)
|
|
12
|
+
system(env, "docker-compose", *compose_options(image, options), "up", "-d")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def compose_env(image, options={})
|
|
18
|
+
{
|
|
19
|
+
"DOCKER_IMAGE" => docker.image_url(image),
|
|
20
|
+
"DOCKER_NAME" => options[:name]
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def compose_options(image, options={})
|
|
25
|
+
["-f", config_file(image), "-p", options[:name]]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def config_file(image)
|
|
29
|
+
root = File.expand_path("../../..", __FILE__)
|
|
30
|
+
File.join(root, "config", "#{docker.image_name(image)}.yml")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def docker
|
|
34
|
+
@docker ||= Penkit::Docker.new
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: penkit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1.rc2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Don Humphreys
|
|
8
|
+
- Sam Lachance
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2017-03-12 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: thor
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - "~>"
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: 0.19.4
|
|
21
|
+
type: :runtime
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - "~>"
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: 0.19.4
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: rspec
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - "~>"
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '3.5'
|
|
35
|
+
type: :development
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - "~>"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '3.5'
|
|
42
|
+
description: Command-line interface for managing Penkit containers
|
|
43
|
+
email:
|
|
44
|
+
- don@penkit.io
|
|
45
|
+
- sam@penkit.io
|
|
46
|
+
executables:
|
|
47
|
+
- penkit
|
|
48
|
+
extensions: []
|
|
49
|
+
extra_rdoc_files: []
|
|
50
|
+
files:
|
|
51
|
+
- LICENSE
|
|
52
|
+
- TERMS
|
|
53
|
+
- bin/penkit
|
|
54
|
+
- config/wordpress.yml
|
|
55
|
+
- lib/penkit.rb
|
|
56
|
+
- lib/penkit/cli.rb
|
|
57
|
+
- lib/penkit/cli/penkit.rb
|
|
58
|
+
- lib/penkit/docker.rb
|
|
59
|
+
- lib/penkit/docker_compose.rb
|
|
60
|
+
- lib/penkit/version.rb
|
|
61
|
+
homepage: http://penkit.io
|
|
62
|
+
licenses:
|
|
63
|
+
- MIT
|
|
64
|
+
metadata: {}
|
|
65
|
+
post_install_message:
|
|
66
|
+
rdoc_options: []
|
|
67
|
+
require_paths:
|
|
68
|
+
- lib
|
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">"
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: 1.3.1
|
|
79
|
+
requirements: []
|
|
80
|
+
rubyforge_project:
|
|
81
|
+
rubygems_version: 2.5.2
|
|
82
|
+
signing_key:
|
|
83
|
+
specification_version: 4
|
|
84
|
+
summary: Penkit CLI
|
|
85
|
+
test_files: []
|