gitlabrat 1.2__tar.gz → 1.3__tar.gz
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.
- {gitlabrat-1.2 → gitlabrat-1.3}/.gitignore +1 -1
- gitlabrat-1.3/PKG-INFO +59 -0
- gitlabrat-1.3/README.md +34 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/cli/agents.py +1 -1
- gitlabrat-1.3/labrat/cli/groups.py +55 -0
- gitlabrat-1.3/labrat/controllers/groups.py +81 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/main.py +2 -2
- {gitlabrat-1.2 → gitlabrat-1.3}/pyproject.toml +5 -5
- gitlabrat-1.2/PKG-INFO +0 -91
- gitlabrat-1.2/README.md +0 -66
- {gitlabrat-1.2 → gitlabrat-1.3}/LICENSE +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/__init__.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/cli/__init__.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/cli/auth.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/cli/common.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/cli/projects.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/cli/users.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/controllers/__init__.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/controllers/agents.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/controllers/auth.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/controllers/projects.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/controllers/users.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/core/__init__.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/core/agent.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/core/config.py +0 -0
- {gitlabrat-1.2 → gitlabrat-1.3}/labrat/core/utils.py +0 -0
|
@@ -183,7 +183,7 @@ cython_debug/
|
|
|
183
183
|
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
184
184
|
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
185
185
|
# you could uncomment the following to ignore the entire vscode folder
|
|
186
|
-
|
|
186
|
+
.vscode/
|
|
187
187
|
|
|
188
188
|
# Ruff stuff:
|
|
189
189
|
.ruff_cache/
|
gitlabrat-1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gitlabrat
|
|
3
|
+
Version: 1.3
|
|
4
|
+
Summary: LabRat: GitLab exploitation orchestrator
|
|
5
|
+
Project-URL: Homepage, https://github.com/JChamblee99/Labrat
|
|
6
|
+
Project-URL: Repository, https://github.com/JChamblee99/Labrat.git
|
|
7
|
+
Project-URL: Issues, https://github.com/JChamblee99/Labrt/issues
|
|
8
|
+
Author-email: John Chamblee <conway.py@proton.farm>
|
|
9
|
+
License: GPL-3.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Requires-Dist: beautifulsoup4>=4.9.0
|
|
21
|
+
Requires-Dist: gitpython>=3.1.0
|
|
22
|
+
Requires-Dist: python-gitlab>=3.0.0
|
|
23
|
+
Requires-Dist: requests>=2.25.0
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
<div align="center">
|
|
27
|
+
|
|
28
|
+
# Labrat
|
|
29
|
+
|
|
30
|
+
**Living rent-free in the walls of your GitLab.**
|
|
31
|
+
|
|
32
|
+
[](https://pypi.org/project/gitlabrat/)
|
|
33
|
+
[](https://pypi.org/project/gitlabrat/)
|
|
34
|
+
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
35
|
+
[](https://github.com/JChamblee99/LabRat/commits/main)
|
|
36
|
+
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Overview
|
|
42
|
+
|
|
43
|
+
Labrat automates workflows for gaining and maintaining access to GitLab instances and CI/CD pipelines.
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install gitlabrat
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Authenticate to a GitLab instance
|
|
55
|
+
labrat auth -t https://gitlab.example.com -u username -p password
|
|
56
|
+
|
|
57
|
+
# List authenticated agents
|
|
58
|
+
labrat agents ls
|
|
59
|
+
```
|
gitlabrat-1.3/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# Labrat
|
|
4
|
+
|
|
5
|
+
**Living rent-free in the walls of your GitLab.**
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/gitlabrat/)
|
|
8
|
+
[](https://pypi.org/project/gitlabrat/)
|
|
9
|
+
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
10
|
+
[](https://github.com/JChamblee99/LabRat/commits/main)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Overview
|
|
17
|
+
|
|
18
|
+
Labrat automates workflows for gaining and maintaining access to GitLab instances and CI/CD pipelines.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install gitlabrat
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Authenticate to a GitLab instance
|
|
30
|
+
labrat auth -t https://gitlab.example.com -u username -p password
|
|
31
|
+
|
|
32
|
+
# List authenticated agents
|
|
33
|
+
labrat agents ls
|
|
34
|
+
```
|
|
@@ -21,7 +21,7 @@ def build_parser(parsers):
|
|
|
21
21
|
|
|
22
22
|
def handle_list_args(args):
|
|
23
23
|
# Prepare table
|
|
24
|
-
headers = ["Host", "ID", "Username", "Name", "Authenticated", "Is Admin", "Is Bot", "Password", "Private Token"]
|
|
24
|
+
headers = ["Host", "ID", "Username", "Name", "Is Authenticated", "Is Admin", "Is Bot", "Password", "Private Token"]
|
|
25
25
|
data = []
|
|
26
26
|
|
|
27
27
|
for agent in args.controller.list(args.filter):
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
3
|
+
import gitlab
|
|
4
|
+
|
|
5
|
+
from labrat.cli import common
|
|
6
|
+
from labrat.controllers.groups import Groups
|
|
7
|
+
|
|
8
|
+
def build_parser(parsers):
|
|
9
|
+
parser = parsers.add_parser("groups", help="Manage GitLab groups")
|
|
10
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
11
|
+
|
|
12
|
+
list_parser = common.add_filtered_parser(subparsers, "list", handle_list_args, aliases=["ls"], help="List GitLab groups", filter_required=False)
|
|
13
|
+
list_parser.add_argument("-m", "--min-access-level", required=False, type=int, help="Minimum access level to filter groups", default=0)
|
|
14
|
+
list_parser.add_argument("-u", "--user", action="append", required=False, help="Filter agent performing action")
|
|
15
|
+
|
|
16
|
+
create_token_parser = common.add_filtered_parser(subparsers, "create_token", handle_create_token_args, help="Create an access token", filter_required=True)
|
|
17
|
+
create_token_parser.add_argument("-l", "--access-level", required=False, type=int, help="Access level for the access token", default=50)
|
|
18
|
+
create_token_parser.add_argument("-d", "--days", required=False, type=int, help="Number of days until the token expires", default=60)
|
|
19
|
+
create_token_parser.add_argument("-n", "--token-name", required=False, help="Name for the access token", default="project_bot")
|
|
20
|
+
create_token_parser.add_argument("-s", "--scopes", required=False, help="Comma-separated list of scopes for the access token", default="api,read_repository,write_repository")
|
|
21
|
+
create_token_parser.add_argument("-u", "--user", action="append", required=False, help="Filter agent performing action")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
parser.set_defaults(controller=Groups())
|
|
25
|
+
return subparsers
|
|
26
|
+
|
|
27
|
+
def handle_list_args(args):
|
|
28
|
+
headers = ["Host", "ID", "Name", "Access Level", "Agents"]
|
|
29
|
+
data = []
|
|
30
|
+
|
|
31
|
+
for group in args.controller.list(args.filter, args.user):
|
|
32
|
+
# color each username by that agent's access level (higher -> brighter)
|
|
33
|
+
usernames = []
|
|
34
|
+
for agent in group.agents:
|
|
35
|
+
colored_username = common.color_access_level(agent.access_level, f"{agent.username} ({agent.access_level})")
|
|
36
|
+
usernames.append(colored_username)
|
|
37
|
+
|
|
38
|
+
# Add group information to data table
|
|
39
|
+
data.append([
|
|
40
|
+
group.host,
|
|
41
|
+
group.id,
|
|
42
|
+
group.name,
|
|
43
|
+
f"{group.access_level} ({gitlab.const.AccessLevel(group.access_level).name.lower()})",
|
|
44
|
+
", ".join(usernames)
|
|
45
|
+
])
|
|
46
|
+
|
|
47
|
+
common.print_table(headers, data)
|
|
48
|
+
|
|
49
|
+
def handle_create_token_args(args):
|
|
50
|
+
expiration = (datetime.datetime.now() + datetime.timedelta(days=args.days)).strftime("%Y-%m-%d")
|
|
51
|
+
for group, agent, err in args.controller.create_token(args.token_name, args.access_level, args.scopes.split(","), expiration, args.user, args.filter):
|
|
52
|
+
if err:
|
|
53
|
+
print(f"[!] Failed to create access token for {group.web_url}: {err}")
|
|
54
|
+
else:
|
|
55
|
+
print(f"[+] Successfully created access token for {group.web_url}: {agent.private_token}")
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
|
|
3
|
+
from labrat.core.agent import Agent
|
|
4
|
+
from labrat.core.config import Config
|
|
5
|
+
from labrat.core.utils import obj_filter
|
|
6
|
+
|
|
7
|
+
class Groups:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
self.config = Config(authed_only=True)
|
|
10
|
+
|
|
11
|
+
def list(self, filter=None, agent_filter=None, min_level=0):
|
|
12
|
+
"""List groups accessible by agents.
|
|
13
|
+
|
|
14
|
+
Keyword arguments:
|
|
15
|
+
- filter: Regex filter and field selection passed to `utils.obj_filter()` for group objects
|
|
16
|
+
- agent_filter: Regex filter and field selection passed to `utils.obj_filter()` for agent objects
|
|
17
|
+
- min_level: Minimum desired access level for agent to return a group
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
group_map = {}
|
|
21
|
+
for section, agent in self.config.filter(agent_filter):
|
|
22
|
+
groups = agent.gitlab.groups.list(all=True)
|
|
23
|
+
for group in groups:
|
|
24
|
+
access_level = self.get_group_access_level(agent, group)
|
|
25
|
+
if access_level < min_level:
|
|
26
|
+
continue
|
|
27
|
+
|
|
28
|
+
# Agent enrichment with shallow copy
|
|
29
|
+
agent_copy = copy.copy(agent)
|
|
30
|
+
agent_copy.access_level = access_level
|
|
31
|
+
|
|
32
|
+
# Group enrichment
|
|
33
|
+
group.host = agent.host
|
|
34
|
+
|
|
35
|
+
# Add group and agent to map
|
|
36
|
+
if group.web_url not in group_map:
|
|
37
|
+
group.agents = [agent_copy]
|
|
38
|
+
group.access_level = access_level
|
|
39
|
+
group_map[group.web_url] = group
|
|
40
|
+
else:
|
|
41
|
+
group_map[group.web_url].agents.append(agent_copy)
|
|
42
|
+
group_map[group.web_url].access_level = max(group_map[group.web_url].access_level, access_level)
|
|
43
|
+
|
|
44
|
+
return [group for group in group_map.values() if not filter or obj_filter(group, filter)]
|
|
45
|
+
|
|
46
|
+
def create_token(self, name, access_level, scopes, expires_at, agent_filter=None, filter=None):
|
|
47
|
+
""" Create Group Access Tokens.
|
|
48
|
+
|
|
49
|
+
Keyword arguments:
|
|
50
|
+
- name: Name of the access token.
|
|
51
|
+
- access_level: Access level of the created PAT.
|
|
52
|
+
- scopes: List of scopes for the created PAT. (e.g. `['read_repository', 'write_repository']`)
|
|
53
|
+
- expires_at: ISO format expiration date for the created PAT.
|
|
54
|
+
- agent_filter: Regex filter and field selection passed to `utils.obj_filter()` for agent objects.
|
|
55
|
+
- filter: Regex filter and field selection passed to `utils.obj_filter()` for group objects.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
for group in self.list(filter=filter, agent_filter=agent_filter, min_level=50):
|
|
59
|
+
agent = group.agents[0]
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
req = group.access_tokens.create({
|
|
63
|
+
'name': name,
|
|
64
|
+
'access_level': access_level,
|
|
65
|
+
'scopes': scopes,
|
|
66
|
+
'expires_at': expires_at
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
section = f"{req.user_id}_{group.id}@{agent.host}"
|
|
70
|
+
group_agent = Agent(agent.url, username=name, private_token=req.token, section=section)
|
|
71
|
+
self.config[section] = group_agent.to_dict()
|
|
72
|
+
|
|
73
|
+
yield group, group_agent, None
|
|
74
|
+
except Exception as e:
|
|
75
|
+
yield group, None, e
|
|
76
|
+
|
|
77
|
+
def get_group_access_level(self, agent, group):
|
|
78
|
+
try:
|
|
79
|
+
return group.members.get(agent.id).access_level
|
|
80
|
+
except Exception as e:
|
|
81
|
+
return 60 if agent.is_admin else 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# labrat/main.py
|
|
2
2
|
import argparse
|
|
3
|
-
from labrat.cli import agents, auth, projects, users
|
|
3
|
+
from labrat.cli import agents, auth, projects, groups, users
|
|
4
4
|
|
|
5
5
|
def main():
|
|
6
6
|
parser = argparse.ArgumentParser(
|
|
@@ -9,7 +9,7 @@ def main():
|
|
|
9
9
|
)
|
|
10
10
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
11
11
|
|
|
12
|
-
for command in [agents, auth, projects, users]:
|
|
12
|
+
for command in [agents, auth, projects, groups, users]:
|
|
13
13
|
command.build_parser(subparsers)
|
|
14
14
|
|
|
15
15
|
args = parser.parse_args()
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gitlabrat"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.3"
|
|
8
8
|
description = "LabRat: GitLab exploitation orchestrator"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -13,7 +13,7 @@ authors = [
|
|
|
13
13
|
]
|
|
14
14
|
license = {text = "GPL-3.0"}
|
|
15
15
|
classifiers = [
|
|
16
|
-
"Development Status ::
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
17
|
"Intended Audience :: Developers",
|
|
18
18
|
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
19
19
|
"Programming Language :: Python :: 3",
|
|
@@ -30,9 +30,9 @@ dependencies = [
|
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
[project.urls]
|
|
33
|
-
Homepage = "https://github.com/JChamblee99/
|
|
34
|
-
Repository = "https://github.com/JChamblee99/
|
|
35
|
-
Issues = "https://github.com/JChamblee99/
|
|
33
|
+
Homepage = "https://github.com/JChamblee99/Labrat"
|
|
34
|
+
Repository = "https://github.com/JChamblee99/Labrat.git"
|
|
35
|
+
Issues = "https://github.com/JChamblee99/Labrt/issues"
|
|
36
36
|
|
|
37
37
|
[project.scripts]
|
|
38
38
|
labrat = "labrat.main:main"
|
gitlabrat-1.2/PKG-INFO
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: gitlabrat
|
|
3
|
-
Version: 1.2
|
|
4
|
-
Summary: LabRat: GitLab exploitation orchestrator
|
|
5
|
-
Project-URL: Homepage, https://github.com/JChamblee99/LabRat
|
|
6
|
-
Project-URL: Repository, https://github.com/JChamblee99/LabRat.git
|
|
7
|
-
Project-URL: Issues, https://github.com/JChamblee99/LabRat/issues
|
|
8
|
-
Author-email: John Chamblee <conway.py@proton.farm>
|
|
9
|
-
License: GPL-3.0
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Classifier: Development Status :: 3 - Alpha
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
Requires-Python: >=3.8
|
|
20
|
-
Requires-Dist: beautifulsoup4>=4.9.0
|
|
21
|
-
Requires-Dist: gitpython>=3.1.0
|
|
22
|
-
Requires-Dist: python-gitlab>=3.0.0
|
|
23
|
-
Requires-Dist: requests>=2.25.0
|
|
24
|
-
Description-Content-Type: text/markdown
|
|
25
|
-
|
|
26
|
-
<div align="center">
|
|
27
|
-
|
|
28
|
-
# LabRat
|
|
29
|
-
|
|
30
|
-
**GitLab exploitation orchestrator.**
|
|
31
|
-
|
|
32
|
-
[](https://pypi.org/project/gitlabrat/)
|
|
33
|
-
[](https://pypi.org/project/gitlabrat/)
|
|
34
|
-
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
35
|
-
[](https://github.com/JChamblee99/LabRat/commits/main)
|
|
36
|
-
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Overview
|
|
42
|
-
|
|
43
|
-
LabRat automates common GitLab exploitation workflows: credential spraying, token creation, project enumeration, repository cloning, and bulk updates.
|
|
44
|
-
|
|
45
|
-
## Features
|
|
46
|
-
|
|
47
|
-
- **Authentication** — Spray credentials or combo lists across GitLab instances with optional LDAP support
|
|
48
|
-
- **Agent management** — Track access tokens and push SSH keys across available agents
|
|
49
|
-
- **Project operations** — Enumerate, clone, create access tokens, and perform procedural updates on repositories
|
|
50
|
-
- **User enumeration** — List users with advanced filtering and create access tokens
|
|
51
|
-
|
|
52
|
-
## Installation
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
pip install gitlabrat
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
> Requires **Python 3.8+**
|
|
59
|
-
|
|
60
|
-
## Quick Start
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
# Authenticate to a GitLab instance
|
|
64
|
-
labrat auth -t https://gitlab.example.com -u username -p password
|
|
65
|
-
|
|
66
|
-
# List authenticated agents
|
|
67
|
-
labrat agents ls
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Usage
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
labrat [-h] {agents,auth,projects,users} ...
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Dependencies
|
|
77
|
-
|
|
78
|
-
| Package | Purpose |
|
|
79
|
-
|---------|---------|
|
|
80
|
-
| [python-gitlab](https://python-gitlab.readthedocs.io/) | GitLab API client |
|
|
81
|
-
| [GitPython](https://gitpython.readthedocs.io/) | Git repository operations |
|
|
82
|
-
| [BeautifulSoup4](https://www.crummy.com/software/BeautifulSoup/) | HTML parsing for session auth |
|
|
83
|
-
| [Requests](https://docs.python-requests.org/) | HTTP session management |
|
|
84
|
-
|
|
85
|
-
## Disclaimer
|
|
86
|
-
|
|
87
|
-
This tool is intended for **authorized security testing and research only**. The author assumes no liability for misuse. Always obtain proper authorization before testing against any system you do not own.
|
|
88
|
-
|
|
89
|
-
## License
|
|
90
|
-
|
|
91
|
-
[GNU General Public License v3.0](LICENSE)
|
gitlabrat-1.2/README.md
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
# LabRat
|
|
4
|
-
|
|
5
|
-
**GitLab exploitation orchestrator.**
|
|
6
|
-
|
|
7
|
-
[](https://pypi.org/project/gitlabrat/)
|
|
8
|
-
[](https://pypi.org/project/gitlabrat/)
|
|
9
|
-
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
10
|
-
[](https://github.com/JChamblee99/LabRat/commits/main)
|
|
11
|
-
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Overview
|
|
17
|
-
|
|
18
|
-
LabRat automates common GitLab exploitation workflows: credential spraying, token creation, project enumeration, repository cloning, and bulk updates.
|
|
19
|
-
|
|
20
|
-
## Features
|
|
21
|
-
|
|
22
|
-
- **Authentication** — Spray credentials or combo lists across GitLab instances with optional LDAP support
|
|
23
|
-
- **Agent management** — Track access tokens and push SSH keys across available agents
|
|
24
|
-
- **Project operations** — Enumerate, clone, create access tokens, and perform procedural updates on repositories
|
|
25
|
-
- **User enumeration** — List users with advanced filtering and create access tokens
|
|
26
|
-
|
|
27
|
-
## Installation
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
pip install gitlabrat
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
> Requires **Python 3.8+**
|
|
34
|
-
|
|
35
|
-
## Quick Start
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
# Authenticate to a GitLab instance
|
|
39
|
-
labrat auth -t https://gitlab.example.com -u username -p password
|
|
40
|
-
|
|
41
|
-
# List authenticated agents
|
|
42
|
-
labrat agents ls
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Usage
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
labrat [-h] {agents,auth,projects,users} ...
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Dependencies
|
|
52
|
-
|
|
53
|
-
| Package | Purpose |
|
|
54
|
-
|---------|---------|
|
|
55
|
-
| [python-gitlab](https://python-gitlab.readthedocs.io/) | GitLab API client |
|
|
56
|
-
| [GitPython](https://gitpython.readthedocs.io/) | Git repository operations |
|
|
57
|
-
| [BeautifulSoup4](https://www.crummy.com/software/BeautifulSoup/) | HTML parsing for session auth |
|
|
58
|
-
| [Requests](https://docs.python-requests.org/) | HTTP session management |
|
|
59
|
-
|
|
60
|
-
## Disclaimer
|
|
61
|
-
|
|
62
|
-
This tool is intended for **authorized security testing and research only**. The author assumes no liability for misuse. Always obtain proper authorization before testing against any system you do not own.
|
|
63
|
-
|
|
64
|
-
## License
|
|
65
|
-
|
|
66
|
-
[GNU General Public License v3.0](LICENSE)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|