Compare commits

...
Author SHA1 Message Date
moloch-- 56aee7d6e4 Add missing pkg 2025-11-02 09:21:34 -07:00
moloch-- b4f07e8629 Fix various uses of util in implant/ 2025-11-02 08:39:31 -07:00
moloch-- 280cb34049 Replace most instances of insecureRand with util funcs wrapping secure rand 2025-11-02 08:25:14 -07:00
Joe 8e5c5f1450 Merge commit from fork
Fix GHSA-q8j9-34qf-7vq7
2025-10-27 15:58:48 -07:00
Joe b8f4f0c1ea Merge pull request #2027 from BishopFox/dbf6dependabot/github_actions/actions/upload-artifact-5
Bump actions/upload-artifact from 4 to 5
2025-10-26 22:16:59 -07:00
Joe 17cb7fbd50 Merge pull request #2030 from BishopFox/cd33dependabot/github_actions/actions/download-artifact-6
Bump actions/download-artifact from 5 to 6
2025-10-26 22:16:47 -07:00
Joe 9963bc6a3f Merge pull request #2031 from BishopFox/implant/dep-updates
Update implant's x/crypto version
2025-10-26 22:16:30 -07:00
moloch-- 274943f383 Update implant's x/crypto version 2025-10-26 20:13:26 -07:00
dependabot[bot] be81755056 Bump actions/download-artifact from 5 to 6
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-27 03:05:46 +00:00
dependabot[bot] e3025a2da2 Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-27 03:03:53 +00:00
Joe 40cc1f4eeb Merge pull request #2024 from BishopFox/blincoln-2025-10-21-01
Fix Windows network adapter retrieval for DNS C2, add additional logging
2025-10-24 11:41:04 -07:00
Ben Lincoln b117a1325d Fix Windows network adapter retrieval for DNS C2, add additional logging 2025-10-21 12:08:44 -07:00
Joe a809989536 Merge pull request #2022 from BishopFox/go/v1.25.3
Update to Go v1.25.3
2025-10-19 22:11:07 -07:00
moloch-- a9ee3ca9ed Update some deps 2025-10-19 21:31:03 -07:00
moloch-- 56d972dd32 Update some deps 2025-10-19 21:17:40 -07:00
moloch-- b4091264d7 Update to Go v1.25.3 2025-10-19 21:09:39 -07:00
Joe 23bf325a66 Merge pull request #2015 from BishopFox/sgn-wasm
Sgn wasm
2025-10-19 20:42:54 -07:00
moloch-- d9344a4c79 Run native bin for unit tests 2025-10-19 19:41:04 -07:00
moloch-- 67d9a772e3 Add shellcode+sgn build to unit tests 2025-10-19 18:56:08 -07:00
moloch-- dae284e62e Add sgn unit tests to go-tests.sh 2025-10-19 18:35:11 -07:00
moloch-- 60f48bdc51 Add sgn unit tests 2025-10-19 18:26:15 -07:00
moloch-- 0d7885de29 Replace subprocess with library call 2025-10-19 17:18:34 -07:00
moloch-- d41d29fc1e Replace CGO build of sgn with wasm/pure-go 2025-10-19 17:09:36 -07:00
Joe 3f400bd3f0 Merge pull request #2004 from BishopFox/5069dependabot/github_actions/actions/upload-pages-artifact-4
Bump actions/upload-pages-artifact from 3 to 4
2025-10-12 15:39:17 -07:00
Joe d43f664821 Merge pull request #2003 from BishopFox/7682dependabot/github_actions/actions/setup-go-6
Bump actions/setup-go from 5 to 6
2025-10-12 15:39:06 -07:00
Joe 85c57c07da Merge pull request #2006 from BishopFox/3c4bdependabot/github_actions/actions/download-artifact-5
Bump actions/download-artifact from 4 to 5
2025-10-12 15:38:56 -07:00
Joe 60d15447e0 Merge pull request #2005 from BishopFox/dd46dependabot/github_actions/actions/setup-node-5
Bump actions/setup-node from 4 to 5
2025-10-12 15:38:44 -07:00
Joe 6351b2d671 Merge pull request #2007 from BishopFox/52f6dependabot/github_actions/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-10-12 15:38:32 -07:00
dependabot[bot] c7535ec509 Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-06 03:03:10 +00:00
dependabot[bot] 67e17d073b Bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-06 03:03:05 +00:00
dependabot[bot] c5cb4dcb6c Bump actions/setup-node from 4 to 5
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-06 03:03:02 +00:00
dependabot[bot] 0b9fe603a8 Bump actions/upload-pages-artifact from 3 to 4
Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-pages-artifact
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-06 03:02:59 +00:00
dependabot[bot] c7141892d1 Bump actions/setup-go from 5 to 6
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2025-10-06 03:02:56 +00:00
Joe c5556f9e2b Merge pull request #2001 from BishopFox/codex/ioutil
Codex refactors ioutil usage
2025-10-05 18:06:31 -07:00
Joe 1bc45c2ab2 Merge pull request #1985 from hypnoticpattern/fix-daemon-multiplayer-conflict
Add info about potential causes for sliver daemon port binding error
2025-10-05 17:03:19 -07:00
moloch-- 739ad98b81 Codex refactors ioutil usage 2025-10-05 17:02:37 -07:00
Joe 95c1697d1b Merge pull request #1979 from z3xddd/add-ntcreatethreadex-syscall
feat: Add NtCreateThreadEx syscall for advanced evasion techniques
2025-10-05 12:09:34 -07:00
moloch-- f7b9571cfc Increase workflow time limits 2025-10-05 11:52:21 -07:00
Joe 0d08f8c62f Merge pull request #2000 from BishopFox/codex/deps
Dependency Updates
2025-10-05 11:51:52 -07:00
Joe aa9c8d89e9 Merge branch 'master' into add-ntcreatethreadex-syscall 2025-10-05 10:38:30 -07:00
moloch-- 152e60ba29 Fix fmt string syntax 2025-10-05 10:05:52 -07:00
moloch-- d13a71b808 Update most go deps, compiles okay 2025-10-05 10:04:24 -07:00
moloch-- b17e2f056f Update most go deps, compiles okay 2025-10-05 10:04:11 -07:00
moloch-- 42fb1e835e Snap to anchor on load 2025-10-04 21:09:02 -07:00
moloch-- 521356ff6e Make sidebar sticky 2025-10-04 21:03:39 -07:00
moloch-- 74b5d720b2 Fix docs build errors 2025-10-04 20:02:48 -07:00
moloch-- cd75545323 Add mobile version of docs site 2025-10-04 19:07:13 -07:00
Joe 396dc9724f Merge branch 'master' into add-ntcreatethreadex-syscall 2025-10-04 18:05:59 -07:00
moloch-- 33398146d3 Fix broken AV links 2025-10-04 18:02:52 -07:00
moloch-- 21039554e5 Add NoStarch 'Red Team Engineering' book to Community Guides 2025-10-04 18:02:07 -07:00
moloch-- cca73be1c8 Add missing types pkg 2025-10-04 17:57:09 -07:00
moloch-- 596bc455d8 Apply a pixel offset to anchor links 2025-10-04 17:55:28 -07:00
moloch-- 400c36c5df Small tweaks to how code blocks are rendered 2025-10-04 17:52:42 -07:00
moloch-- c94dde3efb Add docs watcher in dev mode, fix markdown syntax, update cross-compiler instructions 2025-10-04 17:32:26 -07:00
moloch-- 827a9ca156 Fix docs errors and warnings 2025-10-04 16:53:56 -07:00
Joe d066dbc49a Merge pull request #1999 from moloch--/codex/docs
Update Docs and Fix Various Quirks
2025-10-04 16:47:31 -07:00
Joe f1fbc345a2 Merge branch 'master' into codex/docs 2025-10-04 16:47:20 -07:00
moloch-- 2889c1ee29 Fix font for <code> 2025-10-04 16:46:31 -07:00
moloch-- 28ee216b36 Fix styling of <pre> blocks 2025-10-04 16:44:17 -07:00
moloch-- 2dd3e84f60 Re-implement markdown rendering 2025-10-04 15:39:20 -07:00
moloch-- 067cdf712d Sticky sidebar 2025-10-04 15:21:37 -07:00
moloch-- 22ae941e17 Tweak sidebar radius 2025-10-04 15:15:10 -07:00
moloch-- 7c0c2c2dda Tweak scroll styling 2025-10-04 15:12:55 -07:00
moloch-- 39de742223 Tweak styling 2025-10-04 15:10:03 -07:00
moloch-- b07e750cf5 Add missing tailwind.config.js 2025-10-04 15:06:19 -07:00
Joe 8786979001 Merge pull request #1998 from moloch--/codex/basics
Codex/basics
2025-10-04 14:53:40 -07:00
moloch-- aa223e4488 Update docs to latest tailwind, react, and heroui, some formatting broken 2025-10-04 14:26:03 -07:00
moloch-- 8785c55cf3 Update zig download to use mirrors 2025-10-04 13:27:52 -07:00
Joe 38fa64d266 Merge branch 'master' into codex/basics 2025-10-04 11:51:50 -07:00
moloch-- b04fff21fd Fix format str errors 2025-10-04 11:49:32 -07:00
moloch-- 3f656da786 Add readmes and AGENT.md 2025-10-04 10:25:58 -07:00
Joe 55311868a7 Merge pull request #1983 from hypnoticpattern/enrich-session-logs
Enrich client logging in implant sessions
2025-10-03 07:21:04 -07:00
Ronan Kervella 422a1d39c3 Merge pull request #1996 from moloch--/go/v1.25
Go v1.25.1
2025-09-18 07:57:18 -07:00
moloch-- 6938759e9d Update workflows to use go v1.25.x 2025-09-17 12:09:56 -07:00
moloch-- 5febe5e539 Go v1.25.1 2025-09-17 10:11:12 -07:00
hypnoticpattern 38479e34aa Add comment about the conflict 2025-08-10 15:02:59 -07:00
hypnoticpattern abe8f8e77b Enrich client logging in implant sessions 2025-08-10 10:39:33 -07:00
Israel Comazzetto dos Reis c0f3161525 feat: Add NtCreateThreadEx syscall for advanced evasion techniques 2025-07-29 01:57:48 -03:00
moloch-- c6bbba16e1 Go v1.24.5 2025-07-21 15:33:25 -07:00
Joe af4f99de51 Merge pull request #1970 from atomicchonk/master
Suggested adjective and noun changes
2025-07-18 07:59:28 -07:00
Max Andreacchi 8e6e8e18ad Update nouns.txt
Suggested updates to nouns list to remove some nouns that result in NSFW names upon beacon generation.

Signed-off-by: Max Andreacchi <[email protected]>
2025-07-17 20:05:13 -04:00
Max Andreacchi 544e577eb2 Update adjectives.txt
Updated list to remove adjectives that could result in NSFW names for beacons

Signed-off-by: Max Andreacchi <[email protected]>
2025-07-17 20:01:30 -04:00
Joe 9939d2c320 Merge pull request #1956 from tandem97/master
closes #1955
2025-06-30 13:28:41 -07:00
Joe f47af1e94e Merge pull request #1958 from Hunter-0x07/fix-c2generator-closure
Fix: correct closure capture in C2Generator to prevent loop variable bug
2025-06-16 17:52:10 -07:00
Hunter-0x07 d3302583f5 Fix: correct closure capture in C2Generator to prevent loop variable bug 2025-06-03 14:37:14 +08:00
tandem97 d9403c7f05 fixes #1955 2025-05-31 00:23:40 +03:00
Joe 65eb72506b Merge pull request #1947 from BishopFox/bugfix_shellcodeDefaultExport
add exports when creating profile for windows shellcode
2025-05-15 06:57:19 -07:00
Tim Makram Ghatas d86cdcad8e add exports when creating profile for windows shellcode 2025-05-15 11:53:39 +02:00
Joe 7d7f858c15 Merge pull request #1943 from Signum21/ps_faronics_anti_executable
Added ps detection for Faronics Anti-Executable processes
2025-05-13 09:08:06 -07:00
Joe ee1ad9edd1 Merge pull request #1944 from BishopFox/bugfix_addDefaultExport
Bugfix add default export
2025-05-13 09:07:52 -07:00
Signum21 927ff9c4ab Added ps detection for Faronics Anti-Executable processes
Signed-off-by: Signum21 <[email protected]>
2025-05-09 00:07:37 +02:00
rkervella 87dfe96ee9 Remove insertion to db, already performed elsewhere 2025-04-18 12:32:48 -07:00
rkervella 5bb4338d76 Add an IPTable to the tun device and set the default INPUT
chain to deny everything. Add an `AllowTCPPort` method to add
exceptions at runtime.
2025-04-18 12:31:45 -07:00
rkervella bb35fa56d6 Use AllowTCPPort to whitelist the required ports for the wg listner 2025-04-18 12:30:59 -07:00
rkervella fbab18b2fe Remove job insertion to db, already done elsewhere 2025-04-18 12:30:22 -07:00
3828 changed files with 1777509 additions and 658127 deletions

No files matched your search

