____ _ ____ ____ ____ ____ _ _
|___ | |___ | | |___ | | \/
| | | |__| | |__| _/\_
FIFOFox v1.2.3 (ilegnisi) - Windows named-pipe security auditor & fuzzer
FIFOFox is a single-file, zero-dependency Windows named-pipe security toolkit
written in pure C, no installer, no runtime, no NuGet/pip. One small .exe takes
you from recon all the way to protocol reverse-engineering:
- Enumerate & grade every pipe's DACL on the box, and flag the dangerous ones.
- Deep-audit a single endpoint: SDDL, geometry, server/client PIDs, squattability.
- Capture live traffic through an interception (MITM) relay and bank a fuzz corpus.
- Fuzz a pipe server with crash detection - blind or structure-aware from a corpus.
- Squat / impersonate a pipe name for the dual-use escalation cases (gated).
- Craft, send, and decode length-prefixed protobuf IPC messages, so you can actually talk to a service and read what it says back.
It is deliberately a standard-user tool first: the most interesting view of a pipe's attack surface is the one a low-privileged process sees. Admin only adds visibility; a service context is needed only to weaponize impersonation.
⚠️ Warning.fuzz,capture, andsquatare intrusive and can crash services;squat --impersonateis precisely the behavior EDR rules flag. Use only on systems you own or are explicitly authorized to test.
The
decodeandcraftprotocol tooling in this build grew directly out of a live named-pipe research engagement against a LocalSystem updater IPC. See the companion Zero Science Lab write-up - https://www.zeroscience.mk/#/lablog/named-pipes-a-signature-gate-and-a-dead-end-lpe
- 1. Build
- 2. Administrator rights
- 3. Command synopsis
- 4. Commands in detail
- 5. Severity model
- 6. HTML reports
- 7. Output files
- 8. Limitations and caveats
- 9. Exit codes
- 10. Typical workflow
- 11. Changelog
- 12. Credits
| Mode | What it does |
|---|---|
enum |
Enumerate and grade every pipe's DACL; optional HTML report. |
listeners |
Enumerate loopback/wildcard TCP IPC endpoints + owner/privilege (the other half of local IPC). |
audit |
Deep single-pipe report: SDDL, geometry, PIDs, squattability, owning-service escalation surface + trust-predicate linter. |
capture |
Interception relay (MITM); logs both directions + writes a fuzz corpus. |
fuzz |
Frame fuzzer with crash detection; structure-aware with a corpus. |
squat |
Claim/relay a pipe name; optional --impersonate (gated). |
send |
Deliver one message (raw/framed or a crafted kiros frame) and decode the reply. |
craft |
Build a Logitech "kiros" protobuf request frame from flags. |
decode |
Offline protobuf/framing dissector (file / corpus / hex). |
No external dependencies beyond advapi32 (SDDL/ACL/SID/token) and kernel32
(pipe APIs). C89-clean; builds on both major Windows toolchains.
:: MSVC (from a "x64 Native Tools" Developer Command Prompt)
cl /W3 /O2 /D_CRT_SECURE_NO_WARNINGS fifofox.c
:: MinGW-w64
gcc -O2 -Wall -o fifofox.exe fifofox.c -ladvapi32Under MSVC the advapi32.lib link is automatic via #pragma comment(lib,...).
Under MinGW you must pass -ladvapi32 as shown.
No - and running as a standard user is usually the most informative way to use it, because that is exactly the low-privilege attack surface you want to measure. Admin/SYSTEM only adds visibility; a service context is needed only to weaponize impersonation.
| Operation | Standard user | Administrator | SYSTEM / service (SeImpersonatePrivilege) |
|---|---|---|---|
Enumerate \\.\pipe\ (enum) |
yes | yes | yes |
| Read a pipe's SD / grade DACL | yes if the DACL grants the caller READ_CONTROL (most do; restrictive ones show N/A) |
yes (reads more restrictive SDs) | yes |
Resolve server image path (audit, HTML) |
partial - denied for processes owned by other users / SYSTEM → (OpenProcess denied) |
yes (resolves most) | yes |
Connect + send/fuzz a pipe |
yes if the DACL grants connect (e.g. Everyone:FA, NULL DACL) |
yes | yes |
capture (create competing instance) |
yes unless server used FILE_FLAG_FIRST_PIPE_INSTANCE |
yes | yes |
squat (claim a free name) |
yes | yes | yes |
Weaponize squat --impersonate → act as SYSTEM |
no (token obtained but not usable) | no | yes (requires SeImpersonatePrivilege) |
decode / craft (offline) |
yes (no connection at all) | yes | yes |
Recommendation: run enum/audit first as your normal account to see the real
low-priv exposure, then optionally re-run elevated to fill in server image paths
and any SDs you couldn't read.
fifofox enum [--all] [--squat] [--html <file>]
fifofox listeners [--all] (loopback TCP IPC endpoints + owner)
fifofox audit <pipe> [--html <file>]
fifofox capture <pipe> --authorized [--count N]
fifofox fuzz <pipe> --authorized [options]
fifofox squat <pipe> --authorized [--impersonate] [--timeout <sec>]
fifofox send <pipe> --authorized (--str|--json <txt>|--data <f>|--kiros ...) [--frame F] [--nl] [--read ms]
fifofox decode <file> [--corpus] | decode --hex <hexbytes>
fifofox craft --path <topic> [--type <url> --arg <s>] [--out <f>]
fifofox version | help
<pipe> may be a bare name (cowork-vm-service) or a full device path
(\\.\pipe\cowork-vm-service). The bare form is expanded to \\.\pipe\<name>.
| Flag | Effect |
|---|---|
-v, --verbose |
Narrate each step to stderr ([*] ...). Keeps stdout/HTML clean for redirection. |
--debug |
Verbose plus handles, Win32 error codes, and per-iteration fuzz detail ([dbg] ...). Implies -v. |
--color |
Force ANSI color on (even when redirected). |
--no-color |
Force ANSI color off. |
--no-banner |
Suppress the startup banner. |
--no-decode (alias --raw) |
Print raw hex only; skip the protobuf/framing dissection that send, capture, and decode apply by default. |
--no-service |
In audit, skip the owning-service / unquoted-path / directory-ACL escalation-surface check. |
Operational logging goes to stderr on purpose, so fifofox enum --html r.html -v
won't pollute the report or any piped stdout. Console color is auto-enabled on an
interactive VT console and auto-disabled when stdout is redirected/piped or when
NO_COLOR is set, so a redirected report/log never contains escape codes.
Walks \\.\pipe\*, reads each pipe's security descriptor, converts it to SDDL, and
grades the DACL (see 5). By default prints only flagged
pipes (WARN/DANGER) plus a summary. Each row also shows the pipe's owner (from
its security descriptor, e.g. NT AUTHORITY\SYSTEM, BUILTIN\Administrators, or a
user SID), so a privileged-owned pipe with a permissive DACL stands out at a glance.
| Option | Meaning |
|---|---|
--all |
Also list OK pipes and unreadable ones (N/A), not just flagged. |
--squat |
Active probe. For each pipe, also attempt a FILE_FLAG_FIRST_PIPE_INSTANCE create; if it succeeds the name has no owner → flagged DANGER (squattable). |
--html <file> |
Additionally write a standalone HTML security-overview report. |
fifofox enum :: just the flagged pipes + summary
fifofox enum --all :: everything, including OK / N/A
fifofox enum --all --html report.html :: full report to console + HTMLBehaviour note:
enumopens a client handle (READ_CONTROL) to each pipe to read its SD. On some servers this registers as a momentary connection. It is read-only, but be aware of it on sensitive hosts.
Named pipes are one local-IPC transport; loopback TCP is the other half (auto-updaters,
agents, "Elevator" helpers). Lists every 127.0.0.1/::1 (and wildcard 0.0.0.0/::)
TCP listener with its owning process and account/privilege - because any local
user can connect to a loopback listener (TCP has no DACL), so the risk is the owner's
privilege. A SYSTEM-owned loopback listener is the auto-updater IPC attack surface.
| Option | Meaning |
|---|---|
| (none) | loopback + wildcard listeners only |
--all |
include listeners on every interface |
Owners are resolved via the service account first (so SYSTEM services resolve even
when OpenProcess is denied), else the process token. Grading: DANGER = SYSTEM/
LocalSystem owner; WARN = LocalService/NetworkService; ok = normal user.
fifofox listeners :: loopback/wildcard endpoints + owner
fifofox listeners --all :: every interface
[DANGER] 127.0.0.1:4767 (loopback) PID 5092 PanGPS.exe owner: LocalSystem [svc:PanGPS]
[ ok ] 127.0.0.1:19010 (loopback) PID 4270 logioptionsplus_agent.exe owner: LAB17\you
Then probe an interesting one's protocol with a client / decode (it speaks JSON, protobuf,
DCE/RPC, …). TCP listeners have no HTML report yet.
Full report for one pipe: GetNamedPipeInfo geometry (type, buffer sizes, max
instances), server + client PID and image path, the pipe owner (from its SD), a
best-effort live server integrity level (Low/Medium/High/System, or "denied" =
higher-IL than you), SDDL, ACE-by-ACE grade, and a live squattability test.
| Option | Meaning |
|---|---|
--html <file> |
Write a single-row HTML report including geometry + squattability. |
--peek |
Passively read any unsolicited server greeting and auto-detect its format (protobuf/DCE-RPC/.NET/JSON/…). Request/response servers that volunteer nothing are reported as such. Opt-in (it connects + reads). |
fifofox audit cowork-vm-service
fifofox audit cowork-vm-service --html pipe.html
fifofox audit \\.\pipe\lsass --debugA squattable result escalates the overall verdict to DANGER independently of the
DACL grade. Because the squat test doesn't need the pipe to currently exist, audit
runs it even for a stopped/not-yet-started service, the most useful case:
can the name be pre-created and squatted before the legitimate server claims it?
Escalation surface behind the pipe. audit then maps the pipe to its owning
service (via the SCM, which a standard user can read even when OpenProcess on a
SYSTEM service is denied) and assesses the classic local-EoP surface behind the
endpoint. Disable with --no-service:
- Service + account - service name, display name, and the account it runs as
(flagged when privileged, i.e.
LocalSystem). - Unquoted ImagePath - flags an unquoted path with spaces and checks whether
any intercept directory is low-priv writable. Inherit-only ACEs are correctly
ignored, so
C:\-rooted unquoted paths are reported "not exploitable" rather than crying wolf - exactly the distinction that separates a real finding from noise. - Binary directory / file - whether a low-priv SID can plant a side-load DLL in the service's program directory or replace the executable; DANGER when the service is privileged, WARN (cross-user code-integrity) otherwise.
- Trust-predicate linter (heuristic, static) - greps the service binary (ASCII +
UTF-16) for the recurring auto-updater weaknesses:
CryptQueryObject/cert-chain APIs withoutWinVerifyTrust(CWE-347, signature existence != validity), hardcodedCN=signer strings (substring-match risk), a temp path +CreateProcessAsUser(copy->verify->exec TOCTOU), and toggleable*signature*/check_msi_digestconfig flags. Notes only - it flags leads to confirm, it does not change the verdict grade.
--- owning service / escalation surface ---
service OptionsPlusUpdaterService - Logi Options+
account LocalSystem (privileged)
imagepath "C:\Program Files\LogiOptionsPlus\logioptionsplus_updater.exe" --run-as-service
unquoted no (path is quoted)
binary dir [C:\Program Files\LogiOptionsPlus] : not low-priv writable
binary file [...\logioptionsplus_updater.exe] : not low-priv writable
svc verdict OK - no low-priv write into the service's executable surface
For a svchost-hosted (shared) service the per-service binary can't be attributed
from the PID alone, so the unquoted/dir checks are skipped with a note. If the pipe
owner isn't a service at all, audit still reports the owning image's directory ACL
(a DLL-hijack surface for whoever runs it).
Creates a competing instance of the target pipe name, waits for a client to land
on it, dials the real server, and relays bytes both ways, logging every chunk and
writing client→server frames to a corpus for fuzz. With decoding enabled
(default), each direction is also dissected into the transcript.
| Option | Meaning |
|---|---|
--authorized |
Required. Affirms you have permission (else exit 2). |
--count N |
Number of client sessions to relay before exiting (default 1). |
fifofox capture cowork-vm-service --authorized --count 5 -vRequires that the real server did not use FILE_FLAG_FIRST_PIPE_INSTANCE
(check with audit first). If it did, CreateNamedPipe returns ACCESS_DENIED and
capture reports it as impossible, which is itself the security finding. Interception
is opportunistic and EDR-visible.
Connects as a client and sends mutated frames, reads responses non-blocking, and detects when the pipe disappears (probable server crash), dumping a repro.
| Option | Default | Meaning |
|---|---|---|
--authorized |
- | Required. |
--frame <kind> |
raw |
Wire framing: raw, len16le, len16be, len32le, len32be, cmd. |
--cmd <prefix> |
"3 " |
Command prefix when --frame cmd (Timbuktu-style command messages). |
--corpus <file> |
none | Seed mutations from a capture corpus (structure-aware; ~65% of cases mutate a real frame). |
--iters <N> |
500 |
Number of test cases. |
--seed <hex|dec> |
fixed | PRNG seed for reproducible runs (0 → built-in fixed seed). |
--maxlen <N> |
4096 |
Max length of random payloads. |
--delay <ms> |
15 |
Delay between iterations (and pre-read settle time). |
:: blind, length-prefixed
fifofox fuzz cowork-vm-service --authorized --frame len32le --iters 2000
:: structure-aware using a captured corpus, reproducible
fifofox fuzz cowork-vm-service --authorized --corpus fifofox_corpus_123.bin --seed 0xC0FFEE -vWith a corpus, mutation is format-aware: recognised frames (kiros/protobuf, DCE/RPC)
are kept structurally valid and only their inner fields/stub are fuzzed, so the target
parses past the framing into the handler; the rest of the time, byte-level strategies are
cycled (corpus-havoc dominates when a corpus is loaded): random,
long-A overflow walls, format-string, path-traversal, length-lie (tiny
body, declared length 0x7FFFFFFF), 0x00/0xFF boundaries, zero/short, and
corpus-havoc (bit-flips/truncation/padding of real frames). On a crash
(WaitNamedPipe → ERROR_FILE_NOT_FOUND) the offending bytes are saved to
crash_<ts>_<iter>.bin and the run stops.
Claims the pipe name with FILE_FLAG_FIRST_PIPE_INSTANCE, waits for a client, and
optionally impersonates it to show the squat→impersonation risk.
| Option | Meaning |
|---|---|
--authorized |
Required. |
--impersonate |
After a client connects, call ImpersonateNamedPipeClient() and print the impersonated user + integrity level. |
--timeout <sec> |
How long to wait for a client (default 30). |
fifofox squat cowork-vm-service --authorized --impersonate --timeout 60Obtaining a SYSTEM/High token here is only exploitable if your process holds
SeImpersonatePrivilege (service accounts, not standard users). Noisy by design -
the exact behavior the Elastic impersonation rule flags.
Connects as a client, sends one message, and prints + decodes the reply. Use
it to reverse a pipe's wire framing (send a benign message in each framing, see
which one replies), to deliver a crafted trigger, or - with --kiros - to build
and send a Logitech protobuf request in one step.
| Option | Meaning |
|---|---|
--authorized |
Required. |
--str <text> / --json <text> |
Message body = literal text (--json is a semantic hint). |
--data <file> |
Message body = raw file bytes (e.g. a captured/crafted frame). |
--kiros |
Build a kiros protobuf frame from flags instead of a body (see 4.8). |
--path / --type / --arg / --argraw |
(with --kiros) the route, Any type_url, and typed request field. |
--frame <kind> |
Length framing for --str/--json/--data: raw, len16le/be, len32le/be (default raw). |
--nl |
Append a trailing newline (line-delimited protocols). |
--read <ms> |
How long to wait for a reply (default 1500). |
:: probe framing with a benign read-only topic
fifofox send some-service --authorized --json "{\"op\":\"ping\"}" --frame len32le
:: deliver a captured/crafted trigger
fifofox send logitech_kiros_updater --authorized --data trigger.bin
:: craft + send a kiros message in one step (reply auto-decoded)
fifofox send logitech_kiros_agent-<id> --authorized --kiros --path /updates/depot/info ^
--type type.googleapis.com/logi.protocol.updates.Depot.Info --arg logioptionsplusA successful write with no reply still confirms low-priv reachability + write
to the server; silence usually means the framing/schema is wrong, or the server
authenticates the caller before replying. Replies are auto-dissected; add --raw for
hex only.
Turns captured bytes into a readable field tree without connecting to anything -
the same decoder send and capture apply inline. Protobuf is just one format; IPC
payloads come in many, so decode auto-detects the payload format and routes to
the matching dissector:
| Detected format | What it shows |
|---|---|
| protobuf / kiros | the u32be(8)["protobuf"] magic frame (incl. an outer u32le/u32be length wrapper), bare length-prefixed and raw protobuf; field tree (varint/i32/i64/str/bytes/msg) recursing into nested messages and google.protobuf.Any. |
| DCE/RPC (MSRPC) | PDU header (version, packet type, endianness, frag length, call id) + the bound interface UUID (resolved to lsarpc/samr/svcctl/spoolss/efsrpc/…) and the request opnum. |
| .NET serialization | BinaryFormatter / NetDataContractSerializer / NMF streams, flagged as an unsafe-deserialization candidate (feed to ysoserial.net). |
| JSON / XML / text | pretty-printed as text. |
| ASN.1 / DER | TLV skeleton (SEQUENCE/SET/INTEGER/OID/…) walk. |
| binary | hex+ASCII fallback. |
| Option | Meaning |
|---|---|
<file> |
A single captured frame. |
--corpus |
Treat <file> as a capture corpus ([u32le len][frame] records) and dissect each. |
--hex <bytes> |
Dissect an inline hex string instead of a file (whitespace/punctuation ignored). |
--format <f> |
Force the dissector (auto/protobuf/dcerpc/dotnet/json/xml/asn1/text/hex) when auto-detect guesses wrong. |
fifofox decode trigger.bin
fifofox decode fifofox_corpus_1730000000.bin --corpus
fifofox decode --hex "00000008 70726f746f627566 0000000d 0a..."[*] decoding trigger.bin (129 bytes)
[frame] magic="protobuf" payloadlen=113
f1: str[4] "9999"
f2: varint 1
f3: str[19] "/updates/depot/info"
f4: str[7] "backend"
f6: msg[73] {
f1: str[52] "type.googleapis.com/logi.protocol.updates.Depot.Info"
f2: msg[17] { f1: str[15] "logioptionsplus" }
}
So f3 is the route/topic, f6 is the typed Any request, and the inner f1 is
the argument, exactly the fields you set to interact with a service.
The inverse of decode: build a valid kiros request frame from flags, so you can
talk to the service without hand-assembling bytes. craft writes/previews the frame;
send --kiros builds and delivers it in one step.
u32be(8)["protobuf"] u32be(len) [ Message{ f1 msg_id, f2 verb, f3 path, f4 origin, f6 Any{type_url,value} } ]
| Option | Meaning |
|---|---|
--path <topic> |
Required. Route, e.g. /updates/depot/info. |
--type <url> |
google.protobuf.Any type_url (the typed request message). |
--arg <text> |
The request message's first (f1) string field, e.g. a depot name. |
--argraw <hex> |
Raw bytes for the Any value instead of --arg. |
--verb <n> |
Message verb (default 1 = request). |
--reqid <s> / --origin <s> |
Envelope msg_id (default 9999) / origin (default backend). |
--out <file> |
Write the frame to a file (else hex preview + self-decode only). |
:: build a depot-info query and save it for replay / relaying
fifofox craft --path /updates/depot/info ^
--type type.googleapis.com/logi.protocol.updates.Depot.Info --arg logioptionsplus ^
--out q.bin
:: then deliver it to a same-user pipe...
fifofox send logitech_kiros_agent-<id> --authorized --data q.bin --frame rawcraft always self-decodes what it built, so you can verify the frame before sending
it. The kiros decode/craft features are protocol-specific helpers; the rest of
FIFOFox is protocol-agnostic.
A pipe's DACL is graded by what low-privileged SIDs are granted. Low-priv SIDs:
Everyone (S-1-1-0), Authenticated Users (S-1-5-11), Users (S-1-5-32-545),
Anonymous (S-1-5-7), Guests (S-1-5-32-546), Power Users (S-1-5-32-547),
INTERACTIVE (S-1-5-4).
| Grade | Badge | Trigger |
|---|---|---|
| 2 | DANGER | Low-priv SID holds WRITE_DAC / WRITE_OWNER / GENERIC_ALL (object takeover), or a NULL DACL (everyone full), or the name is squattable. |
| 1 | WARN | Low-priv SID can write pipe data (FILE_WRITE_DATA / APPEND_DATA / GENERIC_WRITE / DELETE). |
| 0 | OK | No low-priv write right. |
| - | N/A | SD not readable as the current user. |
Important interpretation:
Everyone:Full("connect + read/write") is common by design for IPC pipes. The serious flags areWRITE_DAC/WRITE_OWNER/GENERIC_ALLto a low-priv SID, or a NULL DACL. A permissive DACL only governs who may connect - real privilege impact depends on the server's in-band authorization (does it authenticate the caller after accept?), which this tool does not evaluate. See 8.
enum --html and audit --html emit a standalone, self-contained HTML page
(embedded CSS, dark theme, no external assets):
- Header with tool version, hostname, and generation timestamp.
- Summary cards: total pipes, Danger / Warn / OK counts - click a card to filter the table to that severity (click Pipes to show all). Pure CSS (hidden radio + sibling combinator); no JavaScript, still a single self-contained file.
- A table per pipe: severity badge, pipe name, server PID, owner, server image path, findings
(flagged ACEs; for
auditalso geometry + squattability), and the full SDDL. - A footer severity key.
The table uses a fixed layout with defined column widths; long values (image paths, SDDL, long pipe names) wrap, and the SDDL/image cells become independently scrollable, so one long value can't stretch the whole report. All dynamic text is HTML-escaped, so SDDL/paths/names cannot break the markup. Safe to share as a report.
fifofox enum --all --html C:\reports\pipes_overview.html
fifofox audit cowork-vm-service --html C:\reports\cowork_pipe.html| File | Produced by | Contents |
|---|---|---|
fifofox_fuzz_<ts>.log |
fuzz |
Per-iteration strategy, declared/actual length, wire-byte hexdump, response hexdump, crash markers. |
crash_<ts>_<iter>.bin |
fuzz |
Exact wire bytes of a suspected crash case (replay to reproduce). |
fifofox_capture_<ts>.log |
capture |
C2S/S2C hexdump transcript (+ decoded field trees) of relayed traffic. |
fifofox_corpus_<ts>.bin |
capture |
Client→server frames as [u32 LE length][bytes] records - feed to fuzz --corpus or decode --corpus. |
<file> |
craft --out |
A single crafted kiros frame (replay with send --data). |
<file> |
--html |
HTML report (see 6). |
<ts> is a Unix timestamp; files land in the current working directory.
- In-band authorization is not assessed. The grade reflects who can connect and write, not whether the server authenticates callers afterward. A WARN/DANGER pipe may still be safe if the server validates the client; an OK pipe may be exploitable via protocol logic.
- TOCTOU / PID-reuse is not auto-detected. A content fuzzer can't find a check-then-use race in the auth layer; confirming that needs static RE plus a dedicated race harness with a protocol-specific oracle.
- Grader evaluates ALLOW ACEs only - it doesn't subtract DENY ACEs, so the grade
is a fast heuristic, not a full
AccessCheck. - Memory-safe targets. Against a Go/Rust/.NET server, the
long-A/length-liestrategies are unlikely to yield classic memory corruption; expect DoS (panic) and OOM signals rather than control-flow hijack. enumconnects to each pipe to read its SD (see 4.1 note).- ASCII names. Uses ANSI APIs; pipe names with non-ASCII characters may be mangled.
captureis opportunistic and EDR-visible (4.3).decode/craftare offline and safe - no connection, no side effects.
| Code | Meaning |
|---|---|
0 |
Success (or help/version). |
1 |
Usage error / missing argument / operation failure. |
2 |
A gated mode (fuzz/capture/squat/send) was run without --authorized. |
:: 1) Survey the whole box (as a standard user) and get a report
fifofox enum --all --html overview.html
:: 2) Drill into an interesting pipe
fifofox audit logitech_kiros_updater --html pipe.html
:: 3) Learn the protocol: dissect a captured/crafted frame
fifofox decode trigger.bin
:: 4) Talk to the service: craft a request, send it, read the decoded reply
fifofox send logitech_kiros_agent-<id> --authorized --kiros --path /updates/depot/info ^
--type type.googleapis.com/logi.protocol.updates.Depot.Info --arg logioptionsplus
:: 5) If not first-instance protected, capture live traffic into a corpus
fifofox capture some-service --authorized --count 5 -v
:: 6) Structure-aware fuzz from the corpus, watching for crashes
fifofox fuzz some-service --authorized --corpus fifofox_corpus_<ts>.bin -v
:: 7) (Optional, gated) demonstrate squat/impersonation feasibility
fifofox squat some-service --authorized --impersonatev1.2.3 (ilegnisi) - current
- New
listenersmode - loopback TCP IPC surface. Enumerates127.0.0.1/::1(and wildcard) TCP listeners with owning process + account/privilege, flagging SYSTEM-owned loopback listeners (the auto-updater/agent attack surface). Owner is resolved via the service account, so SYSTEM services resolve even whenOpenProcessis denied. Extends FIFOFox from a named-pipe tool toward a local-IPC tool. - Trust-predicate linter in
audit. Static heuristics on the owning service binary for the classic updater signature-verification weaknesses (CryptQueryObjectwithoutWinVerifyTrust= CWE-347,CN=substring signer checks, temp+CreateProcessAsUserTOCTOU, toggleable signature config flags). Reports leads; doesn't change the grade. - Multi-format payload dissection.
decode/send/capturenow auto-detect the payload format instead of assuming protobuf: protobuf/kiros, DCE/RPC (header + bound interface UUID + opnum), .NET serialization (flagged as an unsafe- deserialization candidate), JSON, XML, ASN.1/DER, text, or hex.--format <f>forces it. - Format-aware fuzzing.
fuzz --corpusnow keeps recognised frames structurally valid while mutating the inner content (protobuf field values incl. boundary varints and overflow strings; DCE/RPC stub with a fixed-up frag length), so the target parses past the framing into the handler instead of bouncing off the length check. audit --peek. Optional passive read of any unsolicited server greeting, then format auto-detect - tells you what protocol a pipe speaks without a full capture (request/response servers that volunteer nothing are reported as such).- Clickable severity filter in the HTML report. The Danger/Warn/OK summary cards are now clickable and filter the table to that severity (Pipes = show all), pure CSS, no JavaScript, still one self-contained file.
- Owner + integrity surfaced.
enumandauditnow show each pipe's owner (from its security descriptor - readable even when the server process can't be opened), so aSYSTEM/Administrators-owned pipe is obvious at a glance;auditadds a best-effort live server integrity level (Low/Medium/High/System, or "denied" = the server is higher-IL than you). auditnow maps the pipe to its owning service and assesses the escalation surface behind it: service account, unquoted ImagePath (with a writable- intercept-dir check that ignores inherit-only ACEs, soC:\paths aren't false positives), and a low-priv-writable binary directory/file (DLL-plant / replace)- DANGER when the service is privileged. Read-only; disable with
--no-service.
- DANGER when the service is privileged. Read-only; disable with
- New
decodemode - offline protobuf/framing dissector: the["protobuf"]magic frame, an outeru32le/u32belength wrapper (server replies use this), bare length-prefixed protobuf, and raw protobuf; recurses nested messages andgoogle.protobuf.Any. Inputs: a frame file, a--corpus, or inline--hex. - New
craftmode +send --kiros- build a Logitech kiros request frame from flags (--path/--type/--arg/--argraw/--verb/--reqid/--origin/--out);send --kirosbuilds and delivers in one step. - Auto-decode of traffic -
senddissects the reply andcapturedissects both directions into its transcript;--no-decode(alias--raw) prints hex only. - New
sendmode - precise single-message delivery + reply capture (--str/--json/--data,--frame,--nl,--read); the targeted counterpart tofuzzfor framing recovery and crafted-trigger delivery. squatno longer blocks forever: overlappedConnectNamedPipewith a real, configurable--timeout(default 30s) and an accurate wait message.--no-bannerflag; HTML report footer carries the Zero Science Lab attribution.--verbose/-vand--debugoperational logging (to stderr).- HTML security-overview report for
enumandaudit(--html). version/helpsubcommands; version banner in usage.- Structure-aware fuzzing via captured corpus (
capture→fuzz --corpus). - Console ANSI color (auto /
--color/--no-color, honorsNO_COLOR): severity-coded findings, distinct highlight for NULL DACL, color legend. auditreformatted as an aligned attribute table with the interesting rows (grade, squattable, SDDL) highlighted.- HTML readability: fixed table layout,
<colgroup>widths, wrapping + scrollable SDDL/image cells, non-wrapping severity badges. - Squattability escalates to DANGER:
auditfolds squattability into the overall verdict and squat-tests even names that aren't currently open (stopped-service pre-squat); newenum --squatactive probe across the whole box. - Hardening: fuzz startup OOM cleanup; right-sized HTML-escape buffers; documented DENY-ACE grading limitation.
FIFOFox - Powered by Silly Security Inc. - https://sillysec.com