relift

See the attack path first.

Relift audits the databases and hosts you own, verifies credentials you already hold, and joins what it finds into the attack thread that actually connects.

Version 0.2.0 · Linux and Windows · no drivers, no account

scope.json · relift-labexpires 2026-12-31
allow  10.20.0.0/16 *.lab.pixelcity.dev db.internal deny   10.20.4.0/24 prod.internal
ALLOWMatched *.lab.pixelcity.dev. In scope until the engagement expires.

One path down through four layers

relift · the descentscroll to follow the path

Surface

The host answers: open ports, its banner, its certificate, and the SSH algorithms it still agrees to speak.recon.port_scan · tls.certificate · auth.ssh_algorithms

Four layers. One path. Every stage is a finding you can read.

The tool, at real size.

Fragments of the interface, not screenshots of a mock-up. The row below is output from a run against a lab MySQL server, carried through the three states that matter.

observed

db.credCredential for root accepted on mysql127.0.0.1:53306 · mysql 8.0.46 · authenticated · superusercrit
1 of 6 findingsrun 20261107-144439

One row from a real run. No CVSS guess, no adjectives — the credential was accepted and the server said so.

correlated

attack thread · 1 of 2confidence high
threadHeld mysql credential still works and is superusercredential access→privilege escalation→collectioncrit

Rotate the credential, then find its source: config file, CI secret, backup, or an application default. Rotation without that step only resets the clock.

credential accepted

The thread names the stage that breaks it. Tick the box to rotate: the row resolves, and nothing else on the page needs to change.

broken

db.credNo credential on recordRotate the credential in the row above to close this threadclosed
verified once per credential0 retries

Relift attempts each credential once. A thread closes when the finding that carried it is gone, not when someone marks it resolved.

Relift desktop application showing a finished MySQL run: seven findings with severity tags, a critical credential finding and two attack threads.
The desktop application after a real run: seven findings, one critical credential, two threads. Same engine as the CLI, same scope file.
Relift desktop runs table listing stored runs by target, profile, finding count and worst severity.
Every run is stored and re-openable. The audit trail is append-only and the threads are recomputed from the record.

Every thread names where it breaks.

A finding is a fact. A thread is an argument about how the facts join up — and the one control that would have stopped it.

Stages

Every finding takes a stage. The thread will not draw a line between two stages that do not share an asset.

Confidence

High when the join is direct evidence, medium when it is an inference you should check yourself.

No invention

A thread is built only from findings in that run. An empty run produces no threads, not a generic one.

attack thread · analysis.attack_chainsrun 20261107-144439
critHeld mysql credential still works and is superusercredential access→privilege escalation→collectioncrit

Rotate the credential, then find its source: config file, CI secret, backup, or an application default. Rotation without that step only resets the clock.

highmysql accepts reusable credentials in the clearreconnaissance→credential access→pivothigh
2 threads · 6 findings4 of 6 techniques executed

Break point

One control, written as an instruction: rotate the key, bind the listener, enable authentication.

Evidence

The bytes, headers or numbers that produced the stage sit next to it, not in a separate report.

Coverage

What ran and what did not is printed with the findings, so an empty section is a fact rather than an omission.

Three commands, one gate.

Write the scope, read the plan, then decide to send traffic. The plan is free; --execute is the only thing that touches the network.

The plan is the product

target
mysql://10.20.7.9:3306/app
scope
relift-lab · 10.20.0.0/16 · denies 10.20.4.0/24 · expires 2026-12-31
profile
lab — safe plus intrusive, because the scope allows it
execute
off. Six techniques are planned and none is sent until you say so.
shellrelift 0.2.0
# 1. write the allowlist
relift init-scope --engagement lab \
  --host 10.20.0.0/16 --deny 10.20.4.0/24 --out scope.json

# 2. read the plan (no traffic)
relift plan --target mysql://10.20.7.9:3306/app \
  --scope scope.json

# 3. send it
relift scan --target mysql://10.20.7.9:3306/app \
  --scope scope.json --execute

# and the threads, from the stored run
relift chains --run latest

Exit codes are part of the interface: 0 clean, 1 module errors, 2 refused by the gate, 3 bad usage. Nothing is scanned to find out which.

Measured, not promised.

The repository ships its own test suite and its own catalogue. Both numbers are read off the build in front of you.

6database engines spoken at the protocol level, no drivers installed
24techniques in the catalogue, each with a risk tier and a module behind it
159tests covering the scope gate, the wire codecs and the thread rules
1attempt per credential, then graded and recorded. No retry loop exists.

The questions that decide it.

Do I need a scope file?

Yes. Nothing runs without one: an expiring allowlist with an owner, a risk ceiling and an audit log. Deny rules win, a wildcard never matches its apex, and a range wider than /22 is refused unless you say otherwise. That gate is the first thing the engine builds, not a wrapper around it.

Does it guess passwords?

No. There is no wordlist, no default-credential list and no retry loop anywhere in the tree. A database credential is verified once, against a host that already matches your scope, and the result is recorded as accepted, refused, or not attempted.

What does it leave on my servers?

Read-only protocol exchanges. It does not write rows, drop tables, dump schemas or upload files, and the intrusive techniques are the only ones that authenticate at all. The SQL injection check is capped at eight requests with a fixed payload set — no UNION, no stacked statements, no file reads.

Which databases does it speak?

PostgreSQL, MySQL and MariaDB, Redis, MongoDB, MSSQL, and Elasticsearch over HTTP. The wire codecs are hand-written: startup, SCRAM, TDS pre-login, RESP, BSON and OP_MSG. That is why there are no drivers to install and no version drift to chase.

Is the desktop app a different tool?

No. It serves the same runner over a loopback-only API with a per-launch token, and rejects any request carrying a foreign origin. The scope gate is the same code path as the CLI, so the window cannot talk its way past the tier ceiling.

Windows and Linux?

Both. The CLI ships as a single-file executable for each, and the desktop build is a single .exe or ELF binary with the UI bundled inside. The Python package and a portable zipapp are also on the release page.

Lift your own surface.

Download the binary, write a scope file, and read the first plan. If the plan is wrong, you have lost nothing and sent nothing.

Built for your lab, your servers and your VPS. Pointing it anywhere else is on you, and the scope file is the only thing that makes it legal.