+7
View File
@@ -1,4 +1,9 @@
# go-assets.sh downloads
/server/assets/fs/**.zip
/server/assets/fs/**/garble*
/server/assets/fs/**/zig.tar.xz
/server/assets/fs/**/zig.zip
/server/assets/fs/src.zip
/*.sdk.tar.xz
@@ -19,3 +24,5 @@
/SECURITY.md
/README.md
/CONTRIBUTING.md
.downloaded_assets
+11 -11
View File
@@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Go 1.21
uses: actions/setup-go@v5
- name: Go 1.25
uses: actions/setup-go@v6
with:
go-version: "^1.21"
go-version: "^1.25"
- name: OS Packages
run: |
@@ -22,7 +22,7 @@ jobs:
git build-essential zlib1g zlib1g-dev wget zip unzip
- name: Check Out Code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -31,7 +31,7 @@ jobs:
run: make servers
- name: Server Artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: servers
path: ./sliver-server_*
@@ -42,13 +42,13 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Go 1.22
uses: actions/setup-go@v5
- name: Go 1.25
uses: actions/setup-go@v6
with:
go-version: "^1.22"
go-version: "^1.25"
- name: Check Out Code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -57,7 +57,7 @@ jobs:
run: make clients
- name: Client Artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: clients
path: ./sliver-client_*
@@ -72,7 +72,7 @@ jobs:
steps:
- run: mkdir -p ./builds
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v6
with:
path: ./builds
+7 -7
View File
@@ -16,13 +16,13 @@ jobs:
steps:
# Setup go environment
- name: Go 1.22
uses: actions/setup-go@v5
- name: Go 1.25
uses: actions/setup-go@v6
with:
go-version: "^1.22"
go-version: "^1.25"
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# Must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head of the pull request.
@@ -36,10 +36,10 @@ jobs:
git build-essential zlib1g zlib1g-dev wget zip unzip
- name: Check Out Code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
config-file: ./.github/codeql/codeql-config.yml
languages: go
@@ -48,6 +48,6 @@ jobs:
run: make
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
env:
VERSION: ${{github.sha}}
+3 -3
View File
@@ -35,7 +35,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Detect package manager
id: detect-package-manager
@@ -56,7 +56,7 @@ jobs:
fi
- name: Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
cache: "npm"
cache-dependency-path: "**/package-lock.json"
@@ -85,7 +85,7 @@ jobs:
run: ${{ steps.detect-package-manager.outputs.runner }} next build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@v4
with:
path: ${{ github.workspace }}/docs/sliver-docs/out
+24 -26
View File
@@ -21,12 +21,12 @@ jobs:
linux-windows-build-test:
name: Linux & Windows Test
runs-on: ubuntu-latest
timeout-minutes: 90
timeout-minutes: 180
steps:
- name: Go 1.22
uses: actions/setup-go@v5
- name: Go 1.25
uses: actions/setup-go@v6
with:
go-version: "^1.22"
go-version: "^1.25"
- name: OS Packages
run: |
@@ -34,38 +34,36 @@ jobs:
git build-essential zlib1g zlib1g-dev wget zip unzip
- name: Check Out Code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
- name: Make Linux (amd64)
run: make linux-amd64
- name: Test Linux
run: ./sliver-server unpack --force && ./go-tests.sh
- name: Make Windows (amd64)
run: make windows-amd64
- name: Make Linux (arm64)
run: make linux-arm64
- name: Make Linux (amd64)
run: make linux-amd64
- name: Test Linux
run: make clean && make && ./sliver-server unpack --force && ./go-tests.sh
macos-build-test:
name: MacOS Test
runs-on: macos-latest
timeout-minutes: 90
timeout-minutes: 180
steps:
- name: Go 1.22
uses: actions/setup-go@v5
- name: Go 1.25
uses: actions/setup-go@v6
with:
go-version: "^1.22"
- name: Mingw
run: brew install mingw-w64
go-version: "^1.25"
- name: Check Out Code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -73,24 +71,24 @@ jobs:
- name: Make MacOS (amd64)
run: make macos-amd64
- name: Test MacOS (amd64)
run: ./sliver-server unpack --force && ./go-tests.sh
- name: Make MacOS (arm64)
run: make macos-arm64
- name: Test MacOS
run: make clean && make && ./sliver-server unpack --force && ./go-tests.sh
clients-build:
name: Clients Build
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- name: Go 1.22
uses: actions/setup-go@v5
- name: Go 1.25
uses: actions/setup-go@v6
with:
go-version: "^1.22"
go-version: "^1.25"
- name: Check Out Code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
+2
View File
@@ -45,6 +45,8 @@ sliver-server-windows.zip
.DS_Store
dist/
.gocache/
.gomodcache/
# Flag to show that go-assets.sh has been run
.downloaded_assets
+23
View File
@@ -0,0 +1,23 @@
# Repository Guidelines
## Project Structure & Module Organization
Sliver is a Go monorepo. Core client code lives in `client/` (CLI, assets, transports) and server code in `server/` (C2 services, assets, configs). `implant/` holds implant payload sources, while `util/` provides shared helpers that must stay server-side. Protocol buffers live under `protobuf/`, and documentation assets are in `docs/`. Keep generated artifacts (e.g., `sliver-client`, `sliver-server`, `.downloaded_assets`) out of commits.
## Build, Test, and Development Commands
Use `make` targets to stay consistent:
- `make` (or `make default`) compiles client/server binaries with vendored modules and tag defaults.
- `make client` and `make linux-amd64` build platform-specific emitters; prefer `GOOS/GOARCH` env vars over editing sources.
- `./go-assets.sh` refreshes client asset bundles; rerun when static files change.
Regenerate protobuf bindings with `make pb`. For quick checks, `GOFLAGS="-tags client" go build ./client/...` is acceptable, but ensure the matching `server` build also succeeds.
## Coding Style & Naming Conventions
Target Go 1.22+ (see `Makefile` validation). Format code with `gofmt` or `goimports` before committing. Keep package imports segregated (stdlib, third-party, internal). Use lower_snake filenames for assets, PascalCase for exported Go symbols, and prefer explicit names (`sessionID`, `operatorConfig`) over abbreviations. Never import `server` packages inside `client`. Avoid introducing CGO unless justified for cross-platform support.
## Testing Guidelines
Run targeted unit tests with Go’s tooling and project tags, e.g. `go test -tags=client,go_sqlite ./client/command/...`. Full coverage uses `./build.py`; expect long runtimes and ensure ample CPU/RAM. Add tests beside code (`*_test.go`) and mirror package paths. When adding transports or implants, verify integration logs under `~/.sliver/logs/` for regressions and clean up fixtures.
## Commit & Pull Request Guidelines
Sign every commit (`git commit -S`) and write imperative, scoped messages ("Fix DNS canary retry" rather than status updates). Keep vendor updates isolated in their own commit. Pull requests should describe the intent, affected modules, testing performed, and reference GitHub issues. Include before/after screenshots only when UI behavior changes (client console). Ensure CI passes and note any required follow-up.
## Security & Configuration Tips
Default to secure settings: avoid `math/rand` for secrets, prefer vetted crypto (AES-GCM, Curve25519) per `CONTRIBUTING.md`. Lock down file permissions for generated assets and redact secrets from logs. When touching configuration, favor secure defaults even if it means additional setup for operators.
+3 -3
View File
@@ -9,7 +9,7 @@
# STAGE: base
## Compiles Sliver for use
FROM golang:1.23.5 AS base
FROM golang:latest AS base
### Base packages
RUN apt-get update --fix-missing && apt-get -y install \
@@ -20,10 +20,10 @@ RUN groupadd -g 999 sliver && useradd -r -u 999 -g sliver sliver
RUN mkdir -p /home/sliver/ && chown -R sliver:sliver /home/sliver
### Build sliver:
RUN mkdir -p /go/src/github.com/bishopfox/sliver
WORKDIR /go/src/github.com/bishopfox/sliver
ADD . /go/src/github.com/bishopfox/sliver/
RUN make clean-all
RUN make
RUN make
RUN cp -vv sliver-server /opt/sliver-server
# STAGE: test
+1 -1
View File
@@ -27,7 +27,7 @@ GO_VERSION = $(shell $(GO) version)
GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1)
GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
MIN_SUPPORTED_GO_MAJOR_VERSION = 1
MIN_SUPPORTED_GO_MINOR_VERSION = 21
MIN_SUPPORTED_GO_MINOR_VERSION = 24
GO_VERSION_VALIDATION_ERR_MSG = Golang version is not supported, please update to at least $(MIN_SUPPORTED_GO_MAJOR_VERSION).$(MIN_SUPPORTED_GO_MINOR_VERSION)
VERSION ?= $(shell git describe --abbrev=0)
+23 -15
View File
@@ -1,18 +1,26 @@
Client
=======
# client
This directory contains the client implementation, pretty much all of this code is also used by the server console.
## Overview
__Important:__ No code in this directory can import any code from `server/`.
Main command-line client for interacting with and administering Sliver servers. Provides the Cobra entrypoint and aggregates console, command, and transport subsystems.
* `assets/` - Static asset files and management code (e.g. client configs)
* `cli/` - Command line interface implementation
* `command/` - Console command implementations
* `constants/` - Various shared constant values
* `core/` - Client state management
* `licenses/` - Open source licenses
* `spin/` - Console spinner library
* `tcpproxy/` - Local TCP proxy listener code
* `transport/` - Wires the client to the server
* `version/` - Version information
* `main.go` - Entrypoint
## Go Files
- `main.go` – Entry point that initializes the CLI, processes flags, and launches the interactive console.
## Sub-packages
- `assets/` – Manages embedded client asset manifests such as operator profiles, settings, and armory catalogs. Handles serialization, bundling, and lookup of static client metadata.
- `cli/` – Defines the Cobra root command and CLI initialization for the Sliver client binary. Sets up persistent flags, environment bootstrapping, and command wiring.
- `command/` – Shared registration glue, scaffolding, and helpers for Sliver client console command groups. Hosts common utilities for binding Cobra commands to RPC-backed actions.
- `console/` – Renders the interactive console UI, logging, and terminal helpers for the client. Coordinates readline behavior, prompt styling, and message formatting.
- `constants/` – Centralizes constants shared across the client runtime and command packages. Captures strings, flag names, and feature toggles used throughout the CLI.
- `core/` – Maintains client application state, background workers, and RPC coordination. Orchestrates session tracking, event streams, and health checks.
- `credentials/` – Credential management utilities including sniffers and import helpers for operators. Provides parsers, storage helpers, and output formatting for recovered secrets.
- `licenses/` – Holds embedded license metadata bundled with the client distribution. Supplies license retrieval utilities used for attribution commands.
- `overlord/` – Supervises long-running client jobs, scheduling, and task orchestration. Tracks job lifecycle events and exposes status updates to the console.
- `packages/` – Deals with packaged extensions and module discovery for the client. Scans, validates, and caches extension manifests and assets.
- `spin/` – Lightweight terminal spinner utilities used for progress feedback. Wraps spinner styles and timing helpers shared across commands.
- `tcpproxy/` – Implements the local TCP proxy used for port forwarding from the client side. Manages listener lifecycles, connection pumps, and cleanup hooks.
- `transport/` – Client-side transports and RPC wiring to communicate with Sliver servers. Builds authenticated gRPC clients, TLS dialers, and reconnect logic.
- `version/` – Build-time version and semantic metadata for the client binary. Exposes git information, release channels, and helper formatters.
+14 -2
View File
@@ -1,3 +1,15 @@
Assets
======
# client/assets
## Overview
Manages embedded client asset manifests such as operator profiles, settings, and armory catalogs. Handles serialization, bundling, and lookup of static client metadata. Core logic addresses aliases, armories, C2 profiles, and extensions within the assets package.
## Go Files
- `aliases.go` – Provides helpers for discovering, installing, and reading alias manifests shipped with the client.
- `armories.go` – Loads configured armory definitions and persists operator customizations.
- `assets.go` – Central entry point that exposes asset directories, lazy initialization, and filesystem utilities.
- `c2profiles.go` – Embeds default HTTP C2 profile templates and exposes lookup utilities.
- `config.go` – Tracks client configuration paths and manages persistence of runtime options.
- `extensions.go` – Handles embedded extension manifests and supports lookup by command name.
- `settings.go` – Stores default console settings and manages serialization to disk.
+1 -1
View File
@@ -96,7 +96,7 @@ func Setup(force bool, echo bool) {
if force || localVer == "" || localVer != ver.GitCommit {
if echo {
fmt.Printf(`
Sliver Copyright (C) 2022 Bishop Fox
Sliver Copyright (C) 2025 Bishop Fox
This program comes with ABSOLUTELY NO WARRANTY; for details type 'licenses'.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'licenses' for details.`)
+13 -3
View File
@@ -1,4 +1,14 @@
CLI
===
# client/cli
This package implements the Sliver client cli.
## Overview
Defines the Cobra root command and CLI initialization for the Sliver client binary. Sets up persistent flags, environment bootstrapping, and command wiring. Core logic addresses console, implant, import, and version within the cli package.
## Go Files
- `cli.go` – Builds the root Cobra command, wires global flags, and starts the console UI.
- `config.go` – Parses CLI configuration files and environment variables used during startup.
- `console.go` – Launches the interactive console mode and handles profile selection.
- `implant.go` – Implements CLI entry points for implant-specific operations without launching the console.
- `import.go` – Provides import routines for bringing external state into the client (e.g., implants or loot).
- `version.go` – Prints version/build information for the CLI binary.
+62 -11
View File
@@ -1,14 +1,65 @@
Command
=======
# client/command
This package contains all of the client command implementations that are shared between the client and the server console.
## Overview
### Developers
Shared registration glue, scaffolding, and helpers for Sliver client console command groups. Hosts common utilities for binding Cobra commands to RPC-backed actions. Core logic addresses sliver within the command package.
General guidance on the structure of this package:
* One command per file and the name of the file should reflect the command it implements (or there about, trivial commands can go into the same file). This makes it easy to find where a command implementation lives within a package or to search by file name if it is not clear which package implements a given command.
* The root command, and reused code should go into the file named after the command
* For example, code shared between the `generate` and the `regenerate` command should go in `generate.go`, and any `regenerate` specific code should go in `regenerate.go`
* Command entrypoint functions should have the suffix `Cmd` e.g., `GenerateCmd` is the entrypoint for `generate`
* Command entrypoints should always a function signature of `func (ctx *grumble.Context, con *console.SliverConsoleClient)`
* Functions that are only ever exported for other commands to use should go in a `helpers.go`, if the function is used internally and exported follow the guidance above on shared code.
## Go Files
- `command.go` – Provides helpers for binding Cobra commands, flag sets, and visibility filters into the client command tree.
- `server.go` – Defines the server menu composition, wiring each server-side command group onto the root console structure at runtime.
- `sliver.go` – Builds the implant/Sliver menu, attaching per-target command groups and loading alias/extension manifests before exposure.
## Sub-packages
- `alias/` – Implements the 'alias' command group for the Sliver client console.
- `armory/` – Implements the 'armory' command group for the Sliver client console.
- `backdoor/` – Implements the 'backdoor' command group for the Sliver client console.
- `beacons/` – Implements the 'beacons' command group for the Sliver client console.
- `builders/` – Implements the 'builders' command group for the Sliver client console.
- `c2profiles/` – Implements the 'c2profiles' command group for the Sliver client console.
- `certificates/` – Implements the 'certificates' command group for the Sliver client console.
- `clean/` – Implements the 'clean' command group for the Sliver client console.
- `completers/` – Implements the 'completers' command group for the Sliver client console.
- `crack/` – Implements the 'crack' command group for the Sliver client console.
- `creds/` – Implements the 'creds' command group for the Sliver client console.
- `cursed/` – Implements the 'cursed' command group for the Sliver client console.
- `dllhijack/` – Implements the 'dllhijack' command group for the Sliver client console.
- `environment/` – Implements the 'environment' command group for the Sliver client console.
- `exec/` – Implements the 'exec' command group for the Sliver client console.
- `exit/` – Implements the 'exit' command group for the Sliver client console.
- `extensions/` – Implements the 'extensions' command group for the Sliver client console.
- `filesystem/` – Implements the 'filesystem' command group for the Sliver client console.
- `flags/` – Implements the 'flags' command group for the Sliver client console.
- `generate/` – Implements the 'generate' command group for the Sliver client console.
- `help/` – Implements the 'help' command group for the Sliver client console.
- `hosts/` – Implements the 'hosts' command group for the Sliver client console.
- `info/` – Implements the 'info' command group for the Sliver client console.
- `jobs/` – Implements the 'jobs' command group for the Sliver client console.
- `kill/` – Implements the 'kill' command group for the Sliver client console.
- `licenses/` – Implements the 'licenses' command group for the Sliver client console.
- `loot/` – Implements the 'loot' command group for the Sliver client console.
- `monitor/` – Implements the 'monitor' command group for the Sliver client console.
- `network/` – Implements the 'network' command group for the Sliver client console.
- `operators/` – Implements the 'operators' command group for the Sliver client console.
- `pivots/` – Implements the 'pivots' command group for the Sliver client console.
- `portfwd/` – Implements the 'portfwd' command group for the Sliver client console.
- `privilege/` – Implements the 'privilege' command group for the Sliver client console.
- `processes/` – Implements the 'processes' command group for the Sliver client console.
- `reaction/` – Implements the 'reaction' command group for the Sliver client console.
- `reconfig/` – Implements the 'reconfig' command group for the Sliver client console.
- `registry/` – Implements the 'registry' command group for the Sliver client console.
- `rportfwd/` – Implements the 'rportfwd' command group for the Sliver client console.
- `screenshot/` – Implements the 'screenshot' command group for the Sliver client console.
- `sessions/` – Implements the 'sessions' command group for the Sliver client console.
- `settings/` – Implements the 'settings' command group for the Sliver client console.
- `shell/` – Implements the 'shell' command group for the Sliver client console.
- `shikata-ga-nai/` – Implements the 'shikata-ga-nai' command group for the Sliver client console.
- `socks/` – Implements the 'socks' command group for the Sliver client console.
- `taskmany/` – Implements the 'taskmany' command group for the Sliver client console.
- `tasks/` – Implements the 'tasks' command group for the Sliver client console.
- `update/` – Implements the 'update' command group for the Sliver client console.
- `use/` – Implements the 'use' command group for the Sliver client console.
- `wasm/` – Implements the 'wasm' command group for the Sliver client console.
- `websites/` – Implements the 'websites' command group for the Sliver client console.
- `wireguard/` – Implements the 'wireguard' command group for the Sliver client console.
+10 -7
View File
@@ -1,11 +1,14 @@
Alias
===========
# client/command/alias
Wraps external DLLs/tool in Sliver console commands.
## Overview
Implements the 'alias' command group for the Sliver client console. Handlers map Cobra invocations to alias workflows such as install, load, and remove.
## Go Files
### Format
* `alias-dir/`
* * `manifest.json` -
- `alias.go` – Implements runtime alias management, printing installed aliases and exposing tab-completion helpers.
- `alias_test.go` *(tests)* – Exercises manifest parsing logic to ensure alias metadata is interpreted correctly.
- `commands.go` – Wires Cobra commands for listing, installing, loading, and removing aliases into the client console.
- `install.go` – Handles installing alias bundles from directories or archives, writing manifests and payload artifacts to disk.
- `load.go` – Loads alias manifests, validates target compatibility, and registers commands against the active console.
- `remove.go` – Removes installed aliases, prompting for confirmation and deleting associated on-disk assets.
+1 -1
View File
@@ -114,7 +114,7 @@ func InstallFromFile(aliasGzFilePath string, aliasName string, promptToOverwrite
} else {
errorMsg = fmt.Sprintf("Failed to parse %s: %s\n", ManifestFileName, err)
}
con.PrintErrorf(errorMsg)
con.PrintErrorf("%s", errorMsg)
return nil
}
installPath := filepath.Join(assets.GetAliasesDir(), filepath.Base(manifest.CommandName))
+1 -1
View File
@@ -311,7 +311,7 @@ func runAliasCommand(cmd *cobra.Command, con *console.SliverClient, args []strin
} else if !aliasManifest.IsReflective {
msgStr = " Arguments are limited to 256 characters when using the default fork/exec model for non-reflective PE payloads.\n"
}
con.PrintWarnf(msgStr)
con.PrintWarnf("%s", msgStr)
confirm := false
prompt := &survey.Confirm{Message: "Do you want to continue?"}
survey.AskOne(prompt, &confirm, nil)
+16
View File
@@ -0,0 +1,16 @@
# client/command/armory
## Overview
Implements the 'armory' command group for the Sliver client console. Handlers map Cobra invocations to armory workflows such as install, manage, parsers, and search.
## Go Files
- `armory.go` – Maintains the armory cache lifecycle, fetching package metadata, verifying signatures, and presenting bundle listings.
- `armory_test.go` *(tests)* – Placeholder for armory command tests; currently used to keep the package's test harness wired up.
- `commands.go` – Declares the Cobra command hierarchy for armory actions and binds shared flag/completion plumbing.
- `install.go` – Resolves dependencies and installs aliases or extensions from cached metadata, prompting when overwriting existing packages.
- `manage.go` – Implements management helpers for viewing, adding, verifying, and persisting armory configurations.
- `parsers.go` – Provides parsers and HTTP helpers for retrieving armory indexes and packages, including Minisign verification.
- `search.go` – Implements the regex-driven search command that filters cached armory packages.
- `update.go` – Calculates available package updates, presents options to the user, and orchestrates update installation.
+9 -3
View File
@@ -1,4 +1,10 @@
Backdoor
========
# client/command/backdoor
Implements command related to `backdoor`
## Overview
Implements the 'backdoor' command group for the Sliver client console.
## Go Files
- `backdoor.go` – Implements the RPC workflow that backdoors a remote binary with Sliver shellcode for the active session.
- `commands.go` – Registers the Cobra command, binds flags/completions, and restricts usage to applicable targets.
+13 -3
View File
@@ -1,4 +1,14 @@
Beacons
========
# client/command/beacons
This package implements the beacons command, which can be used to list and interact with beacons.
## Overview
Implements the 'beacons' command group for the Sliver client console. Handlers map Cobra invocations to beacons workflows such as prune, RM, and watch.
## Go Files
- `beacons.go` – Retrieves beacon inventories and renders them in tabular form with optional filtering.
- `commands.go` – Declares the beacons command set, binds flags/completions, and wires subcommands like prune, rm, and watch.
- `helpers.go` – Provides helper RPC wrappers for selecting, fetching, and listing beacons.
- `prune.go` – Implements the prune routine that removes stale beacon entries via the backend API.
- `rm.go` – Removes a specific beacon by ID, coordinating confirmation and RPC teardown.
- `watch.go` – Streams beacon events in a watch loop, handling cancellation and console interaction.
+10
View File
@@ -0,0 +1,10 @@
# client/command/builders
## Overview
Implements the 'builders' command group for the Sliver client console.
## Go Files
- `builders.go` – Fetches external builder metadata and formats it for console display.
- `commands.go` – Registers the builders CLI command with its flags and completion helpers.
+10
View File
@@ -0,0 +1,10 @@
# client/command/c2profiles
## Overview
Implements the 'c2profiles' command group for the Sliver client console. Handlers map Cobra invocations to c2profiles workflows such as C2 profiles.
## Go Files
- `c2profiles.go` – Implements listing, import/export, and generation routines for HTTP C2 profiles, including protobuf/JSON conversion helpers.
- `commands.go` – Binds the c2profiles command suite with flag handling and completions for profile management operations.
+10
View File
@@ -0,0 +1,10 @@
# client/command/certificates
## Overview
Implements the 'certificates' command group for the Sliver client console.
## Go Files
- `certificates.go` – Retrieves certificate metadata from the server, formats expiration status, and prints results to the console.
- `commands.go` – Registers the certificates command and binds the flags needed to query certificate inventories.
+9
View File
@@ -0,0 +1,9 @@
# client/command/clean
## Overview
Implements the 'clean' command group for the Sliver client console.
## Go Files
- `clean.go` – Defines the clean command and its helpers that purge local build artifacts, cached profiles, and stale sessions.
+8 -3
View File
@@ -1,4 +1,9 @@
Completers
===========
# client/command/completers
This package contains general purpose completers for the console, note that some package also contain their own package-specific completers.
## Overview
Implements the 'completers' command group for the Sliver client console.
## Go Files
- `completers.go` – Provides reusable carapace completion helpers for selecting client interfaces and proxy endpoints.
+12
View File
@@ -0,0 +1,12 @@
# client/command/crack
## Overview
Implements the 'crack' command group for the Sliver client console. Handlers map Cobra invocations to crack workflows such as crack files.
## Go Files
- `commands.go` – Defines the crack command hierarchy, attaching operations for stations and file management.
- `crack-files.go` – Manages cracking asset uploads, listings, and removals, handling streaming transfers and chunking.
- `crack.go` – Implements station status reporting, health checks, and list rendering for distributed cracking nodes.
- `helpers.go` – Supplies completion helpers and byte formatting utilities for crack subcommands.
+14
View File
@@ -0,0 +1,14 @@
# client/command/creds
## Overview
Implements the 'creds' command group for the Sliver client console. Handlers map Cobra invocations to creds workflows such as ADD, hash types, RM, and select.
## Go Files
- `add.go` – Adds credentials to the client store via interactive or flag-based input.
- `commands.go` – Registers credential management commands and subcommands.
- `creds.go` – Lists stored credentials and formats them for display.
- `hash-types.go` – Enumerates supported hash types and their identifiers.
- `rm.go` – Removes credentials by ID or filter from the store.
- `select.go` – Selects credentials for use in other workflows, updating defaults.
+16 -2
View File
@@ -1,3 +1,17 @@
# Cursed
# client/command/cursed
Cursed is a Sliver Chrome/Electron post-exploitation tool kit based on/integrated with [CursedChrome](https://github.com/mandatoryprogrammer/CursedChrome). Code injection is performed via the [DevTools protocol](https://chromedevtools.github.io/devtools-protocol/).
## Overview
Implements the 'cursed' command group for the Sliver client console. Handlers map Cobra invocations to cursed workflows such as cursed chrome, cursed console, cursed cookies, and cursed edge.
## Go Files
- `commands.go` – Exposes the cursed command suite and binds individual subcommands for supported targets.
- `cursed-chrome.go` – Launches or hijacks Chrome debugging sessions, locating executables and wiring remote control.
- `cursed-console.go` – Provides the interactive cursed console experience atop Chrome DevTools sessions.
- `cursed-cookies.go` – Fetches and displays browser cookies from an active cursed session.
- `cursed-edge.go` – Mirrors the Chrome workflow for Microsoft Edge, including process discovery logic.
- `cursed-electron.go` – Drives cursed interactions with arbitrary Electron apps, validating binaries and starting injected sessions.
- `cursed-rm.go` – Removes cursed sessions from the client cache and tears down associated resources.
- `cursed-screenshot.go` – Captures screenshots from a cursed browser context via DevTools APIs.
- `cursed.go` – Manages the cursed process registry, selection helpers, and remote debugger configuration defaults.
+2 -2
View File
@@ -23,7 +23,6 @@ import (
"errors"
"fmt"
"log"
insecureRand "math/rand"
"os"
"strings"
"time"
@@ -36,6 +35,7 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
)
@@ -213,7 +213,7 @@ func startCursedChromeProcess(isEdge bool, session *clientpb.Session, cmd *cobra
con.PrintInfof("Waiting for %s process to initialize ... ", name)
time.Sleep(2 * time.Second)
bindPort := insecureRand.Intn(10000) + 40000
bindPort := util.Intn(10000) + 40000
bindAddr := fmt.Sprintf("127.0.0.1:%d", bindPort)
remoteAddr := fmt.Sprintf("127.0.0.1:%d", debugPort)
+3 -3
View File
@@ -22,7 +22,6 @@ import (
"context"
"fmt"
"log"
insecureRand "math/rand"
"path"
"time"
@@ -34,6 +33,7 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
)
@@ -118,7 +118,7 @@ func avadaKedavraElectron(electronExe string, session *clientpb.Session, cmd *co
return curse
}
func checkElectronPath(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (bool, error) {
func checkElectronPath(electronExe string, _ *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (bool, error) {
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(cmd),
Path: electronExe,
@@ -175,7 +175,7 @@ func startCursedElectronProcess(electronExe string, session *clientpb.Session, c
con.PrintInfof("Waiting for process to initialize ... ")
time.Sleep(2 * time.Second)
bindPort := insecureRand.Intn(10000) + 40000
bindPort := util.Intn(10000) + 40000
bindAddr := fmt.Sprintf("127.0.0.1:%d", bindPort)
remoteAddr := fmt.Sprintf("127.0.0.1:%d", debugPort)
+2 -2
View File
@@ -21,7 +21,6 @@ package cursed
import (
"bytes"
"fmt"
insecureRand "math/rand"
"strconv"
"strings"
"text/tabwriter"
@@ -30,6 +29,7 @@ import (
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/util"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
)
@@ -115,7 +115,7 @@ func selectCursedProcess(con *console.SliverClient) *core.CursedProcess {
func getRemoteDebuggerPort(cmd *cobra.Command) int {
port, _ := cmd.Flags().GetInt("remote-debugging-port")
if port == 0 {
port = insecureRand.Intn(30000) + 10000
port = util.Intn(30000) + 10000
}
return port
}
+9 -3
View File
@@ -1,4 +1,10 @@
DLL Hijack
===========
# client/command/dllhijack
Implements command related to `dllhijack`.
## Overview
Implements the 'dllhijack' command group for the Sliver client console.
## Go Files
- `commands.go` – Registers the dllhijack command, its flags, and completions for selecting remote DLL targets.
- `dllhijack.go` – Performs the RPC call that plants a Sliver DLL alongside a target executable for hijacking.
+11 -3
View File
@@ -1,4 +1,12 @@
Environment
===========
# client/command/environment
Contains command implementations for manipulating remote environment variables.
## Overview
Implements the 'environment' command group for the Sliver client console. Handlers map Cobra invocations to environment workflows such as GET, SET, and unset.
## Go Files
- `commands.go` – Declares environment command variations and wires subcommands for get/set/unset operations with shared flags.
- `get.go` – Invokes the RPC to retrieve environment variables and prints the results for sessions or beacons.
- `set.go` – Handles setting environment variables remotely, including beacon callback handling and result formatting.
- `unset.go` – Removes environment variables on the remote target and reports task outcomes back to the user.
+18 -3
View File
@@ -1,4 +1,19 @@
Exec
====
# client/command/exec
Implements execution related commands like `execute`, `execute-shellcode`, `execute-assembly`, etc.
## Overview
Implements the 'exec' command group for the Sliver client console. Handlers map Cobra invocations to exec workflows such as execute assembly, execute shellcode, execute, and migrate.
## Go Files
- `commands.go` – Registers the exec command family and binds shared flags across execution techniques.
- `execute-assembly.go` – Uploads .NET assemblies and triggers in-memory execution, handling results and loot capture.
- `execute-shellcode.go` – Executes raw shellcode via RPC, supporting interactive injection and task result printing.
- `execute.go` – Runs arbitrary commands, streams combined stdout/stderr, and persists output as loot when requested.
- `migrate.go` – Implements process migration, moving implants into new host processes and reporting completion.
- `msf-inject.go` – Coordinates Metasploit payload injection tasks and prints remote execution responses.
- `msf.go` – Launches Metasploit jobs on targets and tracks their beacon callbacks.
- `psexec.go` – Provides PsExec-style remote service deployment using generated binaries and random filenames.
- `sideload.go` – Executes unmanaged DLL exports in a remote process and summarizes task output.
- `spawndll.go` – Spawns new processes with DLL injection, capturing returned handles and statuses.
- `ssh.go` – Runs remote commands over SSH, sourcing credentials from loot and presenting command output.
+9 -9
View File
@@ -21,7 +21,6 @@ package exec
import (
"context"
"fmt"
insecureRand "math/rand"
"os"
"strings"
"time"
@@ -32,6 +31,7 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/bishopfox/sliver/util/encoders"
"github.com/spf13/cobra"
)
@@ -175,8 +175,8 @@ func PsExecCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
func randomString() string {
alphanumeric := "abcdefghijklmnopqrstuvwxyz0123456789"
str := ""
for index := 0; index < insecureRand.Intn(8)+1; index++ {
str += string(alphanumeric[insecureRand.Intn(len(alphanumeric))])
for index := 0; index < util.Intn(8)+1; index++ {
str += string(alphanumeric[util.Intn(len(alphanumeric))])
}
return str
}
@@ -184,7 +184,7 @@ func randomString() string {
func randomFileName() string {
noun := randomString()
noun = strings.ToLower(noun)
switch insecureRand.Intn(3) {
switch util.Intn(3) {
case 0:
noun = strings.ToUpper(noun)
case 1:
@@ -192,16 +192,16 @@ func randomFileName() string {
}
separators := []string{"", "", "", "", "", ".", "-", "_", "--", "__"}
sep := separators[insecureRand.Intn(len(separators))]
sep := separators[util.Intn(len(separators))]
alphanumeric := "abcdefghijklmnopqrstuvwxyz0123456789"
prefix := ""
for index := 0; index < insecureRand.Intn(3); index++ {
prefix += string(alphanumeric[insecureRand.Intn(len(alphanumeric))])
for index := 0; index < util.Intn(3); index++ {
prefix += string(alphanumeric[util.Intn(len(alphanumeric))])
}
suffix := ""
for index := 0; index < insecureRand.Intn(6)+1; index++ {
suffix += string(alphanumeric[insecureRand.Intn(len(alphanumeric))])
for index := 0; index < util.Intn(6)+1; index++ {
suffix += string(alphanumeric[util.Intn(len(alphanumeric))])
}
return fmt.Sprintf("%s%s%s%s%s", prefix, sep, noun, sep, suffix)
+9
View File
@@ -0,0 +1,9 @@
# client/command/exit
## Overview
Implements the 'exit' command group for the Sliver client console.
## Go Files
- `exit.go` – Implements the client exit command, ensuring cleanup before terminating the console.
+12 -63
View File
@@ -1,67 +1,16 @@
Extensions
===========
# client/command/extensions
Allows to load and execute 3rd party extensions.
## Overview
Extensions directory structures can be arbitrary, however in the root of the directory or .tar.gz there
must be a `extension.json` or a `alias.json` file. All paths are relative to the manifest/root directory,
parent directories are not allowed. Only files listed in the manifest are copied, any other files will
be ignored.
Implements the 'extensions' command group for the Sliver client console. Handlers map Cobra invocations to extensions workflows such as argparser, install, list, and load.
```shell
/path/to/extension/folder/
├── extension.json
└── windows
│ └── extension.x86.dll
│ └── extension.x64.dll
└── linux
│ └── extension.x86.so
│ └── extension.x64.so
└── darwin
└── extension.x86.dylib
└── extension.x64.dylib
```
## Go Files
Here's an example manifest (i.e., the `extension.json` or a `alias.json`):
```json
{
"name": "foo",
"version": "1.0.0",
"extension_author": "ac1d-burn",
"original_author": "zer0-cool",
"repo_url": "https://github.com/foo/bar",
"help": "Help for foo command",
"entrypoint": "RunFoo",
"init" :"NimMain",
"depends_on": "bar",
"files": [
{
"os": "windows",
"arch": "amd64",
"path": "extension.x64.o",
}
],
"arguments": [
{"name": "pid", "type": "int", "desc": "pid", "optional": false},
]
}
```
The structure is the following one:
- `name`: name of the extension, which will also be the name of the command in the sliver client
- `help`: the documentation for the new command
- `entrypoint`: the name of the exported function to call
- `files`: a list of object pointing to the extensions files to load for each architectures and operating systems
- `init`: the initialization function name (if relevant, can be omitted)
- `arguments`: an optional list of objects (for DLLs), but mandatory for BOFs
- `depends_on`: the name of an extension required by the current extension (won't load if the dependency is not loaded)
The `type` of an argument can be one of the following:
- `string`: regular ASCII string
- `wstring`: string that will be UTF16 encoded
- `int`: will be parsed as a 32 bit unsigned integer
- `short`: will be parsed as a 16 bit unsigned integer
- `file`: a string to a file path on the client side which content will be passed to the BOF
- `argparser.go` – Builds argument buffers for extensions, including BOF-specific marshaling and validation.
- `commands.go` – Declares the extensions command tree and binds subcommands for list, install, load, and remove actions.
- `extensions.go` – Manages installed/temporary extension manifests, printing metadata and supplying completers.
- `extensions_test.go` *(tests)* – Verifies manifest parsing and conversion routines to guard against format regressions.
- `install.go` – Installs extension bundles from directories or archives, handling overwrite prompts and asset extraction.
- `list.go` – Queries the server for matching extensions and renders results categorized by hash or type.
- `load.go` – Loads extension binaries for the active target, registers generated commands, and dispatches execution RPCs.
- `remove.go` – Removes installed extensions, coordinating manifest lookups and filesystem cleanup.
+3 -3
View File
@@ -309,7 +309,7 @@ func validManifest(manifest *ExtensionManifest) error {
// argument specifications.
func ExtensionRegisterCommand(extCmd *ExtCommand, cmd *cobra.Command, con *console.SliverClient) {
if errInvalidArgs := checkExtensionArgs(extCmd); errInvalidArgs != nil {
con.PrintErrorf(errInvalidArgs.Error())
con.PrintErrorf("%s", errInvalidArgs.Error())
return
}
@@ -685,7 +685,7 @@ func PrintExtOutput(extName string, commandName string, outputSchema *packages.O
}
}
if callExtension.Response != nil && callExtension.Response.Err != "" {
con.PrintErrorf(callExtension.Response.Err)
con.PrintErrorf("%s", callExtension.Response.Err)
return
}
}
@@ -855,7 +855,7 @@ func makeExtensionArgCompleter(extCmd *ExtCommand, _ *cobra.Command, comps *cara
usage += " (optional)"
}
actions = append(actions, action.Usage(usage))
actions = append(actions, action.Usage("%s", usage))
}
comps.PositionalCompletion(actions...)
+27 -3
View File
@@ -1,4 +1,28 @@
Filesystem
==========
# client/command/filesystem
This package implements file system commands such as `ls`, `cd`, `rm`, `download`, `upload`, etc.
## Overview
Implements the 'filesystem' command group for the Sliver client console. Handlers map Cobra invocations to filesystem workflows such as CAT, CD, chmod, and chown.
## Go Files
- `cat.go` – Downloads remote files and prints contents locally with optional ANSI colorization.
- `cd.go` – Changes the working directory of the active session or beacon.
- `chmod.go` – Adjusts remote file permissions via RPC for Unix-like targets.
- `chown.go` – Alters remote file ownership metadata where supported.
- `chtimes.go` – Updates remote file access and modification timestamps.
- `commands.go` – Assembles the filesystem command group and wires each file operation subcommand.
- `cp.go` – Copies files on the remote target, handling overwrite prompts and path validation.
- `download.go` – Retrieves files from the target and writes them to the local loot directory.
- `grep.go` – Runs server-side grep equivalents with pattern, highlight, and streaming options.
- `head.go` – Streams the first bytes or lines of a remote file.
- `ls.go` – Lists directory contents with filtering, sorting, and long-format support.
- `memfiles-add.go` – Uploads file data into in-memory implants for later retrieval.
- `memfiles-list.go` – Enumerates in-memory file entries stored on the implant.
- `memfiles-rm.go` – Removes staged in-memory files from the implant cache.
- `mkdir.go` – Creates directories on the remote system, with recursive creation if requested.
- `mount.go` – Mounts remote filesystem paths for live browsing through the client.
- `mv.go` – Moves or renames remote files and directories.
- `pwd.go` – Prints the current working directory of the active target.
- `rm.go` – Deletes remote files or directories with optional recursive behavior.
- `upload.go` – Transfers local files to the target and sets desired permissions.
+9
View File
@@ -0,0 +1,9 @@
# client/command/flags
## Overview
Implements the 'flags' command group for the Sliver client console.
## Go Files
- `flags.go` – Provides shared helpers for binding Cobra flag sets, target filters, and carapace completions to commands.
+22 -3
View File
@@ -1,5 +1,24 @@
Generate
========
# client/command/generate
Implements command related to implant generation such as `generate`, `regenerate`, `profiles`, etc.
## Overview
Implements the 'generate' command group for the Sliver client console. Handlers map Cobra invocations to generate workflows such as canaries, generate beacon, generate info, and implants RM.
## Go Files
- `canaries.go` – Lists DNS canaries, filters burned entries, and prints status tables.
- `commands.go` – Defines the generate command hierarchy spanning implant, profile, and canary tooling.
- `generate-beacon.go` – Builds staged beacons from profile/flag inputs and triggers compilation via RPC.
- `generate-info.go` – Displays build configuration details for a generated implant artifact.
- `generate.go` – Orchestrates implant compilation pipelines, parsing C2 flags and selecting targets/builders.
- `helpers.go` – Supplies completions, helper lookups, and binary retrieval utilities used across generate commands.
- `implants-rm.go` – Deletes stored implant builds from the server catalog.
- `implants-stage.go` – Uploads generated implants into staging slots for later deployment.
- `implants.go` – Lists implant builds, filters them, and resolves selected build metadata.
- `profiles-generate.go` – Generates new implant profiles from templates and selected options.
- `profiles-new.go` – Creates empty implant profiles populated with default settings.
- `profiles-rm.go` – Removes saved implant profiles and confirms deletion state.
- `profiles-stage.go` – Stages implant profiles to facilitate rapid build operations.
- `profiles.go` – Lists profiles, prints detailed info, and resolves profile selections for other commands.
- `regenerate.go` – Rebuilds implants from existing configuration IDs without re-specifying flags.
- `traffic-encoders.go` – Manages generation of HTTP/DNS traffic encoder assets for implants.
+7 -7
View File
@@ -291,6 +291,13 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverClient) (string, *
sgnEnabled := false
var exports []string
exportsArg, _ := cmd.Flags().GetString("exports")
if exportsArg == "" {
con.PrintErrorf("Shared libraries need at least one export\n")
return "", nil
} else {
exports = strings.Split(exportsArg, ",")
}
format, _ := cmd.Flags().GetString("format")
runAtLoad := false
@@ -302,13 +309,6 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverClient) (string, *
configFormat = clientpb.OutputFormat_SHARED_LIB
isSharedLib = true
runAtLoad, _ = cmd.Flags().GetBool("run-at-load")
exportsArg, _ := cmd.Flags().GetString("exports")
if exportsArg == "" {
con.PrintErrorf("Shared libraries need at least one export\n")
return "", nil
} else {
exports = strings.Split(exportsArg, ",")
}
case "shellcode":
configFormat = clientpb.OutputFormat_SHELLCODE
isShellcode = true
+9 -3
View File
@@ -1,4 +1,10 @@
Help
====
# client/command/help
This package contains all of the long-form command help templates that are displayed when a user types `help <cmd>`
## Overview
Implements the 'help' command group for the Sliver client console. Handlers map Cobra invocations to help workflows such as long help.
## Go Files
- `help.go` – Houses the legacy grouped help implementation for the console, kept for reference and future reuse.
- `long-help.go` – Stores long-form help templates and utilities for formatting command documentation.
+12 -3
View File
@@ -1,4 +1,13 @@
Hosts
======
# client/command/hosts
Command to access and manage host information.
## Overview
Implements the 'hosts' command group for the Sliver client console. Handlers map Cobra invocations to hosts workflows such as hosts IOC RM, hosts IOC, and hosts RM.
## Go Files
- `commands.go` – Sets up the hosts command suite and its IOC management subcommands.
- `hosts-ioc-rm.go` – Removes stored indicators of compromise for a host via RPC.
- `hosts-ioc.go` – Lists and prints host IOC data retrieved from the server.
- `hosts-rm.go` – Deletes hosts from inventory and confirms removal operations.
- `hosts.go` – Displays host summaries, filters by query, and renders tabular output.
+10 -3
View File
@@ -1,4 +1,11 @@
Info
====
# client/command/info
Implements session information commands like `info`, `print`, `whoami`, etc.
## Overview
Implements the 'info' command group for the Sliver client console. Handlers map Cobra invocations to info workflows such as ping.
## Go Files
- `commands.go` – Registers information-oriented commands and binds them into the console.
- `info.go` – Queries detailed session or beacon metadata and prints rich status tables.
- `ping.go` – Sends ping requests to implants to test connectivity and round-trip latency.
+2 -2
View File
@@ -2,10 +2,10 @@ package info
import (
"context"
insecureRand "math/rand"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
)
@@ -16,7 +16,7 @@ func PingCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
return
}
nonce := insecureRand.Intn(999999)
nonce := util.Intn(999999)
con.PrintInfof("Ping %d\n", nonce)
pong, err := con.Rpc.Ping(context.Background(), &sliverpb.Ping{
Nonce: int32(nonce),
+15 -3
View File
@@ -1,4 +1,16 @@
Jobs
=====
# client/command/jobs
Implements commands related to starting/killing jobs like `jobs` and starting C2 listeners (`mtls`, `http`, etc.)
## Overview
Implements the 'jobs' command group for the Sliver client console. Handlers map Cobra invocations to jobs workflows such as DNS, HTTP, HTTPS, and mTLS.
## Go Files
- `commands.go` – Declares the jobs command tree and wires transport-specific subcommands.
- `dns.go` – Lists, starts, and stops DNS listener jobs via RPC.
- `http.go` – Manages HTTP listener jobs, including creation and teardown.
- `https.go` – Handles HTTPS listener lifecycle operations with certificate options.
- `jobs.go` – Provides common utilities for rendering job tables and selecting listener IDs.
- `mtls.go` – Controls mTLS listener jobs and prints connection details.
- `stage.go` – Manages staging servers for delivering payloads to new implants.
- `wg.go` – Configures and monitors WireGuard listener jobs for C2 traffic.
+1 -1
View File
@@ -163,5 +163,5 @@ func Commands(con *console.SliverClient) []*cobra.Command {
(*comp)["compress"] = carapace.ActionValues([]string{"zlib", "gzip", "deflate9", "none"}...).Tag("compression formats")
})
return []*cobra.Command{jobsCmd, mtlsCmd, wgCmd, httpCmd, httpsCmd, stageCmd}
return []*cobra.Command{jobsCmd, mtlsCmd, wgCmd, dnsCmd, httpCmd, httpsCmd, stageCmd}
}
+10
View File
@@ -0,0 +1,10 @@
# client/command/kill
## Overview
Implements the 'kill' command group for the Sliver client console.
## Go Files
- `commands.go` – Registers the kill command and binds timeout/target flags.
- `kill.go` – Terminates sessions or beacons on the server, handling confirmations and output messaging.
+9
View File
@@ -0,0 +1,9 @@
# client/command/licenses
## Overview
Implements the 'licenses' command group for the Sliver client console.
## Go Files
- `commands.go` – Displays third-party license information through a dedicated console command.
+14 -3
View File
@@ -1,5 +1,16 @@
Loot
=====
# client/command/loot
Client loot command implementations
## Overview
Implements the 'loot' command group for the Sliver client console. Handlers map Cobra invocations to loot workflows such as fetch, local, remote, and rename.
## Go Files
- `commands.go` – Declares the loot command tree and binds fetch/local/removal subcommands.
- `fetch.go` – Downloads remote loot artifacts and writes them to local storage.
- `helpers.go` – Provides helper functions for lookup, filtering, and formatting loot entries.
- `local.go` – Lists, inspects, and opens loot stored on the client filesystem.
- `loot.go` – Shows remote loot inventory and renders summaries.
- `remote.go` – Interacts with server-side loot, supporting filtering and detail views.
- `rename.go` – Renames loot items while synchronizing local and remote metadata.
- `rm.go` – Deletes loot entries from the server or local cache with confirmation prompts.
+10 -3
View File
@@ -1,5 +1,12 @@
Monitor
========
# client/command/monitor
Contains `monitor` related command implementations.
## Overview
Implements the 'monitor' command group for the Sliver client console. Handlers map Cobra invocations to monitor workflows such as start and stop.
## Go Files
- `commands.go` – Registers the monitor command suite for live session monitoring.
- `config.go` – Parses monitor configuration flags and resolves target selections.
- `start.go` – Starts monitoring jobs and streams event output to the console.
- `stop.go` – Stops active monitor jobs and reports termination status.
+10 -3
View File
@@ -1,4 +1,11 @@
Network
========
# client/command/network
Network related command implementations such as `netstat` and `ifconfig`
## Overview
Implements the 'network' command group for the Sliver client console. Handlers map Cobra invocations to network workflows such as ifconfig and netstat.
## Go Files
- `commands.go` – Registers network inspection commands for implants.
- `ifconfig.go` – Retrieves and prints interface configuration details from the target.
- `netstat.go` – Displays remote socket listings similar to netstat output.
+8 -4
View File
@@ -1,6 +1,10 @@
Operators
==========
# client/command/operators
Operator related command implementations.
## Overview
__NOTE:__ Some operator-related commands are server-side only and are located instead in `server/console`
Implements the 'operators' command group for the Sliver client console.
## Go Files
- `commands.go` – Declares the operators command and binds associated flags.
- `operators.go` – Lists operators connected to the server and prints session details.
+13 -3
View File
@@ -1,5 +1,15 @@
Pivots
=======
# client/command/pivots
Pivot related command implementations, pivots are specifically for pivoting C2 traffic (not to be confused with port forwarding)
## Overview
Implements the 'pivots' command group for the Sliver client console. Handlers map Cobra invocations to pivots workflows such as details, graph, start, and stop.
## Go Files
- `commands.go` – Declares the pivots command family and ties start/stop operations together.
- `details.go` – Prints detailed information about a specific pivot chain.
- `graph.go` – Renders pivot relationships as ASCII graphs for situational awareness.
- `helpers.go` – Supplies shared RPC helpers and completions used across pivot commands.
- `pivots.go` – Lists pivot sessions and summarizes their status.
- `start.go` – Initiates new pivot listeners or routes for the active target.
- `stop.go` – Stops running pivots and cleans up resources on the implant.
+9 -4
View File
@@ -1,7 +1,12 @@
Portfwd
========
# client/command/portfwd
In-band port forwarding related command implementations.
## Overview
__NOTE:__ WireGuard port forwarding commands are located in `client/command/wireguard`
Implements the 'portfwd' command group for the Sliver client console. Handlers map Cobra invocations to portfwd workflows such as portfwd ADD and portfwd RM.
## Go Files
- `commands.go` – Sets up the port forwarding command suite.
- `portfwd-add.go` – Adds new local-to-remote port forwarders on the active session.
- `portfwd-rm.go` – Removes configured port forwarders by ID.
- `portfwd.go` – Lists existing port forwards and renders their configuration.
+13 -3
View File
@@ -1,5 +1,15 @@
Privilege
==========
# client/command/privilege
Commands related to manipulation of operating system privileges, such as Windows Tokens.
## Overview
Implements the 'privilege' command group for the Sliver client console. Handlers map Cobra invocations to privilege workflows such as getprivs, getsystem, impersonate, and make token.
## Go Files
- `commands.go` – Registers privilege escalation commands and binds platform restrictions.
- `getprivs.go` – Queries and prints token privileges for the current user context.
- `getsystem.go` – Attempts to obtain SYSTEM privileges via built-in escalation techniques.
- `impersonate.go` – Handles impersonation of other logon sessions using available tokens.
- `make-token.go` – Creates new logon tokens with supplied credentials for the implant.
- `rev2self.go` – Reverts impersonation back to the implant's original security context.
- `runas.go` – Runs commands under alternate credentials or integrity levels through runas-like workflows.
+13 -3
View File
@@ -1,4 +1,14 @@
Processes
==========
# client/command/processes
Commands for manipulating remote processes, e.g. `ps`, `terminate`, etc.
## Overview
Implements the 'processes' command group for the Sliver client console. Handlers map Cobra invocations to processes workflows such as procdump, PS, pstree, and terminate.
## Go Files
- `commands.go` – Creates the processes command suite and binds subcommands for inspection and control.
- `procdump.go` – Dumps process memory to loot for forensic analysis via RPC tasks.
- `ps.go` – Lists active processes on the target with filtering options.
- `pstree.go` – Renders process hierarchies as a tree view.
- `services.go` – Enumerates Windows services and their states.
- `terminate.go` – Terminates processes by PID with confirmation messaging.
+2
View File
@@ -105,6 +105,8 @@ var knownSecurityTools = map[string][]string{
"cyuserservice.exe": {console.Red, "Palo Alto Cortex"}, // Cortex XDR - user service
"cywscsvc.exe": {console.Red, "Palo Alto Cortex"}, // Cortex XDR - security center service
"tlaworker.exe": {console.Red, "Palo Alto Cortex"}, // Cortex XDR - local analysis worker
"AEEngine.exe": {console.Red, "Faronics Anti-Executable"}, // Faronics Anti-Executable - security service
"Antiexecutable.exe": {console.Red, "Faronics Anti-Executable"}, // Faronics Anti-Executable - gui and tray icon
}
// PsCmd - List processes on the remote system
+13 -3
View File
@@ -1,5 +1,15 @@
Reaction
=========
# client/command/reaction
Commands to set a reaction, or unset a reaction. Reactions allow the operator to automate commands in response to event(s).
## Overview
Implements the 'reaction' command group for the Sliver client console. Handlers map Cobra invocations to reaction workflows such as reload, save, SET, and unset.
## Go Files
- `commands.go` – Wires the reaction command set for automations and triggers.
- `helpers.go` – Supplies shared lookup and persistence helpers for reaction rules.
- `reaction.go` – Lists existing reactions and displays their trigger conditions.
- `reload.go` – Reloads reaction definitions from disk into the client runtime.
- `save.go` – Persists in-memory reaction definitions back to disk.
- `set.go` – Creates or modifies reaction rules interactively.
- `unset.go` – Removes configured reaction rules from the store.
+10 -3
View File
@@ -1,4 +1,11 @@
Reconfig
=========
# client/command/reconfig
Commands used to reconfigure beacon/session times and metadata
## Overview
Implements the 'reconfig' command group for the Sliver client console. Handlers map Cobra invocations to reconfig workflows such as rename.
## Go Files
- `commands.go` – Registers the reconfig command and attaches subcommands such as rename.
- `reconfig.go` – Shows current implant configuration and prompts for updates.
- `rename.go` – Renames implants or beacons on the server for easier identification.
+13 -3
View File
@@ -1,4 +1,14 @@
Registry
========
# client/command/registry
Commands for manipulating the Windows registry.
## Overview
Implements the 'registry' command group for the Sliver client console. Handlers map Cobra invocations to registry workflows such as REG create, REG delete, REG list, and REG read.
## Go Files
- `commands.go` – Exposes registry management commands for Windows targets.
- `reg-create.go` – Creates new registry keys or values remotely.
- `reg-delete.go` – Deletes registry keys/values with confirmation messaging.
- `reg-list.go` – Enumerates registry subkeys and values for a provided path.
- `reg-read.go` – Reads and prints registry value data.
- `reg-write.go` – Writes registry values with type handling for supported data kinds.
+12
View File
@@ -0,0 +1,12 @@
# client/command/rportfwd
## Overview
Implements the 'rportfwd' command group for the Sliver client console. Handlers map Cobra invocations to rportfwd workflows such as portfwd ADD, portfwd RM, and portfwd.
## Go Files
- `commands.go` – Registers reverse port forwarding commands tied to implant callbacks.
- `portfwd-add.go` – Adds new reverse port forwards from remote hosts back to the operator.
- `portfwd-rm.go` – Removes reverse port forwards by identifier.
- `portfwd.go` – Lists active reverse port forwards and summarizes their endpoints.
+8 -3
View File
@@ -1,5 +1,10 @@
Screenshot
===========
# client/command/screenshot
Screenshot command implementation.
## Overview
Implements the 'screenshot' command group for the Sliver client console.
## Go Files
- `commands.go` – Registers the screenshot command and binds output options.
- `screenshot.go` – Requests a screenshot from the implant and saves or displays the resulting image.
+14 -3
View File
@@ -1,4 +1,15 @@
Sessions
=========
# client/command/sessions
Session related command implementations.
## Overview
Implements the 'sessions' command group for the Sliver client console. Handlers map Cobra invocations to sessions workflows such as background, close, interactive, and prune.
## Go Files
- `background.go` – Sends interactive sessions to the background while keeping them connected.
- `close.go` – Closes sessions cleanly via RPC.
- `commands.go` – Assembles the sessions command hierarchy and subcommands.
- `helpers.go` – Provides lookup utilities and prompt helpers for session selection.
- `interactive.go` – Brings sessions into the foreground interactive console.
- `prune.go` – Removes disconnected or dead sessions from the server inventory.
- `sessions.go` – Lists active sessions and renders tabular summaries.
+12 -3
View File
@@ -1,4 +1,13 @@
Style
======
# client/command/settings
Defines terminal interface styles.
## Overview
Implements the 'settings' command group for the Sliver client console. Handlers map Cobra invocations to settings workflows such as beacons, opsec, and tables.
## Go Files
- `beacons.go` – Configures beacon polling, jitter, and other runtime options.
- `commands.go` – Registers the settings command namespace and attaches subcommands.
- `opsec.go` – Manages operational security settings like auto tasks and notifications.
- `settings.go` – Lists and updates general client settings persisted to disk.
- `tables.go` – Adjusts table formatting preferences for console output.
+10 -3
View File
@@ -1,5 +1,12 @@
Shell
======
# client/command/shell
Implements the interactive `shell` command.
## Overview
Implements the 'shell' command group for the Sliver client console. Handlers map Cobra invocations to shell workflows such as filter reader generic and filter reader windows.
## Go Files
- `commands.go` – Exposes the interactive shell command and binds its options.
- `filter-reader_generic.go` – Provides output filtering for shell streams on POSIX targets.
- `filter-reader_windows.go` – Implements CRLF-aware filtering and decoding for Windows shell sessions.
- `shell.go` – Launches interactive command shells over RPC and manages IO loops.
+10
View File
@@ -0,0 +1,10 @@
# client/command/shikata-ga-nai
## Overview
Implements the 'shikata-ga-nai' command group for the Sliver client console. Handlers map Cobra invocations to shikata ga nai workflows such as SGN.
## Go Files
- `commands.go` – Registers shikata-ga-nai encoder commands for payload generation.
- `sgn.go` – Interfaces with the SGN service to build XOR polymorphic payloads and prints results.
+13
View File
@@ -0,0 +1,13 @@
# client/command/socks
## Overview
Implements the 'socks' command group for the Sliver client console. Handlers map Cobra invocations to socks workflows such as rootcommands, socks start, and socks stop.
## Go Files
- `commands.go` – Registers SOCKS proxy commands within the client console.
- `rootCommands.go` – Provides shared root-level wiring for SOCKS commands used in multiple menus.
- `socks-start.go` – Starts local SOCKS proxy listeners tied to implants.
- `socks-stop.go` – Stops running SOCKS proxies and frees ports.
- `socks.go` – Lists SOCKS proxies and prints their connection details.
+9 -3
View File
@@ -1,3 +1,9 @@
Taskmany
========
This package implements the `taskmany` command, which is used to task multiple beacons or sessions at once
# client/command/taskmany
## Overview
Implements the 'taskmany' command group for the Sliver client console.
## Go Files
- `taskmany.go` – Batches task execution across multiple sessions or beacons using shared parameters.
+11 -3
View File
@@ -1,5 +1,13 @@
Tasks
=======
# client/command/tasks
Manage and interact with Beacon tasks
## Overview
Implements the 'tasks' command group for the Sliver client console. Handlers map Cobra invocations to tasks workflows such as fetch and tasks cancel.
## Go Files
- `commands.go` – Registers task management commands for viewing and controlling job history.
- `fetch.go` – Downloads task artifacts and output generated by implants.
- `helpers.go` – Provides shared utilities for task lookups, formatting, and completion.
- `tasks-cancel.go` – Cancels queued or running tasks targeting implants.
- `tasks.go` – Lists recent tasks with filters for status and target.
+9 -3
View File
@@ -1,4 +1,10 @@
Update
======
# client/command/update
Implements the `update` command
## Overview
Implements the 'update' command group for the Sliver client console.
## Go Files
- `commands.go` – Registers the update command for checking new releases.
- `update.go` – Contacts the update endpoint and reports available client/server versions.
+11 -3
View File
@@ -1,4 +1,12 @@
Use
====
# client/command/use
This package implements the `use` command, which is used to select active sessions/beacons.
## Overview
Implements the 'use' command group for the Sliver client console. Handlers map Cobra invocations to use workflows such as beacons and sessions.
## Go Files
- `beacons.go` – Switches the active target to a selected beacon.
- `commands.go` – Registers the use command and subcommands for session selection.
- `sessions.go` – Sets the active session context for subsequent commands.
- `use.go` – Implements shared helper logic for switching targets and updating prompts.
+11
View File
@@ -0,0 +1,11 @@
# client/command/wasm
## Overview
Implements the 'wasm' command group for the Sliver client console. Handlers map Cobra invocations to wasm workflows such as memfs.
## Go Files
- `commands.go` – Registers WebAssembly-related commands.
- `memfs.go` – Manages the WASM in-memory filesystem cache for implants.
- `wasm.go` – Lists installed WASM modules and orchestrates execution requests.
+13 -3
View File
@@ -1,4 +1,14 @@
Websites
========
# client/command/websites
Commands related to managing `website`'s
## Overview
Implements the 'websites' command group for the Sliver client console. Handlers map Cobra invocations to websites workflows such as websites ADD content, websites RM content, websites RM, and websites update content.
## Go Files
- `commands.go` – Registers website management commands for hosted phishing content.
- `websites-add-content.go` – Uploads new site content (files or strings) to the server.
- `websites-rm-content.go` – Removes specific content entries from a hosted site.
- `websites-rm.go` – Deletes entire website definitions from the server.
- `websites-update-content.go` – Replaces or updates existing hosted content assets.
- `websites.go` – Lists configured websites and prints their metadata.
+13 -4
View File
@@ -1,7 +1,16 @@
WireGuard
==========
# client/command/wireguard
This package implements commands related to WireGuard functionality such as `wg-socks` and `wg-portfwd`
## Overview
__NOTE:__ Listener code for WireGuard (and all other protocols) is located in the `client/command/jobs` package
Implements the 'wireguard' command group for the Sliver client console. Handlers map Cobra invocations to wireguard workflows such as WG config, WG portfwd ADD, WG portfwd RM, and WG portfwd.
## Go Files
- `commands.go` – Registers WireGuard-centric commands and their subcommands.
- `wg-config.go` – Generates and displays WireGuard configuration files for implants.
- `wg-portfwd-add.go` – Adds WireGuard-based port forwarding rules.
- `wg-portfwd-rm.go` – Removes WireGuard port forwarding entries.
- `wg-portfwd.go` – Lists WireGuard forwarding rules with status information.
- `wg-socks-start.go` – Starts SOCKS proxies over WireGuard tunnels.
- `wg-socks-stop.go` – Stops WireGuard-backed SOCKS proxies.
- `wg-socks.go` – Lists SOCKS proxies running over WireGuard connections.
+9 -3
View File
@@ -1,4 +1,10 @@
Console (Client)
=================
# client/console
Contains the entrypoint for the console client
## Overview
Renders the interactive console UI, logging, and terminal helpers for the client. Coordinates readline behavior, prompt styling, and message formatting.
## Go Files
- `console.go` – Implements the interactive console, prompt rendering, and RPC client integration.
- `log.go` – Provides structured logging utilities and output filters tailored to the console experience.
+4 -4
View File
@@ -24,7 +24,6 @@ import (
"fmt"
"io"
"log"
insecureRand "math/rand"
"os"
"path/filepath"
"strconv"
@@ -40,6 +39,7 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/util"
"github.com/gofrs/uuid"
"github.com/reeflective/console"
"github.com/reeflective/readline"
@@ -356,7 +356,7 @@ func (con *SliverClient) triggerReactions(event *clientpb.Event) {
for _, reaction := range reactions {
for _, line := range reaction.Commands {
con.PrintInfof(Bold+"Execute reaction: '%s'"+Normal, line)
err := con.App.ActiveMenu().RunCommandLine(line)
err := con.App.ActiveMenu().RunCommandLine(context.Background(), line)
if err != nil {
con.PrintErrorf("Reaction command error: %s\n", err)
}
@@ -431,9 +431,9 @@ func (con *SliverClient) PrintLogo() {
}
serverSemVer := fmt.Sprintf("%d.%d.%d", serverVer.Major, serverVer.Minor, serverVer.Patch)
logo := asciiLogos[insecureRand.Intn(len(asciiLogos))]
logo := asciiLogos[util.Intn(len(asciiLogos))]
fmt.Println(strings.ReplaceAll(logo, "\n", "\r\n"))
fmt.Println("All hackers gain " + abilities[insecureRand.Intn(len(abilities))] + "\r")
fmt.Println("All hackers gain " + abilities[util.Intn(len(abilities))] + "\r")
fmt.Printf(Info+"Server v%s - %s%s\r\n", serverSemVer, serverVer.Commit, dirty)
if version.GitCommit != serverVer.Commit {
fmt.Printf(Info+"Client %s\r\n", version.FullVersion())
+19 -1
View File
@@ -78,6 +78,24 @@ func (con *SliverClient) logCommand(args []string) ([]string, error) {
return args, nil
}
logger := slog.New(con.jsonHandler).With(slog.String("type", "command"))
// Attach active target context if available
if session := con.ActiveTarget.GetSession(); session != nil {
logger = logger.With(
slog.String("id", session.ID),
slog.String("name", session.Name),
slog.String("hostname", session.Hostname),
slog.String("username", session.Username),
)
} else if beacon := con.ActiveTarget.GetBeacon(); beacon != nil {
logger = logger.With(
slog.String("id", beacon.ID),
slog.String("name", beacon.Name),
slog.String("hostname", beacon.Hostname),
slog.String("username", beacon.Username),
)
}
logger.Debug(strings.Join(args, " "))
return args, nil
}
@@ -144,7 +162,7 @@ func (con *SliverClient) PrintAsyncResponse(resp *commonpb.Response) {
defer cancel()
beacon, err := con.Rpc.GetBeacon(ctx, &clientpb.Beacon{ID: resp.BeaconID})
if err != nil {
con.PrintWarnf(err.Error())
con.PrintWarnf("%s", err.Error())
return
}
con.PrintInfof("Tasked beacon %s (%s)\n", beacon.Name, strings.Split(resp.TaskID, "-")[0])
+8 -3
View File
@@ -1,4 +1,9 @@
Constants
==========
# client/constants
A package of re-used strings and other constants
## Overview
Centralizes constants shared across the client runtime and command packages. Captures strings, flag names, and feature toggles used throughout the CLI.
## Go Files
- `constants.go` – Defines shared string and feature constants referenced across client packages.
+16
View File
@@ -0,0 +1,16 @@
# client/core
## Overview
Maintains client application state, background workers, and RPC coordination. Orchestrates session tracking, event streams, and health checks. Core logic addresses BOF, curses, portfwd, and reactions within the core package.
## Go Files
- `bof.go` – Defines Beacon Object File argument buffers and helpers for executing BOF modules.
- `curses.go` – Manages cursed browser sessions, caching processes and coordinating lifecycle events.
- `portfwd.go` – Tracks active port forwards and exposes shared state for command packages.
- `reactions.go` – Stores reaction definitions and evaluates triggers when new events arrive.
- `socks.go` – Maintains SOCKS proxy metadata and orchestrates background goroutines.
- `tunnel.go` – Represents individual tunnels and their configuration details.
- `tunnel_io.go` – Implements IO handling and relay loops for tunnel data streams.
- `tunnels.go` – Coordinates tunnel creation, lookup, and teardown across the client.
+11
View File
@@ -0,0 +1,11 @@
# client/credentials
## Overview
Credential management utilities including sniffers and import helpers for operators. Provides parsers, storage helpers, and output formatting for recovered secrets. Core logic addresses sniff within the credentials package.
## Go Files
- `credentials.go` – Implements credential storage, lookup, and formatting helpers for the client.
- `sniff.go` – Provides credential sniffing routines that parse captured outputs into structured records.
- `sniff_test.go` *(tests)* – Validates the sniffing/parsing helpers against sample credential data.
+7 -3
View File
@@ -1,5 +1,9 @@
Licenses
=========
# client/licenses
Copies of OSS licenses to be included in binary distributions.
## Overview
Holds embedded license metadata bundled with the client distribution. Supplies license retrieval utilities used for attribution commands.
## Go Files
- `licenses.go` – Provides accessors for embedded OSS license text and metadata.
-17
View File
@@ -19,26 +19,9 @@ package main
*/
import (
"crypto/rand"
"encoding/binary"
insecureRand "math/rand"
"time"
"github.com/bishopfox/sliver/client/cli"
)
// Attempt to seed insecure rand with secure rand, but we really
// don't care that much if it fails since it's insecure anyways
func init() {
buf := make([]byte, 8)
_, err := rand.Read(buf)
if err != nil {
insecureRand.Seed(int64(time.Now().Unix()))
} else {
insecureRand.Seed(int64(binary.LittleEndian.Uint64(buf)))
}
}
func main() {
cli.Execute()
}
+9
View File
@@ -0,0 +1,9 @@
# client/overlord
## Overview
Supervises long-running client jobs, scheduling, and task orchestration. Tracks job lifecycle events and exposes status updates to the console.
## Go Files
- `overlord.go` – Manages background job scheduling, tracking, and event delivery to the console.
+9
View File
@@ -0,0 +1,9 @@
# client/packages
## Overview
Deals with packaged extensions and module discovery for the client. Scans, validates, and caches extension manifests and assets. Core logic addresses output within the packages package.
## Go Files
- `output.go` – Defines schemas for extension output and assists with marshaling results.
+9
View File
@@ -0,0 +1,9 @@
# client/spin
## Overview
Lightweight terminal spinner utilities used for progress feedback. Wraps spinner styles and timing helpers shared across commands.
## Go Files
- `spin.go` – Implements the console spinner and helper functions for running operations with progress feedback.
+9
View File
@@ -0,0 +1,9 @@
# client/tcpproxy
## Overview
Implements the local TCP proxy used for port forwarding from the client side. Manages listener lifecycles, connection pumps, and cleanup hooks.
## Go Files
- `tcpproxy.go` – Implements the client-side TCP proxy listener, connection handlers, and shutdown logic.
+9
View File
@@ -0,0 +1,9 @@
# client/transport
## Overview
Client-side transports and RPC wiring to communicate with Sliver servers. Builds authenticated gRPC clients, TLS dialers, and reconnect logic. Core logic addresses mTLS within the transport package.
## Go Files
- `mtls.go` – Configures the mutual TLS gRPC transport, including dial options and credential refresh logic.
+10
View File
@@ -0,0 +1,10 @@
# client/version
## Overview
Build-time version and semantic metadata for the client binary. Exposes git information, release channels, and helper formatters. Core logic addresses sliver version and updates within the version package.
## Go Files
- `sliver-version.go` – Stores build metadata (version strings, commit hashes) and helper formatters.
- `updates.go` – Tracks update state, caches release info, and signals when new versions are available.
+1
View File
@@ -5,6 +5,7 @@ public/sitemap.json
public/docs.json
public/tutorials.json
/www.zip
util/__generated__/
# code editor files
.vscode/
+28
View File
@@ -0,0 +1,28 @@
# Repository Guidelines
## Project Structure & Module Organization
- `pages/` contains Next.js routes; Markdown docs live in `pages/docs/md`, tutorials under `pages/tutorials`.
- `components/` hosts reusable UI; `util/` stores loaders such as `Docs` and `Themes`.
- `public/` serves static assets and the generated `docs.json` consumed by search.
- `prebuild/` scripts run during `next build` to turn Markdown into JSON payloads.
- Tailwind config sits in `tailwind.config.ts`; shared CSS lives in `styles/`.
## Build, Test, and Development Commands
- `npm install` sets up dependencies.
- `npm run dev` starts the docs server with hot reload on `http://localhost:3000`.
- `npm run build` exports the static site and regenerates `public/docs.json` plus tutorials JSON.
- `npm run start` serves the last build for smoke tests.
- `npm run lint` runs the Next.js ESLint suite.
- `npm run offline` builds, then zips `out/` for offline distribution.
## Coding Style & Naming Conventions
Use TypeScript with 2-space indentation and ES module imports. Keep React components and files in `components/` PascalCase, helpers camelCase, and Markdown files kebab-case so search slugs stay predictable. Favor function components, hooks, and Tailwind utility classes; let ESLint autofix formatting issues and keep shared constants in `util/`.
## Testing Guidelines
No unit-test runner ships with this project, so treat `npm run lint` and `npm run build` as required gates. When adding interactive behavior, create targeted Playwright or Cypress checks under a `__tests__/` directory and describe how to run them in the PR. Always smoke-test the search panel locally after updating Markdown to confirm newly generated `docs.json` entries render.
## Commit & Pull Request Guidelines
History favors concise, imperative subjects (e.g., "Update workflows to use go v1.25.x"). Group related changes, reference issues with `#1234`, and avoid drive-by refactors. Pull requests should state purpose, call out UI diffs with screenshots or GIFs, confirm that `npm run lint` and `npm run build` both pass, and note any new content sources. Request a docs reviewer whenever Markdown copy changes.
## Content Authoring Tips
Edit or add docs in `pages/docs/md`; keep files flat so the generator exports clean slugs. After content updates, run `npm run build` to refresh `public/docs.json`, then spot-check sidebar headings in `npm run dev`. Tutorials follow the same workflow via `prebuild/generate-tutorials.js`, so align metadata fields to keep search results balanced.
+1 -1
View File
@@ -59,7 +59,7 @@ const CodeViewer = (props: CodeViewerProps) => {
const [scriptSourceCode, setScriptSourceCode] = React.useState(
props.script.source_code
);
const [fontSize, setFontSize] = React.useState(props.fontSize || 14);
const [fontSize, setFontSize] = React.useState(props.fontSize || 13);
const editorContainerClassName = React.useMemo(() => {
return theme === Themes.DARK
? "col-span-12 mt-4 rounded-2xl overflow-hidden"
+616 -77
View File
@@ -1,11 +1,26 @@
import CodeViewer, { CodeSchema } from "@/components/code";
import { Themes } from "@/util/themes";
import { useTheme } from "next-themes";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import {
ComponentPropsWithoutRef,
ReactNode,
createElement,
isValidElement,
useCallback,
useEffect,
useMemo,
useRef,
} from "react";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { useTheme } from "next-themes";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import {
oneDark,
oneLight,
} from "react-syntax-highlighter/dist/cjs/styles/prism";
import AsciinemaPlayer from "./asciinema";
import Youtube from "./youtube";
@@ -21,29 +36,238 @@ type MarkdownAsciiCast = {
idleTimeLimit?: number;
};
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
type HeadingProps = ComponentPropsWithoutRef<"h1"> & {
node?: unknown;
};
const mergeClassNames = (
...classes: Array<string | false | null | undefined>
) => {
return classes.filter(Boolean).join(" ");
};
const extractText = (node: ReactNode): string => {
if (node === null || node === undefined) {
return "";
}
if (typeof node === "string" || typeof node === "number") {
return String(node);
}
if (Array.isArray(node)) {
return node.map(extractText).join("");
}
if (isValidElement(node)) {
const { children } = node.props as { children?: ReactNode };
return extractText(children);
}
return "";
};
const slugify = (value: string) => {
return value
.toLowerCase()
.trim()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.replace(/[^a-z0-9\s-]/g, "")
.replace(/\s+/g, "-")
.replace(/-+/g, "-")
.replace(/^-|-$/g, "");
};
const headingClassNames: Record<HeadingLevel, string> = {
1: "mt-12 text-3xl font-semibold tracking-tight text-slate-900 first:mt-0 dark:text-slate-100",
2: "mt-10 text-2xl font-semibold tracking-tight text-slate-900 dark:text-slate-100",
3: "mt-8 text-xl font-semibold tracking-tight text-slate-900 dark:text-slate-100",
4: "mt-6 text-lg font-semibold tracking-tight text-slate-900 dark:text-slate-100",
5: "mt-6 text-base font-semibold tracking-tight text-slate-900 dark:text-slate-100",
6: "mt-6 text-base font-semibold uppercase tracking-wide text-slate-700 dark:text-slate-300",
};
const MarkdownViewer = (props: MarkdownProps) => {
const { theme } = useTheme();
const router = useRouter();
return (
<div
className={
theme === Themes.DARK ? "prose dark:prose-invert" : "prose prose-slate"
const slugCounterRef = useRef<Map<string, number>>(new Map());
useEffect(() => {
slugCounterRef.current = new Map();
}, [props.markdown]);
useEffect(() => {
if (typeof window === "undefined" || !props.markdown) {
return;
}
const hash = router.asPath.split("#")[1];
if (!hash) {
return;
}
const scrollToHash = () => {
const target = document.getElementById(hash);
if (target) {
target.scrollIntoView({ behavior: "auto", block: "start" });
return true;
}
>
<Markdown
key={props.key || `${Math.random()}`}
remarkPlugins={[remarkGfm]}
components={{
a(props) {
const { href, children, ...rest } = props;
return false;
};
if (scrollToHash()) {
return;
}
let cancelled = false;
let frameId: number | null = null;
const maxAttempts = 10;
let attempts = 0;
const tryScroll = () => {
if (cancelled) {
return;
}
if (scrollToHash()) {
return;
}
if (attempts >= maxAttempts) {
return;
}
attempts += 1;
frameId = window.requestAnimationFrame(tryScroll);
};
const timeoutId = window.setTimeout(() => {
tryScroll();
}, 0);
return () => {
cancelled = true;
window.clearTimeout(timeoutId);
if (frameId !== null) {
window.cancelAnimationFrame(frameId);
}
};
}, [props.markdown, router.asPath]);
const getAnchor = useCallback((rawValue: string) => {
const baseSlug = slugify(rawValue);
const safeBase = baseSlug || `section-${slugCounterRef.current.size + 1}`;
const usage = slugCounterRef.current.get(safeBase) ?? 0;
slugCounterRef.current.set(safeBase, usage + 1);
return usage === 0 ? safeBase : `${safeBase}-${usage}`;
}, []);
const headingComponents = useMemo(() => {
const createHeadingComponent = (level: HeadingLevel) => {
const HeadingComponent = ({
children,
className,
...rest
}: HeadingProps) => {
const textContent = extractText(children);
const anchorRef = useRef<string | null>(null);
if (!anchorRef.current) {
anchorRef.current = getAnchor(textContent);
}
const anchor = anchorRef.current;
const HeadingTag = `h${level}`;
return createElement(
HeadingTag,
{
...rest,
id: anchor || undefined,
className: mergeClassNames(
headingClassNames[level],
"scroll-mt-[70px]",
className
),
},
<span className="group inline-flex items-baseline gap-2">
<span className="font-inherit">{children}</span>
{anchor && (
<a
href={`#${anchor}`}
aria-label="Copy link to section"
className="inline-flex h-6 w-6 items-center justify-center rounded-md text-slate-400 transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 hover:text-primary dark:text-slate-500"
>
<svg
aria-hidden="true"
className="h-3.5 w-3.5"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.25 2.75a2.5 2.5 0 0 1 4.243-1.768l1.525 1.525a2.5 2.5 0 0 1 0 3.536l-1.232 1.232"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
<path
d="M8.75 13.25a2.5 2.5 0 0 1-4.243 1.768l-1.525-1.525a2.5 2.5 0 0 1 0-3.536l1.232-1.232"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
<path
d="M6 10l4-4"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
</svg>
</a>
)}
</span>
);
};
HeadingComponent.displayName = `MarkdownHeading${level}`;
return HeadingComponent;
};
return {
h1: createHeadingComponent(1),
h2: createHeadingComponent(2),
h3: createHeadingComponent(3),
h4: createHeadingComponent(4),
h5: createHeadingComponent(5),
h6: createHeadingComponent(6),
};
}, [getAnchor]);
const proseClassName = mergeClassNames(
"markdown-body prose max-w-none leading-7",
theme === Themes.DARK ? "dark:prose-invert prose-slate" : "prose-slate",
"prose-pre:bg-slate-950/90 prose-pre:text-slate-100 prose-code:font-mono prose-img:rounded-xl"
);
return (
<div className="relative">
<div className={proseClassName}>
<Markdown
key={props.key || `${Math.random()}`}
remarkPlugins={[remarkGfm]}
components={{
...headingComponents,
a(anchorProps) {
const { href, children, className, ...rest } = anchorProps;
if (href?.startsWith("/")) {
return (
// @ts-ignore
<a
{...rest}
href={href}
className="text-primary hover:text-primary-dark"
className={mergeClassNames(
"font-medium text-primary transition-colors duration-150 hover:text-primary-dark",
className
)}
onClick={(e) => {
e.preventDefault();
router.push(href);
@@ -53,94 +277,340 @@ const MarkdownViewer = (props: MarkdownProps) => {
</a>
);
}
const url = new URL(href || "");
if (url.protocol !== "http:" && url.protocol !== "https:") {
return <></>;
if (!href) {
return <>{children}</>;
}
let url: URL | null = null;
try {
const base =
typeof window !== "undefined"
? window.location.origin
: "https://sliver.sh";
url = /^https?:/i.test(href)
? new URL(href)
: new URL(href, base);
} catch (error) {
return <>{children}</>;
}
if (url.protocol !== "http:" && url.protocol !== "https:") {
return <>{children}</>;
}
const anchorClassName = mergeClassNames(
"font-medium text-primary transition-colors duration-150 underline-offset-4 hover:text-primary-dark",
className
);
if (url.host === "sliver.sh") {
return (
// @ts-ignore
<Link
{...rest}
href={url.toString()}
className="text-primary hover:text-primary-dark"
>
<Link {...rest} href={url.toString()} className={anchorClassName}>
{children}
</Link>
);
}
return (
<a
{...rest}
href={url.toString()}
rel="noopener noreferrer"
target="_blank"
className="text-primary hover:text-primary-dark"
className={mergeClassNames(
anchorClassName,
"after:ml-1 after:text-xs after:content-[\"\\2197\"]"
)}
>
{children}
</a>
);
},
pre(props) {
p(paragraphProps) {
const { className, children, ...rest } = paragraphProps;
return (
<p
{...rest}
className={mergeClassNames(
"my-6 text-base leading-7 text-slate-700 dark:text-slate-300",
className
)}
>
{children}
</p>
);
},
ul(listProps) {
const { className, children, ...rest } = listProps;
return (
<ul
{...rest}
className={mergeClassNames(
"my-6 list-disc space-y-2 pl-6 text-slate-700 marker:text-primary dark:text-slate-300",
className
)}
>
{children}
</ul>
);
},
ol(listProps) {
const { className, children, ...rest } = listProps;
return (
<ol
{...rest}
className={mergeClassNames(
"my-6 list-decimal space-y-2 pl-6 text-slate-700 marker:text-primary dark:text-slate-300",
className
)}
>
{children}
</ol>
);
},
li(listItemProps) {
const { className, children, ...rest } = listItemProps;
return (
<li
{...rest}
className={mergeClassNames(
"leading-6 text-slate-700 dark:text-slate-300",
className
)}
>
{children}
</li>
);
},
blockquote(blockquoteProps) {
const { className, children, ...rest } = blockquoteProps;
return (
<blockquote
{...rest}
className={mergeClassNames(
"my-8 border-l-4 border-slate-200 bg-slate-50 px-6 py-4 text-base italic text-slate-700 shadow-sm dark:border-slate-700 dark:bg-slate-900/50 dark:text-slate-300",
className
)}
>
{children}
</blockquote>
);
},
hr(hrProps) {
const { className, ...rest } = hrProps;
return (
<hr
{...rest}
className={mergeClassNames(
"my-12 border-t border-slate-200 dark:border-slate-800",
className
)}
/>
);
},
table(tableProps) {
const { className, children, ...rest } = tableProps;
return (
<div className="my-8 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-950/40">
<table
{...rest}
className={mergeClassNames(
"w-full min-w-max divide-y divide-slate-200 text-left text-sm dark:divide-slate-800",
className
)}
>
{children}
</table>
</div>
);
},
thead(theadProps) {
const { className, children, ...rest } = theadProps;
return (
<thead
{...rest}
className={mergeClassNames(
"bg-slate-50 text-sm font-semibold uppercase tracking-wide text-slate-600 dark:bg-slate-900/60 dark:text-slate-300",
className
)}
>
{children}
</thead>
);
},
tbody(tbodyProps) {
const { className, children, ...rest } = tbodyProps;
return (
<tbody
{...rest}
className={mergeClassNames(
"divide-y divide-slate-200 dark:divide-slate-800",
className
)}
>
{children}
</tbody>
);
},
tr(trProps) {
const { className, children, ...rest } = trProps;
return (
<tr
{...rest}
className={mergeClassNames(
"transition-colors hover:bg-slate-50 dark:hover:bg-slate-900/60",
className
)}
>
{children}
</tr>
);
},
th(thProps) {
const { className, children, ...rest } = thProps;
return (
<th
{...rest}
className={mergeClassNames(
"px-4 py-3 text-left text-sm font-semibold text-slate-600 dark:text-slate-200",
className
)}
>
{children}
</th>
);
},
td(tdProps) {
const { className, children, ...rest } = tdProps;
return (
<td
{...rest}
className={mergeClassNames(
"px-4 py-3 align-top text-sm text-slate-700 dark:text-slate-300",
className
)}
>
{children}
</td>
);
},
strong(strongProps) {
const { className, children, ...rest } = strongProps;
return (
<strong
{...rest}
className={mergeClassNames(
"font-semibold text-slate-900 dark:text-slate-100",
className
)}
>
{children}
</strong>
);
},
em(emProps) {
const { className, children, ...rest } = emProps;
return (
<em
{...rest}
className={mergeClassNames(
"text-slate-700 dark:text-slate-300",
className
)}
>
{children}
</em>
);
},
pre(preProps) {
// We need to look at the child nodes to avoid wrapping
// a monaco code block in a <pre> tag
const { children, className, node, ...rest } = props;
const { children, className, node, ...rest } = preProps as any;
const childClass = (children as any)?.props?.className;
if (
childClass &&
childClass.startsWith("language-") &&
childClass !== "language-plaintext"
) {
// @ts-ignore
return <div {...rest}>{children}</div>;
}
const textContent = extractText(children);
return (
<pre {...rest} className={className}>
{children}
<pre
{...rest}
className={mergeClassNames(
"my-6 overflow-x-auto rounded-xl border border-slate-200 bg-slate-50 p-4 text-[13px] leading-6 text-slate-900 shadow-inner dark:border-slate-800 dark:bg-slate-950/90 dark:text-slate-100",
className
)}
>
{textContent || children}
</pre>
);
},
img(props) {
const { src, alt, ...rest } = props;
img(imageProps) {
const { src, alt, className, ...rest } = imageProps;
const imageSrc = typeof src === "string" ? src : "";
return (
// @ts-ignore
<Image
{...rest}
src={src || ""}
src={imageSrc}
alt={alt || ""}
width={500}
height={500}
className="w-full rounded-medium"
width={1200}
height={720}
className={mergeClassNames(
"my-8 w-full rounded-xl border border-slate-200 object-contain shadow-sm dark:border-slate-800",
className
)}
/>
);
},
code(props) {
const { children, className, node, ...rest } = props;
const langTag = /language-(\w+)/.exec(className || "");
const lang = langTag ? langTag[1] : "plaintext";
if (lang === "plaintext") {
return (
<span className="prose-sm">
<code {...rest} className={className}>
{children}
</code>
</span>
);
}
code(codeProps) {
const { inline, children, className, node, ...rest } =
codeProps as any;
if (lang === "youtube") {
const embedId = (children as string) || "";
const languageClass =
typeof className === "string"
? className
.split(" ")
.find((cls: string) => cls.startsWith("language-"))
: undefined;
const lang = languageClass
? languageClass.replace("language-", "")
: "plaintext";
const normalizedLang = lang.toLowerCase();
const childValue = Array.isArray(children)
? children.join("")
: children;
const sourceCode = typeof childValue === "string" ? childValue : "";
if (normalizedLang === "youtube") {
const embedId = sourceCode || "";
return <Youtube embedId={embedId.trim()} />;
}
if (lang === "asciinema") {
const asciiCast: MarkdownAsciiCast = JSON.parse(
children as string
);
if (normalizedLang === "asciinema") {
const asciiCast: MarkdownAsciiCast = JSON.parse(sourceCode);
const src = asciiCast.src?.startsWith("/")
? `${window.location.origin}${asciiCast.src}`
: asciiCast.src || "";
@@ -161,32 +631,101 @@ const MarkdownViewer = (props: MarkdownProps) => {
);
}
const sourceCode = (children as string) || "";
const lines = sourceCode.split("\n").length;
if (inline || normalizedLang === "plaintext") {
return (
<code
{...rest}
className={mergeClassNames(
"rounded-md bg-slate-100 px-1.5 py-0.5 font-mono text-[13px] text-slate-700 dark:bg-slate-800/80 dark:text-slate-200",
className
)}
>
{children}
</code>
);
}
const baseTheme = theme === Themes.DARK ? oneDark : oneLight;
const themeOverrides = baseTheme as Record<string, Record<string, unknown>>;
const preStyles = themeOverrides['pre[class*="language-"]'] || {};
const codeStyles = themeOverrides['code[class*="language-"]'] || {};
const syntaxTheme = {
...baseTheme,
'pre[class*="language-"]': {
...preStyles,
background: "transparent",
backgroundColor: "transparent",
},
'code[class*="language-"]': {
...codeStyles,
background: "transparent",
backgroundColor: "transparent",
},
};
if (normalizedLang.startsWith("monaco")) {
const rawScriptType = lang.includes(":")
? lang.substring(lang.indexOf(":") + 1)
: lang === "monaco"
? "plaintext"
: lang;
const scriptType = (rawScriptType || "plaintext").trim() || "plaintext";
const lines = sourceCode.split("\n").length;
return (
<CodeViewer
className={
lines < 7
? "min-h-[120px]"
: lines < 17
? "min-h-[260px]"
: "min-h-[480px]"
}
fontSize={13}
script={
{
script_type: scriptType,
source_code: sourceCode,
} as CodeSchema
}
/>
);
}
const formattedSourceCode = sourceCode.replace(/\n$/, "");
const preWrapperClassName = mergeClassNames(
"not-prose mt-4 overflow-x-auto rounded-2xl border border-slate-200 bg-slate-50 px-4 py-4 text-[13px] leading-6 text-slate-900 shadow-sm dark:border-slate-800 dark:bg-slate-950/90 dark:text-slate-100",
className
);
return (
<CodeViewer
className={
lines < 7
? "min-h-[100px]"
: lines < 17
? "min-h-[250px]"
: "min-h-[450px]"
}
key={`${Math.random()}`}
fontSize={11}
script={
{
script_type: lang,
source_code: sourceCode,
} as CodeSchema
}
/>
<pre className={preWrapperClassName}>
<SyntaxHighlighter
language={lang}
style={syntaxTheme}
PreTag="code"
customStyle={{
background: "transparent",
color: "inherit",
margin: 0,
padding: 0,
fontFamily:
"Fira Code, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace",
fontSize: "inherit",
lineHeight: "inherit",
}}
wrapLongLines={false}
>
{formattedSourceCode}
</SyntaxHighlighter>
</pre>
);
},
}}
>
{props.markdown}
</Markdown>
>
{props.markdown}
</Markdown>
</div>
</div>
);
};
+127 -30
View File
@@ -5,10 +5,12 @@ import { useSearchContext } from "@/util/search-context";
import { Themes } from "@/util/themes";
import { faGithub } from "@fortawesome/free-brands-svg-icons";
import {
faBars,
faHome,
faMoon,
faSearch,
faSun,
faXmark,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
@@ -20,7 +22,7 @@ import {
NavbarContent,
NavbarItem,
Tooltip,
} from "@nextui-org/react";
} from "@heroui/react";
import { useTheme } from "next-themes";
import { useRouter } from "next/router";
import React from "react";
@@ -31,20 +33,62 @@ export default function TopNavbar(props: TopNavbarProps) {
const router = useRouter();
const search = useSearchContext();
const { theme, setTheme } = useTheme();
const lightDarkModeIcon = React.useMemo(
() => (theme === Themes.DARK ? faSun : faMoon),
[theme]
);
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => {
setMounted(true);
}, []);
const lightDarkModeIcon = React.useMemo(() => {
if (!mounted) {
return faMoon;
}
return theme === Themes.DARK ? faSun : faMoon;
}, [mounted, theme]);
const [query, setQuery] = React.useState("");
const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false);
React.useEffect(() => {
setIsMobileMenuOpen(false);
}, [router.pathname]);
const handleSearchSubmit = React.useCallback(() => {
if (query.trim().length === 0) {
return;
}
router.push({ pathname: "/search/", query: { search: query } });
setQuery("");
}, [query, router]);
const renderSearchInput = (wrapperClassName?: string) => (
<div className={wrapperClassName}>
<Tooltip content="Press enter to search" isOpen={query.length > 0}>
<Input
size="sm"
placeholder="Search..."
value={query}
onChange={(e) => setQuery(e.target.value)}
onClear={() => setQuery("")}
startContent={<FontAwesomeIcon icon={faSearch} />}
onKeyDown={(e) => {
if (e.key === "Enter") {
handleSearchSubmit();
}
}}
/>
</Tooltip>
</div>
);
return (
<Navbar
isBordered
maxWidth="full"
classNames={{
item: [
"flex",
<>
<Navbar
isBordered
maxWidth="full"
classNames={{
item: [
"flex",
"relative",
"h-full",
"items-center",
@@ -66,7 +110,7 @@ export default function TopNavbar(props: TopNavbarProps) {
</span>
</NavbarBrand>
<NavbarContent>
<NavbarContent className="hidden md:flex">
<NavbarItem isActive={router.pathname === "/"}>
<Button
variant="light"
@@ -101,29 +145,14 @@ export default function TopNavbar(props: TopNavbarProps) {
</NavbarItem>
</NavbarContent>
<NavbarContent as="div" justify="end">
<Tooltip content="Press enter to search" isOpen={query.length > 0}>
<Input
size="sm"
placeholder="Search..."
value={query}
onChange={(e) => setQuery(e.target.value)}
onClear={() => setQuery("")}
startContent={<FontAwesomeIcon icon={faSearch} />}
onKeyDown={(e) => {
if (e.key === "Enter") {
router.push({ pathname: `/search/`, query: { search: query } });
setQuery("");
}
}}
/>
</Tooltip>
<NavbarContent as="div" justify="end" className="hidden md:flex">
{renderSearchInput("w-64")}
<Button
variant="ghost"
onPress={() => {
setTheme(theme === Themes.DARK ? Themes.LIGHT : Themes.DARK);
}}
isDisabled={!mounted}
>
<FontAwesomeIcon icon={lightDarkModeIcon} />
</Button>
@@ -137,6 +166,74 @@ export default function TopNavbar(props: TopNavbarProps) {
<FontAwesomeIcon icon={faGithub} />
</Button>
</NavbarContent>
<div className="flex items-center gap-2 md:hidden">
<Button
variant="ghost"
onPress={() => {
setTheme(theme === Themes.DARK ? Themes.LIGHT : Themes.DARK);
}}
isDisabled={!mounted}
>
<FontAwesomeIcon icon={lightDarkModeIcon} />
</Button>
<Button
variant="ghost"
aria-label={isMobileMenuOpen ? "Close menu" : "Open menu"}
onPress={() => setIsMobileMenuOpen((current) => !current)}
>
<FontAwesomeIcon icon={isMobileMenuOpen ? faXmark : faBars} />
</Button>
</div>
</Navbar>
{isMobileMenuOpen ? (
<div className="md:hidden border-b border-default-200 dark:border-default-100/40 bg-content1 px-4 pb-4 shadow-sm">
<div className="mt-3">{renderSearchInput("w-full")}</div>
<div className="mt-4 flex flex-col gap-2">
<Button
variant={router.pathname === "/" ? "solid" : "light"}
color={router.pathname === "/" ? "primary" : "default"}
onPress={() => {
router.push("/");
setIsMobileMenuOpen(false);
}}
startContent={<FontAwesomeIcon fixedWidth icon={faHome} />}
>
Home
</Button>
<Button
variant={router.pathname.startsWith("/tutorials") ? "solid" : "light"}
color={router.pathname.startsWith("/tutorials") ? "primary" : "default"}
onPress={() => {
router.push("/tutorials");
setIsMobileMenuOpen(false);
}}
>
Tutorials
</Button>
<Button
variant={router.pathname.startsWith("/docs") ? "solid" : "light"}
color={router.pathname.startsWith("/docs") ? "primary" : "default"}
onPress={() => {
router.push("/docs");
setIsMobileMenuOpen(false);
}}
>
Docs
</Button>
<Button
variant="light"
onPress={() => {
window.open("https://github.com/BishopFox/sliver", "_blank");
}}
startContent={<FontAwesomeIcon icon={faGithub} />}
>
GitHub
</Button>
</div>
</div>
) : null}
</>
);
}
@@ -1,4 +1,4 @@
import { Button, Card, CardFooter, CardHeader } from "@nextui-org/react";
import { Button, Card, CardFooter, CardHeader } from "@heroui/react";
import AsciinemaPlayer from "./asciinema";
import { faChevronRight } from "@fortawesome/free-solid-svg-icons";
+10 -2
View File
@@ -1,3 +1,6 @@
const { spawnSync } = require('child_process');
const path = require('path');
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
@@ -10,8 +13,13 @@ const nextConfig = {
},
webpack: (config, { isServer }) => {
if (isServer) {
require('./prebuild/generate-docs');
require('./prebuild/generate-tutorials');
const result = spawnSync(process.execPath, [path.join(__dirname, 'prebuild/run-prebuild.js')], {
stdio: 'inherit',
});
if (result.status !== 0) {
throw new Error('[prebuild] webpack hook failed');
}
}
return config;
}
+7283 -4069
View File
File diff suppressed because it is too large. Load diff
+37 -29
View File
@@ -3,42 +3,50 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"dev": "npm run prebuild && concurrently -k -n prebuild,dev \"npm run prebuild:watch -- --skip-initial\" \"next dev\"",
"build": "npm run prebuild && next build",
"start": "next start",
"lint": "next lint",
"offline": "next build && zip -r www.zip ./out"
"prebuild": "node ./prebuild/run-prebuild.js",
"prebuild:watch": "node ./prebuild/watch.js",
"offline": "npm run build && zip -r www.zip ./out",
"postinstall": "node ./prebuild/run-prebuild.js"
},
"dependencies": {
"@fontsource/fira-code": "^5.0.16",
"@fortawesome/free-brands-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@monaco-editor/react": "^4.6.0",
"@nextui-org/react": "^2.2.9",
"@tanstack/react-query": "^5.13.4",
"asciinema-player": "^3.6.3",
"framer-motion": "^10.16.16",
"fuse.js": "^7.0.0",
"@fontsource/fira-code": "^5.2.7",
"@fortawesome/fontawesome-svg-core": "^7.1.0",
"@fortawesome/free-brands-svg-icons": "^7.1.0",
"@fortawesome/free-solid-svg-icons": "^7.1.0",
"@fortawesome/react-fontawesome": "^3.1.0",
"@heroui/react": "^2.8.5",
"@monaco-editor/react": "^4.7.0",
"@tailwindcss/postcss": "^4.1.14",
"@tanstack/react-query": "^5.90.2",
"asciinema-player": "^3.11.0",
"framer-motion": "^12.23.22",
"fuse.js": "^7.1.0",
"lunr": "^2.3.9",
"next": "^14.2.22",
"next-themes": "^0.2.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-markdown": "^9.0.1",
"remark-gfm": "^4.0.0"
"next": "^15.5.4",
"next-themes": "^0.4.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-markdown": "^10.1.0",
"react-syntax-highlighter": "^15.6.6",
"remark-gfm": "^4.0.1"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.10",
"@tailwindcss/typography": "^0.5.19",
"@types/lunr": "^2.3.7",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"eslint": "^8",
"eslint-config-next": "14.0.4",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "^5"
"@types/node": "^24.6.2",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@types/react-syntax-highlighter": "^15.5.13",
"autoprefixer": "^10.4.21",
"concurrently": "^9.1.0",
"eslint": "^9.37.0",
"eslint-config-next": "^15.5.4",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.14",
"typescript": "^5.9.3"
}
}
+112 -59
View File
@@ -1,96 +1,149 @@
import Navbar from "@/components/navbar";
import "@/styles/globals.css";
import { Docs } from "@/util/docs";
import { PREBUILD_VERSION } from "@/util/__generated__/prebuild-version";
import { Tutorials } from "@/util/tutorials";
import { SearchContext, SearchCtx } from "@/util/search-context";
import { fetchDocs as fetchDocsContent, fetchTutorials as fetchTutorialsContent } from "@/util/content-fetchers";
import { Themes } from "@/util/themes";
import { faExternalLink } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { NextUIProvider } from "@nextui-org/react";
import { HeroUIProvider } from "@heroui/react";
import {
HydrationBoundary,
QueryClient,
QueryClientProvider,
} from "@tanstack/react-query";
import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes";
import { ThemeProvider as NextThemesProvider } from "next-themes";
import type { AppProps } from "next/app";
import React from "react";
export default function App({ Component, pageProps }: AppProps) {
// Initialize theme
const { theme, setTheme } = useTheme();
function getThemeState(): Themes {
if (typeof window !== "undefined") {
const loadedTheme = localStorage.getItem("theme");
const currentTheme = loadedTheme ? (loadedTheme as Themes) : Themes.DARK;
setTheme(currentTheme);
}
return Themes.DARK;
}
// Initialize search
const [search, setSearch] = React.useState(new SearchCtx());
const [search] = React.useState(() => new SearchCtx());
// Initialize query client
const [queryClient] = React.useState(() => new QueryClient());
queryClient.prefetchQuery({
queryKey: ["docs"],
queryFn: async (): Promise<Docs> => {
const res = await fetch("/docs.json");
const docs: Docs = await res.json();
search.addDocs(docs);
return docs;
},
});
const versionRef = React.useRef(PREBUILD_VERSION);
queryClient.prefetchQuery({
queryKey: ["tutorials"],
queryFn: async (): Promise<Tutorials> => {
const res = await fetch("/tutorials.json");
const tutorials: Tutorials = await res.json();
search.addTutorials(tutorials);
return tutorials;
},
React.useEffect(() => {
const docsFetcher = () => fetchDocsContent(versionRef.current);
const tutorialsFetcher = () => fetchTutorialsContent(versionRef.current);
queryClient.setQueryDefaults(["docs"], {
queryFn: docsFetcher,
});
queryClient.setQueryDefaults(["tutorials"], {
queryFn: tutorialsFetcher,
});
}, [queryClient]);
React.useEffect(() => {
const syncSearch = () => {
const docsQueries = queryClient.getQueriesData<Docs>({ queryKey: ["docs"] });
docsQueries.forEach(([, data]) => {
if (data) {
search.addDocs(data);
}
});
const tutorialQueries = queryClient.getQueriesData<Tutorials>({ queryKey: ["tutorials"] });
tutorialQueries.forEach(([, data]) => {
if (data) {
search.addTutorials(data);
}
});
};
syncSearch();
const unsubscribe = queryClient.getQueryCache().subscribe(syncSearch);
return unsubscribe;
}, [queryClient, search]);
React.useEffect(() => {
const docsFetcher = () => fetchDocsContent(versionRef.current);
const tutorialsFetcher = () => fetchTutorialsContent(versionRef.current);
void queryClient.prefetchQuery({
queryKey: ["docs", versionRef.current],
queryFn: docsFetcher,
});
void queryClient.prefetchQuery({
queryKey: ["tutorials", versionRef.current],
queryFn: tutorialsFetcher,
});
}, [queryClient]);
React.useEffect(() => {
if (versionRef.current !== PREBUILD_VERSION) {
versionRef.current = PREBUILD_VERSION;
queryClient.invalidateQueries({ queryKey: ["docs"] });
queryClient.invalidateQueries({ queryKey: ["tutorials"] });
const docsFetcher = () => fetchDocsContent(versionRef.current);
const tutorialsFetcher = () => fetchTutorialsContent(versionRef.current);
void queryClient.prefetchQuery({
queryKey: ["docs", versionRef.current],
queryFn: docsFetcher,
});
void queryClient.prefetchQuery({
queryKey: ["tutorials", versionRef.current],
queryFn: tutorialsFetcher,
});
}
});
return (
<NextUIProvider>
<NextThemesProvider attribute="class" defaultTheme={getThemeState()}>
<HeroUIProvider>
<NextThemesProvider
attribute="class"
defaultTheme={Themes.DARK}
enableSystem={false}
storageKey="theme"
>
<QueryClientProvider client={queryClient}>
<HydrationBoundary state={pageProps.dehydratedState}>
<SearchContext.Provider value={search}>
<Navbar />
<Component {...pageProps} />
<div className="mb-12"></div>
<footer className="fixed bottom-0 left-0 z-20 w-full p-2 bg-white border-t border-gray-200 shadow md:flex md:items-center md:justify-between md:p-6 dark:bg-black dark:border-gray-600">
<span className="text-sm text-gray-500 sm:text-center dark:text-gray-400">
© {new Date().getFullYear()}{" "}
<a
href="https://bishopfox.com/"
className="hover:underline"
rel="noreferrer"
target="_blank"
>
Bishop Fox
</a>
{" - "}
<a
href="https://github.com/BishopFox/sliver/pulls"
rel="noreferrer"
className="hover:underline"
target="_blank"
>
You can help improve this documentation by opening a pull
request on Github <FontAwesomeIcon icon={faExternalLink} />
</a>
</span>
<ul className="flex flex-wrap items-center mt-3 text-sm font-medium text-gray-500 dark:text-gray-400 sm:mt-0">
<div className="mb-16 md:mb-20"></div>
<footer className="z-20 w-full border-t border-gray-200 bg-white px-3 py-4 text-center shadow dark:bg-black dark:border-gray-600 md:fixed md:bottom-0 md:left-0 md:flex md:items-center md:justify-between md:px-6 md:py-4">
<div className="flex flex-col items-center gap-2 text-xs leading-snug text-gray-500 sm:text-sm md:flex-row md:items-center md:gap-3 md:text-left dark:text-gray-400">
<span>
© {new Date().getFullYear()}&nbsp;
<a
href="https://bishopfox.com/"
className="hover:underline"
rel="noreferrer"
target="_blank"
>
Bishop Fox
</a>
</span>
<span className="hidden md:inline" aria-hidden="true">
·
</span>
<span className="max-w-xs md:max-w-none">
<a
href="https://github.com/BishopFox/sliver/pulls"
rel="noreferrer"
className="hover:underline"
target="_blank"
>
Help improve this documentation
<span className="ml-1 inline-block">
<FontAwesomeIcon icon={faExternalLink} />
</span>
</a>
</span>
</div>
<ul className="mt-3 flex flex-wrap items-center justify-center gap-3 text-xs font-medium text-gray-500 md:mt-0 md:gap-6 md:text-sm dark:text-gray-400">
<li>
<a
href="https://github.com/BishopFox/sliver/blob/master/LICENSE"
target="_blank"
rel="noreferrer"
className="hover:underline me-4 md:me-6"
className="hover:underline"
>
GPLv3 License
</a>
@@ -101,6 +154,6 @@ export default function App({ Component, pageProps }: AppProps) {
</HydrationBoundary>
</QueryClientProvider>
</NextThemesProvider>
</NextUIProvider>
</HeroUIProvider>
);
}
Loaded 100 of 3828 files, more files were not shown because too many files have changed in this diff. Show more