/
docker_helpers.py
164 lines (129 loc) · 4.57 KB
/
docker_helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import subprocess
import json
import time
import sys
import os
ROOT_PATH = os.path.dirname(os.path.realpath(__file__))
DOCKER_RUN = ('docker run'
' -d'
' -v ~/.w3af:/root/.w3af'
' -v ~/w3af-shared:/root/w3af-shared'
' -p 44444:44444'
' andresriancho/w3af')
def start_container(tag, command=DOCKER_RUN):
"""
Start a new w3af container so we can connect using SSH and run w3af
:return: The container id we just started
"""
if tag is not None:
docker_run = command + ':%s' % tag
else:
docker_run = command + ':latest'
try:
container_id = subprocess.check_output(docker_run, shell=True)
except subprocess.CalledProcessError, cpe:
print('w3af container failed to start: "%s"' % cpe)
sys.exit(1)
else:
# Let the container start the ssh daemon
time.sleep(1)
return container_id.strip()
def stop_container(container_id):
"""
Stop a running w3af container
"""
try:
subprocess.check_output('docker stop %s' % container_id, shell=True)
except subprocess.CalledProcessError, cpe:
print('w3af container failed to stop: "%s"' % cpe)
sys.exit(1)
def create_volumes():
"""
Create the directories if they don't exist
"""
w3af_home = os.path.expanduser('~/.w3af')
w3af_shared = os.path.expanduser('~/w3af-shared')
if not os.path.exists(w3af_home):
os.mkdir(w3af_home)
if not os.path.exists(w3af_shared):
os.mkdir(w3af_shared)
def connect_to_container(container_id, cmd, extra_ssh_flags=()):
"""
Connect to a running container, start one if not running.
"""
try:
cont_data = subprocess.check_output('docker inspect %s' % container_id,
shell=True)
except subprocess.CalledProcessError:
print('Failed to inspect container with id %s' % container_id)
sys.exit(1)
try:
ip_address = json.loads(cont_data)[0]['NetworkSettings']['IPAddress']
except ValueError:
print('Invalid JSON output from inspect command')
sys.exit(1)
ssh_key = os.path.join(ROOT_PATH, 'w3af-docker.prv')
# git can't store this
# https://stackoverflow.com/questions/11230171
os.chmod(ssh_key, 600)
# Create the SSH connection command
ssh_cmd = ['ssh', '-i', ssh_key, '-t', '-t', '-oStrictHostKeyChecking=no',
'-o UserKnownHostsFile=/dev/null',
'-o LogLevel=quiet']
# Add the extra ssh flags
for extra_ssh_flag in extra_ssh_flags:
ssh_cmd.append(extra_ssh_flag)
ssh_cmd.append('root@' + ip_address)
ssh_cmd.append(cmd)
try:
subprocess.call(ssh_cmd)
finally:
# revert previous chmod to avoid annoying git change
os.chmod(ssh_key, 436)
def check_root():
# if not root...kick out
if not os.geteuid() == 0:
sys.exit('Only root can run this script')
def restore_file_ownership():
"""
There are some issues with "sudo w3af_api_docker" (and any other *_docker)
where we write to the ~/.w3af/ file but we're doing it as root, and then
the user wants to execute ./w3af_api and this message appears:
Either the w3af home directory "/home/user/.w3af" or its contents are not
writable or readable. Please set the correct permissions and ownership.
This usually happens when running w3af as root using "sudo"
So we restore the file ownership of all files inside ~/.w3af/ before exit
:return: True if we were able to apply the changes
"""
path = os.path.join(os.path.expanduser('~/'), '.w3af')
if not os.path.exists(path):
return False
try:
# These two are set by sudo, which is the most common way our users
# will run w3af inside docker: sudo w3af_console_docker
uid = int(os.getenv('SUDO_UID'))
gid = int(os.getenv('SUDO_GID'))
except ValueError:
# TODO: More things to be implemented here
return False
try:
_chown(path, uid, gid)
except:
return False
return True
def _chown(path, uid, gid):
"""
Change permissions recursively
:param path: The path to apply changes to
:param uid: User id
:param gid: Group id
:return: None
"""
os.chown(path, uid, gid)
for item in os.listdir(path):
item_path = os.path.join(path, item)
if os.path.isfile(item_path):
os.chown(item_path, uid, gid)
elif os.path.isdir(item_path):
os.chown(item_path, uid, gid)
_chown(item_path, uid, gid)