htb 0.1.0
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/.rspec +3 -0
- data/CHANGELOG.md +18 -0
- data/LICENSE.txt +21 -0
- data/README.md +369 -0
- data/Rakefile +8 -0
- data/exe/htb +7 -0
- data/htb.gemspec +42 -0
- data/lib/htb/challenges.rb +111 -0
- data/lib/htb/cli/challenges.rb +195 -0
- data/lib/htb/cli/machines.rb +211 -0
- data/lib/htb/cli/main.rb +202 -0
- data/lib/htb/cli/users.rb +149 -0
- data/lib/htb/cli/vm.rb +129 -0
- data/lib/htb/cli/vpn.rb +182 -0
- data/lib/htb/cli.rb +116 -0
- data/lib/htb/client.rb +78 -0
- data/lib/htb/config.rb +50 -0
- data/lib/htb/machines.rb +142 -0
- data/lib/htb/users.rb +100 -0
- data/lib/htb/version.rb +5 -0
- data/lib/htb/vm.rb +63 -0
- data/lib/htb/vpn.rb +83 -0
- data/lib/htb.rb +42 -0
- metadata +225 -0
data/lib/htb/machines.rb
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HTB
|
|
4
|
+
class Machines
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# List all machines
|
|
10
|
+
# GET /api/v4/machine/list
|
|
11
|
+
def list
|
|
12
|
+
@client.get("/machine/list")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Get machine profile by ID or name
|
|
16
|
+
# GET /api/v4/machine/profile/{id_or_name}
|
|
17
|
+
def profile(id_or_name)
|
|
18
|
+
@client.get("/machine/profile/#{id_or_name}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Get active machine
|
|
22
|
+
# GET /api/v4/machine/active
|
|
23
|
+
def active
|
|
24
|
+
@client.get("/machine/active")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Play/start a machine (free VPN users)
|
|
28
|
+
# POST /api/v4/machine/play/{machine_id}
|
|
29
|
+
def play(machine_id)
|
|
30
|
+
@client.post("/machine/play/#{machine_id}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Stop a machine
|
|
34
|
+
# POST /api/v4/machine/stop
|
|
35
|
+
def stop
|
|
36
|
+
@client.post("/machine/stop")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Submit flag for machine ownership
|
|
40
|
+
# POST /api/v4/machine/own
|
|
41
|
+
# @param machine_id [Integer] Machine ID
|
|
42
|
+
# @param flag [String] The flag to submit
|
|
43
|
+
# @param difficulty [Integer] Difficulty rating (10-100)
|
|
44
|
+
def own(machine_id:, flag:, difficulty: 50)
|
|
45
|
+
@client.post("/machine/own", {
|
|
46
|
+
id: machine_id,
|
|
47
|
+
flag: flag,
|
|
48
|
+
difficulty: difficulty
|
|
49
|
+
})
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Submit user flag
|
|
53
|
+
# POST /api/v4/machine/own/user/{machine_id}
|
|
54
|
+
def own_user(machine_id, flag:, difficulty: 50)
|
|
55
|
+
@client.post("/machine/own/user/#{machine_id}", {
|
|
56
|
+
flag: flag,
|
|
57
|
+
difficulty: difficulty
|
|
58
|
+
})
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Submit root flag
|
|
62
|
+
# POST /api/v4/machine/own/root/{machine_id}
|
|
63
|
+
def own_root(machine_id, flag:, difficulty: 50)
|
|
64
|
+
@client.post("/machine/own/root/#{machine_id}", {
|
|
65
|
+
flag: flag,
|
|
66
|
+
difficulty: difficulty
|
|
67
|
+
})
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get machine activity
|
|
71
|
+
# GET /api/v4/machine/activity/{machine_id}
|
|
72
|
+
def activity(machine_id)
|
|
73
|
+
@client.get("/machine/activity/#{machine_id}")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Get todo list for machine
|
|
77
|
+
# GET /api/v4/machine/todo/{machine_id}
|
|
78
|
+
def todo(machine_id)
|
|
79
|
+
@client.get("/machine/todo/#{machine_id}")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Update todo status for machine
|
|
83
|
+
# POST /api/v4/machine/todo/update/{machine_id}
|
|
84
|
+
def update_todo(machine_id, flag_type:)
|
|
85
|
+
@client.post("/machine/todo/update/#{machine_id}", { flag_type: flag_type })
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Submit machine review
|
|
89
|
+
# POST /api/v4/machine/review
|
|
90
|
+
# @param machine_id [Integer] Machine ID
|
|
91
|
+
# @param stars [Integer] Star rating (1-5)
|
|
92
|
+
# @param headline [String] Review headline
|
|
93
|
+
# @param review [String] Review text
|
|
94
|
+
def review(machine_id:, stars:, headline:, review:)
|
|
95
|
+
@client.post("/machine/review", {
|
|
96
|
+
id: machine_id,
|
|
97
|
+
stars: stars,
|
|
98
|
+
headline: headline,
|
|
99
|
+
review: review
|
|
100
|
+
})
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Get recommended machines
|
|
104
|
+
# GET /api/v4/machine/recommended
|
|
105
|
+
def recommended
|
|
106
|
+
@client.get("/machine/recommended")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Get spawned machines
|
|
110
|
+
# GET /api/v4/machine/spawned
|
|
111
|
+
def spawned
|
|
112
|
+
@client.get("/machine/spawned")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Get retired machines
|
|
116
|
+
# GET /api/v4/machine/list/retired
|
|
117
|
+
def retired
|
|
118
|
+
@client.get("/machine/list/retired")
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Get starting point machines
|
|
122
|
+
# GET /api/v4/machine/list/sp
|
|
123
|
+
def starting_point
|
|
124
|
+
@client.get("/machine/list/sp")
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Get paginated machine list
|
|
128
|
+
# GET /api/v4/machine/paginated
|
|
129
|
+
def paginated(page: 1, per_page: 20, sort_by: nil, sort_type: nil)
|
|
130
|
+
params = { page: page, per_page: per_page }
|
|
131
|
+
params[:sort_by] = sort_by if sort_by
|
|
132
|
+
params[:sort_type] = sort_type if sort_type
|
|
133
|
+
@client.get("/machine/paginated", params)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Search machines
|
|
137
|
+
# GET /api/v4/search/fetch?query={query}&tags=[]
|
|
138
|
+
def search(query, tags: [])
|
|
139
|
+
@client.get("/search/fetch", { query: query, tags: tags })
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
data/lib/htb/users.rb
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HTB
|
|
4
|
+
class Users
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Get current user info
|
|
10
|
+
# GET /api/v4/user/info
|
|
11
|
+
def info
|
|
12
|
+
@client.get("/user/info")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Get user profile by ID
|
|
16
|
+
# GET /api/v4/user/profile/basic/{user_id}
|
|
17
|
+
def profile(user_id)
|
|
18
|
+
@client.get("/user/profile/basic/#{user_id}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Get current user's profile
|
|
22
|
+
# GET /api/v4/user/profile/basic/me
|
|
23
|
+
def me
|
|
24
|
+
@client.get("/user/profile/basic/me")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Get user's activity
|
|
28
|
+
# GET /api/v4/user/profile/activity/{user_id}
|
|
29
|
+
def activity(user_id)
|
|
30
|
+
@client.get("/user/profile/activity/#{user_id}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Get user's bloods (first solves)
|
|
34
|
+
# GET /api/v4/user/profile/bloods/{user_id}
|
|
35
|
+
def bloods(user_id)
|
|
36
|
+
@client.get("/user/profile/bloods/#{user_id}")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Get user's progress
|
|
40
|
+
# GET /api/v4/user/profile/progress/machines/os/{user_id}
|
|
41
|
+
def machine_progress(user_id)
|
|
42
|
+
@client.get("/user/profile/progress/machines/os/#{user_id}")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Get user's challenge progress
|
|
46
|
+
# GET /api/v4/user/profile/progress/challenges/{user_id}
|
|
47
|
+
def challenge_progress(user_id)
|
|
48
|
+
@client.get("/user/profile/progress/challenges/#{user_id}")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Get user's content (writeups, etc.)
|
|
52
|
+
# GET /api/v4/user/profile/content/{user_id}
|
|
53
|
+
def content(user_id)
|
|
54
|
+
@client.get("/user/profile/content/#{user_id}")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Update user settings
|
|
58
|
+
# PUT /api/v4/user/settings
|
|
59
|
+
def update_settings(settings)
|
|
60
|
+
@client.put("/user/settings", settings)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get user's connections (followers/following)
|
|
64
|
+
# GET /api/v4/user/profile/connections/{user_id}
|
|
65
|
+
def connections(user_id)
|
|
66
|
+
@client.get("/user/profile/connections/#{user_id}")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Follow a user
|
|
70
|
+
# POST /api/v4/user/follow/{user_id}
|
|
71
|
+
def follow(user_id)
|
|
72
|
+
@client.post("/user/follow/#{user_id}")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Unfollow a user
|
|
76
|
+
# DELETE /api/v4/user/follow/{user_id}
|
|
77
|
+
def unfollow(user_id)
|
|
78
|
+
@client.delete("/user/follow/#{user_id}")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Get user's badges
|
|
82
|
+
# GET /api/v4/user/profile/badges/{user_id}
|
|
83
|
+
def badges(user_id)
|
|
84
|
+
@client.get("/user/profile/badges/#{user_id}")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Get subscriptions info
|
|
88
|
+
# GET /api/v4/user/subscriptions
|
|
89
|
+
def subscriptions
|
|
90
|
+
@client.get("/user/subscriptions")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Get user's rank history
|
|
94
|
+
# GET /api/v4/user/profile/graph/{period}/{user_id}
|
|
95
|
+
# period: 1M, 3M, 6M, 1Y
|
|
96
|
+
def rank_history(user_id, period: "1Y")
|
|
97
|
+
@client.get("/user/profile/graph/#{period}/#{user_id}")
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
data/lib/htb/version.rb
ADDED
data/lib/htb/vm.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HTB
|
|
4
|
+
class VM
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Spawn a machine (VIP/Starting Point)
|
|
10
|
+
# POST /api/v4/vm/spawn
|
|
11
|
+
# @param machine_id [Integer] The machine ID to spawn
|
|
12
|
+
# @return [Hash] Response containing spawn status
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# client.vm.spawn(811)
|
|
16
|
+
# # => { "success" => "1", "message" => "Machine is being spawned..." }
|
|
17
|
+
#
|
|
18
|
+
# Note: This endpoint is used for VIP and Starting Point machines.
|
|
19
|
+
# The base URI changed from www.hackthebox.com to labs.hackthebox.com
|
|
20
|
+
def spawn(machine_id)
|
|
21
|
+
@client.post("/vm/spawn", { machine_id: machine_id })
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Terminate a running machine
|
|
25
|
+
# POST /api/v4/vm/terminate
|
|
26
|
+
# @param machine_id [Integer] The machine ID to terminate
|
|
27
|
+
def terminate(machine_id)
|
|
28
|
+
@client.post("/vm/terminate", { machine_id: machine_id })
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Reset a machine
|
|
32
|
+
# POST /api/v4/vm/reset
|
|
33
|
+
# @param machine_id [Integer] The machine ID to reset
|
|
34
|
+
def reset(machine_id)
|
|
35
|
+
@client.post("/vm/reset", { machine_id: machine_id })
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Extend machine time
|
|
39
|
+
# POST /api/v4/vm/extend
|
|
40
|
+
# @param machine_id [Integer] The machine ID to extend
|
|
41
|
+
def extend(machine_id)
|
|
42
|
+
@client.post("/vm/extend", { machine_id: machine_id })
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Get VM status
|
|
46
|
+
# GET /api/v4/vm/status
|
|
47
|
+
def status
|
|
48
|
+
@client.get("/vm/status")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Get active VM
|
|
52
|
+
# GET /api/v4/vm/active
|
|
53
|
+
def active
|
|
54
|
+
@client.get("/vm/active")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Transfer VM to another lab
|
|
58
|
+
# POST /api/v4/vm/transfer
|
|
59
|
+
def transfer(machine_id:, lab_id:)
|
|
60
|
+
@client.post("/vm/transfer", { machine_id: machine_id, lab_id: lab_id })
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/htb/vpn.rb
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HTB
|
|
4
|
+
class VPN
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Get VPN server list
|
|
10
|
+
# GET /api/v4/connections/servers
|
|
11
|
+
def servers
|
|
12
|
+
@client.get("/connections/servers")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Get current VPN connection status
|
|
16
|
+
# GET /api/v4/connections/status
|
|
17
|
+
def status
|
|
18
|
+
@client.get("/connections/status")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Switch VPN server
|
|
22
|
+
# POST /api/v4/connections/servers/switch/{server_id}
|
|
23
|
+
def switch(server_id)
|
|
24
|
+
@client.post("/connections/servers/switch/#{server_id}")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Regenerate VPN config
|
|
28
|
+
# POST /api/v4/connections/regenerate
|
|
29
|
+
def regenerate
|
|
30
|
+
@client.post("/connections/regenerate")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Download VPN config
|
|
34
|
+
# GET /api/v4/access/ovpnfile/{server_id}/{tcp_or_udp}
|
|
35
|
+
# @param server_id [Integer] VPN server ID
|
|
36
|
+
# @param protocol [String] "tcp" or "udp" (default: "udp")
|
|
37
|
+
def download_config(server_id, protocol: "udp")
|
|
38
|
+
@client.get("/access/ovpnfile/#{server_id}/#{protocol}")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Get labs list
|
|
42
|
+
# GET /api/v4/labs/list
|
|
43
|
+
def labs
|
|
44
|
+
@client.get("/labs/list")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Get available labs for user
|
|
48
|
+
# GET /api/v4/labs/available
|
|
49
|
+
def available_labs
|
|
50
|
+
@client.get("/labs/available")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Get lab info
|
|
54
|
+
# GET /api/v4/lab/info/{lab_id}
|
|
55
|
+
def lab_info(lab_id)
|
|
56
|
+
@client.get("/lab/info/#{lab_id}")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Get prolabs list
|
|
60
|
+
# GET /api/v4/prolab/list
|
|
61
|
+
def prolabs
|
|
62
|
+
@client.get("/prolab/list")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Get prolab info
|
|
66
|
+
# GET /api/v4/prolab/info/{prolab_id}
|
|
67
|
+
def prolab_info(prolab_id)
|
|
68
|
+
@client.get("/prolab/info/#{prolab_id}")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Get fortress list
|
|
72
|
+
# GET /api/v4/fortress/list
|
|
73
|
+
def fortresses
|
|
74
|
+
@client.get("/fortress/list")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Get endgame list
|
|
78
|
+
# GET /api/v4/endgame/list
|
|
79
|
+
def endgames
|
|
80
|
+
@client.get("/endgame/list")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
data/lib/htb.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "faraday"
|
|
4
|
+
require "faraday/multipart"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
require_relative "htb/version"
|
|
8
|
+
require_relative "htb/config"
|
|
9
|
+
require_relative "htb/client"
|
|
10
|
+
require_relative "htb/machines"
|
|
11
|
+
require_relative "htb/users"
|
|
12
|
+
require_relative "htb/vm"
|
|
13
|
+
require_relative "htb/challenges"
|
|
14
|
+
require_relative "htb/vpn"
|
|
15
|
+
|
|
16
|
+
module HTB
|
|
17
|
+
class Error < StandardError; end
|
|
18
|
+
class AuthenticationError < Error; end
|
|
19
|
+
class RateLimitError < Error; end
|
|
20
|
+
class NotFoundError < Error; end
|
|
21
|
+
|
|
22
|
+
# Base URI for HTB API v4
|
|
23
|
+
# Note: The base URI changed from www.hackthebox.com to labs.hackthebox.com
|
|
24
|
+
BASE_URI = "https://labs.hackthebox.com"
|
|
25
|
+
API_VERSION = "v4"
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
attr_accessor :api_token
|
|
29
|
+
|
|
30
|
+
def configure
|
|
31
|
+
yield self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def client
|
|
35
|
+
@client ||= Client.new(api_token: api_token)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def reset_client!
|
|
39
|
+
@client = nil
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: htb
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- usiegj00
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-17 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: faraday-multipart
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: thor
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: tty-table
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0.12'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0.12'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: tty-spinner
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.9'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.9'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: tty-prompt
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0.23'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0.23'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: pastel
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0.8'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0.8'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: bundler
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '2.0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '2.0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rake
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '13.0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '13.0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: rspec
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '3.0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '3.0'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: webmock
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '3.0'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '3.0'
|
|
167
|
+
description: A Ruby gem for interacting with the Hack The Box (HTB) API v4. Supports
|
|
168
|
+
machine management, user profiles, VM spawning, flag submission, and more.
|
|
169
|
+
email:
|
|
170
|
+
- usiegj00@users.noreply.github.com
|
|
171
|
+
executables:
|
|
172
|
+
- htb
|
|
173
|
+
extensions: []
|
|
174
|
+
extra_rdoc_files: []
|
|
175
|
+
files:
|
|
176
|
+
- ".rspec"
|
|
177
|
+
- CHANGELOG.md
|
|
178
|
+
- LICENSE.txt
|
|
179
|
+
- README.md
|
|
180
|
+
- Rakefile
|
|
181
|
+
- exe/htb
|
|
182
|
+
- htb.gemspec
|
|
183
|
+
- lib/htb.rb
|
|
184
|
+
- lib/htb/challenges.rb
|
|
185
|
+
- lib/htb/cli.rb
|
|
186
|
+
- lib/htb/cli/challenges.rb
|
|
187
|
+
- lib/htb/cli/machines.rb
|
|
188
|
+
- lib/htb/cli/main.rb
|
|
189
|
+
- lib/htb/cli/users.rb
|
|
190
|
+
- lib/htb/cli/vm.rb
|
|
191
|
+
- lib/htb/cli/vpn.rb
|
|
192
|
+
- lib/htb/client.rb
|
|
193
|
+
- lib/htb/config.rb
|
|
194
|
+
- lib/htb/machines.rb
|
|
195
|
+
- lib/htb/users.rb
|
|
196
|
+
- lib/htb/version.rb
|
|
197
|
+
- lib/htb/vm.rb
|
|
198
|
+
- lib/htb/vpn.rb
|
|
199
|
+
homepage: https://github.com/aluminumio/htb-ruby
|
|
200
|
+
licenses:
|
|
201
|
+
- MIT
|
|
202
|
+
metadata:
|
|
203
|
+
homepage_uri: https://github.com/aluminumio/htb-ruby
|
|
204
|
+
source_code_uri: https://github.com/aluminumio/htb-ruby
|
|
205
|
+
changelog_uri: https://github.com/aluminumio/htb-ruby/blob/main/CHANGELOG.md
|
|
206
|
+
post_install_message:
|
|
207
|
+
rdoc_options: []
|
|
208
|
+
require_paths:
|
|
209
|
+
- lib
|
|
210
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
211
|
+
requirements:
|
|
212
|
+
- - ">="
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: 2.7.0
|
|
215
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
216
|
+
requirements:
|
|
217
|
+
- - ">="
|
|
218
|
+
- !ruby/object:Gem::Version
|
|
219
|
+
version: '0'
|
|
220
|
+
requirements: []
|
|
221
|
+
rubygems_version: 3.0.3.1
|
|
222
|
+
signing_key:
|
|
223
|
+
specification_version: 4
|
|
224
|
+
summary: Ruby client for the Hack The Box API v4
|
|
225
|
+
test_files: []
|