pyntcli 0.1.110__py3-none-any.whl → 0.1.112__py3-none-any.whl

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.
pyntcli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.110"
1
+ __version__ = "0.1.112"
pyntcli/auth/login.py CHANGED
@@ -46,15 +46,15 @@ class Login():
46
46
  def create_login_request(self):
47
47
  request_id = uuid.uuid4()
48
48
  request_url = self.base_authorization_url + \
49
- urllib.parse.urlencode(
50
- {"request_id": request_id, "utm_source": "cli"})
49
+ urllib.parse.urlencode(
50
+ {"request_id": request_id, "utm_source": "cli"})
51
51
  webbrowser.open(request_url)
52
52
 
53
53
  ui_thread.print(ui_thread.PrinterText("To continue, you need to log in to your account.")
54
- .with_line("You will now be redirected to the login page.")
55
- .with_line("")
56
- .with_line("If you are not automatically redirected, please click on the link provided below (or copy to your web browser)")
57
- .with_line(request_url))
54
+ .with_line("You will now be redirected to the login page.")
55
+ .with_line("")
56
+ .with_line("If you are not automatically redirected, please click on the link provided below (or copy to your web browser)")
57
+ .with_line(request_url))
58
58
  return request_id
59
59
 
60
60
  def get_token_using_request_id(self, request_id):
@@ -62,7 +62,7 @@ class Login():
62
62
  start = time.time()
63
63
  while start + self.login_wait_period > time.time():
64
64
  response = pynt_requests.get(self.poll_url, params={
65
- "request_id": request_id})
65
+ "request_id": request_id})
66
66
  if response.status_code == 200:
67
67
  return response.json()
68
68
  time.sleep(self.delay)
@@ -85,6 +85,7 @@ def refresh_token():
85
85
  token = store.get("token")
86
86
 
87
87
  if not token:
88
+ ui_thread.print_verbose("Token not found, logging in")
88
89
  Login().login()
89
90
 
90
91
  access_token = token.get("access_token")
@@ -93,11 +94,13 @@ def refresh_token():
93
94
 
94
95
  refresh = token.get("refresh_token", None)
95
96
  if not refresh:
97
+ ui_thread.print_verbose("Refresh token not found, logging in")
96
98
  Login().login()
97
99
  return
98
100
 
99
101
  refresh_response = refresh_request(refresh)
100
102
  if refresh_response.status_code != 200:
103
+ ui_thread.print_verbose("Failed to refresh token, logging in")
101
104
  Login().login()
102
105
  return
103
106
 
@@ -172,9 +175,11 @@ def should_login():
172
175
  token = store.get("token")
173
176
 
174
177
  if not token or token == store.connector.default_value:
178
+ ui_thread.print_verbose("Token is default or not found")
175
179
  return True
176
180
 
177
181
  if not token.get("refresh_token"):
182
+ ui_thread.print_verbose("Refresh token not found")
178
183
  return True
179
184
 
180
185
  return False
pyntcli/commands/burp.py CHANGED
@@ -51,9 +51,11 @@ def decode_request(item) -> str:
51
51
  return base64.b64decode(item["request"]["#text"]).decode(encoding)
52
52
  except UnicodeDecodeError as e:
53
53
  error = e
54
+ ui_thread.print_verbose(f"Error decoding request: {e}, skipping...")
54
55
  continue
55
56
  except Exception as e:
56
57
  error = e
58
+ ui_thread.print_verbose(f"Error decoding request: {e}, breaking...")
57
59
  break
58
60
 
