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
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 2e6caea0b99b8c05235a7d882577af1a106b5313efdbe8e8034bdd18a18f1c83
|
|
4
|
+
data.tar.gz: d8e9addfbe08acc7acaaf30d5a033871b93b9271bcc93a0d85dd2bd33c914da5
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 053eb8609fd604dd1921c30279a686bc86d4362f9e4756e518168a505deeb720210d75aea4e2d84ddedf8510da71e49a036e7076560f304ab19076a2a96f3787
|
|
7
|
+
data.tar.gz: 853a12f640c67d268078cbf8fbf540bf5d7875d186ee8c1b0896d58db2b3f1f0f64b5c58bfcc3d4702fae675a2b902c401d631bdbd9c53cc71be2b2d94294e81
|
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2025-01-17
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release
|
|
13
|
+
- Machine management (list, profile, play, stop, own)
|
|
14
|
+
- VM management (spawn, terminate, reset, extend)
|
|
15
|
+
- User profiles and activity
|
|
16
|
+
- Challenge management
|
|
17
|
+
- VPN and lab information
|
|
18
|
+
- Support for the updated base URI (`labs.hackthebox.com`)
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 usiegj00
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
# HTB Ruby
|
|
2
|
+
|
|
3
|
+
A Ruby gem for interacting with the [Hack The Box](https://www.hackthebox.com/) API v4.
|
|
4
|
+
|
|
5
|
+
## Important: Base URI Change
|
|
6
|
+
|
|
7
|
+
The HTB API base URI has changed from the legacy `www.hackthebox.com` to `labs.hackthebox.com`. This gem uses the correct, updated base URI.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'htb'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
And then execute:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bundle install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or install it yourself as:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
gem install htb
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Configuration
|
|
30
|
+
|
|
31
|
+
You'll need an HTB API token. You can obtain one from your [HTB Account Settings](https://app.hackthebox.com/profile/settings).
|
|
32
|
+
|
|
33
|
+
### Interactive Login (Recommended)
|
|
34
|
+
|
|
35
|
+
The easiest way to configure your token:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
htb login
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This will:
|
|
42
|
+
1. Prompt you for your API token (input is masked)
|
|
43
|
+
2. Validate the token with HTB
|
|
44
|
+
3. Save it securely to `~/.htbrc` (with 600 permissions)
|
|
45
|
+
|
|
46
|
+
### Environment Variable
|
|
47
|
+
|
|
48
|
+
Alternatively, set an environment variable (takes priority over config file):
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
export HTB_API_TOKEN=your_token_here
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Managing Configuration
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
htb config # Show current configuration
|
|
58
|
+
htb login # Set/update API token
|
|
59
|
+
htb logout # Remove saved token
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CLI Usage
|
|
63
|
+
|
|
64
|
+
The gem includes a full-featured command-line interface.
|
|
65
|
+
|
|
66
|
+
### Quick Start
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# First time? Login to save your token
|
|
70
|
+
htb login
|
|
71
|
+
|
|
72
|
+
# Show your profile
|
|
73
|
+
htb me
|
|
74
|
+
|
|
75
|
+
# Show current status (VM + VPN)
|
|
76
|
+
htb status
|
|
77
|
+
|
|
78
|
+
# List machines
|
|
79
|
+
htb machines list
|
|
80
|
+
htb machines list --retired
|
|
81
|
+
htb machines list --sp
|
|
82
|
+
|
|
83
|
+
# Get machine info
|
|
84
|
+
htb machines info Gavel
|
|
85
|
+
htb machines info 811
|
|
86
|
+
|
|
87
|
+
# Spawn/terminate machines
|
|
88
|
+
htb spawn 811
|
|
89
|
+
htb terminate 811
|
|
90
|
+
|
|
91
|
+
# Or using subcommands
|
|
92
|
+
htb vm spawn 811
|
|
93
|
+
htb vm terminate 811
|
|
94
|
+
htb vm reset 811
|
|
95
|
+
htb vm extend 811
|
|
96
|
+
|
|
97
|
+
# Submit flags
|
|
98
|
+
htb machines own 811 --flag "HTB{...}"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### All CLI Commands
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Main commands
|
|
105
|
+
htb status # Show VM and VPN status
|
|
106
|
+
htb me # Show your profile
|
|
107
|
+
htb spawn MACHINE_ID # Spawn a machine (shortcut)
|
|
108
|
+
htb terminate MACHINE_ID # Terminate a machine (shortcut)
|
|
109
|
+
htb version # Show version
|
|
110
|
+
|
|
111
|
+
# Machine commands
|
|
112
|
+
htb machines list # List active machines
|
|
113
|
+
htb machines list --retired # List retired machines
|
|
114
|
+
htb machines list --sp # List Starting Point machines
|
|
115
|
+
htb machines info NAME # Show machine details
|
|
116
|
+
htb machines active # Show active machine
|
|
117
|
+
htb machines play ID # Start machine (free VPN)
|
|
118
|
+
htb machines stop # Stop current machine
|
|
119
|
+
htb machines own ID --flag FLAG # Submit a flag
|
|
120
|
+
htb machines search QUERY # Search machines
|
|
121
|
+
htb machines recommended # Show recommendations
|
|
122
|
+
|
|
123
|
+
# VM commands
|
|
124
|
+
htb vm spawn ID # Spawn machine (VIP/SP)
|
|
125
|
+
htb vm terminate ID # Terminate machine
|
|
126
|
+
htb vm reset ID # Reset machine
|
|
127
|
+
htb vm extend ID # Extend time
|
|
128
|
+
htb vm status # Show VM status
|
|
129
|
+
htb vm active # Show active VM
|
|
130
|
+
|
|
131
|
+
# User commands
|
|
132
|
+
htb users me # Your profile
|
|
133
|
+
htb users info USER_ID # User profile by ID
|
|
134
|
+
htb users activity USER_ID # User activity
|
|
135
|
+
htb users bloods USER_ID # User's first bloods
|
|
136
|
+
htb users badges USER_ID # User's badges
|
|
137
|
+
htb users subscriptions # Your subscriptions
|
|
138
|
+
|
|
139
|
+
# Challenge commands
|
|
140
|
+
htb challenges list # List challenges
|
|
141
|
+
htb challenges list --retired # Retired challenges
|
|
142
|
+
htb challenges info ID # Challenge details
|
|
143
|
+
htb challenges start ID # Start a challenge
|
|
144
|
+
htb challenges stop ID # Stop a challenge
|
|
145
|
+
htb challenges spawn ID # Spawn instance
|
|
146
|
+
htb challenges own ID --flag FLAG # Submit flag
|
|
147
|
+
htb challenges categories # List categories
|
|
148
|
+
htb challenges active # Show active challenge
|
|
149
|
+
|
|
150
|
+
# VPN commands
|
|
151
|
+
htb vpn status # Connection status
|
|
152
|
+
htb vpn servers # List VPN servers
|
|
153
|
+
htb vpn switch ID # Switch server
|
|
154
|
+
htb vpn regenerate # Regenerate config
|
|
155
|
+
htb vpn labs # List labs
|
|
156
|
+
htb vpn prolabs # List Pro Labs
|
|
157
|
+
htb vpn endgames # List Endgames
|
|
158
|
+
htb vpn fortresses # List Fortresses
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Ruby Library Usage
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
require 'htb'
|
|
165
|
+
|
|
166
|
+
# Configure globally
|
|
167
|
+
HTB.configure do |config|
|
|
168
|
+
config.api_token = ENV['HTB_API_TOKEN']
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Or create a client directly
|
|
172
|
+
client = HTB::Client.new(api_token: ENV['HTB_API_TOKEN'])
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Library Examples
|
|
176
|
+
|
|
177
|
+
### Machines
|
|
178
|
+
|
|
179
|
+
```ruby
|
|
180
|
+
client = HTB::Client.new(api_token: ENV['HTB_API_TOKEN'])
|
|
181
|
+
|
|
182
|
+
# List all machines
|
|
183
|
+
machines = client.machines.list
|
|
184
|
+
|
|
185
|
+
# Get machine profile
|
|
186
|
+
machine = client.machines.profile("Gavel") # by name
|
|
187
|
+
machine = client.machines.profile(811) # by ID
|
|
188
|
+
|
|
189
|
+
# Get active machine
|
|
190
|
+
active = client.machines.active
|
|
191
|
+
|
|
192
|
+
# Get retired machines
|
|
193
|
+
retired = client.machines.retired
|
|
194
|
+
|
|
195
|
+
# Get Starting Point machines
|
|
196
|
+
sp = client.machines.starting_point
|
|
197
|
+
|
|
198
|
+
# Submit a flag
|
|
199
|
+
client.machines.own(machine_id: 811, flag: "HTB{...}", difficulty: 50)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### VM Management (Spawn/Terminate)
|
|
203
|
+
|
|
204
|
+
```ruby
|
|
205
|
+
# Spawn a machine (VIP/Starting Point)
|
|
206
|
+
client.vm.spawn(811)
|
|
207
|
+
|
|
208
|
+
# Get VM status
|
|
209
|
+
status = client.vm.status
|
|
210
|
+
|
|
211
|
+
# Get active VM
|
|
212
|
+
active = client.vm.active
|
|
213
|
+
|
|
214
|
+
# Terminate a machine
|
|
215
|
+
client.vm.terminate(811)
|
|
216
|
+
|
|
217
|
+
# Reset a machine
|
|
218
|
+
client.vm.reset(811)
|
|
219
|
+
|
|
220
|
+
# Extend machine time
|
|
221
|
+
client.vm.extend(811)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Users
|
|
225
|
+
|
|
226
|
+
```ruby
|
|
227
|
+
# Get current user info
|
|
228
|
+
me = client.users.me
|
|
229
|
+
|
|
230
|
+
# Get user profile by ID
|
|
231
|
+
user = client.users.profile(12345)
|
|
232
|
+
|
|
233
|
+
# Get user activity
|
|
234
|
+
activity = client.users.activity(12345)
|
|
235
|
+
|
|
236
|
+
# Get user badges
|
|
237
|
+
badges = client.users.badges(12345)
|
|
238
|
+
|
|
239
|
+
# Get subscriptions
|
|
240
|
+
subs = client.users.subscriptions
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Challenges
|
|
244
|
+
|
|
245
|
+
```ruby
|
|
246
|
+
# List all challenges
|
|
247
|
+
challenges = client.challenges.list
|
|
248
|
+
|
|
249
|
+
# Get challenge info
|
|
250
|
+
challenge = client.challenges.info(123)
|
|
251
|
+
|
|
252
|
+
# Start a challenge
|
|
253
|
+
client.challenges.start(123)
|
|
254
|
+
|
|
255
|
+
# Submit flag
|
|
256
|
+
client.challenges.own(challenge_id: 123, flag: "HTB{...}", difficulty: 50)
|
|
257
|
+
|
|
258
|
+
# Stop a challenge
|
|
259
|
+
client.challenges.stop(123)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### VPN
|
|
263
|
+
|
|
264
|
+
```ruby
|
|
265
|
+
# Get VPN servers
|
|
266
|
+
servers = client.vpn.servers
|
|
267
|
+
|
|
268
|
+
# Get connection status
|
|
269
|
+
status = client.vpn.status
|
|
270
|
+
|
|
271
|
+
# Get available labs
|
|
272
|
+
labs = client.vpn.labs
|
|
273
|
+
|
|
274
|
+
# Get Prolabs list
|
|
275
|
+
prolabs = client.vpn.prolabs
|
|
276
|
+
|
|
277
|
+
# Get Endgames list
|
|
278
|
+
endgames = client.vpn.endgames
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## API Endpoints Reference
|
|
282
|
+
|
|
283
|
+
This gem implements the HTB v4 API endpoints. The base URI is `https://labs.hackthebox.com/api/v4`.
|
|
284
|
+
|
|
285
|
+
### Machines
|
|
286
|
+
| Method | Endpoint | Description |
|
|
287
|
+
|--------|----------|-------------|
|
|
288
|
+
| GET | `/machine/list` | List all machines |
|
|
289
|
+
| GET | `/machine/profile/{id_or_name}` | Get machine profile |
|
|
290
|
+
| GET | `/machine/active` | Get active machine |
|
|
291
|
+
| POST | `/machine/play/{machine_id}` | Play machine (free VPN) |
|
|
292
|
+
| POST | `/machine/stop` | Stop machine |
|
|
293
|
+
| POST | `/machine/own` | Submit flag |
|
|
294
|
+
| GET | `/machine/recommended` | Get recommended machines |
|
|
295
|
+
| GET | `/machine/list/retired` | List retired machines |
|
|
296
|
+
| GET | `/machine/list/sp` | List Starting Point machines |
|
|
297
|
+
|
|
298
|
+
### VM Management
|
|
299
|
+
| Method | Endpoint | Description |
|
|
300
|
+
|--------|----------|-------------|
|
|
301
|
+
| POST | `/vm/spawn` | Spawn a machine (VIP/SP) |
|
|
302
|
+
| POST | `/vm/terminate` | Terminate a machine |
|
|
303
|
+
| POST | `/vm/reset` | Reset a machine |
|
|
304
|
+
| POST | `/vm/extend` | Extend machine time |
|
|
305
|
+
| GET | `/vm/status` | Get VM status |
|
|
306
|
+
| GET | `/vm/active` | Get active VM |
|
|
307
|
+
|
|
308
|
+
### Users
|
|
309
|
+
| Method | Endpoint | Description |
|
|
310
|
+
|--------|----------|-------------|
|
|
311
|
+
| GET | `/user/info` | Get current user info |
|
|
312
|
+
| GET | `/user/profile/basic/{user_id}` | Get user profile |
|
|
313
|
+
| GET | `/user/profile/basic/me` | Get own profile |
|
|
314
|
+
| GET | `/user/profile/activity/{user_id}` | Get user activity |
|
|
315
|
+
| GET | `/user/profile/bloods/{user_id}` | Get user bloods |
|
|
316
|
+
| GET | `/user/profile/badges/{user_id}` | Get user badges |
|
|
317
|
+
|
|
318
|
+
### Challenges
|
|
319
|
+
| Method | Endpoint | Description |
|
|
320
|
+
|--------|----------|-------------|
|
|
321
|
+
| GET | `/challenge/list` | List all challenges |
|
|
322
|
+
| GET | `/challenge/info/{id}` | Get challenge info |
|
|
323
|
+
| POST | `/challenge/start/{id}` | Start a challenge |
|
|
324
|
+
| POST | `/challenge/stop/{id}` | Stop a challenge |
|
|
325
|
+
| POST | `/challenge/own` | Submit flag |
|
|
326
|
+
| GET | `/challenge/categories/list` | Get categories |
|
|
327
|
+
|
|
328
|
+
### VPN & Labs
|
|
329
|
+
| Method | Endpoint | Description |
|
|
330
|
+
|--------|----------|-------------|
|
|
331
|
+
| GET | `/connections/servers` | Get VPN servers |
|
|
332
|
+
| GET | `/connections/status` | Get VPN status |
|
|
333
|
+
| GET | `/labs/list` | Get labs list |
|
|
334
|
+
| GET | `/prolab/list` | Get Prolabs list |
|
|
335
|
+
| GET | `/endgame/list` | Get Endgames list |
|
|
336
|
+
|
|
337
|
+
## Error Handling
|
|
338
|
+
|
|
339
|
+
```ruby
|
|
340
|
+
begin
|
|
341
|
+
client.machines.profile("nonexistent")
|
|
342
|
+
rescue HTB::AuthenticationError => e
|
|
343
|
+
puts "Invalid API token"
|
|
344
|
+
rescue HTB::NotFoundError => e
|
|
345
|
+
puts "Resource not found"
|
|
346
|
+
rescue HTB::RateLimitError => e
|
|
347
|
+
puts "Rate limited, slow down"
|
|
348
|
+
rescue HTB::Error => e
|
|
349
|
+
puts "API error: #{e.message}"
|
|
350
|
+
end
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Development
|
|
354
|
+
|
|
355
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
|
356
|
+
|
|
357
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
358
|
+
|
|
359
|
+
## Contributing
|
|
360
|
+
|
|
361
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/aluminumio/htb-ruby.
|
|
362
|
+
|
|
363
|
+
## License
|
|
364
|
+
|
|
365
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
366
|
+
|
|
367
|
+
## Disclaimer
|
|
368
|
+
|
|
369
|
+
This gem is not officially affiliated with or endorsed by Hack The Box. Use responsibly and in accordance with HTB's Terms of Service.
|
data/Rakefile
ADDED
data/exe/htb
ADDED
data/htb.gemspec
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = "htb"
|
|
5
|
+
spec.version = "0.1.0"
|
|
6
|
+
spec.authors = ["usiegj00"]
|
|
7
|
+
spec.email = ["usiegj00@users.noreply.github.com"]
|
|
8
|
+
|
|
9
|
+
spec.summary = "Ruby client for the Hack The Box API v4"
|
|
10
|
+
spec.description = "A Ruby gem for interacting with the Hack The Box (HTB) API v4. " \
|
|
11
|
+
"Supports machine management, user profiles, VM spawning, flag submission, and more."
|
|
12
|
+
spec.homepage = "https://github.com/aluminumio/htb-ruby"
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
spec.required_ruby_version = ">= 2.7.0"
|
|
15
|
+
|
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
17
|
+
spec.metadata["source_code_uri"] = "https://github.com/aluminumio/htb-ruby"
|
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/aluminumio/htb-ruby/blob/main/CHANGELOG.md"
|
|
19
|
+
|
|
20
|
+
spec.files = Dir.chdir(__dir__) do
|
|
21
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
22
|
+
(File.expand_path(f) == __FILE__) ||
|
|
23
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
spec.bindir = "exe"
|
|
27
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
28
|
+
spec.require_paths = ["lib"]
|
|
29
|
+
|
|
30
|
+
spec.add_dependency "faraday", "~> 2.0"
|
|
31
|
+
spec.add_dependency "faraday-multipart", "~> 1.0"
|
|
32
|
+
spec.add_dependency "thor", "~> 1.0"
|
|
33
|
+
spec.add_dependency "tty-table", "~> 0.12"
|
|
34
|
+
spec.add_dependency "tty-spinner", "~> 0.9"
|
|
35
|
+
spec.add_dependency "tty-prompt", "~> 0.23"
|
|
36
|
+
spec.add_dependency "pastel", "~> 0.8"
|
|
37
|
+
|
|
38
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
|
39
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
40
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
|
41
|
+
spec.add_development_dependency "webmock", "~> 3.0"
|
|
42
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HTB
|
|
4
|
+
class Challenges
|
|
5
|
+
def initialize(client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# List all challenges
|
|
10
|
+
# GET /api/v4/challenge/list
|
|
11
|
+
def list
|
|
12
|
+
@client.get("/challenge/list")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Get challenge info by ID
|
|
16
|
+
# GET /api/v4/challenge/info/{challenge_id}
|
|
17
|
+
def info(challenge_id)
|
|
18
|
+
@client.get("/challenge/info/#{challenge_id}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Get active challenge
|
|
22
|
+
# GET /api/v4/challenge/active
|
|
23
|
+
def active
|
|
24
|
+
@client.get("/challenge/active")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Start a challenge
|
|
28
|
+
# POST /api/v4/challenge/start/{challenge_id}
|
|
29
|
+
def start(challenge_id)
|
|
30
|
+
@client.post("/challenge/start/#{challenge_id}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Stop a challenge
|
|
34
|
+
# POST /api/v4/challenge/stop/{challenge_id}
|
|
35
|
+
def stop(challenge_id)
|
|
36
|
+
@client.post("/challenge/stop/#{challenge_id}")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Submit flag for challenge
|
|
40
|
+
# POST /api/v4/challenge/own
|
|
41
|
+
# @param challenge_id [Integer] Challenge ID
|
|
42
|
+
# @param flag [String] The flag to submit
|
|
43
|
+
# @param difficulty [Integer] Difficulty rating
|
|
44
|
+
def own(challenge_id:, flag:, difficulty: 50)
|
|
45
|
+
@client.post("/challenge/own", {
|
|
46
|
+
id: challenge_id,
|
|
47
|
+
flag: flag,
|
|
48
|
+
difficulty: difficulty
|
|
49
|
+
})
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Download challenge files
|
|
53
|
+
# GET /api/v4/challenge/download/{challenge_id}
|
|
54
|
+
def download(challenge_id)
|
|
55
|
+
@client.get("/challenge/download/#{challenge_id}")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Get challenge categories
|
|
59
|
+
# GET /api/v4/challenge/categories/list
|
|
60
|
+
def categories
|
|
61
|
+
@client.get("/challenge/categories/list")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Get retired challenges
|
|
65
|
+
# GET /api/v4/challenge/list/retired
|
|
66
|
+
def retired
|
|
67
|
+
@client.get("/challenge/list/retired")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get challenge activity
|
|
71
|
+
# GET /api/v4/challenge/activity/{challenge_id}
|
|
72
|
+
def activity(challenge_id)
|
|
73
|
+
@client.get("/challenge/activity/#{challenge_id}")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Submit challenge review
|
|
77
|
+
# POST /api/v4/challenge/review
|
|
78
|
+
def review(challenge_id:, stars:, headline:, review:)
|
|
79
|
+
@client.post("/challenge/review", {
|
|
80
|
+
id: challenge_id,
|
|
81
|
+
stars: stars,
|
|
82
|
+
headline: headline,
|
|
83
|
+
review: review
|
|
84
|
+
})
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Get recommended challenges
|
|
88
|
+
# GET /api/v4/challenge/recommended
|
|
89
|
+
def recommended
|
|
90
|
+
@client.get("/challenge/recommended")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Get challenge todo status
|
|
94
|
+
# GET /api/v4/challenge/todo/{challenge_id}
|
|
95
|
+
def todo(challenge_id)
|
|
96
|
+
@client.get("/challenge/todo/#{challenge_id}")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Spawn challenge instance
|
|
100
|
+
# POST /api/v4/challenge/spawn
|
|
101
|
+
def spawn(challenge_id)
|
|
102
|
+
@client.post("/challenge/spawn", { challenge_id: challenge_id })
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Terminate challenge instance
|
|
106
|
+
# POST /api/v4/challenge/terminate
|
|
107
|
+
def terminate(challenge_id)
|
|
108
|
+
@client.post("/challenge/terminate", { challenge_id: challenge_id })
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|