New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

PyHackTheBox

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

PyHackTheBox - pypi Package Compare versions

Comparing version
0.4.3
to
0.4.4
+13
-0
hackthebox/challenge.py

@@ -0,1 +1,14 @@

"""
Examples:
Starting a challenge and submitting the flag::
challenge = client.get_challenge(100)
instance = challenge.start()
r = remote(instance.ip, instance.port)
# Do the challenge.....
instance.stop()
challenge.submit(flag, difficulty=50)
"""
from __future__ import annotations

@@ -2,0 +15,0 @@

+1
-1
API_BASE = "https://www.hackthebox.eu/api/v4/"
USER_AGENT = "htb-api/0.4.3"
USER_AGENT = "htb-api/0.4.4"
DOWNLOAD_COOLDOWN = 30

@@ -150,7 +150,7 @@ from __future__ import annotations

# noinspection PyUnresolvedReferences
def get_machine(self, machine_id: int) -> "Machine":
def get_machine(self, machine_id: int | str) -> "Machine":
"""
Args:
machine_id: The platform ID of the `Machine` to fetch
machine_id: The platform ID or name of the `Machine` to fetch

@@ -185,7 +185,7 @@ Returns: The requested `Machine`

# noinspection PyUnresolvedReferences
def get_challenge(self, challenge_id: int) -> "Challenge":
def get_challenge(self, challenge_id: int | str) -> "Challenge":
"""
Args:
challenge_id: The platform ID of the `Challenge` to fetch
challenge_id: The platform ID or name of the `Challenge` to fetch

@@ -374,3 +374,3 @@ Returns: The requested `Challenge`

"""
Returns: A list of `VPNServer`s
Returns: A list of `VPNServer`

@@ -377,0 +377,0 @@ Args:

@@ -1,8 +0,9 @@

from typing import List
import dateutil.parser
from datetime import datetime, timedelta
from typing import List, Union
from . import htb
import dateutil.parser
from . import htb, vpn
from .errors import IncorrectArgumentException, IncorrectFlagException
from .solve import MachineSolve
from .errors import IncorrectArgumentException, IncorrectFlagException
from .utils import parse_delta

@@ -21,3 +22,3 @@

root_owns: The number of root owns the Machine has
free: Whethere the Machine is available on free servers
free: Whether the Machine is available on free servers
user_owned: Whether the active User has owned the Machine's user account

@@ -29,2 +30,3 @@ root_owned: Whether the active User has owned the Machine's user account

difficulty: The difficulty of the machine
ip: The IP address of the machine

@@ -74,2 +76,4 @@ active: Whether the Machine is active

_author_ids: List[int] = None
_is_release: bool = None
_ip: str = None

@@ -110,2 +114,57 @@ def submit(self, flag: str, difficulty: int):

@property
def is_release(self):
if self._is_release is not None:
return self._is_release
self._is_release = False
data = self._client.do_request("connections")["data"]
try:
if data['release_arena']['machine']['id'] == self.id:
self._is_release = True
except AttributeError:
pass
return self._is_release
@property
def ip(self):
"""The IP of an active machine."""
if self._ip is not None:
return self._ip
listing = self._client.do_request("machine/list")["info"]
m = next(filter(lambda x: x["id"] == self.id, listing))
self._ip = m["ip"]
return self._ip
def start(self, release_arena=False) -> Union["MachineInstance", None]:
"""Alias for `Machine.spawn()`"""
return self.spawn(release_arena)
def spawn(self, release_arena=False) -> "MachineInstance":
"""Spawn an instance of this machine.
Args:
release_arena: Whether to use Release Arena to spawn the machine
Returns:
The spawned `MachineInstance`
"""
if release_arena:
if not self.is_release:
# TODO: Better exception
raise Exception("Machine is not on release arena")
data = self._client.do_request("release_arena/spawn", post=True)
if data.get("success") != 1:
raise Exception(f"Failed to spawn: {data}")
ip = self._client.do_request("release_arena/active")["info"]["ip"]
server = self._client.get_current_vpn_server(release_arena=True)
else:
data = self._client.do_request("vm/spawn", json_data={"machine_id": self.id})
if "Machine deployed" in data.get("message"):
ip = self._client.do_request(f"machine/profile/{self.id}")["info"]["ip"]
server = self._client.get_current_vpn_server()
else:
raise Exception(f"Failed to spawn: {data}")
return MachineInstance(ip, server, self, self._client)
def __repr__(self):

@@ -164,1 +223,40 @@ return f"<Machine '{self.name}'>"

self._is_summary = True
class MachineInstance:
"""Representation of an active machine instance
Attributes:
ip: The IP the instance can be reached at
server: The `VPNServer` that the machine is on
machine: The `Machine` this is an instance of
client: The passed-through API client
"""
ip: str = None
server: vpn.VPNServer = None
client: htb.HTBClient = None
machine: Machine = None
def __init__(self, ip: str, server: vpn.VPNServer, machine: Machine, client: htb.HTBClient):
self.client = client
self.ip = ip
self.server = server
self.machine = machine
def __repr__(self):
return f"<'{self.machine.name}'@{self.server.friendly_name} - {self.ip}>"
def stop(self):
"""Request the instance be stopped."""
if self.machine.is_release:
self.client.do_request("release_arena/terminate", post=True)
else:
self.client.do_request("vm/terminate", json_data={"machine_id": self.machine.id})
# Can't delete references to the object from here so we just have
# to set everything to None and prevent further usage
self.server = None
self.ip = None
self.client = None
self.machine = None

@@ -0,1 +1,16 @@

"""
Examples:
Retrieving the current VPN server::
print(client.get_current_vpn_server())
Switching to a given VPN server::
req = input("What server? ")
server = next(filter(lambda x: x.friendly_name == req), client.get_all_vpn_servers()))
server.switch()
server.download(path="/tmp/out.ovpn")
"""
from __future__ import annotations

@@ -24,3 +39,2 @@

def __init__(self, data: dict, client: "HTBClient", summary=False):
"""Initialise a `VPNServer` using API data"""
self._client = client

@@ -38,2 +52,7 @@ self._detailed_func = lambda x: None

def switch(self) -> bool:
"""
Switches the client to use this VPN server
Returns: Whether the switch was completed successfully
"""
# TODO: Throw exception on failure

@@ -40,0 +59,0 @@ return self._client.do_request(f"connections/servers/switch/{self.id}", post=True)["status"] is True

Metadata-Version: 2.1
Name: PyHackTheBox
Version: 0.4.3
Version: 0.4.4
Summary: A wrapper for the Hack The Box API.

@@ -5,0 +5,0 @@ Home-page: https://github.com/clubby789/htb-api

Metadata-Version: 2.1
Name: PyHackTheBox
Version: 0.4.3
Version: 0.4.4
Summary: A wrapper for the Hack The Box API.

@@ -5,0 +5,0 @@ Home-page: https://github.com/clubby789/htb-api

@@ -11,3 +11,3 @@ import setuptools

name="PyHackTheBox",
version="0.4.3",
version="0.4.4",
author="clubby789@github.com",

@@ -14,0 +14,0 @@ author_email="clubby789@gmail.com",