59
61
  ui_thread.print(
@@ -94,6 +96,8 @@ def replay_req(item, proxy_port):
94
96
  headers[key] = value
95
97
 
96
98
  body = decoded_req.split("\r\n\r\n")[1]
99
+ if body:
100
+ body = body.encode("utf-8")
97
101
  resp = pynt_requests.request_from_xml(
98
102
  method=method,
99
103
  url=url,
@@ -147,6 +151,7 @@ def burp_usage():
147
151
  .with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
148
152
  .with_line("\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
149
153
  .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
154
+ .with_line("\t--tag - Tag the scan. Repeat for multiple tags")
150
155
  .with_line("\t--verbose - Use to get more detailed information about the run")
151
156
  )
152
157
 
@@ -40,6 +40,7 @@ def command_usage():
40
40
  .with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
41
41
  .with_line("\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
42
42
  .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
43
+ .with_line("\t--tag - Tag the scan. Repeat for multiple tags")
43
44
  .with_line("\t--verbose - Use to get more detailed information about the run")
44
45
  )
45
46
 
pyntcli/commands/har.py CHANGED
@@ -29,6 +29,7 @@ def har_usage():
29
29
  "\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN."
30
30
  )
31
31
  .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
32
+ .with_line("\t--tag - Tag the scan. Repeat for multiple tags")
32
33
  .with_line("\t--verbose - Use to get more detailed information about the run")
33
34
  .with_line("")
34
35
  )
@@ -34,6 +34,7 @@ def listen_usage():
34
34
  .with_line("\t--insecure - use when target uses self signed certificates")
35
35
  .with_line("\t--host-ca - path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
36
36
  .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
37
+ .with_line("\t--tag - Tag the scan. Repeat for multiple tags")
37
38
  .with_line("\t--verbose - Use to get more detailed information about the run")
38
39
  )
39
40
 
@@ -29,6 +29,7 @@ def newman_usage():
29
29
  "\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io"
30
30
  )
31
31
  .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
32
+ .with_line("\t--tag - Tag the scan. Repeat for multiple tags")
32
33
  .with_line("\t--verbose - Use to get more detailed information about the run")
33
34
  )
34
35
 
@@ -36,6 +36,7 @@ def postman_usage():
36
36
  .with_line("\t--port - set the port pynt will listen to (DEFAULT: 5001)") \
37
37
  .with_line("\t--insecure - use when target uses self signed certificates") \
38
38
  .with_line("\t--host-ca - path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.") \
39
+ .with_line("\t--tag - Tag the scan. Repeat for multiple tags") \
39
40
  .with_line("\t--verbose - Use to get more detailed information about the run")
40
41
 
41
42
 
pyntcli/commands/root.py CHANGED
@@ -96,6 +96,14 @@ class BaseCommand:
96
96
  type=str,
97
97
  help=argparse.SUPPRESS,
98
98
  )
99
+ parser.add_argument(
100
+ "--tag",
101
+ default=[],
102
+ required=False,
103
+ nargs="+",
104
+ action="append",
105
+ help=argparse.SUPPRESS,
106
+ )
99
107
 
100
108
  def get_subparser(self) -> argparse._SubParsersAction:
101
109
  if self.subparser is None:
@@ -107,6 +115,7 @@ class BaseCommand:
107
115
  analytics.emit(analytics.LOGIN_START)
108
116
 
109
117
  if login.should_login():
118
+ ui_thread.print_verbose("User should login")
110
119
  l = login.Login().login()
111
120
  else:
112
121
  login.refresh_token()
@@ -26,6 +26,7 @@ def template_usage():
26
26
  .with_line("\t--urls - Path to the file containing the base URLs (with new line separator) for the attacks")
27
27
  .with_line("\t--reporters - Output results to json")
28
28
  .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default)")
29
+ .with_line("\t--tag - Tag the scan. Repeat for multiple tags")
29
30
  .with_line("\t--verbose - Use to get more detailed information about the run")
30
31
  .with_line("")
31
32
  )
@@ -1,4 +1,5 @@
1
1
  import platform
2
+ import shutil
2
3
  import subprocess
3
4
  import os
4
5
  import json
@@ -166,6 +167,10 @@ def build_docker_args(integration_name: str, args: argparse.Namespace, port_args
166
167
  if "verbose" in args and args.verbose:
167
168
  docker_arguments.append("--verbose")
168
169
 
170
+ if "tag" in args and args.tag:
171
+ for tag in args.tag:
172
+ docker_arguments += ["--tag", tag[0]]
173
+
169
174
  for port_arg in port_args:
170
175
  docker_arguments += [port_arg.name, str(port_arg.port)]
171
176
 
@@ -216,7 +221,8 @@ class PyntContainerNative:
216
221
 
217
222
  self.fetch_and_validate_image()
218
223
  args = self.config.docker_arguments if self.config.docker_arguments else None
219
- docker_command = ["docker", "run", "--rm", "-d", "--name", self.container_name]
224
+ docker_exec = shutil.which("docker")
225
+ docker_command = [docker_exec, "run", "--rm", "-d", "--name", self.container_name]
220
226
 
221
227
  mounts = []
222
228
  for mount in self.config.mounts:
@@ -224,7 +230,7 @@ class PyntContainerNative:
224
230
 
225
231
  env_vars = []
226
232
  for key, value in self.config.env_vars.items():
227
- env_vars.extend(self.adapt_environment_variable_partial(key, value))
233
+ env_vars.extend(["-e", f"{key}={value}"])
228
234
 
229
235
  if is_network_host():
230
236
  ports_exposure = ["--network=host"]
@@ -239,13 +245,11 @@ class PyntContainerNative:
239
245
  docker_command += [f"{self.config.image.name}"]
240
246
  docker_command += args
241
247
 
242
- command = self.adapt_run_command(docker_command)
243
-
244
248
  ui_thread.print_verbose(f"Running command (contains sensitive user secrets, do not paste outside this machine!):\n"
245
- f"#########################\n {' '.join(command)}\n#########################\n")
249
+ f"#########################\n {' '.join(docker_command)}\n#########################\n")
246
250
 
247
251
  PyntContainerRegistry.instance().register_container(self)
248
- process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
252
+ process = subprocess.Popen(docker_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
249
253
  stdout, stderr = process.communicate()
250
254
 
251
255
  if stderr:
@@ -339,16 +343,6 @@ class PyntContainerNative:
339
343
  self.kill_other_instances(report_to_user=False)
340
344
  self.running = False
341
345
 
342
- def adapt_run_command(self, docker_command=[]):
343
- if self.system == "windows":
344
- return ' '.join(docker_command)
345
- return docker_command
346
-
347
- def adapt_environment_variable_partial(self, key, value):
348
- if self.system == "windows":
349
- return ["-e", f"{key}={json.dumps(value)}"]
350
- return ["-e", f"{key}={value}"]
351
-
352
346
  def pre_run_validation(self, port):
353
347
  self.kill_other_instances()
354
348
 
@@ -5,6 +5,8 @@ import pem
5
5
  import certifi
6
6
  import tempfile
7
7
 
8
+ from pyntcli.ui import ui_thread
9
+
8
10
 
9
11
  class HostCaException(Exception):
10
12
  pass
@@ -71,3 +73,6 @@ def request_from_xml(method, url, proxies=None, data=None, **kwargs):
71
73
  return url
72
74
  except requests.exceptions.TooManyRedirects as e:
73
75
  return "Too many redirects for {}".format(url)
76
+ except Exception as e:
77
+ ui_thread.print_verbose(f"Failed to send request to {url} - {e}")
78
+ raise e
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pyntcli
3
- Version: 0.1.110
3
+ Version: 0.1.112
4
4
  Summary: Command line utility to handle all of Pynt's different integrations
5
5
  Author-email: Pynt-io <support@pynt.io>
6
6
  Project-URL: Homepage, https://pynt.io
@@ -12,4 +12,3 @@ Requires-Dist: certifi>=2017.4.17
12
12
  Requires-Dist: websocket-client
13
13
  Requires-Dist: xmltodict
14
14
  Requires-Dist: timedinput==0.1.1
15
-
@@ -1,37 +1,37 @@
1
1
  ignoreTests/conftest.py,sha256=gToq5K74GtgeGQXjFvXSzMaE6axBYxAzcFG5XJPOXjI,427
2
2
  ignoreTests/auth/login.py,sha256=KFlzWhXBAuwdi7GXf16gCB3ya94LQG2wjcSChE149rQ,3798
3
3
  ignoreTests/store/cred_store.py,sha256=_7-917EtNC9eKEumO2_lt-7KuDmCwOZFaowCm7DbA_A,254
4
- pyntcli/__init__.py,sha256=IdGt47yTByl81nIAWmL37jegJ46MzryO0ztrSBIalyA,24
4
+ pyntcli/__init__.py,sha256=NcX8fgfLWWXa9SmAPHplHcOIvbX0m3-mYipZHIVAlvg,24
5
5
  pyntcli/main.py,sha256=RD0W2_0ogYBCXubo-YewxHYkiIXxNv6NkZOh3n1VujE,5964
6
6
  pyntcli/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  pyntcli/analytics/send.py,sha256=0hJ0WJNFHLqyohtRr_xOg5WEXzxHrUOlcePPg-k65Hk,3846
8
8
  pyntcli/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- pyntcli/auth/login.py,sha256=TljsRXbEkNI1YUrKm5mlTw4YiecYScYUsit8Z8vstss,5228
9
+ pyntcli/auth/login.py,sha256=dnjDT4_3RLzOT3zknUic3iRYHS8D6y00xWwNoaxOL2U,5524
10
10
  pyntcli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- pyntcli/commands/burp.py,sha256=sR5D2vlOXj9Qae3c1-VWfIXMouXoEv2Ik3O-C-Wqqkc,13891
12
- pyntcli/commands/command.py,sha256=mMf1_bU7IFbE54FN3S3FuPODjHSSSu8aHzHJX-MgEFA,10832
13
- pyntcli/commands/har.py,sha256=v6yWTuxPpXLlEi3yJ7gUDhFFGJZSpNQ3ehl2oaZJ-wc,4202
11
+ pyntcli/commands/burp.py,sha256=AUJU2cIJ-PSUATxYoHRwDy0K5feqCs-mGdkGle2WcDw,14173
12
+ pyntcli/commands/command.py,sha256=3egvDDr68sTUnyJpUE0bO9TfVy_rgeuM2C4zkMA-9GQ,10903
13
+ pyntcli/commands/har.py,sha256=FKWgTOWwvYFJGazeuttsTJTFjP6g_PUJxzzNoDl8v28,4273
14
14
  pyntcli/commands/id_command.py,sha256=UBEgMIpm4vauTCsKyixltiGUolNg_OfHEJvJ_i5BpJY,943
15
- pyntcli/commands/listen.py,sha256=bsO7c3cHmZyxUTXspCcq_O9BR8tI2qYqOpHtJDb8hZY,8827
16
- pyntcli/commands/newman.py,sha256=68P1bCjSSjTWrzOwKN_-fGQC4j484KlVpMbezMJOCMo,5045
17
- pyntcli/commands/postman.py,sha256=ExfvG0iLRmK_rHcqIj8itcd3mh2-BdPuQEDm8viLP6Q,4891
15
+ pyntcli/commands/listen.py,sha256=18D9OdW1EakkK1u54hiOjwAuT5J6nsYb2vqlP1nw8p4,8898
16
+ pyntcli/commands/newman.py,sha256=ssMXY7VvYdMCXS38uLftF7uQ4HmDMYYHra4GvZhcR-g,5116
17
+ pyntcli/commands/postman.py,sha256=kN1PkzPpcUnsbirg17AN9JwJZu6VBt6OeKYrLGrvtFc,4964
18
18
  pyntcli/commands/pynt_cmd.py,sha256=AeXxKy8dtZTdwWhTirHVvkPkeFUSoZNb3FRyuwkL6kg,7103
19
- pyntcli/commands/root.py,sha256=UtGky7LfbfQ6mELHoNJcdHznFrUVBlhXI47_8QdApfc,4068
19
+ pyntcli/commands/root.py,sha256=Lr31nsx2sgM-o3OYEbfqakaxzXHY6irr9uj-X6QWiqk,4325
20
20
  pyntcli/commands/static_file_extensions.py,sha256=PZJb02BI-64tbU-j3rdCNsXzTh7gkIDGxGKbKNw3h5k,1995
21
21
  pyntcli/commands/sub_command.py,sha256=GF3-rE_qk2L4jGPFqHLm9SdGINmu3EakhjJTFyWjRms,374
22
- pyntcli/commands/template.py,sha256=KocIH1T7occrrjaWJQaKKGgGWrU1bieTKEJbhFw3KLI,7976
22
+ pyntcli/commands/template.py,sha256=wl-0GhIUUqdO39fyoO7mMsEKXnYqG32XkQdUJhLkdiA,8047
23
23
  pyntcli/commands/util.py,sha256=ev06aUlJ9tCSw1eAGVIsGlVVY4u0H6AJG9b5MB_bAzs,4594
24
24
  pyntcli/log/__init__.py,sha256=cOGwOYzMoshEbZiiasBGkj6wF0SBu3Jdpl-AuakDesw,19
25
25
  pyntcli/log/log.py,sha256=YXCvcCzuhQ5QUT2L02uQEdN_lTCzLEuet4OnLuEnjlM,112
26
26
  pyntcli/pynt_docker/__init__.py,sha256=PQIOVxc7XXtMLfEX7ojgwf_Z3mmTllO3ZvzUZTPOxQY,30
27
27
  pyntcli/pynt_docker/container_utils.py,sha256=_Onn7loInzyJAG2-Uk6CGpsuRyelmUFHOvtJj4Uzi9A,175
28
- pyntcli/pynt_docker/pynt_container.py,sha256=c86YmbPMzj-LIkwRikNs3vXLL4uV0qrxIqVrcQ8Ayd4,14103
28
+ pyntcli/pynt_docker/pynt_container.py,sha256=u87rBT52rxDYNg8gc0NAs3GhTDS1MFwKLpShJkPlKbA,13861
29
29
  pyntcli/store/__init__.py,sha256=1fP8cEAQCF_myja3gnhHH9FEqtBiOJ-2aBmUXSKBdFA,41
30
30
  pyntcli/store/json_connector.py,sha256=UGs3uORw3iyn0YJ8kzab-veEZToA6d-ByXYuqEleWsA,560
31
31
  pyntcli/store/store.py,sha256=Kl_HT9FJFdKlAH7SwAt3g4-bW-r-1ve_u13OPggQai0,2529
32
32
  pyntcli/store/store_connector.py,sha256=w4LzcpRZesUZL1f63RmLlWEFRtJ6Y6rcS6PkkGtO4MA,357
33
33
  pyntcli/transport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- pyntcli/transport/pynt_requests.py,sha256=C7OPvcKkRTcxSYuyiWKE59KgA9sRX0d6fm1wnopAmPo,1719
34
+ pyntcli/transport/pynt_requests.py,sha256=gOPwBpPj6qIymDRFNgcQmwoI5Rqs4GMk4pfBvaCBeTo,1870
35
35
  pyntcli/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  pyntcli/ui/progress.py,sha256=RrnO_jJNunoyupylakmWmHOEPw3lh99OHpKBzL6OBiE,1008
37
37
  pyntcli/ui/prompt.py,sha256=tK3BFYvgT7ZgSrsN5ASkltcsbhy8tOdNfEjRyCjOk6Q,1570
@@ -40,8 +40,8 @@ pyntcli/ui/report.py,sha256=W-icPSZrGLOubXgam0LpOvHLl_aZg9Zx9qIkL8Ym5PE,1930
40
40
  pyntcli/ui/ui_thread.py,sha256=XUBgLpYQjVhrilU-ofw7VSXgTiwneSdTxm61EvC3x4Q,5091
41
41
  tests/test_utils.py,sha256=t5fTQUk1U_Js6iMxcGYGqt4C-crzOJ0CqCKtLkRtUi0,2050
42
42
  tests/commands/test_pynt_cmd.py,sha256=BjGFCFACcSziLrNA6_27t6TjSmvdu54wx9njwLpRSJY,8379
43
- pyntcli-0.1.110.dist-info/METADATA,sha256=rIqnBOeMS4-WHejM5GIJkVjygadDPYKPJBzhDsLhqXk,428
44
- pyntcli-0.1.110.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
45
- pyntcli-0.1.110.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
46
- pyntcli-0.1.110.dist-info/top_level.txt,sha256=64XSgBzSpgwjYjEKHZE7q3JH2a816zEeyZBXfJi3AKI,42
47
- pyntcli-0.1.110.dist-info/RECORD,,
43
+ pyntcli-0.1.112.dist-info/METADATA,sha256=f4PXxcRTkaLVSvJiaGUickD5MC1-8MNtmVF8YFbOVXE,427
44
+ pyntcli-0.1.112.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
45
+ pyntcli-0.1.112.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
46
+ pyntcli-0.1.112.dist-info/top_level.txt,sha256=64XSgBzSpgwjYjEKHZE7q3JH2a816zEeyZBXfJi3AKI,42
47
+ pyntcli-0.1.112.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.4.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5