Compare commits

...
Author SHA1 Message Date
rkervella 77fea4f81c Update readline lib 2024-01-03 13:14:19 -08:00
rkervella 2ad8aa4829 Fix last merge issues 2024-01-02 16:13:26 -08:00
rkervella eecaeabf45 Merge branch 'beacon-commands' of https://github.com/maxlandon/sliver into maxlandon-beacon-commands 2024-01-02 16:11:42 -08:00
Ronan Kervella 67f92d6b4d Merge pull request #1536 from BishopFox/migrate-beacon
Add `migrate` support to beacons
2024-01-02 14:10:30 -08:00
Raf 8fd2cd98c7 Merging master into migrate-beacon 2024-01-02 15:33:04 -05:00
Raf 3d79a60464 Finishing support for migrating when using a beacon 2024-01-02 15:30:54 -05:00
Ronan Kervella 5c8f0f46d1 Merge pull request #1535 from BishopFox/migrate-with-name
Addressing Migrate "record not found"
2024-01-02 08:26:02 -08:00
Raf a58889ce14 Merge branch 'master' into migrate-beacon 2024-01-02 07:58:24 -05:00
Raf 37d7395f91 Populating the name of the implant in the migrate request from the client 2024-01-02 07:37:23 -05:00
Joe dd2af38196 Merge pull request #1531 from audibleblink/fix/migrate-cli
no positional arg needed
2023-12-30 12:13:58 -06:00
Joe 77c3d851a2 Merge pull request #1526 from BishopFox/7983dependabot/github_actions/actions/upload-pages-artifact-3
Bump actions/upload-pages-artifact from 1 to 3
2023-12-29 20:12:35 -06:00
Joe 99b15a0d71 Merge pull request #1527 from BishopFox/090adependabot/github_actions/actions/deploy-pages-4
Bump actions/deploy-pages from 2 to 4
2023-12-29 20:12:22 -06:00
Joe 04e869ce48 Merge pull request #1530 from BishopFox/sgn-stage-listener
Encode Shellcode with SGN when generating via stage-listener
2023-12-29 20:04:21 -06:00
Alex Flores dc467bcfee adds help menu to account for new usage 2023-12-29 16:44:18 -05:00
Alex Flores 21aa7d0ce9 no positional arg needed 2023-12-29 16:10:51 -05:00
Raf 32a60456e5 Encoding shellcode with SGN for shellcode generated by stage-listener, if enabled in the profile 2023-12-29 10:09:24 -05:00
Raf 01719c15c7 Initial changes to support migrating beacons 2023-12-27 04:44:11 -05:00
dependabot[bot] 8a29924a12 Bump actions/deploy-pages from 2 to 4
Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 2 to 4.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v2...v4)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-12-25 03:56:38 +00:00
dependabot[bot] 59eb25a5ad Bump actions/upload-pages-artifact from 1 to 3
Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 1 to 3.
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v1...v3)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-12-25 03:56:32 +00:00
Joe b4cf8482c1 Merge pull request #1525 from BishopFox/fix-c2-db-duplication
Fix C2 URL Duplication in Database
2023-12-22 13:55:22 -06:00
Raf de7d466acb Fixing an issue where C2 URLs are duplicated every time a profile is used to generate an implant. 2023-12-22 12:23:19 -05:00
Ronan Kervella a84f13e8a0 Merge pull request #1424 from C-Sto/extensionargs
Extensionargs
2023-12-20 16:05:03 -08:00
C_Sto dfaadfb5c0 Merge branch 'master' into extensionargs
Signed-off-by: C_Sto <[email protected]>
2023-12-20 09:19:21 +08:00
Ronan Kervella 478dabf5e1 Merge pull request #1397 from C-Sto/multiextensions
multimanifest extension support
2023-12-19 09:51:01 -08:00
Ronan Kervella 5767abe616 Merge branch 'master' into multiextensions 2023-12-19 08:29:57 -08:00
Joe 2fabbee6bf Merge pull request #1523 from BishopFox/8b62dependabot/go_modules/golang.org/x/crypto-0.17.0
Bump golang.org/x/crypto from 0.15.0 to 0.17.0
2023-12-19 10:08:20 -06:00
C-Sto 1e6d91fb6a menu better 2023-12-19 13:12:36 +08:00
moloch-- 31022c12db Add offline docs script 2023-12-18 20:47:17 -06:00
dependabot[bot] e82975d1bd Bump golang.org/x/crypto from 0.15.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.15.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.15.0...v0.17.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-12-18 23:59:26 +00:00
Ronan Kervella 1205defc3e Merge branch 'master' into extensionargs 2023-12-18 09:25:56 -08:00
Ronan Kervella 33613d25da Merge branch 'master' into multiextensions 2023-12-18 08:52:47 -08:00
moloch-- 5c9b4a6af7 fix typos 2023-12-18 08:08:11 -06:00
moloch-- cfdbe6d467 Fix more links 2023-12-17 17:53:48 -06:00
moloch-- 8ad5d44114 Adjust page title 2023-12-17 16:34:55 -06:00
moloch-- ada14762cd Self host images 2023-12-17 16:26:17 -06:00
moloch-- 5f0b778c18 Add page title 2023-12-17 12:20:47 -06:00
moloch-- 78038a8dcc Fix typo 2023-12-17 12:16:55 -06:00
moloch-- 9f0f9b1206 Update generate beacon example 2023-12-17 11:48:30 -06:00
moloch-- a02f1ac529 Update generate session example 2023-12-17 11:32:46 -06:00
moloch-- dd51a66b63 Add service status 2023-12-17 10:35:58 -06:00
moloch-- d98810a65e Update install cast 2023-12-17 10:04:50 -06:00
moloch-- 803adef634 Fix code block 2023-12-17 09:43:50 -06:00
moloch-- 03c3d45500 Fix more links 2023-12-16 23:36:59 -06:00
moloch-- ec31b5dfa6 Fix more links 2023-12-16 23:33:35 -06:00
moloch-- f1ce927e1d Simplify name/md state mgmt 2023-12-16 23:24:11 -06:00
moloch-- a4ee4dc5e9 Fix more links 2023-12-16 23:01:04 -06:00
moloch-- d4e0c562ee Fix links, enable scroll restoration 2023-12-16 22:55:38 -06:00
moloch-- 7047ec1c52 Add asciinema markdown renderer 2023-12-16 22:51:09 -06:00
moloch-- cdfc2cd241 Tweak footer 2023-12-16 21:11:18 -06:00
moloch-- c4597cca76 fix links to c2 2023-12-16 20:50:53 -06:00
moloch-- 727693f3f2 Update intro paragraph 2023-12-16 19:38:15 -06:00
moloch-- 2d51293792 Tweak timers 2023-12-16 19:29:14 -06:00
moloch-- aa1850b8e6 Update readme 2023-12-16 19:27:34 -06:00
moloch-- a84b01ed40 Tweak timers 2023-12-16 19:10:35 -06:00
moloch-- 84808f626e Implement cards 2023-12-16 18:52:50 -06:00
moloch-- a10770ae2c Override ap-control-bar class 2023-12-16 18:33:47 -06:00
moloch-- 5d8d3a5d78 Fix bottom marge in search results 2023-12-16 17:32:21 -06:00
moloch-- a0a59ee540 Add footer 2023-12-16 17:00:08 -06:00
moloch-- 58be6c5a10 Add gh button 2023-12-16 16:44:18 -06:00
moloch-- 9cd27ed805 Various small tweaks 2023-12-16 16:40:09 -06:00
moloch-- 147e06d058 Remove old install script file 2023-12-16 16:27:04 -06:00
moloch-- 26aad81968 Fix various rel links 2023-12-16 16:24:56 -06:00
moloch-- 0f26ad1396 Fix relative navigation 2023-12-16 16:20:40 -06:00
moloch-- aac3c142e5 Implement search 2023-12-16 15:41:06 -06:00
moloch-- 4e012113cf Adjust border in dark mode 2023-12-16 13:38:39 -06:00
moloch-- 6916dbe684 Fixed docs sidebar 2023-12-16 13:23:23 -06:00
moloch-- 97e5142b7a Open 3rd party links in new tab 2023-12-16 10:25:54 -06:00
moloch-- 06fc398033 Implement onClear 2023-12-15 18:24:03 -06:00
moloch-- c2f4856255 Implement fuzzy filter 2023-12-15 18:22:52 -06:00
moloch-- ad7e1dcafa Fix theme on dark landing page 2023-12-15 18:01:21 -06:00
moloch-- 8c5d3dd637 Fix theme on dark landing page 2023-12-15 17:50:32 -06:00
Joe 2e7498c94c Merge pull request #1512 from BishopFox/docs/next
Docs/next
2023-12-15 17:44:46 -06:00
moloch-- dee26bcb3d Add paths to unit tests 2023-12-15 17:44:18 -06:00
moloch-- 67c6710ff9 Add asciinema intro 2023-12-15 17:40:05 -06:00
Joe e4a98e9a34 Merge pull request #1511 from BishopFox/docs/next
Docs/next
2023-12-15 16:21:36 -06:00
moloch-- 15781566ab Add more pages 2023-12-15 16:18:23 -06:00
moloch-- 2bcaf9a78f Store doc state in frag 2023-12-15 15:59:26 -06:00
Joe d8fe33d20a Merge pull request #1510 from BishopFox/docs/next
Fix image rendering
2023-12-15 15:48:38 -06:00
moloch-- 3a846e41a7 Fix image rendering 2023-12-15 15:44:56 -06:00
Joe d3ad2dc84f Merge pull request #1508 from BishopFox/fix-hosts-rm
Fix for hosts command and host IDs for loot
2023-12-15 15:40:04 -06:00
Joe 8aa4dd4a28 Merge pull request #1507 from BishopFox/fix-ioc-rm
Fixes for removing IOCs
2023-12-15 15:39:31 -06:00
Joe b360eae3fb Merge pull request #1509 from BishopFox/docs/next
Docs/next
2023-12-15 15:39:10 -06:00
moloch-- 8260c90288 Add more pages 2023-12-15 15:36:01 -06:00
Raf b080e06039 Fixing issue with removal of hosts and an issue where the host ID for loot did not populate in the database 2023-12-15 13:49:17 -05:00
Raf d394a5936d Associating IOC Protobuf objects with database objects to fix IOC deletion, changing some error messages 2023-12-15 11:52:22 -05:00
moloch-- 7ab9ddb68f Implement monaco code viewer 2023-12-15 09:15:27 -06:00
Joe 7d496d9036 Merge pull request #1506 from BishopFox/docs/next
Fix dark mode docs
2023-12-14 18:30:28 -06:00
moloch-- 99c3bde7df Fix dark mode docs 2023-12-14 18:29:52 -06:00
Joe bc5c1e0d8a Merge pull request #1505 from BishopFox/docs/next
Docs/next
2023-12-14 18:24:09 -06:00
moloch-- 84c4832ff4 Basic renderer working 2023-12-14 18:18:01 -06:00
moloch-- 1a280c3677 Fix root document 2023-12-14 17:57:31 -06:00
moloch-- c16737bfe9 Implement docs.json scheme 2023-12-14 16:40:29 -06:00
Joe b84796f723 Merge pull request #1478 from BishopFox/2ee9dependabot/go_modules/gorm.io/driver/sqlite-1.5.4
Bump gorm.io/driver/sqlite from 1.5.2 to 1.5.4
2023-12-14 14:01:33 -06:00
Joe 5c206cdd01 Merge pull request #1504 from BishopFox/fix-iocs
IOC Fixes
2023-12-14 12:43:07 -06:00
Raf f2be8a41e7 Fixing associations between database models and IOC data objects so that IOCs are properly recorded; changed recorded IOC hash to the hash of the non-gzipped data 2023-12-14 11:46:36 -05:00
moloch-- 2e6904d838 Update docs readme 2023-12-13 18:43:09 -06:00
Joe e197ba9438 Merge pull request #1503 from BishopFox/docs/next
Docs/next
2023-12-13 18:25:40 -06:00
moloch-- f92067ef7d Place holders 2023-12-13 18:25:15 -06:00
moloch-- 33e678684f Add asciinema and monaco 2023-12-13 18:23:57 -06:00
moloch-- 0c2e8e1164 Add page dirs 2023-12-13 18:12:06 -06:00
moloch-- f7e3fd99e4 Initial commit 2023-12-13 17:57:31 -06:00
moloch-- 5539016c9b Fix out path 2023-12-13 17:23:54 -06:00
moloch-- 96fd678b3e Try to fix npm and node being stupid 2023-12-13 17:22:32 -06:00
moloch-- d2ccfb288d Node being dumb as usual 2023-12-13 17:20:28 -06:00
moloch-- cd834fcab4 Fix docs paths 2023-12-13 17:15:42 -06:00
moloch-- 8e9899e6c4 Change working directory 2023-12-13 17:14:24 -06:00
moloch-- 84d82aedcf Change working directory 2023-12-13 17:13:00 -06:00
moloch-- a3d1015449 Fix paths to subdir 2023-12-13 17:09:25 -06:00
Joe 60da181cc6 Merge pull request #1502 from BishopFox/docs/next
Add nextjs docs app
2023-12-13 17:06:15 -06:00
moloch-- a1abcaa6c8 Add nextjs docs app 2023-12-13 17:04:22 -06:00
Ronan Kervella 3974b53301 Merge pull request #1495 from vitorfhc/master
Adds the "permissions" flag to operator cmd in cli
2023-12-13 08:52:38 -08:00
Ronan Kervella dabc301108 Merge branch 'master' into master 2023-12-13 08:24:07 -08:00
Joe e32d0dd283 Merge pull request #1498 from BishopFox/4997dependabot/github_actions/actions/setup-go-5
Bump actions/setup-go from 4 to 5
2023-12-13 09:27:54 -06:00
dependabot[bot] 823d10c43c Bump actions/setup-go from 4 to 5
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-12-11 03:26:17 +00:00
Vitor Falcao fc7e0a8d19 Adds the "permissions" flag to operator cmd in cli 2023-12-06 15:39:33 -03:00
Ronan Kervella 48562a4221 Merge branch 'master' into extensionargs 2023-12-06 09:07:26 -08:00
Joe c1242a82a6 Merge pull request #1489 from Z3ratu1/fix/correct-section-length-in-evasion_windows.go
correct section length in evasion_windows.go
2023-12-04 12:27:39 -08:00
z3ratu1 d2bd8ddd42 correct section length in evasion_windows.go(fix for issue #1189) 2023-12-04 12:13:11 +08:00
dependabot[bot] e9cc6804bf Bump gorm.io/driver/sqlite from 1.5.2 to 1.5.4
Bumps [gorm.io/driver/sqlite](https://github.com/go-gorm/sqlite) from 1.5.2 to 1.5.4.
- [Commits](https://github.com/go-gorm/sqlite/compare/v1.5.2...v1.5.4)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-27 16:52:42 +00:00
Joe 061166755d Merge pull request #1477 from BishopFox/347bdependabot/go_modules/github.com/spf13/cobra-1.8.0
Bump github.com/spf13/cobra from 1.7.0 to 1.8.0
2023-11-27 08:49:58 -08:00
dependabot[bot] 489678e635 Bump github.com/spf13/cobra from 1.7.0 to 1.8.0
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.7.0...v1.8.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-27 16:17:54 +00:00
Joe 93f86ac79b Merge pull request #1476 from BishopFox/61f3dependabot/go_modules/github.com/reeflective/readline-1.0.11
Bump github.com/reeflective/readline from 1.0.10 to 1.0.11
2023-11-27 08:15:10 -08:00
dependabot[bot] 6ea60eeffc Bump github.com/reeflective/readline from 1.0.10 to 1.0.11
Bumps [github.com/reeflective/readline](https://github.com/reeflective/readline) from 1.0.10 to 1.0.11.
- [Release notes](https://github.com/reeflective/readline/releases)
- [Changelog](https://github.com/reeflective/readline/blob/master/history.go)
- [Commits](https://github.com/reeflective/readline/compare/v1.0.10...v1.0.11)

---
updated-dependencies:
- dependency-name: github.com/reeflective/readline
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-27 03:47:58 +00:00
Joe 2bc427f551 Merge pull request #1467 from BishopFox/5fa4dependabot/go_modules/github.com/yiya1989/sshkrb5-0.0.1
Bump github.com/yiya1989/sshkrb5 from 0.0.0-20201110125252-a1455b75a35e to 0.0.1
2023-11-21 12:28:42 -08:00
dependabot[bot] 59f54706a0 Bump github.com/yiya1989/sshkrb5
Bumps [github.com/yiya1989/sshkrb5](https://github.com/yiya1989/sshkrb5) from 0.0.0-20201110125252-a1455b75a35e to 0.0.1.
- [Release notes](https://github.com/yiya1989/sshkrb5/releases)
- [Commits](https://github.com/yiya1989/sshkrb5/commits/v0.0.1)

---
updated-dependencies:
- dependency-name: github.com/yiya1989/sshkrb5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-21 17:43:58 +00:00
Joe cb61b81459 Merge pull request #1469 from BishopFox/fecbdependabot/go_modules/github.com/google/uuid-1.4.0
Bump github.com/google/uuid from 1.3.1 to 1.4.0
2023-11-21 09:42:17 -08:00
Joe 880eb6091b Merge pull request #1468 from BishopFox/34ffdependabot/go_modules/github.com/miekg/dns-1.1.57
Bump github.com/miekg/dns from 1.1.56 to 1.1.57
2023-11-21 09:41:45 -08:00
dependabot[bot] 36ed8ad5b9 Bump github.com/miekg/dns from 1.1.56 to 1.1.57
Bumps [github.com/miekg/dns](https://github.com/miekg/dns) from 1.1.56 to 1.1.57.
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.56...v1.1.57)

---
updated-dependencies:
- dependency-name: github.com/miekg/dns
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-20 22:25:37 +00:00
dependabot[bot] 1b6af55b14 Bump github.com/google/uuid from 1.3.1 to 1.4.0
Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.1 to 1.4.0.
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.3.1...v1.4.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-20 22:25:11 +00:00
Joe 95a2eead7d Merge pull request #1470 from BishopFox/eda5dependabot/go_modules/github.com/mattn/go-sqlite3-1.14.18
Bump github.com/mattn/go-sqlite3 from 1.14.17 to 1.14.18
2023-11-20 14:24:08 -08:00
Joe c02b87030e Merge pull request #1471 from BishopFox/c9f2dependabot/go_modules/github.com/reeflective/readline-1.0.10
Bump github.com/reeflective/readline from 1.0.8 to 1.0.10
2023-11-20 14:23:55 -08:00
dependabot[bot] 9f252327ca Bump github.com/reeflective/readline from 1.0.8 to 1.0.10
Bumps [github.com/reeflective/readline](https://github.com/reeflective/readline) from 1.0.8 to 1.0.10.
- [Release notes](https://github.com/reeflective/readline/releases)
- [Changelog](https://github.com/reeflective/readline/blob/master/history.go)
- [Commits](https://github.com/reeflective/readline/compare/v1.0.8...v1.0.10)

---
updated-dependencies:
- dependency-name: github.com/reeflective/readline
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-20 03:57:56 +00:00
dependabot[bot] c3889e160c Bump github.com/mattn/go-sqlite3 from 1.14.17 to 1.14.18
Bumps [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) from 1.14.17 to 1.14.18.
- [Release notes](https://github.com/mattn/go-sqlite3/releases)
- [Commits](https://github.com/mattn/go-sqlite3/compare/v1.14.17...v1.14.18)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-sqlite3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-20 03:57:49 +00:00
moloch-- 853fb02e9f Fix duplicate sectool names 2023-11-19 11:01:05 -07:00
moloch-- 4f9943ec41 Fix duplicate sectool names 2023-11-19 10:59:42 -07:00
moloch-- 3e72fff43b Minor cleanups 2023-11-19 10:27:21 -07:00
moloch-- 13178f5849 Tweak token err msg 2023-11-18 13:36:31 -07:00
moloch-- 88c67e88d9 Merge branch 'operator/permissions' 2023-11-18 13:34:24 -07:00
moloch-- 14e78df896 Add more nil checks 2023-11-18 13:34:09 -07:00
moloch-- b3429f5f88 Fix err nil deref 2023-11-18 13:31:47 -07:00
Joe 0402d622e1 Merge pull request #1466 from BishopFox/operator/permissions
Operator/permissions
2023-11-18 12:11:59 -08:00
moloch-- 04d8d2aac7 Add missing builder permissions 2023-11-18 12:39:34 -07:00
moloch-- b71759f3b2 Add basic methods 2023-11-18 12:33:06 -07:00
moloch-- 13c68a7f50 Implement method checks 2023-11-18 12:27:39 -07:00
moloch-- 1f894f50ff Add permissions to operator config 2023-11-18 12:14:33 -07:00
moloch-- 33ea66de58 Add production 'slim' Docker stage 2023-11-18 10:19:14 -07:00
moloch-- 9a432f583d Add missing libs to docker test 2023-11-18 10:09:32 -07:00
moloch-- cbcd948c83 Add comments to Dockerfile 2023-11-18 09:24:21 -07:00
Joe 2ada8bf8ed Merge pull request #1465 from BishopFox/vendor/ssh
Update ssh and garble
2023-11-18 08:16:16 -08:00
moloch-- 02a4657d14 Additional tweaks to dockerfile 2023-11-18 08:53:46 -07:00
Joe b7cef9a07c Merge branch 'master' into vendor/ssh 2023-11-18 07:06:53 -08:00
moloch-- 49606ba753 Update ssh and garble 2023-11-18 07:49:03 -07:00
Joe 116431a049 Merge pull request #1421 from BishopFox/upload-dir
Adding the ability to upload directories
2023-11-17 10:03:09 -08:00
Joe ae5ac2af0f Merge branch 'master' into upload-dir 2023-11-17 09:34:45 -08:00
Joe b03c2ca6cd Merge pull request #1464 from BishopFox/vendor/gorilla
Update deps
2023-11-16 17:55:34 -08:00
Joe 6a4276e1e2 Merge pull request #1463 from BishopFox/http/default-config
Update default http c2 config
2023-11-16 17:55:17 -08:00
moloch-- c7358f8e63 Remove uneeded rand seeding 2023-11-16 18:32:54 -07:00
moloch-- de2fb65ee0 Improve cert randomization 2023-11-16 18:28:48 -07:00
moloch-- c52ca054a0 Update default http c2 config 2023-11-16 18:22:50 -07:00
moloch-- ffdbaba982 Update default http c2 config 2023-11-16 18:17:04 -07:00
moloch-- d23d814368 Update deps 2023-11-16 17:20:33 -07:00
Joe a57a67b6e0 Merge pull request #1461 from BishopFox/vendor/sqlite
Update sqlite deps
2023-11-16 15:59:35 -08:00
Ronan Kervella 8c1194283b Merge branch 'master' into upload-dir 2023-11-10 14:05:05 -08:00
Ronan Kervella 28397eb7a9 Merge branch 'master' into extensionargs 2023-11-10 13:02:13 -08:00
Raf 8ebd7da9a8 Merge branch 'master' into upload-dir 2023-11-08 08:15:02 -05:00
Raf a511af6fd2 Merge branch 'master' into upload-dir 2023-11-01 10:52:23 -04:00
Raf 97a22bb8eb Merging master into this branch and making some tweaks to upload. 2023-11-01 10:38:34 -04:00
Ronan Kervella 342ed489f3 Merge branch 'master' into multiextensions 2023-10-20 10:30:30 -07:00
Ronan Kervella 6b88a01fad Merge branch 'master' into upload-dir 2023-10-19 15:31:56 -07:00
Ronan Kervella 5e5e0df4ec Merge branch 'master' into multiextensions 2023-10-16 09:03:17 -07:00
C-Sto c02c40cb65 improve extensions UX 2023-10-08 10:48:29 +08:00
C-Sto be222e3ffa use bof arg packer for extensions 2023-10-08 07:16:34 +08:00
Raf 7747df7b96 Addressing potential zip slip issue, fixing bug when uploading directories without a filter 2023-10-04 11:11:49 -04:00
Raf efe747b8aa Adding the ability to upload directories 2023-10-04 10:13:04 -04:00
C-Sto 4421ec1698 make client work with updated manifest schema 2023-09-30 14:07:29 +08:00
C-Sto 7815b67a8a revise manifest schema 2023-09-30 14:07:02 +08:00
Ronan Kervella 84aed0720f Merge branch 'master' into multiextensions 2023-09-27 10:53:29 -07:00
Ronan Kervella b212e0fb99 Merge branch 'master' into multiextensions 2023-09-25 11:14:16 -07:00
Ronan Kervella b3ab5ea62e Merge branch 'master' into multiextensions 2023-08-31 10:15:36 -07:00
C-Sto 9d4486f906 multimanifest extension support 2023-08-31 10:57:27 +08:00
Joe a79b397d17 Merge branch 'master' into beacon-commands 2023-08-09 19:05:56 -05:00
Ronan Kervella 46a33851fd Merge branch 'master' into beacon-commands 2023-08-08 11:14:44 -07:00
Ronan Kervella 1da52a3fec Merge branch 'master' into beacon-commands 2023-08-08 09:33:37 -07:00
maxlandon 12065fdb99 Rename SliverConsoleClient to SliverClient 2023-07-23 19:48:38 +02:00
maxlandon d5c1daaa48 Simplify binding commands with groups 2023-07-23 19:36:57 +02:00
maxlandon be65f1ce58 Filter portfwd/socks commands out of beacons 2023-07-23 19:23:13 +02:00
maxlandon 163c11b60c Fmt 2023-07-23 19:04:44 +02:00
maxlandon 47a280cc16 Fix beacon compile flags + debug level for client asciicast 2023-07-23 19:04:20 +02:00
maxlandon ba34df3b4b Merge remote-tracking branch 'BishopFox/master' into beacon-commands 2023-07-19 02:37:44 +02:00
maxlandon 51473ec137 Add many missing completers 2023-06-22 20:26:04 +02:00
maxlandon 2da61c1e54 Finish splits. Compiles 2023-06-22 19:29:04 +02:00
maxlandon e23f040962 Split sliver commands in their files 2023-06-22 17:55:32 +02:00
maxlandon f370e96058 Finish splitting server commands in their files 2023-06-20 13:28:03 +02:00
maxlandon ec88f9bd02 Start splitting commands declarations 2023-06-07 23:00:29 +02:00
maxlandon bce0c8de06 Add a flags package, in which we store some command utility functions to
bind flags, completions, apply command filters, etc.
2023-06-07 22:24:19 +02:00
maxlandon 44ceccff12 Fix some newlines printed or not 2023-06-07 21:44:01 +02:00
763 changed files with 115382 additions and 14914 deletions

No files matched your search

+2 -2
View File
@@ -12,7 +12,7 @@ jobs:
timeout-minutes: 45
steps:
- name: Go 1.21
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "^1.21"
@@ -43,7 +43,7 @@ jobs:
timeout-minutes: 45
steps:
- name: Go 1.21
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "^1.21"
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
steps:
# Setup go environment
- name: Go 1.21
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "^1.21"
+102
View File
@@ -0,0 +1,102 @@
# Sample workflow for building and deploying a Next.js site to GitHub Pages
#
# To get started with Next.js see: https://nextjs.org/docs/getting-started
#
name: Sliver Docs
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ github.workspace }}/docs/sliver-docs
env:
working-directory: ${{ github.workspace }}/docs/sliver-docs
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Detect package manager
id: detect-package-manager
run: |
if [ -f "${{ github.workspace }}/docs/sliver-docs/yarn.lock" ]; then
echo "manager=yarn" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=yarn" >> $GITHUB_OUTPUT
exit 0
elif [ -f "${{ github.workspace }}/docs/sliver-docs/package.json" ]; then
echo "manager=npm" >> $GITHUB_OUTPUT
echo "command=ci" >> $GITHUB_OUTPUT
echo "runner=npx --no-install" >> $GITHUB_OUTPUT
exit 0
else
echo "Unable to determine package manager"
exit 1
fi
- name: Setup Node
uses: actions/setup-node@v4
with:
cache: "npm"
cache-dependency-path: "**/package-lock.json"
node-version: "lts/*"
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Restore cache
uses: actions/cache@v3
with:
path: |
.next/cache
# Generate a new cache whenever packages or source files change.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
# If source files changed but packages didn't, rebuild from a prior cache.
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-
- name: Install dependencies
working-directory: ${{ env.working-directory}}
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
- name: Build with Next.js
working-directory: ${{ env.working-directory}}
run: ${{ steps.detect-package-manager.outputs.runner }} next build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ${{ github.workspace }}/docs/sliver-docs/out
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
+11 -3
View File
@@ -3,6 +3,14 @@ on:
pull_request:
branches:
- master
paths:
- "go.mod"
- "go.sum"
- "Makefile"
- "**/*.go"
- "**/*.c"
- "**/*.h"
- "**/*.sh"
types:
- opened
- reopened
@@ -16,7 +24,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Go 1.21
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "^1.21"
@@ -50,7 +58,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Go 1.21
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "^1.21"
@@ -81,7 +89,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Go 1.21
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "^1.21"
+82 -24
View File
@@ -1,3 +1,12 @@
#
# For production:
# docker build --target production -t sliver .
# docker run -it --rm -v $HOME/.sliver:/home/sliver/.sliver sliver
#
# For unit testing:
# docker build --target test .
#
# STAGE: base
## Compiles Sliver for use
FROM --platform=linux/amd64 golang:1.21.4 as base
@@ -22,25 +31,10 @@ RUN cp -vv sliver-server /opt/sliver-server
## Use `--target test` in the docker build command to run this stage
FROM --platform=linux/amd64 base as test
### Install testing packages
RUN apt-get update --fix-missing && apt-get -y install \
libxml2 libxml2-dev libxslt-dev locate curl \
libreadline6-dev libcurl4-openssl-dev git-core \
libssl-dev libyaml-dev openssl autoconf libtool \
ncurses-dev bison curl xsel postgresql \
postgresql-contrib postgresql-client libpq-dev \
libapr1 libaprutil1 libsvn1 \
libpcap-dev libsqlite3-dev libgmp3-dev \
mingw-w64 binutils-mingw-w64 g++-mingw-w64 \
nasm gcc-multilib
### Install MSF for testing
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 apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get -y install \
curl gcc-multilib build-essential mingw-w64 binutils-mingw-w64 g++-mingw-w64
RUN /opt/sliver-server unpack --force
@@ -51,17 +45,81 @@ RUN /go/src/github.com/bishopfox/sliver/go-tests.sh
## Final dockerized form of Sliver
FROM --platform=linux/amd64 debian:bookworm-slim as production
### Install production packages
RUN apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get -y install \
libxml2 libxml2-dev libxslt-dev locate gnupg \
libreadline6-dev libcurl4-openssl-dev git-core \
libssl-dev libyaml-dev openssl autoconf libtool \
ncurses-dev bison curl xsel postgresql \
postgresql-contrib postgresql-client libpq-dev \
curl libapr1 libaprutil1 libsvn1 \
libpcap-dev libsqlite3-dev libgmp3-dev \
mingw-w64 binutils-mingw-w64 g++-mingw-w64 \
nasm gcc-multilib
### Install MSF for stager generation
RUN curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall \
&& chmod 755 msfinstall \
&& ./msfinstall \
&& mkdir -p ~/.msf4/ \
&& touch ~/.msf4/initial_setup_complete
### Cleanup unneeded packages
RUN apt-get remove -y curl gnupg \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
### Add sliver user
RUN groupadd -g 999 sliver \
&& useradd -r -u 999 -g sliver sliver \
&& mkdir -p /home/sliver/ \
&& chown -R sliver:sliver /home/sliver \
&& su -l sliver -c 'mkdir -p ~/.msf4/ && touch ~/.msf4/initial_setup_complete'
### Copy compiled binary
COPY --from=base /opt/sliver-server /opt/sliver-server
### Add sliver user
RUN groupadd -g 999 sliver && useradd -r -u 999 -g sliver sliver
RUN mkdir -p /home/sliver/ && chown -R sliver:sliver /home/sliver
### Unpack Sliver:
USER sliver
RUN /opt/sliver-server unpack --force
WORKDIR /home/sliver/
VOLUME [ "/home/sliver/.sliver" ]
ENTRYPOINT [ "/opt/sliver-server" ]
# STAGE: production-slim (about 1Gb smaller)
### Slim production image, i.e. without MSF and assoicated libraries
### Still include GCC and MinGW for cross-platform generation
FROM --platform=linux/amd64 debian:bookworm-slim as production-slim
### Install production packages
RUN apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get -y install \
build-essential mingw-w64 binutils-mingw-w64 g++-mingw-w64 gcc-multilib
### Cleanup unneeded packages
RUN apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
### Add sliver user
RUN groupadd -g 999 sliver \
&& useradd -r -u 999 -g sliver sliver \
&& mkdir -p /home/sliver/ \
&& chown -R sliver:sliver /home/sliver
### Copy compiled binary
COPY --from=base /opt/sliver-server /opt/sliver-server
### Unpack Sliver:
USER sliver
RUN /opt/sliver-server unpack --force
USER sliver
WORKDIR /home/sliver/
VOLUME [ "/home/sliver/.sliver" ]
ENTRYPOINT [ "/opt/sliver-server" ]
+7 -7
View File
@@ -8,7 +8,7 @@ The server and client support MacOS, Windows, and Linux. Implants are supported
# v1.6.0 / `master`
**NOTE:** You are looking the latest master branch of Sliver v1.6.0; PRs should target this branch starting on 6/1/2023 ('MURICA format). However, this branch is NOT RECOMMENDED for production use yet. Please use release tagged versions for the best experience.
**NOTE:** You are looking the latest master branch of Sliver v1.6.0; new PRs should target this branch. However, this branch is NOT RECOMMENDED for production use yet. Please use release tagged versions for the best experience.
For PRs containing bug fixes specific to Sliver v1.5, please target the [`v1.5.x/master` branch](https://github.com/BishopFox/sliver/tree/v1.5.x/master).
@@ -18,9 +18,9 @@ For PRs containing bug fixes specific to Sliver v1.5, please target the [`v1.5.x
- Compile-time obfuscation
- Multiplayer-mode
- Staged and Stageless payloads
- [Procedurally generated C2](<https://github.com/BishopFox/sliver/wiki/HTTP(S)-C2#under-the-hood>) over HTTP(S)
- [DNS canary](https://github.com/BishopFox/sliver/wiki/DNS-C2#dns-canaries) blue team detection
- [Secure C2](https://github.com/BishopFox/sliver/wiki/Transport-Encryption) over mTLS, WireGuard, HTTP(S), and DNS
- [Procedurally generated C2](https://sliver.sh/docs?name=HTTPS+C2) over HTTP(S)
- [DNS canary](https://sliver.sh/docs?name=DNS+C2) blue team detection
- [Secure C2](https://sliver.sh/docs?name=Transport+Encryption) over mTLS, WireGuard, HTTP(S), and DNS
- Fully scriptable using [JavaScript/TypeScript](https://github.com/moloch--/sliver-script) or [Python](https://github.com/moloch--/sliver-py)
- Windows process migration, process injection, user token manipulation, etc.
- Let's Encrypt integration
@@ -31,7 +31,7 @@ For PRs containing bug fixes specific to Sliver v1.5, please target the [`v1.5.x
### Getting Started
Download the latest [release](https://github.com/BishopFox/sliver/releases) and see the Sliver [wiki](https://github.com/BishopFox/sliver/wiki/Getting-Started) for a quick tutorial on basic setup and usage. To get the very latest and greatest compile from source.
Download the latest [release](https://github.com/BishopFox/sliver/releases) and see the Sliver [wiki](https://sliver.sh/docs?name=Getting+Started) for a quick tutorial on basic setup and usage. To get the very latest and greatest compile from source.
#### Linux One Liner
@@ -39,11 +39,11 @@ Download the latest [release](https://github.com/BishopFox/sliver/releases) and
### Help!
Please checkout the [wiki](https://github.com/BishopFox/sliver/wiki), or start a [GitHub discussion](https://github.com/BishopFox/sliver/discussions). We also tend to hang out in the #golang Slack channel on the [Bloodhound Gang](https://bloodhoundgang.herokuapp.com/) server.
Please checkout the [wiki](https://sliver.sh/), or start a [GitHub discussion](https://github.com/BishopFox/sliver/discussions). We also tend to hang out in the #golang Slack channel on the [Bloodhound Gang](https://bloodhoundgang.herokuapp.com/) server.
### Compile From Source
See the [wiki](https://github.com/BishopFox/sliver/wiki/Compile-From-Source).
See the [wiki](https://sliver.sh/docs?name=Compile+from+Source).
### Feedback
+4 -5
View File
@@ -24,11 +24,10 @@ import (
"os"
"path"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/version"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
)
const (
@@ -37,7 +36,7 @@ const (
var sliverServerVersion = fmt.Sprintf("v%s", version.FullVersion())
// Initialize logging
// Initialize logging.
func initLogging(appDir string) *os.File {
log.SetFlags(log.LstdFlags | log.Lshortfile)
logFile, err := os.OpenFile(path.Join(appDir, logFileName), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o600)
@@ -88,7 +87,7 @@ var rootCmd = &cobra.Command{
Long: ``,
}
// Execute - Execute root command
// Execute - Execute root command.
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
-1
View File
@@ -23,7 +23,6 @@ import (
"sort"
"github.com/bishopfox/sliver/client/assets"
"gopkg.in/AlecAivazis/survey.v1"
)
+5 -6
View File
@@ -3,18 +3,17 @@ package cli
import (
"fmt"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/transport"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)
// consoleCmd generates the console with required pre/post runners
func consoleCmd(con *console.SliverConsoleClient) *cobra.Command {
// consoleCmd generates the console with required pre/post runners.
func consoleCmd(con *console.SliverClient) *cobra.Command {
consoleCmd := &cobra.Command{
Use: "console",
Short: "Start the sliver client console",
@@ -25,7 +24,7 @@ func consoleCmd(con *console.SliverConsoleClient) *cobra.Command {
return consoleCmd
}
func consoleRunnerCmd(con *console.SliverConsoleClient, run bool) (pre, post func(cmd *cobra.Command, args []string) error) {
func consoleRunnerCmd(con *console.SliverClient, run bool) (pre, post func(cmd *cobra.Command, args []string) error) {
var ln *grpc.ClientConn
pre = func(_ *cobra.Command, _ []string) error {
+7 -8
View File
@@ -3,17 +3,16 @@ package cli
import (
"errors"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/command"
"github.com/bishopfox/sliver/client/command/use"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
func implantCmd(con *console.SliverConsoleClient) *cobra.Command {
func implantCmd(con *console.SliverClient) *cobra.Command {
con.IsCLI = true
makeCommands := command.SliverCommands(con)
@@ -34,7 +33,7 @@ func implantCmd(con *console.SliverConsoleClient) *cobra.Command {
return cmd
}
func makeRunners(implantCmd *cobra.Command, con *console.SliverConsoleClient) (pre, post func(cmd *cobra.Command, args []string) error) {
func makeRunners(implantCmd *cobra.Command, con *console.SliverClient) (pre, post func(cmd *cobra.Command, args []string) error) {
startConsole, closeConsole := consoleRunnerCmd(con, false)
// The pre-run function connects to the server and sets up a "fake" console,
@@ -59,7 +58,7 @@ func makeRunners(implantCmd *cobra.Command, con *console.SliverConsoleClient) (p
return pre, closeConsole
}
func makeCompleters(cmd *cobra.Command, con *console.SliverConsoleClient) {
func makeCompleters(cmd *cobra.Command, con *console.SliverClient) {
comps := carapace.Gen(cmd)
comps.PreRun(func(cmd *cobra.Command, args []string) {
@@ -67,7 +66,7 @@ func makeCompleters(cmd *cobra.Command, con *console.SliverConsoleClient) {
})
// Bind completers to flags (wrap them to use the same pre-runners)
command.FlagComps(cmd, func(comp *carapace.ActionMap) {
command.BindFlagCompletions(cmd, func(comp *carapace.ActionMap) {
(*comp)["use"] = carapace.ActionCallback(func(c carapace.Context) carapace.Action {
cmd.PersistentPreRunE(cmd, c.Args)
return use.SessionIDCompleter(con)
+1 -2
View File
@@ -22,10 +22,9 @@ import (
"fmt"
"os"
"github.com/bishopfox/sliver/client/assets"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/assets"
)
func importCmd() *cobra.Command {
+1 -2
View File
@@ -21,9 +21,8 @@ package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/version"
"github.com/spf13/cobra"
)
var cmdVersion = &cobra.Command{
+7 -8
View File
@@ -27,15 +27,14 @@ import (
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
)
// AliasesCmd - The alias command
func AliasesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) error {
// AliasesCmd - The alias command.
func AliasesCmd(cmd *cobra.Command, con *console.SliverClient, args []string) error {
if 0 < len(loadedAliases) {
PrintAliases(con)
} else {
@@ -45,8 +44,8 @@ func AliasesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []str
return nil
}
// PrintAliases - Print a list of loaded aliases
func PrintAliases(con *console.SliverConsoleClient) {
// PrintAliases - Print a list of loaded aliases.
func PrintAliases(con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
@@ -88,8 +87,8 @@ func PrintAliases(con *console.SliverConsoleClient) {
con.Println(tw.Render())
}
// AliasCommandNameCompleter - Completer for installed extensions command names
func AliasCommandNameCompleter(prefix string, args []string, con *console.SliverConsoleClient) []string {
// AliasCommandNameCompleter - Completer for installed extensions command names.
func AliasCommandNameCompleter(prefix string, args []string, con *console.SliverClient) []string {
results := []string{}
for name := range loadedAliases {
if strings.HasPrefix(name, prefix) {
@@ -129,7 +128,7 @@ func getInstalledManifests() map[string]*AliasManifest {
return installedManifests
}
// AliasCommandNameCompleter - Completer for installed extensions command names
// AliasCommandNameCompleter - Completer for installed extensions command names.
func AliasCompleter() carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
results := []string{}
+61
View File
@@ -0,0 +1,61 @@
package alias
import (
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
)
// Commands returns the `alias` command and its child commands.
func Commands(con *console.SliverClient) []*cobra.Command {
aliasCmd := &cobra.Command{
Use: consts.AliasesStr,
Short: "List current aliases",
Long: help.GetHelpFor([]string{consts.AliasesStr}),
Run: func(cmd *cobra.Command, args []string) {
AliasesCmd(cmd, con, args)
},
GroupID: consts.GenericHelpGroup,
}
aliasLoadCmd := &cobra.Command{
Use: consts.LoadStr + " [ALIAS]",
Short: "Load a command alias",
Long: help.GetHelpFor([]string{consts.AliasesStr, consts.LoadStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
AliasesLoadCmd(cmd, con, args)
},
}
aliasCmd.AddCommand(aliasLoadCmd)
flags.NewCompletions(aliasLoadCmd).PositionalCompletion(carapace.ActionDirectories().Tag("alias directory").Usage("path to the alias directory"))
aliasInstallCmd := &cobra.Command{
Use: consts.InstallStr + " [ALIAS]",
Short: "Install a command alias",
Long: help.GetHelpFor([]string{consts.AliasesStr, consts.InstallStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
AliasesInstallCmd(cmd, con, args)
},
}
aliasCmd.AddCommand(aliasInstallCmd)
flags.NewCompletions(aliasInstallCmd).PositionalCompletion(carapace.ActionFiles().Tag("alias file"))
aliasRemove := &cobra.Command{
Use: consts.RmStr + " [ALIAS]",
Short: "Remove an alias",
Long: help.GetHelpFor([]string{consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
AliasesRemoveCmd(cmd, con, args)
},
}
flags.NewCompletions(aliasRemove).PositionalCompletion(AliasCompleter())
aliasCmd.AddCommand(aliasRemove)
return []*cobra.Command{aliasCmd}
}
+8 -9
View File
@@ -25,15 +25,14 @@ import (
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
)
// AliasesInstallCmd - Install an alias
func AliasesInstallCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// AliasesInstallCmd - Install an alias.
func AliasesInstallCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
aliasLocalPath := args[0]
fi, err := os.Stat(aliasLocalPath)
if os.IsNotExist(err) {
@@ -47,8 +46,8 @@ func AliasesInstallCmd(cmd *cobra.Command, con *console.SliverConsoleClient, arg
}
}
// Install an extension from a directory
func installFromDir(aliasLocalPath string, con *console.SliverConsoleClient) {
// Install an extension from a directory.
func installFromDir(aliasLocalPath string, con *console.SliverClient) {
manifestData, err := os.ReadFile(filepath.Join(aliasLocalPath, ManifestFileName))
if err != nil {
con.PrintErrorf("Error reading %s: %s", ManifestFileName, err)
@@ -100,8 +99,8 @@ func installFromDir(aliasLocalPath string, con *console.SliverConsoleClient) {
con.Printf("done!\n")
}
// Install an extension from a .tar.gz file
func InstallFromFile(aliasGzFilePath string, autoOverwrite bool, con *console.SliverConsoleClient) *string {
// Install an extension from a .tar.gz file.
func InstallFromFile(aliasGzFilePath string, autoOverwrite bool, con *console.SliverClient) *string {
manifestData, err := util.ReadFileFromTarGz(aliasGzFilePath, fmt.Sprintf("./%s", ManifestFileName))
if err != nil {
con.PrintErrorf("Failed to read %s from '%s': %s\n", ManifestFileName, aliasGzFilePath, err)
@@ -152,7 +151,7 @@ func InstallFromFile(aliasGzFilePath string, autoOverwrite bool, con *console.Sl
return &installPath
}
func installArtifact(aliasGzFilePath string, installPath, artifactPath string, con *console.SliverConsoleClient) error {
func installArtifact(aliasGzFilePath string, installPath, artifactPath string, con *console.SliverClient) error {
data, err := util.ReadFileFromTarGz(aliasGzFilePath, fmt.Sprintf("./%s", strings.TrimPrefix(artifactPath, string(os.PathSeparator))))
if err != nil {
return err
+21 -22
View File
@@ -28,11 +28,6 @@ import (
"strings"
"github.com/AlecAivazis/survey/v2"
app "github.com/reeflective/console"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/protobuf/proto"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
@@ -40,6 +35,10 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
app "github.com/reeflective/console"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/protobuf/proto"
)
const (
@@ -53,7 +52,7 @@ const (
)
var (
// alias name -> manifest/command
// alias name -> manifest/command.
loadedAliases = map[string]*loadedAlias{}
defaultHostProc = map[string]string{
@@ -63,20 +62,20 @@ var (
}
)
// Ties the manifest struct to the command struct
// Ties the manifest struct to the command struct.
type loadedAlias struct {
Manifest *AliasManifest
Command *cobra.Command
}
// AliasFile - An OS/Arch specific file
// AliasFile - An OS/Arch specific file.
type AliasFile struct {
OS string `json:"os"`
Arch string `json:"arch"`
Path string `json:"path"`
}
// AliasManifest - The manifest for an alias, contains metadata
// AliasManifest - The manifest for an alias, contains metadata.
type AliasManifest struct {
Name string `json:"name"`
Version string `json:"version"`
@@ -124,7 +123,7 @@ func (a *AliasManifest) getFileForTarget(cmdName string, targetOS string, target
}
// AliasesLoadCmd - Locally load a alias into the Sliver shell.
func AliasesLoadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func AliasesLoadCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
dirPath := args[0]
// dirPath := ctx.Args.String("dir-path")
alias, err := LoadAlias(dirPath, cmd.Root(), con)
@@ -135,8 +134,8 @@ func AliasesLoadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args [
}
}
// LoadAlias - Load an alias into the Sliver shell from a given directory
func LoadAlias(manifestPath string, cmd *cobra.Command, con *console.SliverConsoleClient) (*AliasManifest, error) {
// LoadAlias - Load an alias into the Sliver shell from a given directory.
func LoadAlias(manifestPath string, cmd *cobra.Command, con *console.SliverClient) (*AliasManifest, error) {
// retrieve alias manifest
var err error
manifestPath, err = filepath.Abs(manifestPath)
@@ -205,7 +204,7 @@ func LoadAlias(manifestPath string, cmd *cobra.Command, con *console.SliverConso
return aliasManifest, nil
}
// ParseAliasManifest - Parse an alias manifest
// ParseAliasManifest - Parse an alias manifest.
func ParseAliasManifest(data []byte) (*AliasManifest, error) {
// parse it
alias := &AliasManifest{}
@@ -241,7 +240,7 @@ func ParseAliasManifest(data []byte) (*AliasManifest, error) {
return alias, nil
}
func runAliasCommand(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func runAliasCommand(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -474,26 +473,26 @@ func runAliasCommand(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
// PrintSpawnDLLOutput - Prints the output of a spawn dll command
func PrintSpawnDLLOutput(cmdName string, spawnDllResp *sliverpb.SpawnDll, outFilePath *os.File, con *console.SliverConsoleClient) {
// PrintSpawnDLLOutput - Prints the output of a spawn dll command.
func PrintSpawnDLLOutput(cmdName string, spawnDllResp *sliverpb.SpawnDll, outFilePath *os.File, con *console.SliverClient) {
con.PrintInfof("%s output:\n%s", cmdName, spawnDllResp.GetResult())
if outFilePath != nil {
outFilePath.Write([]byte(spawnDllResp.GetResult()))
outFilePath.WriteString(spawnDllResp.GetResult())
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
}
// PrintSideloadOutput - Prints the output of a sideload command
func PrintSideloadOutput(cmdName string, sideloadResp *sliverpb.Sideload, outFilePath *os.File, con *console.SliverConsoleClient) {
// PrintSideloadOutput - Prints the output of a sideload command.
func PrintSideloadOutput(cmdName string, sideloadResp *sliverpb.Sideload, outFilePath *os.File, con *console.SliverClient) {
con.PrintInfof("%s output:\n%s", cmdName, sideloadResp.GetResult())
if outFilePath != nil {
outFilePath.Write([]byte(sideloadResp.GetResult()))
outFilePath.WriteString(sideloadResp.GetResult())
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
}
// PrintAssemblyOutput - Prints the output of an execute-assembly command
func PrintAssemblyOutput(cmdName string, execAsmResp *sliverpb.ExecuteAssembly, outFilePath *os.File, con *console.SliverConsoleClient) {
// PrintAssemblyOutput - Prints the output of an execute-assembly command.
func PrintAssemblyOutput(cmdName string, execAsmResp *sliverpb.ExecuteAssembly, outFilePath *os.File, con *console.SliverClient) {
con.PrintInfof("%s output:\n%s", cmdName, string(execAsmResp.GetOutput()))
if outFilePath != nil {
outFilePath.Write(execAsmResp.GetOutput())
+4 -5
View File
@@ -25,14 +25,13 @@ import (
"path/filepath"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/console"
"github.com/spf13/cobra"
)
// AliasesRemoveCmd - Locally load a alias into the Sliver shell.
func AliasesRemoveCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func AliasesRemoveCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
name := args[0]
// name := ctx.Args.String("name")
if name == "" {
@@ -54,8 +53,8 @@ func AliasesRemoveCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
// RemoveAliasByCommandName - Remove an alias by command name
func RemoveAliasByCommandName(commandName string, con *console.SliverConsoleClient) error {
// RemoveAliasByCommandName - Remove an alias by command name.
func RemoveAliasByCommandName(commandName string, con *console.SliverClient) error {
if commandName == "" {
return errors.New("command name is required")
}
+20 -16
View File
@@ -105,7 +105,7 @@ var (
)
// ArmoryCmd - The main armory command
func ArmoryCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func ArmoryCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
armoriesConfig := assets.GetArmoriesConfig()
con.PrintInfof("Fetching %d armory index(es) ... ", len(armoriesConfig))
clientConfig := parseArmoryHTTPConfig(cmd)
@@ -141,7 +141,7 @@ func ArmoryCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
if cacheEntry.Pkg.IsAlias {
aliases = append(aliases, cacheEntry.Alias)
} else {
exts = append(exts, cacheEntry.Extension)
exts = append(exts, cacheEntry.Extension) //todo: check this isn't a bug
}
}
return true
@@ -183,7 +183,7 @@ func packagesInCache() ([]*alias.AliasManifest, []*extensions.ExtensionManifest)
if cacheEntry.Pkg.IsAlias {
aliases = append(aliases, cacheEntry.Alias)
} else {
exts = append(exts, cacheEntry.Extension)
exts = append(exts, cacheEntry.Extension) //todo: check this isn't a bug
}
}
return true
@@ -217,9 +217,11 @@ func AliasExtensionOrBundleCompleter() carapace.Action {
aliasesComps := carapace.ActionValuesDescribed(results...).Tag("aliases").Invoke(ctx)
results = make([]string, 0)
for _, extensionPkg := range exts {
results = append(results, extensionPkg.CommandName)
results = append(results, extensionPkg.Help)
for _, extension := range exts {
for _, extensionPkg := range extension.ExtCommand {
results = append(results, extensionPkg.CommandName)
results = append(results, extensionPkg.Help)
}
}
extentionComps := carapace.ActionValuesDescribed(results...).Tag("extensions").Invoke(ctx)
results = make([]string, 0)
@@ -240,7 +242,7 @@ func AliasExtensionOrBundleCompleter() carapace.Action {
}
// PrintArmoryPackages - Prints the armory packages
func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.ExtensionManifest, con *console.SliverConsoleClient) {
func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.ExtensionManifest, con *console.SliverClient) {
width, _, err := term.GetSize(0)
if err != nil {
width = 1
@@ -291,14 +293,16 @@ func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.Exte
URL: aliasPkg.RepoURL,
})
}
for _, extension := range exts {
entries = append(entries, pkgInfo{
CommandName: extension.CommandName,
Version: extension.Version,
Type: "Extension",
Help: extension.Help,
URL: extension.RepoURL,
})
for _, extm := range exts {
for _, extension := range extm.ExtCommand {
entries = append(entries, pkgInfo{
CommandName: extension.CommandName,
Version: extension.Manifest.Version,
Type: "Extension",
Help: extension.Help,
URL: extension.Manifest.RepoURL,
})
}
}
sliverMenu := con.App.Menu("implant")
@@ -331,7 +335,7 @@ func PrintArmoryPackages(aliases []*alias.AliasManifest, exts []*extensions.Exte
}
// PrintArmoryBundles - Prints the armory bundles
func PrintArmoryBundles(bundles []*ArmoryBundle, con *console.SliverConsoleClient) {
func PrintArmoryBundles(bundles []*ArmoryBundle, con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.SetTitle(console.Bold + "Bundles" + console.Normal)
+73
View File
@@ -0,0 +1,73 @@
package armory
import (
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/command/completers"
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
)
// Commands returns the `armory` command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
armoryCmd := &cobra.Command{
Use: consts.ArmoryStr,
Short: "Automatically download and install extensions/aliases",
Long: help.GetHelpFor([]string{consts.ArmoryStr}),
Run: func(cmd *cobra.Command, args []string) {
ArmoryCmd(cmd, con, args)
},
GroupID: consts.GenericHelpGroup,
}
flags.Bind("connection", true, armoryCmd, func(f *pflag.FlagSet) {
f.BoolP("insecure", "I", false, "skip tls certificate validation")
f.StringP("proxy", "p", "", "specify a proxy url (e.g. http://localhost:8080)")
f.BoolP("ignore-cache", "c", false, "ignore metadata cache, force refresh")
f.StringP("timeout", "t", "15m", "download timeout")
})
flags.BindFlagCompletions(armoryCmd, func(comp *carapace.ActionMap) {
(*comp)["proxy"] = completers.LocalProxyCompleter()
})
armoryInstallCmd := &cobra.Command{
Use: consts.InstallStr,
Short: "Install an alias or extension",
Long: help.GetHelpFor([]string{consts.ArmoryStr, consts.InstallStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ArmoryInstallCmd(cmd, con, args)
},
}
armoryCmd.AddCommand(armoryInstallCmd)
flags.NewCompletions(armoryInstallCmd).PositionalCompletion(
AliasExtensionOrBundleCompleter().Usage("name of the extension or alias to install"),
)
armoryUpdateCmd := &cobra.Command{
Use: consts.UpdateStr,
Short: "Update installed an aliases and extensions",
Long: help.GetHelpFor([]string{consts.ArmoryStr, consts.UpdateStr}),
Run: func(cmd *cobra.Command, args []string) {
ArmoryUpdateCmd(cmd, con, args)
},
}
armoryCmd.AddCommand(armoryUpdateCmd)
armorySearchCmd := &cobra.Command{
Use: consts.SearchStr,
Short: "Search for aliases and extensions by name (regex)",
Long: help.GetHelpFor([]string{consts.ArmoryStr, consts.SearchStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ArmorySearchCmd(cmd, con, args)
},
}
armoryCmd.AddCommand(armorySearchCmd)
flags.NewCompletions(armorySearchCmd).PositionalCompletion(carapace.ActionValues().Usage("a name regular expression"))
return []*cobra.Command{armoryCmd}
}
+47 -55
View File
@@ -39,7 +39,7 @@ import (
var ErrPackageNotFound = errors.New("package not found")
// ArmoryInstallCmd - The armory install command
func ArmoryInstallCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func ArmoryInstallCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
name := args[0]
// name := ctx.Args.String("name")
if name == "" {
@@ -77,7 +77,7 @@ func ArmoryInstallCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
con.PrintErrorf("No package or bundle named '%s' was found", name)
}
func installBundle(bundle *ArmoryBundle, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) {
func installBundle(bundle *ArmoryBundle, clientConfig ArmoryHTTPConfig, con *console.SliverClient) {
for _, pkgName := range bundle.Packages {
err := installPackageByName(pkgName, clientConfig, con)
if err != nil {
@@ -86,7 +86,7 @@ func installBundle(bundle *ArmoryBundle, clientConfig ArmoryHTTPConfig, con *con
}
}
func installPackageByName(name string, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) error {
func installPackageByName(name string, clientConfig ArmoryHTTPConfig, con *console.SliverClient) error {
aliases, extensions := packagesInCache()
for _, alias := range aliases {
if alias.CommandName == name || name == "all" {
@@ -96,11 +96,13 @@ func installPackageByName(name string, clientConfig ArmoryHTTPConfig, con *conso
}
}
}
for _, ext := range extensions {
if ext.CommandName == name || name == "all" {
installExtension(ext, clientConfig, con)
if name != "all" {
return nil
for _, extm := range extensions {
for _, ext := range extm.ExtCommand {
if ext.CommandName == name || name == "all" {
installExtension(ext.Manifest, clientConfig, con)
if name != "all" {
return nil
}
}
}
}
@@ -112,7 +114,7 @@ func installPackageByName(name string, clientConfig ArmoryHTTPConfig, con *conso
return ErrPackageNotFound
}
func installAlias(alias *alias.AliasManifest, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) {
func installAlias(alias *alias.AliasManifest, clientConfig ArmoryHTTPConfig, con *console.SliverClient) {
err := installAliasPackageByName(alias.CommandName, clientConfig, con)
if err != nil {
con.PrintErrorf("Failed to install alias '%s': %s", alias.CommandName, err)
@@ -120,7 +122,7 @@ func installAlias(alias *alias.AliasManifest, clientConfig ArmoryHTTPConfig, con
}
}
func installAliasPackageByName(name string, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) error {
func installAliasPackageByName(name string, clientConfig ArmoryHTTPConfig, con *console.SliverClient) error {
var entry *pkgCacheEntry
pkgCache.Range(func(key, value interface{}) bool {
cacheEntry := value.(pkgCacheEntry)
@@ -186,30 +188,32 @@ func installAliasPackageByName(name string, clientConfig ArmoryHTTPConfig, con *
return nil
}
func installExtension(ext *extensions.ExtensionManifest, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) {
func installExtension(extm *extensions.ExtensionManifest, clientConfig ArmoryHTTPConfig, con *console.SliverClient) {
deps := make(map[string]struct{})
resolveExtensionPackageDependencies(ext.CommandName, deps, clientConfig, con)
sliverMenu := con.App.Menu(constants.ImplantMenu)
for dep := range deps {
if extensions.CmdExists(dep, sliverMenu.Command) {
continue // Dependency is already installed
for _, ext := range extm.ExtCommand {
resolveExtensionPackageDependencies(ext.CommandName, deps, clientConfig, con)
sliverMenu := con.App.Menu(constants.ImplantMenu).Root()
for dep := range deps {
if extensions.CmdExists(dep, sliverMenu) {
continue // Dependency is already installed
}
err := installExtensionPackageByName(dep, clientConfig, con)
if err != nil {
con.PrintErrorf("Failed to install extension dependency '%s': %s", dep, err)
return
}
}
err := installExtensionPackageByName(dep, clientConfig, con)
err := installExtensionPackageByName(ext.CommandName, clientConfig, con)
if err != nil {
con.PrintErrorf("Failed to install extension dependency '%s': %s", dep, err)
con.PrintErrorf("Failed to install extension '%s': %s", ext.CommandName, err)
return
}
}
err := installExtensionPackageByName(ext.CommandName, clientConfig, con)
if err != nil {
con.PrintErrorf("Failed to install extension '%s': %s", ext.CommandName, err)
return
}
}
const maxDepDepth = 10 // Arbitrary recursive limit for dependencies
func resolveExtensionPackageDependencies(name string, deps map[string]struct{}, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) {
func resolveExtensionPackageDependencies(name string, deps map[string]struct{}, clientConfig ArmoryHTTPConfig, con *console.SliverClient) {
var entry *pkgCacheEntry
pkgCache.Range(func(key, value interface{}) bool {
cacheEntry := value.(pkgCacheEntry)
@@ -222,27 +226,28 @@ func resolveExtensionPackageDependencies(name string, deps map[string]struct{},
if entry == nil {
return
}
for _, multiExt := range entry.Extension.ExtCommand {
if multiExt.DependsOn == "" {
continue // Avoid adding empty dependency
}
if entry.Extension.DependsOn == "" {
return // Avoid adding empty dependency
if multiExt.DependsOn == name {
continue // Avoid infinite loop of something that depends on itself
}
// We also need to look out for circular dependencies, so if we've already
// seen this dependency, we stop resolving
if _, ok := deps[multiExt.DependsOn]; ok {
continue // Already resolved
}
if maxDepDepth < len(deps) {
continue
}
deps[multiExt.DependsOn] = struct{}{}
resolveExtensionPackageDependencies(multiExt.DependsOn, deps, clientConfig, con)
}
if entry.Extension.DependsOn == name {
return // Avoid infinite loop of something that depends on itself
}
// We also need to look out for circular dependencies, so if we've already
// seen this dependency, we stop resolving
if _, ok := deps[entry.Extension.DependsOn]; ok {
return // Already resolved
}
if maxDepDepth < len(deps) {
return
}
deps[entry.Extension.DependsOn] = struct{}{}
resolveExtensionPackageDependencies(entry.Extension.DependsOn, deps, clientConfig, con)
}
func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) error {
func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, con *console.SliverClient) error {
var entry *pkgCacheEntry
pkgCache.Range(func(key, value interface{}) bool {
cacheEntry := value.(pkgCacheEntry)
@@ -297,20 +302,7 @@ func installExtensionPackageByName(name string, clientConfig ArmoryHTTPConfig, c
con.Printf(console.Clearln + "\r") // Clear download message
installPath := extensions.InstallFromFilePath(tmpFile.Name(), true, con)
if installPath == nil {
return errors.New("failed to install extension")
}
extCmd, err := extensions.LoadExtensionManifest(filepath.Join(*installPath, extensions.ManifestFileName))
if err != nil {
return err
}
extensions.InstallFromDir(tmpFile.Name(), con, true)
sliverMenu := con.App.Menu(constants.ImplantMenu)
//
// if extensions.CmdExists(extCmd.Name, sliverMenu.Command) {
// con.App.Commands().Remove(extCmd.Name)
// }
extensions.ExtensionRegisterCommand(extCmd, sliverMenu.Command, con)
return nil
}
+6 -4
View File
@@ -29,7 +29,7 @@ import (
)
// ArmorySearchCmd - Search for packages by name
func ArmorySearchCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func ArmorySearchCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
con.PrintInfof("Refreshing package cache ... ")
clientConfig := parseArmoryHTTPConfig(cmd)
refresh(clientConfig)
@@ -55,9 +55,11 @@ func ArmorySearchCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
matchedExts := []*extensions.ExtensionManifest{}
for _, ext := range exts {
if nameExpr.MatchString(ext.CommandName) {
matchedExts = append(matchedExts, ext)
for _, extm := range exts {
for _, ext := range extm.ExtCommand {
if nameExpr.MatchString(ext.CommandName) {
matchedExts = append(matchedExts, extm)
}
}
}
if len(matchedAliases) == 0 && len(matchedExts) == 0 {
+6 -5
View File
@@ -31,7 +31,7 @@ import (
)
// ArmoryUpdateCmd - Update all installed extensions/aliases
func ArmoryUpdateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func ArmoryUpdateCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
con.PrintInfof("Refreshing package cache ... ")
clientConfig := parseArmoryHTTPConfig(cmd)
refresh(clientConfig)
@@ -66,7 +66,7 @@ func ArmoryUpdateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
func checkForAliasUpdates(clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) []string {
func checkForAliasUpdates(clientConfig ArmoryHTTPConfig, con *console.SliverClient) []string {
cachedAliases, _ := packagesInCache()
results := []string{}
for _, aliasManifestPath := range assets.GetInstalledAliasManifests() {
@@ -89,7 +89,7 @@ func checkForAliasUpdates(clientConfig ArmoryHTTPConfig, con *console.SliverCons
return results
}
func checkForExtensionUpdates(clientConfig ArmoryHTTPConfig, con *console.SliverConsoleClient) []string {
func checkForExtensionUpdates(clientConfig ArmoryHTTPConfig, con *console.SliverClient) []string {
_, cachedExtensions := packagesInCache()
results := []string{}
for _, extManifestPath := range assets.GetInstalledExtensionManifests() {
@@ -104,10 +104,11 @@ func checkForExtensionUpdates(clientConfig ArmoryHTTPConfig, con *console.Sliver
for _, latestExt := range cachedExtensions {
// Right now we don't try to enforce any kind of versioning, it is assumed if the version from
// the armory differs at all from the local version, the extension is out of date.
if latestExt.CommandName == localManifest.CommandName && latestExt.Version != localManifest.Version {
results = append(results, localManifest.CommandName)
if latestExt.Name == localManifest.Name && latestExt.Version != localManifest.Version {
results = append(results, localManifest.Name)
}
}
}
return results
}
+3 -4
View File
@@ -21,14 +21,13 @@ package backdoor
import (
"fmt"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/spf13/cobra"
)
// BackdoorCmd - Command to inject implant code into an existing binary
func BackdoorCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// BackdoorCmd - Command to inject implant code into an existing binary.
func BackdoorCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
+38
View File
@@ -0,0 +1,38 @@
package backdoor
import (
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/generate"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
backdoorCmd := &cobra.Command{
Use: consts.BackdoorStr,
Short: "Infect a remote file with a sliver shellcode",
Long: help.GetHelpFor([]string{consts.BackdoorStr}),
Args: cobra.ExactArgs(1),
GroupID: consts.ExecutionHelpGroup,
Annotations: flags.RestrictTargets(consts.WindowsCmdsFilter),
Run: func(cmd *cobra.Command, args []string) {
BackdoorCmd(cmd, con, args)
},
}
flags.Bind("", false, backdoorCmd, func(f *pflag.FlagSet) {
f.StringP("profile", "p", "", "profile to use for service binary")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
flags.BindFlagCompletions(backdoorCmd, func(comp *carapace.ActionMap) {
(*comp)["profile"] = generate.ProfileNameCompleter(con)
})
carapace.Gen(backdoorCmd).PositionalCompletion(carapace.ActionValues().Usage("path to the remote file to backdoor"))
return []*cobra.Command{backdoorCmd}
}
+3 -3
View File
@@ -36,7 +36,7 @@ import (
)
// BeaconsCmd - Display/interact with beacons
func BeaconsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func BeaconsCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
killFlag, _ := cmd.Flags().GetString("kill")
killAll, _ := cmd.Flags().GetBool("kill-all")
@@ -94,7 +94,7 @@ func BeaconsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []str
}
// PrintBeacons - Display a list of beacons
func PrintBeacons(beacons []*clientpb.Beacon, filter string, filterRegex *regexp.Regexp, con *console.SliverConsoleClient) {
func PrintBeacons(beacons []*clientpb.Beacon, filter string, filterRegex *regexp.Regexp, con *console.SliverClient) {
if len(beacons) == 0 {
con.PrintInfof("No beacons 🙁\n")
return
@@ -103,7 +103,7 @@ func PrintBeacons(beacons []*clientpb.Beacon, filter string, filterRegex *regexp
con.Printf("%s\n", tw.Render())
}
func renderBeacons(beacons []*clientpb.Beacon, filter string, filterRegex *regexp.Regexp, con *console.SliverConsoleClient) table.Writer {
func renderBeacons(beacons []*clientpb.Beacon, filter string, filterRegex *regexp.Regexp, con *console.SliverClient) table.Writer {
width, _, err := term.GetSize(0)
if err != nil {
width = 999
+102
View File
@@ -0,0 +1,102 @@
package beacons
import (
"context"
"fmt"
"strings"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/commonpb"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
beaconsCmd := &cobra.Command{
Use: consts.BeaconsStr,
Short: "Manage beacons",
Long: help.GetHelpFor([]string{consts.BeaconsStr}),
GroupID: consts.SliverHelpGroup,
Run: func(cmd *cobra.Command, args []string) {
BeaconsCmd(cmd, con, args)
},
}
flags.Bind("beacons", true, beaconsCmd, func(f *pflag.FlagSet) {
f.IntP("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
flags.Bind("beacons", false, beaconsCmd, func(f *pflag.FlagSet) {
f.StringP("kill", "k", "", "kill the designated beacon")
f.BoolP("kill-all", "K", false, "kill all beacons")
f.BoolP("force", "F", false, "force killing the beacon")
f.StringP("filter", "f", "", "filter beacons by substring")
f.StringP("filter-re", "e", "", "filter beacons by regular expression")
})
flags.BindFlagCompletions(beaconsCmd, func(comp *carapace.ActionMap) {
(*comp)["kill"] = BeaconIDCompleter(con)
})
beaconsRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a beacon",
Long: help.GetHelpFor([]string{consts.BeaconsStr, consts.RmStr}),
Run: func(cmd *cobra.Command, args []string) {
BeaconsRmCmd(cmd, con, args)
},
}
carapace.Gen(beaconsRmCmd).PositionalCompletion(BeaconIDCompleter(con))
beaconsCmd.AddCommand(beaconsRmCmd)
beaconsWatchCmd := &cobra.Command{
Use: consts.WatchStr,
Short: "Watch your beacons",
Long: help.GetHelpFor([]string{consts.BeaconsStr, consts.WatchStr}),
Run: func(cmd *cobra.Command, args []string) {
BeaconsWatchCmd(cmd, con, args)
},
}
beaconsCmd.AddCommand(beaconsWatchCmd)
beaconsPruneCmd := &cobra.Command{
Use: consts.PruneStr,
Short: "Prune stale beacons automatically",
Long: help.GetHelpFor([]string{consts.BeaconsStr, consts.PruneStr}),
Run: func(cmd *cobra.Command, args []string) {
BeaconsPruneCmd(cmd, con, args)
},
}
flags.Bind("beacons", false, beaconsPruneCmd, func(f *pflag.FlagSet) {
f.StringP("duration", "d", "1h", "duration to prune beacons that have missed their last checkin")
})
beaconsCmd.AddCommand(beaconsPruneCmd)
return []*cobra.Command{beaconsCmd}
}
// BeaconIDCompleter completes beacon IDs
func BeaconIDCompleter(con *console.SliverClient) carapace.Action {
callback := func(_ carapace.Context) carapace.Action {
results := make([]string, 0)
beacons, err := con.Rpc.GetBeacons(context.Background(), &commonpb.Empty{})
if err == nil {
for _, b := range beacons.Beacons {
link := fmt.Sprintf("[%s <- %s]", b.ActiveC2, b.RemoteAddress)
id := fmt.Sprintf("%s (%d)", b.Name, b.PID)
userHost := fmt.Sprintf("%s@%s", b.Username, b.Hostname)
desc := strings.Join([]string{id, userHost, link}, " ")
results = append(results, b.ID[:8])
results = append(results, desc)
}
}
return carapace.ActionValuesDescribed(results...).Tag("beacons")
}
return carapace.ActionCallback(callback)
}
+3 -3
View File
@@ -43,7 +43,7 @@ var (
)
// SelectBeacon - Interactive menu for the user to select an session, optionally only display live sessions
func SelectBeacon(con *console.SliverConsoleClient) (*clientpb.Beacon, error) {
func SelectBeacon(con *console.SliverClient) (*clientpb.Beacon, error) {
grpcCtx, cancel := con.GrpcContext(nil)
defer cancel()
beacons, err := con.Rpc.GetBeacons(grpcCtx, &commonpb.Empty{})
@@ -102,7 +102,7 @@ func SelectBeacon(con *console.SliverConsoleClient) (*clientpb.Beacon, error) {
return nil, ErrNoSelection
}
func GetBeacon(con *console.SliverConsoleClient, beaconID string) (*clientpb.Beacon, error) {
func GetBeacon(con *console.SliverClient, beaconID string) (*clientpb.Beacon, error) {
grpcCtx, cancel := con.GrpcContext(nil)
defer cancel()
beacons, err := con.Rpc.GetBeacons(grpcCtx, &commonpb.Empty{})
@@ -120,7 +120,7 @@ func GetBeacon(con *console.SliverConsoleClient, beaconID string) (*clientpb.Bea
return nil, ErrBeaconNotFound
}
func GetBeacons(con *console.SliverConsoleClient) (*clientpb.Beacons, error) {
func GetBeacons(con *console.SliverClient) (*clientpb.Beacons, error) {
grpcCtx, cancel := con.GrpcContext(nil)
defer cancel()
beacons, err := con.Rpc.GetBeacons(grpcCtx, &commonpb.Empty{})
+1 -1
View File
@@ -30,7 +30,7 @@ import (
)
// BeaconsPruneCmd - Prune stale beacons automatically
func BeaconsPruneCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func BeaconsPruneCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
duration, _ := cmd.Flags().GetString("duration")
pruneDuration, err := time.ParseDuration(duration)
if err != nil {
+1 -1
View File
@@ -25,7 +25,7 @@ import (
)
// BeaconsRmCmd - Display/interact with beacons
func BeaconsRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func BeaconsRmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
beacon, err := SelectBeacon(con)
if err != nil {
con.PrintErrorf("%s\n", err)
+1 -1
View File
@@ -31,7 +31,7 @@ import (
)
// BeaconsWatchCmd - Watch your beacons in real-ish time
func BeaconsWatchCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func BeaconsWatchCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
done := waitForInput()
defer func() {
con.Printf(console.UpN+console.Clearln+"\r", 1)
+5 -6
View File
@@ -23,17 +23,16 @@ import (
"fmt"
"strings"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
"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"
)
// BuildersCmd - List external builders
func BuildersCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// BuildersCmd - List external builders.
func BuildersCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
builders, err := con.Rpc.Builders(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s", err)
@@ -46,7 +45,7 @@ func BuildersCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
}
}
func PrintBuilders(externalBuilders []*clientpb.Builder, con *console.SliverConsoleClient) {
func PrintBuilders(externalBuilders []*clientpb.Builder, con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
+28
View File
@@ -0,0 +1,28 @@
package builders
import (
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
buildersCmd := &cobra.Command{
Use: consts.BuildersStr,
Short: "List external builders",
Long: help.GetHelpFor([]string{consts.BuildersStr}),
Run: func(cmd *cobra.Command, args []string) {
BuildersCmd(cmd, con, args)
},
GroupID: consts.PayloadsHelpGroup,
}
flags.Bind("builders", false, buildersCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
return []*cobra.Command{buildersCmd}
}
+3 -3
View File
@@ -39,7 +39,7 @@ import (
)
// C2ProfileCmd list available http profiles
func C2ProfileCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func C2ProfileCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
profileName, _ := cmd.Flags().GetString("name")
if profileName == constants.DefaultC2Profile {
@@ -61,7 +61,7 @@ func C2ProfileCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []s
PrintC2Profiles(profile, con)
}
func ImportC2ProfileCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func ImportC2ProfileCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
protocols := []string{constants.HttpStr, constants.HttpsStr}
profileName, _ := cmd.Flags().GetString("name")
if profileName == "" {
@@ -248,7 +248,7 @@ func C2ConfigToProtobuf(profileName string, config *assets.HTTPC2Config) *client
}
// PrintImplantBuilds - Print the implant builds on the server
func PrintC2Profiles(profile *clientpb.HTTPC2Config, con *console.SliverConsoleClient) {
func PrintC2Profiles(profile *clientpb.HTTPC2Config, con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
+69 -10
View File
@@ -21,6 +21,7 @@ package command
import (
"strings"
client "github.com/bishopfox/sliver/client/console"
"github.com/reeflective/console"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
@@ -29,11 +30,11 @@ import (
const defaultTimeout = 60
// Flags is a convenience function to bind flags to a given command.
// Bind is a convenience function to bind flags to a given command.
// name - The name of the flag set (can be empty).
// cmd - The command to which the flags should be bound.
// flags - A function exposing the flag set through which flags are declared.
func Flags(name string, persistent bool, cmd *cobra.Command, flags func(f *pflag.FlagSet)) {
func Bind(name string, persistent bool, cmd *cobra.Command, flags func(f *pflag.FlagSet)) {
flagSet := pflag.NewFlagSet(name, pflag.ContinueOnError) // Create the flag set.
flags(flagSet) // Let the user bind any number of flags to it.
@@ -44,22 +45,21 @@ func Flags(name string, persistent bool, cmd *cobra.Command, flags func(f *pflag
}
}
// FlagComps is a convenience function for adding completions to a command's flags.
// BindFlagCompletions is a convenience function for adding completions to a command's flags.
// cmd - The command owning the flags to complete.
// bind - A function exposing a map["flag-name"]carapace.Action.
func FlagComps(cmd *cobra.Command, bind func(comp *carapace.ActionMap)) {
func BindFlagCompletions(cmd *cobra.Command, bind func(comp *carapace.ActionMap)) {
comps := make(carapace.ActionMap)
bind(&comps)
carapace.Gen(cmd).FlagCompletion(comps)
}
// hideCommand generates a cobra annotation map with a single
// console.CommandHiddenFilter key, which value is a comma-separated list
// of filters to use in order to expose/hide commands based on requirements.
// Ex: cmd.Annotations = hideCommand("windows") will hide the cmd
// if the target session/beacon is not a Windows host.
func hideCommand(filters ...string) map[string]string {
// RestrictTargets generates a cobra annotation map with a single console.CommandHiddenFilter key
// to a comma-separated list of filters to use in order to expose/hide commands based on requirements.
// Ex: cmd.Annotations = RestrictTargets("windows") will only show the command if the target is Windows.
// Ex: cmd.Annotations = RestrictTargets("windows", "beacon") show the command if target is a beacon on Windows.
func RestrictTargets(filters ...string) map[string]string {
if len(filters) == 0 {
return nil
}
@@ -76,3 +76,62 @@ func hideCommand(filters ...string) map[string]string {
console.CommandFilterKey: filts,
}
}
// makeBind returns a commandBinder helper function
// @menu - The command menu to which the commands should be bound (either server or implant menu).
func makeBind(cmd *cobra.Command, con *client.SliverClient) func(group string, cmds ...func(con *client.SliverClient) []*cobra.Command) {
return func(group string, cmds ...func(con *client.SliverClient) []*cobra.Command) {
found := false
// Ensure the given command group is available in the menu.
if group != "" {
for _, grp := range cmd.Groups() {
if grp.Title == group {
found = true
break
}
}
if !found {
cmd.AddGroup(&cobra.Group{
ID: group,
Title: group,
})
}
}
// Bind the command to the root
for _, command := range cmds {
cmd.AddCommand(command(con)...)
}
}
}
// commandBinder is a helper used to bind commands to a given menu, for a given "command help group".
//
// @group - Name of the group under which the command should be shown. Preferably use a string in the constants package.
// @ cmds - A list of functions returning a list of root commands to bind. See any package's `commands.go` file and function.
type commandBinder func(group string, cmds ...func(con *client.SliverClient) []*cobra.Command)
// [ Core ]
// [ Sessions ]
// [ Execution ]
// [ Filesystem ]
// [ Info ]
// [ Network (C2)]
// [ Network tools ]
// [ Payloads ]
// [ Privileges ]
// [ Processes ]
// [ Aliases ]
// [ Extensions ]
// Commands not to bind in CLI:
// - portforwarders
// - Socks (and wg-socks ?)
// - shell ?
// Take care of:
// - double bind help command
// - double bind session commands
// - don't bind readline command in CLI.
+29
View File
@@ -55,3 +55,32 @@ func ClientInterfacesCompleter() carapace.Action {
return carapace.ActionValues(results...).Tag("client interfaces").NoSpace(':')
})
}
// LocalProxyCompleter gives URL completion to all flags/arguments that accept a client proxy address.
func LocalProxyCompleter() carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
prefix := ""
hostPort := carapace.ActionMultiParts(":", func(c carapace.Context) carapace.Action {
switch len(c.Parts) {
case 0:
return ClientInterfacesCompleter()
case 1:
return carapace.ActionMessage("server port")
default:
return carapace.ActionValues()
}
})
return carapace.ActionMultiParts("://", func(c carapace.Context) carapace.Action {
switch len(c.Parts) {
case 0:
return carapace.ActionValues("http", "https").Tag("proxy protocols").Suffix("://")
case 1:
return hostPort
default:
return carapace.ActionValues()
}
}).Invoke(c).Prefix(prefix).ToA()
})
}
+143
View File
@@ -0,0 +1,143 @@
package crack
import (
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
crackCmd := &cobra.Command{
Use: consts.CrackStr,
Short: "Crack: GPU password cracking",
Long: help.GetHelpFor([]string{consts.CrackStr}),
GroupID: consts.GenericHelpGroup,
Run: func(cmd *cobra.Command, args []string) {
CrackCmd(cmd, con, args)
},
}
flags.Bind("", true, crackCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
crackStationsCmd := &cobra.Command{
Use: consts.StationsStr,
Short: "Manage crackstations",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.StationsStr}),
Run: func(cmd *cobra.Command, args []string) {
CrackStationsCmd(cmd, con, args)
},
}
crackCmd.AddCommand(crackStationsCmd)
wordlistsCmd := &cobra.Command{
Use: consts.WordlistsStr,
Short: "Manage wordlists",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.WordlistsStr}),
Run: func(cmd *cobra.Command, args []string) {
CrackWordlistsCmd(cmd, con, args)
},
}
crackCmd.AddCommand(wordlistsCmd)
wordlistsAddCmd := &cobra.Command{
Use: consts.AddStr,
Short: "Add a wordlist",
Run: func(cmd *cobra.Command, args []string) {
CrackWordlistsAddCmd(cmd, con, args)
},
}
flags.Bind("", false, wordlistsAddCmd, func(f *pflag.FlagSet) {
f.StringP("name", "n", "", "wordlist name (blank = filename)")
})
carapace.Gen(wordlistsAddCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to local wordlist file"))
wordlistsCmd.AddCommand(wordlistsAddCmd)
wordlistsRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a wordlist",
Run: func(cmd *cobra.Command, args []string) {
CrackWordlistsRmCmd(cmd, con, args)
},
}
wordlistsCmd.AddCommand(wordlistsRmCmd)
carapace.Gen(wordlistsRmCmd).PositionalCompletion(CrackWordlistCompleter(con).Usage("wordlist to remove"))
rulesCmd := &cobra.Command{
Use: consts.RulesStr,
Short: "Manage rule files",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.RulesStr}),
Run: func(cmd *cobra.Command, args []string) {
CrackRulesCmd(cmd, con, args)
},
}
crackCmd.AddCommand(rulesCmd)
rulesAddCmd := &cobra.Command{
Use: consts.AddStr,
Short: "Add a rules file",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.RulesStr, consts.AddStr}),
Run: func(cmd *cobra.Command, args []string) {
CrackRulesAddCmd(cmd, con, args)
},
}
flags.Bind("", false, rulesAddCmd, func(f *pflag.FlagSet) {
f.StringP("name", "n", "", "rules name (blank = filename)")
})
carapace.Gen(rulesAddCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to local rules file"))
rulesCmd.AddCommand(rulesAddCmd)
rulesRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove rules",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.RulesStr, consts.RmStr}),
Run: func(cmd *cobra.Command, args []string) {
CrackRulesRmCmd(cmd, con, args)
},
}
carapace.Gen(rulesRmCmd).PositionalCompletion(CrackRulesCompleter(con).Usage("rules to remove"))
rulesCmd.AddCommand(rulesRmCmd)
hcstat2Cmd := &cobra.Command{
Use: consts.Hcstat2Str,
Short: "Manage markov hcstat2 files",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.Hcstat2Str}),
Run: func(cmd *cobra.Command, args []string) {
CrackHcstat2Cmd(cmd, con, args)
},
}
crackCmd.AddCommand(hcstat2Cmd)
hcstat2AddCmd := &cobra.Command{
Use: consts.AddStr,
Short: "Add a hcstat2 file",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.Hcstat2Str, consts.AddStr}),
Run: func(cmd *cobra.Command, args []string) {
CrackHcstat2AddCmd(cmd, con, args)
},
}
flags.Bind("", false, hcstat2AddCmd, func(f *pflag.FlagSet) {
f.StringP("name", "n", "", "hcstat2 name (blank = filename)")
})
carapace.Gen(hcstat2AddCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to local hcstat2 file"))
hcstat2Cmd.AddCommand(hcstat2AddCmd)
hcstat2RmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove hcstat2 file",
Long: help.GetHelpFor([]string{consts.CrackStr, consts.Hcstat2Str, consts.RmStr}),
Run: func(cmd *cobra.Command, args []string) {
CrackHcstat2RmCmd(cmd, con, args)
},
}
carapace.Gen(hcstat2RmCmd).PositionalCompletion(CrackHcstat2Completer(con).Usage("hcstat2 to remove"))
hcstat2Cmd.AddCommand(hcstat2RmCmd)
return []*cobra.Command{crackCmd}
}
+24 -25
View File
@@ -25,18 +25,17 @@ import (
"io"
"os"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/klauspost/compress/zstd"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/util"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/klauspost/compress/zstd"
"github.com/spf13/cobra"
)
// CrackWordlistsCmd - Manage GPU cracking stations
func CrackWordlistsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackWordlistsCmd - Manage GPU cracking stations.
func CrackWordlistsCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
wordlists, err := con.Rpc.CrackFilesList(context.Background(), &clientpb.CrackFile{Type: clientpb.CrackFileType_WORDLIST})
if err != nil {
con.PrintErrorf("%s\n", err)
@@ -55,8 +54,8 @@ func CrackWordlistsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, arg
}
}
// CrackRulesCmd - Manage GPU cracking stations
func CrackRulesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackRulesCmd - Manage GPU cracking stations.
func CrackRulesCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
rules, err := con.Rpc.CrackFilesList(context.Background(), &clientpb.CrackFile{Type: clientpb.CrackFileType_RULES})
if err != nil {
con.PrintErrorf("%s\n", err)
@@ -75,8 +74,8 @@ func CrackRulesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []
}
}
// CrackHcstat2Cmd - Manage GPU cracking stations
func CrackHcstat2Cmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackHcstat2Cmd - Manage GPU cracking stations.
func CrackHcstat2Cmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
hcstat2, err := con.Rpc.CrackFilesList(context.Background(), &clientpb.CrackFile{Type: clientpb.CrackFileType_MARKOV_HCSTAT2})
if err != nil {
con.PrintErrorf("%s\n", err)
@@ -95,7 +94,7 @@ func CrackHcstat2Cmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
func PrintCrackFiles(crackFiles *clientpb.CrackFiles, con *console.SliverConsoleClient) {
func PrintCrackFiles(crackFiles *clientpb.CrackFiles, con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{"Name", "Size"})
@@ -105,7 +104,7 @@ func PrintCrackFiles(crackFiles *clientpb.CrackFiles, con *console.SliverConsole
con.Printf("%s\n", tw.Render())
}
func PrintCrackFilesByType(crackFiles *clientpb.CrackFiles, con *console.SliverConsoleClient) {
func PrintCrackFilesByType(crackFiles *clientpb.CrackFiles, con *console.SliverClient) {
wordlistTable := table.NewWriter()
wordlistTable.SetTitle(console.Bold + "Wordlists" + console.Normal)
wordlistTable.SetStyle(settings.GetTableStyle(con))
@@ -162,8 +161,8 @@ func PrintCrackFilesByType(crackFiles *clientpb.CrackFiles, con *console.SliverC
)
}
// CrackWordlistsAddCmd - Manage GPU cracking stations
func CrackWordlistsAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackWordlistsAddCmd - Manage GPU cracking stations.
func CrackWordlistsAddCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
name, _ := cmd.Flags().GetString("name")
var localPath string
@@ -206,8 +205,8 @@ func CrackWordlistsAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient,
addCrackFile(wordlist, crackFile, con)
}
// CrackRulesAddCmd - add a rules file
func CrackRulesAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackRulesAddCmd - add a rules file.
func CrackRulesAddCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
name, _ := cmd.Flags().GetString("name")
var localPath string
@@ -250,8 +249,8 @@ func CrackRulesAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
addCrackFile(rules, crackFile, con)
}
// CrackHcstat2AddCmd - add a hcstat2 file
func CrackHcstat2AddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackHcstat2AddCmd - add a hcstat2 file.
func CrackHcstat2AddCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
name, _ := cmd.Flags().GetString("name")
var localPath string
@@ -294,7 +293,7 @@ func CrackHcstat2AddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, ar
addCrackFile(hcstat2, crackFile, con)
}
func addCrackFile(localFile *os.File, crackFile *clientpb.CrackFile, con *console.SliverConsoleClient) {
func addCrackFile(localFile *os.File, crackFile *clientpb.CrackFile, con *console.SliverClient) {
digest := sha256.New()
wordlistReader := io.TeeReader(localFile, digest)
@@ -402,8 +401,8 @@ func readChunkAt(tmpFile *os.File, offset int64, chunkSize int64) ([]byte, error
return chunkBuf[:n], nil
}
// CrackWordlistsRmCmd - Manage GPU cracking stations
func CrackWordlistsRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackWordlistsRmCmd - Manage GPU cracking stations.
func CrackWordlistsRmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
var wordlistName string
if len(args) > 0 {
wordlistName = args[0]
@@ -436,8 +435,8 @@ func CrackWordlistsRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, a
}
}
// CrackRulesRmCmd - Manage GPU cracking stations
func CrackRulesRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackRulesRmCmd - Manage GPU cracking stations.
func CrackRulesRmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
var rulesName string
if len(args) > 0 {
rulesName = args[0]
@@ -470,8 +469,8 @@ func CrackRulesRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
// CrackHcstat2RmCmd - remove a hcstat2 file
func CrackHcstat2RmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CrackHcstat2RmCmd - remove a hcstat2 file.
func CrackHcstat2RmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
var hcstat2Name string
if len(args) > 0 {
hcstat2Name = args[0]
+7 -7
View File
@@ -33,7 +33,7 @@ import (
)
// CrackCmd - GPU password cracking interface
func CrackCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func CrackCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
if !AreCrackersOnline(con) {
PrintNoCrackstations(con)
} else {
@@ -58,7 +58,7 @@ func CrackCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []strin
}
// CrackStationsCmd - Manage GPU cracking stations
func CrackStationsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func CrackStationsCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
crackers, err := con.Rpc.Crackstations(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s\n", err)
@@ -71,11 +71,11 @@ func CrackStationsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
func PrintNoCrackstations(con *console.SliverConsoleClient) {
func PrintNoCrackstations(con *console.SliverClient) {
con.PrintInfof("No crackstations connected to server\n")
}
func AreCrackersOnline(con *console.SliverConsoleClient) bool {
func AreCrackersOnline(con *console.SliverClient) bool {
crackers, err := con.Rpc.Crackstations(context.Background(), &commonpb.Empty{})
if err != nil {
return false
@@ -83,7 +83,7 @@ func AreCrackersOnline(con *console.SliverConsoleClient) bool {
return len(crackers.Crackstations) > 0
}
func PrintCrackers(crackers []*clientpb.Crackstation, con *console.SliverConsoleClient) {
func PrintCrackers(crackers []*clientpb.Crackstation, con *console.SliverClient) {
sort.Slice(crackers, func(i, j int) bool {
return crackers[i].Name < crackers[j].Name
})
@@ -96,7 +96,7 @@ func PrintCrackers(crackers []*clientpb.Crackstation, con *console.SliverConsole
}
}
func printCracker(cracker *clientpb.Crackstation, index int, con *console.SliverConsoleClient) {
func printCracker(cracker *clientpb.Crackstation, index int, con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.SetTitle(console.Bold + console.Orange + fmt.Sprintf(">>> Crackstation %02d - %s (%s)", index+1, cracker.Name, cracker.OperatorName) + console.Normal + "\n")
@@ -135,7 +135,7 @@ func printCracker(cracker *clientpb.Crackstation, index int, con *console.Sliver
printBenchmarks(cracker, con)
}
func printBenchmarks(cracker *clientpb.Crackstation, con *console.SliverConsoleClient) {
func printBenchmarks(cracker *clientpb.Crackstation, con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.SetTitle(console.Bold + "Benchmarks" + console.Normal)
+3 -3
View File
@@ -10,7 +10,7 @@ import (
"github.com/rsteube/carapace"
)
func CrackHcstat2Completer(con *console.SliverConsoleClient) carapace.Action {
func CrackHcstat2Completer(con *console.SliverClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
hcstat2, err := con.Rpc.CrackFilesList(context.Background(), &clientpb.CrackFile{Type: clientpb.CrackFileType_MARKOV_HCSTAT2})
if err != nil {
@@ -33,7 +33,7 @@ func CrackHcstat2Completer(con *console.SliverConsoleClient) carapace.Action {
})
}
func CrackWordlistCompleter(con *console.SliverConsoleClient) carapace.Action {
func CrackWordlistCompleter(con *console.SliverClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
hcstat2, err := con.Rpc.CrackFilesList(context.Background(), &clientpb.CrackFile{Type: clientpb.CrackFileType_MARKOV_HCSTAT2})
if err != nil {
@@ -57,7 +57,7 @@ func CrackWordlistCompleter(con *console.SliverConsoleClient) carapace.Action {
})
}
func CrackRulesCompleter(con *console.SliverConsoleClient) carapace.Action {
func CrackRulesCompleter(con *console.SliverClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
hcstat2, err := con.Rpc.CrackFilesList(context.Background(), &clientpb.CrackFile{Type: clientpb.CrackFileType_MARKOV_HCSTAT2})
if err != nil {
+4 -4
View File
@@ -37,8 +37,8 @@ const (
CSVFormat = "csv" // username,hash\n
)
// CredsCmd - Add new credentials
func CredsAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CredsCmd - Add new credentials.
func CredsAddCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
collection, _ := cmd.Flags().GetString("collection")
username, _ := cmd.Flags().GetString("username")
plaintext, _ := cmd.Flags().GetString("plaintext")
@@ -76,8 +76,8 @@ func CredsAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
PrintCreds(creds.Credentials, con)
}
// CredsCmd - Add new credentials
func CredsAddHashFileCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CredsCmd - Add new credentials.
func CredsAddHashFileCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
collection, _ := cmd.Flags().GetString("collection")
filePath := args[0]
fileFormat, _ := cmd.Flags().GetString("file-format")
+82
View File
@@ -0,0 +1,82 @@
package creds
import (
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
credsCmd := &cobra.Command{
Use: consts.CredsStr,
Short: "Manage the database of credentials",
Long: help.GetHelpFor([]string{consts.CredsStr}),
GroupID: consts.GenericHelpGroup,
Run: func(cmd *cobra.Command, args []string) {
CredsCmd(cmd, con, args)
},
}
flags.Bind("creds", true, credsCmd, func(f *pflag.FlagSet) {
f.IntP("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
credsAddCmd := &cobra.Command{
Use: consts.AddStr,
Short: "Add a credential to the database",
Long: help.GetHelpFor([]string{consts.CredsStr, consts.AddStr}),
Run: func(cmd *cobra.Command, args []string) {
CredsAddCmd(cmd, con, args)
},
}
flags.Bind("", false, credsAddCmd, func(f *pflag.FlagSet) {
f.StringP("collection", "c", "", "name of collection")
f.StringP("username", "u", "", "username for the credential")
f.StringP("plaintext", "p", "", "plaintext for the credential")
f.StringP("hash", "P", "", "hash of the credential")
f.StringP("hash-type", "H", "", "hash type of the credential")
})
flags.BindFlagCompletions(credsAddCmd, func(comp *carapace.ActionMap) {
(*comp)["hash-type"] = CredsHashTypeCompleter(con)
})
credsCmd.AddCommand(credsAddCmd)
credsAddFileCmd := &cobra.Command{
Use: consts.FileStr,
Short: "Add a credential to the database",
Long: help.GetHelpFor([]string{consts.CredsStr, consts.AddStr, consts.FileStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
CredsAddHashFileCmd(cmd, con, args)
},
}
flags.Bind("", false, credsAddFileCmd, func(f *pflag.FlagSet) {
f.StringP("collection", "c", "", "name of collection")
f.StringP("file-format", "F", HashNewlineFormat, "file format of the credential file")
f.StringP("hash-type", "H", "", "hash type of the credential")
})
flags.BindFlagCompletions(credsAddFileCmd, func(comp *carapace.ActionMap) {
(*comp)["collection"] = CredsCollectionCompleter(con)
(*comp)["file-format"] = CredsHashFileFormatCompleter(con)
(*comp)["hash-type"] = CredsHashTypeCompleter(con)
})
carapace.Gen(credsAddFileCmd).PositionalCompletion(carapace.ActionFiles().Tag("credential file"))
credsAddCmd.AddCommand(credsAddFileCmd)
credsRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a credential to the database",
Long: help.GetHelpFor([]string{consts.CredsStr, consts.RmStr}),
Run: func(cmd *cobra.Command, args []string) {
CredsRmCmd(cmd, con, args)
},
}
carapace.Gen(credsRmCmd).PositionalCompletion(CredsCredentialIDCompleter(con).Usage("id of credential to remove (leave empty to select)"))
credsCmd.AddCommand(credsRmCmd)
return []*cobra.Command{credsCmd}
}
+13 -14
View File
@@ -23,18 +23,17 @@ import (
"fmt"
"strings"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"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/rsteube/carapace"
"github.com/spf13/cobra"
)
// CredsCmd - Manage credentials
func CredsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CredsCmd - Manage credentials.
func CredsCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
creds, err := con.Rpc.Creds(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("%s\n", err)
@@ -47,7 +46,7 @@ func CredsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []strin
PrintCreds(creds.Credentials, con)
}
func PrintCreds(creds []*clientpb.Credential, con *console.SliverConsoleClient) {
func PrintCreds(creds []*clientpb.Credential, con *console.SliverClient) {
collections := make(map[string][]*clientpb.Credential)
for _, cred := range creds {
collections[cred.Collection] = append(collections[cred.Collection], cred)
@@ -58,7 +57,7 @@ func PrintCreds(creds []*clientpb.Credential, con *console.SliverConsoleClient)
}
}
func printCollection(collection string, creds []*clientpb.Credential, con *console.SliverConsoleClient) {
func printCollection(collection string, creds []*clientpb.Credential, con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
if collection != "" {
@@ -88,7 +87,7 @@ func printCollection(collection string, creds []*clientpb.Credential, con *conso
}
// CredsHashTypeCompleter completes hash types.
func CredsHashTypeCompleter(con *console.SliverConsoleClient) carapace.Action {
func CredsHashTypeCompleter(con *console.SliverClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
results := make([]string, 0)
@@ -101,8 +100,8 @@ func CredsHashTypeCompleter(con *console.SliverConsoleClient) carapace.Action {
})
}
// CredsHashFileFormatCompleter completes file formats for hash-files
func CredsHashFileFormatCompleter(con *console.SliverConsoleClient) carapace.Action {
// CredsHashFileFormatCompleter completes file formats for hash-files.
func CredsHashFileFormatCompleter(con *console.SliverClient) carapace.Action {
return carapace.ActionValuesDescribed(
UserColonHashNewlineFormat, "One hash per line.",
HashNewlineFormat, "A file containing lines of 'username:hash' pairs.",
@@ -110,8 +109,8 @@ func CredsHashFileFormatCompleter(con *console.SliverConsoleClient) carapace.Act
).Tag("hash file formats")
}
// CredsCollectionCompleter completes existing creds collection names
func CredsCollectionCompleter(con *console.SliverConsoleClient) carapace.Action {
// CredsCollectionCompleter completes existing creds collection names.
func CredsCollectionCompleter(con *console.SliverClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
results := make([]string, 0)
@@ -134,7 +133,7 @@ func CredsCollectionCompleter(con *console.SliverConsoleClient) carapace.Action
}
// CredsCredentialIDCompleter completes credential IDs.
func CredsCredentialIDCompleter(con *console.SliverConsoleClient) carapace.Action {
func CredsCredentialIDCompleter(con *console.SliverClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
results := make([]string, 0)
+2 -2
View File
@@ -27,8 +27,8 @@ import (
"github.com/spf13/cobra"
)
// CredsCmd - Add new credentials
func CredsRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CredsCmd - Add new credentials.
func CredsRmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
var id string
if len(args) > 0 {
id = args[0]
+2 -3
View File
@@ -9,14 +9,13 @@ import (
"text/tabwriter"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
)
// SelectCredential - Interactive menu for the user to select a credentials from the database
func SelectCredential(plaintext bool, hashType clientpb.HashType, con *console.SliverConsoleClient) (*clientpb.Credential, error) {
// SelectCredential - Interactive menu for the user to select a credentials from the database.
func SelectCredential(plaintext bool, hashType clientpb.HashType, con *console.SliverClient) (*clientpb.Credential, error) {
var creds *clientpb.Credentials
var err error
if hashType == clientpb.HashType_INVALID {
+149
View File
@@ -0,0 +1,149 @@
package cursed
import (
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
cursedCmd := &cobra.Command{
Use: consts.Cursed,
Short: "Chrome/electron post-exploitation tool kit (∩`-´)⊃━☆゚.*・。゚",
Long: help.GetHelpFor([]string{consts.Cursed}),
GroupID: consts.ExecutionHelpGroup,
Annotations: flags.RestrictTargets(consts.SessionCmdsFilter),
Run: func(cmd *cobra.Command, args []string) {
CursedCmd(cmd, con, args)
},
}
flags.Bind("", true, cursedCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
cursedRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a Curse from a process",
Long: help.GetHelpFor([]string{consts.Cursed, consts.CursedConsole}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
CursedRmCmd(cmd, con, args)
},
}
cursedCmd.AddCommand(cursedRmCmd)
flags.Bind("", false, cursedRmCmd, func(f *pflag.FlagSet) {
f.BoolP("kill", "k", false, "kill the process after removing the curse")
})
carapace.Gen(cursedRmCmd).PositionalCompletion(carapace.ActionValues().Usage("bind port of the Cursed process to stop"))
cursedConsoleCmd := &cobra.Command{
Use: consts.CursedConsole,
Short: "Start a JavaScript console connected to a debug target",
Long: help.GetHelpFor([]string{consts.Cursed, consts.CursedConsole}),
Run: func(cmd *cobra.Command, args []string) {
CursedConsoleCmd(cmd, con, args)
},
}
cursedCmd.AddCommand(cursedConsoleCmd)
flags.Bind("", false, cursedConsoleCmd, func(f *pflag.FlagSet) {
f.IntP("remote-debugging-port", "r", 0, "remote debugging tcp port (0 = random)`")
})
cursedChromeCmd := &cobra.Command{
Use: consts.CursedChrome,
Short: "Automatically inject a Cursed Chrome payload into a remote Chrome extension",
Long: help.GetHelpFor([]string{consts.Cursed, consts.CursedChrome}),
Run: func(cmd *cobra.Command, args []string) {
CursedChromeCmd(cmd, con, args)
},
}
cursedCmd.AddCommand(cursedChromeCmd)
flags.Bind("", false, cursedChromeCmd, func(f *pflag.FlagSet) {
f.IntP("remote-debugging-port", "r", 0, "remote debugging tcp port (0 = random)")
f.BoolP("restore", "R", true, "restore the user's session after process termination")
f.StringP("exe", "e", "", "chrome/chromium browser executable path (blank string = auto)")
f.StringP("user-data", "u", "", "user data directory (blank string = auto)")
f.StringP("payload", "p", "", "cursed chrome payload file path (.js)")
f.BoolP("keep-alive", "k", false, "keeps browser alive after last browser window closes")
f.BoolP("headless", "H", false, "start browser process in headless mode")
})
flags.BindFlagCompletions(cursedChromeCmd, func(comp *carapace.ActionMap) {
(*comp)["payload"] = carapace.ActionFiles("js").Tag("javascript files")
})
cursedChromeCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
carapace.Gen(cursedChromeCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("additional Chrome CLI arguments"))
cursedEdgeCmd := &cobra.Command{
Use: consts.CursedEdge,
Short: "Automatically inject a Cursed Chrome payload into a remote Edge extension",
Long: help.GetHelpFor([]string{consts.Cursed, consts.CursedEdge}),
Run: func(cmd *cobra.Command, args []string) {
CursedEdgeCmd(cmd, con, args)
},
}
cursedCmd.AddCommand(cursedEdgeCmd)
flags.Bind("", false, cursedEdgeCmd, func(f *pflag.FlagSet) {
f.IntP("remote-debugging-port", "r", 0, "remote debugging tcp port (0 = random)")
f.BoolP("restore", "R", true, "restore the user's session after process termination")
f.StringP("exe", "e", "", "edge browser executable path (blank string = auto)")
f.StringP("user-data", "u", "", "user data directory (blank string = auto)")
f.StringP("payload", "p", "", "cursed chrome payload file path (.js)")
f.BoolP("keep-alive", "k", false, "keeps browser alive after last browser window closes")
f.BoolP("headless", "H", false, "start browser process in headless mode")
})
flags.BindFlagCompletions(cursedEdgeCmd, func(comp *carapace.ActionMap) {
(*comp)["payload"] = carapace.ActionFiles("js").Tag("javascript files")
})
cursedEdgeCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
carapace.Gen(cursedEdgeCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("additional Edge CLI arguments"))
cursedElectronCmd := &cobra.Command{
Use: consts.CursedElectron,
Short: "Curse a remote Electron application",
Long: help.GetHelpFor([]string{consts.Cursed, consts.CursedElectron}),
Run: func(cmd *cobra.Command, args []string) {
CursedElectronCmd(cmd, con, args)
},
}
cursedCmd.AddCommand(cursedElectronCmd)
flags.Bind("", false, cursedElectronCmd, func(f *pflag.FlagSet) {
f.StringP("exe", "e", "", "remote electron executable absolute path")
f.IntP("remote-debugging-port", "r", 0, "remote debugging tcp port (0 = random)")
})
cursedElectronCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
carapace.Gen(cursedElectronCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("additional Electron CLI arguments"))
CursedCookiesCmd := &cobra.Command{
Use: consts.CursedCookies,
Short: "Dump all cookies from cursed process",
Long: help.GetHelpFor([]string{consts.Cursed, consts.CursedCookies}),
Run: func(cmd *cobra.Command, args []string) {
CursedCookiesCmd(cmd, con, args)
},
}
cursedCmd.AddCommand(CursedCookiesCmd)
flags.Bind("", false, CursedCookiesCmd, func(f *pflag.FlagSet) {
f.StringP("save", "s", "", "save to file")
})
cursedScreenshotCmd := &cobra.Command{
Use: consts.ScreenshotStr,
Short: "Take a screenshot of a cursed process debug target",
Long: help.GetHelpFor([]string{consts.Cursed, consts.ScreenshotStr}),
Run: func(cmd *cobra.Command, args []string) {
CursedScreenshotCmd(cmd, con, args)
},
}
cursedCmd.AddCommand(cursedScreenshotCmd)
flags.Bind("", false, cursedScreenshotCmd, func(f *pflag.FlagSet) {
f.Int64P("quality", "q", 100, "screenshot quality (1 - 100)")
f.StringP("save", "s", "", "save to file")
})
return []*cobra.Command{cursedCmd}
}
+8 -9
View File
@@ -29,8 +29,6 @@ import (
"time"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
@@ -38,6 +36,7 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
)
var (
@@ -51,8 +50,8 @@ var (
cursedChromePermissionsAlt = []string{overlord.AllHTTP, overlord.AllHTTPS, overlord.WebRequest, overlord.WebRequestBlocking}
)
// CursedChromeCmd - Execute a .NET assembly in-memory
func CursedChromeCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CursedChromeCmd - Execute a .NET assembly in-memory.
func CursedChromeCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
@@ -112,7 +111,7 @@ func CursedChromeCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
func avadaKedavraChrome(session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient, cargs []string) *core.CursedProcess {
func avadaKedavraChrome(session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient, cargs []string) *core.CursedProcess {
chromeProcess, err := getChromeProcess(session, cmd, con)
if err != nil {
con.PrintErrorf("%s\n", err)
@@ -154,7 +153,7 @@ func avadaKedavraChrome(session *clientpb.Session, cmd *cobra.Command, con *cons
return curse
}
func startCursedChromeProcess(isEdge bool, session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient, cargs []string) (*core.CursedProcess, error) {
func startCursedChromeProcess(isEdge bool, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient, cargs []string) (*core.CursedProcess, error) {
name := "Chrome"
if isEdge {
name = "Edge"
@@ -254,7 +253,7 @@ func startCursedChromeProcess(isEdge bool, session *clientpb.Session, cmd *cobra
return curse, nil
}
func findChromeUserDataDir(isEdge bool, session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient) (string, error) {
func findChromeUserDataDir(isEdge bool, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (string, error) {
userDataFlag, _ := cmd.Flags().GetString("user-data")
if userDataFlag != "" {
return userDataFlag, nil
@@ -307,7 +306,7 @@ func findChromeUserDataDir(isEdge bool, session *clientpb.Session, cmd *cobra.Co
}
}
func findChromeExecutablePath(isEdge bool, session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient) (string, error) {
func findChromeExecutablePath(isEdge bool, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (string, error) {
exeFlag, _ := cmd.Flags().GetString("exe")
if exeFlag != "" {
return exeFlag, nil
@@ -417,7 +416,7 @@ func isChromeProcess(executable string) bool {
return false
}
func getChromeProcess(session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient) (*commonpb.Process, error) {
func getChromeProcess(session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (*commonpb.Process, error) {
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(cmd),
})
+5 -6
View File
@@ -27,15 +27,14 @@ import (
"text/tabwriter"
"github.com/AlecAivazis/survey/v2"
"github.com/reeflective/readline"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
"github.com/reeflective/readline"
"github.com/spf13/cobra"
)
func CursedConsoleCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func CursedConsoleCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
curse := selectCursedProcess(con)
if curse == nil {
return
@@ -56,7 +55,7 @@ func CursedConsoleCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
startCursedConsole(curse, true, target, con)
}
func selectDebugTarget(targets []overlord.ChromeDebugTarget, con *console.SliverConsoleClient) *overlord.ChromeDebugTarget {
func selectDebugTarget(targets []overlord.ChromeDebugTarget, con *console.SliverClient) *overlord.ChromeDebugTarget {
if len(targets) < 1 {
con.PrintErrorf("No debug targets\n")
return nil
@@ -94,7 +93,7 @@ var helperHooks = []string{
"console.log = (...a) => {return a;}", // console.log
}
func startCursedConsole(curse *core.CursedProcess, helpers bool, target *overlord.ChromeDebugTarget, con *console.SliverConsoleClient) {
func startCursedConsole(curse *core.CursedProcess, helpers bool, target *overlord.ChromeDebugTarget, con *console.SliverClient) {
tmpFile, _ := os.CreateTemp("", "cursed")
shell := readline.NewShell()
shell.History.AddFromFile("cursed history", tmpFile.Name())
+2 -3
View File
@@ -24,13 +24,12 @@ import (
"strings"
"time"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/overlord"
"github.com/spf13/cobra"
)
func CursedCookiesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func CursedCookiesCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
curse := selectCursedProcess(con)
if curse == nil {
return
+5 -7
View File
@@ -21,22 +21,20 @@ package cursed
import (
"context"
"os"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
)
// CursedChromeCmd - Execute a .NET assembly in-memory
func CursedEdgeCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CursedChromeCmd - Execute a .NET assembly in-memory.
func CursedEdgeCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
@@ -96,7 +94,7 @@ func CursedEdgeCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []
}
}
func avadaKedavraEdge(session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient, cargs []string) *core.CursedProcess {
func avadaKedavraEdge(session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient, cargs []string) *core.CursedProcess {
edgeProcess, err := getEdgeProcess(session, cmd, con)
if err != nil {
con.PrintErrorf("%s\n", err)
@@ -153,7 +151,7 @@ func isEdgeProcess(executable string) bool {
return false
}
func getEdgeProcess(session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient) (*commonpb.Process, error) {
func getEdgeProcess(session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (*commonpb.Process, error) {
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(cmd),
})
+6 -7
View File
@@ -27,8 +27,6 @@ import (
"time"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/client/overlord"
@@ -36,9 +34,10 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
)
func CursedElectronCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func CursedElectronCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
@@ -68,7 +67,7 @@ func CursedElectronCmd(cmd *cobra.Command, con *console.SliverConsoleClient, arg
con.PrintInfof("Found %d debug targets, good hunting!\n", len(targets))
}
func avadaKedavraElectron(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient, cargs []string) *core.CursedProcess {
func avadaKedavraElectron(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient, cargs []string) *core.CursedProcess {
exists, err := checkElectronPath(electronExe, session, cmd, con)
if err != nil {
con.PrintErrorf("%s", err)
@@ -119,7 +118,7 @@ func avadaKedavraElectron(electronExe string, session *clientpb.Session, cmd *co
return curse
}
func checkElectronPath(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient) (bool, error) {
func checkElectronPath(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (bool, error) {
ls, err := con.Rpc.Ls(context.Background(), &sliverpb.LsReq{
Request: con.ActiveTarget.Request(cmd),
Path: electronExe,
@@ -130,7 +129,7 @@ func checkElectronPath(electronExe string, session *clientpb.Session, cmd *cobra
return ls.GetExists(), nil
}
func checkElectronProcess(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient) (*commonpb.Process, error) {
func checkElectronProcess(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient) (*commonpb.Process, error) {
ps, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(cmd),
})
@@ -148,7 +147,7 @@ func checkElectronProcess(electronExe string, session *clientpb.Session, cmd *co
return nil, nil
}
func startCursedElectronProcess(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverConsoleClient, cargs []string) (*core.CursedProcess, error) {
func startCursedElectronProcess(electronExe string, session *clientpb.Session, cmd *cobra.Command, con *console.SliverClient, cargs []string) (*core.CursedProcess, error) {
con.PrintInfof("Starting '%s' ... ", path.Base(electronExe))
debugPort := getRemoteDebuggerPort(cmd)
args := []string{
+2 -3
View File
@@ -23,14 +23,13 @@ import (
"strconv"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
)
func CursedRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func CursedRmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
+2 -3
View File
@@ -23,13 +23,12 @@ import (
"os"
"time"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/overlord"
"github.com/spf13/cobra"
)
func CursedScreenshotCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func CursedScreenshotCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
curse := selectCursedProcess(con)
if curse == nil {
return
+6 -7
View File
@@ -27,16 +27,15 @@ import (
"text/tabwriter"
"github.com/AlecAivazis/survey/v2"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
)
// CursedChromeCmd - Execute a .NET assembly in-memory
func CursedCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CursedChromeCmd - Execute a .NET assembly in-memory.
func CursedCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
// Collect existing curses from core
cursedProcesses := [][]string{}
core.CursedProcesses.Range(func(key, value interface{}) bool {
@@ -71,8 +70,8 @@ func CursedCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
}
}
// selectCursedProcess - Interactively select a cursed process from a list
func selectCursedProcess(con *console.SliverConsoleClient) *core.CursedProcess {
// selectCursedProcess - Interactively select a cursed process from a list.
func selectCursedProcess(con *console.SliverClient) *core.CursedProcess {
cursedProcesses := []*core.CursedProcess{}
core.CursedProcesses.Range(func(key, value interface{}) bool {
cursedProcesses = append(cursedProcesses, value.(*core.CursedProcess))
+43
View File
@@ -0,0 +1,43 @@
package dllhijack
import (
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/generate"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
dllhijackCmd := &cobra.Command{
Use: consts.DLLHijackStr,
Short: "Plant a DLL for a hijack scenario",
Long: help.GetHelpFor([]string{consts.DLLHijackStr}),
GroupID: consts.ExecutionHelpGroup,
Annotations: flags.RestrictTargets(consts.WindowsCmdsFilter),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
DllHijackCmd(cmd, con, args)
},
}
flags.Bind("", false, dllhijackCmd, func(f *pflag.FlagSet) {
f.StringP("reference-path", "r", "", "Path to the reference DLL on the remote system")
f.StringP("reference-file", "R", "", "Path to the reference DLL on the local system")
f.StringP("file", "f", "", "Local path to the DLL to plant for the hijack")
f.StringP("profile", "p", "", "Profile name to use as a base DLL")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
flags.BindFlagCompletions(dllhijackCmd, func(comp *carapace.ActionMap) {
(*comp)["reference-file"] = carapace.ActionFiles()
(*comp)["file"] = carapace.ActionFiles()
(*comp)["profile"] = generate.ProfileNameCompleter(con)
})
carapace.Gen(dllhijackCmd).PositionalCompletion(carapace.ActionValues().Usage("Path to upload the DLL to on the remote system"))
return []*cobra.Command{dllhijackCmd}
}
+1 -1
View File
@@ -34,7 +34,7 @@ import (
// dllhijack --ref-path c:\windows\system32\msasn1.dll --ref-file /tmp/ref.dll --profile dll TARGET_PATH
// DllHijackCmd -- implements the dllhijack command
func DllHijackCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func DllHijackCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
var (
localRefData []byte
targetDLLData []byte
+59
View File
@@ -0,0 +1,59 @@
package environment
import (
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
envCmd := &cobra.Command{
Use: consts.EnvStr,
Short: "List environment variables",
Long: help.GetHelpFor([]string{consts.EnvStr}),
Args: cobra.RangeArgs(0, 1),
Run: func(cmd *cobra.Command, args []string) {
EnvGetCmd(cmd, con, args)
},
GroupID: consts.InfoHelpGroup,
}
flags.Bind("", true, envCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(envCmd).PositionalCompletion(carapace.ActionValues().Usage("environment variable to fetch (optional)"))
envSetCmd := &cobra.Command{
Use: consts.SetStr,
Short: "Set environment variables",
Long: help.GetHelpFor([]string{consts.EnvStr, consts.SetStr}),
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
EnvSetCmd(cmd, con, args)
},
}
envCmd.AddCommand(envSetCmd)
carapace.Gen(envSetCmd).PositionalCompletion(
carapace.ActionValues().Usage("environment variable name"),
carapace.ActionValues().Usage("value to assign"),
)
envUnsetCmd := &cobra.Command{
Use: consts.UnsetStr,
Short: "Clear environment variables",
Long: help.GetHelpFor([]string{consts.EnvStr, consts.UnsetStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
EnvUnsetCmd(cmd, con, args)
},
}
envCmd.AddCommand(envUnsetCmd)
carapace.Gen(envUnsetCmd).PositionalCompletion(carapace.ActionValues().Usage("environment variable name"))
return []*cobra.Command{envCmd}
}
+2 -2
View File
@@ -31,7 +31,7 @@ import (
)
// EnvGetCmd - Get a remote environment variable
func EnvGetCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func EnvGetCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -66,7 +66,7 @@ func EnvGetCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
}
// PrintGetEnvInfo - Print the results of the env get command
func PrintGetEnvInfo(envInfo *sliverpb.EnvInfo, con *console.SliverConsoleClient) {
func PrintGetEnvInfo(envInfo *sliverpb.EnvInfo, con *console.SliverClient) {
if envInfo.Response != nil && envInfo.Response.Err != "" {
con.PrintErrorf("%s\n", envInfo.Response.Err)
return
+2 -2
View File
@@ -32,7 +32,7 @@ import (
)
// EnvSetCmd - Set a remote environment variable
func EnvSetCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func EnvSetCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -72,7 +72,7 @@ func EnvSetCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
}
// PrintSetEnvInfo - Print the set environment info
func PrintSetEnvInfo(name string, value string, envInfo *sliverpb.SetEnv, con *console.SliverConsoleClient) {
func PrintSetEnvInfo(name string, value string, envInfo *sliverpb.SetEnv, con *console.SliverClient) {
if envInfo.Response != nil && envInfo.Response.Err != "" {
con.PrintErrorf("%s\n", envInfo.Response.Err)
return
+2 -2
View File
@@ -31,7 +31,7 @@ import (
)
// EnvUnsetCmd - Unset a remote environment variable
func EnvUnsetCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func EnvUnsetCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -67,7 +67,7 @@ func EnvUnsetCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
}
// PrintUnsetEnvInfo - Print the set environment info
func PrintUnsetEnvInfo(name string, envInfo *sliverpb.UnsetEnv, con *console.SliverConsoleClient) {
func PrintUnsetEnvInfo(name string, envInfo *sliverpb.UnsetEnv, con *console.SliverClient) {
if envInfo.Response != nil && envInfo.Response.Err != "" {
con.PrintErrorf("%s\n", envInfo.Response.Err)
return
+278
View File
@@ -0,0 +1,278 @@
package exec
import (
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/generate"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
executeCmd := &cobra.Command{
Use: consts.ExecuteStr,
Short: "Execute a program on the remote system",
Long: help.GetHelpFor([]string{consts.ExecuteStr}),
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ExecuteCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
}
flags.Bind("", false, executeCmd, func(f *pflag.FlagSet) {
f.BoolP("token", "T", false, "execute command with current token (Windows only)")
f.BoolP("output", "o", false, "capture command output")
f.BoolP("save", "s", false, "save output to a file")
f.BoolP("loot", "X", false, "save output as loot")
f.BoolP("ignore-stderr", "S", false, "don't print STDERR output")
f.StringP("stdout", "O", "", "remote path to redirect STDOUT to")
f.StringP("stderr", "E", "", "remote path to redirect STDERR to")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.Uint32P("ppid", "P", 0, "parent process id (optional, Windows only)")
f.BoolP("hidden", "H", false, "hide the window of the spawned process (Windows only)")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
executeCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
carapace.Gen(executeCmd).PositionalCompletion(carapace.ActionValues().Usage("command to execute (required)"))
carapace.Gen(executeCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("arguments to the command (optional)"))
executeAssemblyCmd := &cobra.Command{
Use: consts.ExecuteAssemblyStr,
Short: "Loads and executes a .NET assembly in a child process (Windows Only)",
Long: help.GetHelpFor([]string{consts.ExecuteAssemblyStr}),
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ExecuteAssemblyCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
Annotations: flags.RestrictTargets(consts.WindowsCmdsFilter),
}
flags.Bind("", false, executeAssemblyCmd, func(f *pflag.FlagSet) {
f.StringP("process", "p", "notepad.exe", "hosting process to inject into")
f.StringP("method", "m", "", "Optional method (a method is required for a .NET DLL)")
f.StringP("class", "c", "", "Optional class name (required for .NET DLL)")
f.StringP("app-domain", "d", "", "AppDomain name to create for .NET assembly. Generated randomly if not set.")
f.StringP("arch", "a", "x84", "Assembly target architecture: x86, x64, x84 (x86+x64)")
f.BoolP("in-process", "i", false, "Run in the current sliver process")
f.StringP("runtime", "r", "", "Runtime to use for running the assembly (only supported when used with --in-process)")
f.BoolP("save", "s", false, "save output to file")
f.BoolP("loot", "X", false, "save output as loot")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.Uint32P("ppid", "P", 0, "parent process id (optional)")
f.StringP("process-arguments", "A", "", "arguments to pass to the hosting process")
f.BoolP("amsi-bypass", "M", false, "Bypass AMSI on Windows (only supported when used with --in-process)")
f.BoolP("etw-bypass", "E", false, "Bypass ETW on Windows (only supported when used with --in-process)")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
executeAssemblyCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
carapace.Gen(executeAssemblyCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to assembly file (required)"))
carapace.Gen(executeAssemblyCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("arguments to pass to the assembly entrypoint (optional)"))
executeShellcodeCmd := &cobra.Command{
Use: consts.ExecuteShellcodeStr,
Short: "Executes the given shellcode in the sliver process",
Long: help.GetHelpFor([]string{consts.ExecuteShellcodeStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ExecuteShellcodeCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
}
flags.Bind("", false, executeShellcodeCmd, func(f *pflag.FlagSet) {
f.BoolP("rwx-pages", "r", false, "Use RWX permissions for memory pages")
f.Uint32P("pid", "p", 0, "Pid of process to inject into (0 means injection into ourselves)")
f.StringP("process", "n", `c:\windows\system32\notepad.exe`, "Process to inject into when running in interactive mode")
f.BoolP("interactive", "i", false, "Inject into a new process and interact with it")
f.BoolP("shikata-ga-nai", "S", false, "encode shellcode using shikata ga nai prior to execution")
f.StringP("architecture", "A", "amd64", "architecture of the shellcode: 386, amd64 (used with --shikata-ga-nai flag)")
f.Uint32P("iterations", "I", 1, "number of encoding iterations (used with --shikata-ga-nai flag)")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
flags.BindFlagCompletions(executeShellcodeCmd, func(comp *carapace.ActionMap) {
(*comp)["shikata-ga-nai"] = carapace.ActionValues("386", "amd64").Tag("shikata-ga-nai architectures")
})
carapace.Gen(executeShellcodeCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to shellcode file (required)"))
sideloadCmd := &cobra.Command{
Use: consts.SideloadStr,
Short: "Load and execute a shared object (shared library/DLL) in a remote process",
Long: help.GetHelpFor([]string{consts.SideloadStr}),
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
SideloadCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
}
flags.Bind("", false, sideloadCmd, func(f *pflag.FlagSet) {
f.StringP("entry-point", "e", "", "Entrypoint for the DLL (Windows only)")
f.StringP("process", "p", `c:\windows\system32\notepad.exe`, "Path to process to host the shellcode")
f.BoolP("unicode", "w", false, "Command line is passed to unmanaged DLL function in UNICODE format. (default is ANSI)")
f.BoolP("save", "s", false, "save output to file")
f.BoolP("loot", "X", false, "save output as loot")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.BoolP("keep-alive", "k", false, "don't terminate host process once the execution completes")
f.Uint32P("ppid", "P", 0, "parent process id (optional)")
f.StringP("process-arguments", "A", "", "arguments to pass to the hosting process")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
sideloadCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
carapace.Gen(sideloadCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to shared library file (required)"))
carapace.Gen(sideloadCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("arguments to pass to the binary (optional)"))
spawnDllCmd := &cobra.Command{
Use: consts.SpawnDllStr,
Short: "Load and execute a Reflective DLL in a remote process",
Long: help.GetHelpFor([]string{consts.SpawnDllStr}),
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
SpawnDllCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
Annotations: flags.RestrictTargets(consts.WindowsCmdsFilter),
}
flags.Bind("", false, spawnDllCmd, func(f *pflag.FlagSet) {
f.StringP("process", "p", `c:\windows\system32\notepad.exe`, "Path to process to host the shellcode")
f.StringP("export", "e", "ReflectiveLoader", "Entrypoint of the Reflective DLL")
f.BoolP("save", "s", false, "save output to file")
f.BoolP("loot", "X", false, "save output as loot")
f.StringP("name", "n", "", "name to assign loot (optional)")
f.BoolP("keep-alive", "k", false, "don't terminate host process once the execution completes")
f.UintP("ppid", "P", 0, "parent process id (optional)")
f.StringP("process-arguments", "A", "", "arguments to pass to the hosting process")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
spawnDllCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
carapace.Gen(spawnDllCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to DLL file (required)"))
carapace.Gen(spawnDllCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("arguments to pass to the DLL entrypoint (optional)"))
migrateCmd := &cobra.Command{
Use: consts.MigrateStr,
Short: "Migrate into a remote process",
Long: help.GetHelpFor([]string{consts.MigrateStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
MigrateCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
Annotations: flags.RestrictTargets(consts.WindowsCmdsFilter),
}
flags.Bind("", false, migrateCmd, func(f *pflag.FlagSet) {
f.BoolP("disable-sgn", "S", true, "disable shikata ga nai shellcode encoder")
f.Uint32P("pid", "p", 0, "process id to migrate into")
f.StringP("process-name", "n", "", "name of the process to migrate into")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(migrateCmd).PositionalCompletion(carapace.ActionValues().Usage("PID of process to migrate into"))
msfCmd := &cobra.Command{
Use: consts.MsfStr,
Short: "Execute an MSF payload in the current process",
Long: help.GetHelpFor([]string{consts.MsfStr}),
Run: func(cmd *cobra.Command, args []string) {
MsfCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
}
flags.Bind("", false, msfCmd, func(f *pflag.FlagSet) {
f.StringP("payload", "m", "meterpreter_reverse_https", "msf payload")
f.StringP("lhost", "L", "", "listen host")
f.IntP("lport", "l", 4444, "listen port")
f.StringP("encoder", "e", "", "msf encoder")
f.IntP("iterations", "i", 1, "iterations of the encoder")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
msfInjectCmd := &cobra.Command{
Use: consts.MsfInjectStr,
Short: "Inject an MSF payload into a process",
Long: help.GetHelpFor([]string{consts.MsfInjectStr}),
Run: func(cmd *cobra.Command, args []string) {
MsfInjectCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
}
flags.Bind("", false, msfInjectCmd, func(f *pflag.FlagSet) {
f.IntP("pid", "p", -1, "pid to inject into")
f.StringP("payload", "m", "meterpreter_reverse_https", "msf payload")
f.StringP("lhost", "L", "", "listen host")
f.IntP("lport", "l", 4444, "listen port")
f.StringP("encoder", "e", "", "msf encoder")
f.IntP("iterations", "i", 1, "iterations of the encoder")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
psExecCmd := &cobra.Command{
Use: consts.PsExecStr,
Short: "Start a sliver service on a remote target",
Long: help.GetHelpFor([]string{consts.PsExecStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
PsExecCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
Annotations: flags.RestrictTargets(consts.WindowsCmdsFilter),
}
flags.Bind("", false, psExecCmd, func(f *pflag.FlagSet) {
f.StringP("service-name", "s", "Sliver", "name that will be used to register the service")
f.StringP("service-description", "d", "Sliver implant", "description of the service")
f.StringP("profile", "p", "", "profile to use for service binary")
f.StringP("binpath", "b", "c:\\windows\\temp", "directory to which the executable will be uploaded")
f.StringP("custom-exe", "c", "", "custom service executable to use instead of generating a new Sliver")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
flags.BindFlagCompletions(psExecCmd, func(comp *carapace.ActionMap) {
(*comp)["custom-exe"] = carapace.ActionFiles()
(*comp)["profile"] = generate.ProfileNameCompleter(con)
})
carapace.Gen(psExecCmd).PositionalCompletion(carapace.ActionValues().Usage("hostname (required)"))
sshCmd := &cobra.Command{
Use: consts.SSHStr,
Short: "Run a SSH command on a remote host",
Long: help.GetHelpFor([]string{consts.SSHStr}),
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
SSHCmd(cmd, con, args)
},
GroupID: consts.ExecutionHelpGroup,
}
flags.Bind("", false, sshCmd, func(f *pflag.FlagSet) {
f.UintP("port", "p", 22, "SSH port")
f.StringP("private-key", "i", "", "path to private key file")
f.StringP("password", "P", "", "SSH user password")
f.StringP("login", "l", "", "username to use to connect")
f.BoolP("skip-loot", "s", false, "skip the prompt to use loot credentials")
f.StringP("kerberos-config", "c", "/etc/krb5.conf", "path to remote Kerberos config file")
f.StringP("kerberos-keytab", "k", "", "path to Kerberos keytab file")
f.StringP("kerberos-realm", "r", "", "Kerberos realm")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
sshCmd.Flags().ParseErrorsWhitelist.UnknownFlags = true
flags.BindFlagCompletions(sshCmd, func(comp *carapace.ActionMap) {
(*comp)["private-key"] = carapace.ActionFiles()
(*comp)["kerberos-keytab"] = carapace.ActionFiles()
})
carapace.Gen(sshCmd).PositionalCompletion(carapace.ActionValues().Usage("remote host to SSH to (required)"))
carapace.Gen(sshCmd).PositionalAnyCompletion(carapace.ActionValues().Usage("command line with arguments"))
return []*cobra.Command{executeCmd, executeAssemblyCmd, executeShellcodeCmd, sideloadCmd, spawnDllCmd, migrateCmd, msfCmd, msfInjectCmd, psExecCmd, sshCmd}
}
+5 -6
View File
@@ -25,16 +25,15 @@ import (
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"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"
)
// ExecuteAssemblyCmd - Execute a .NET assembly in-memory
func ExecuteAssemblyCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExecuteAssemblyCmd - Execute a .NET assembly in-memory.
func ExecuteAssemblyCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -132,7 +131,7 @@ func ExecuteAssemblyCmd(cmd *cobra.Command, con *console.SliverConsoleClient, ar
}
}
func HandleExecuteAssemblyResponse(execAssembly *sliverpb.ExecuteAssembly, assemblyPath string, hostName string, cmd *cobra.Command, con *console.SliverConsoleClient) {
func HandleExecuteAssemblyResponse(execAssembly *sliverpb.ExecuteAssembly, assemblyPath string, hostName string, cmd *cobra.Command, con *console.SliverClient) {
saveLoot, _ := cmd.Flags().GetBool("loot")
lootName, _ := cmd.Flags().GetString("name")
+8 -10
View File
@@ -26,19 +26,17 @@ import (
"log"
"os"
"golang.org/x/term"
"google.golang.org/protobuf/proto"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/core"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
"golang.org/x/term"
"google.golang.org/protobuf/proto"
)
// ExecuteShellcodeCmd - Execute shellcode in-memory
func ExecuteShellcodeCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExecuteShellcodeCmd - Execute shellcode in-memory.
func ExecuteShellcodeCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -128,8 +126,8 @@ func ExecuteShellcodeCmd(cmd *cobra.Command, con *console.SliverConsoleClient, a
}
}
// PrintExecuteShellcode - Display result of shellcode execution
func PrintExecuteShellcode(task *sliverpb.Task, con *console.SliverConsoleClient) {
// PrintExecuteShellcode - Display result of shellcode execution.
func PrintExecuteShellcode(task *sliverpb.Task, con *console.SliverClient) {
if task.Response.GetErr() != "" {
con.PrintErrorf("%s\n", task.Response.GetErr())
} else {
@@ -137,7 +135,7 @@ func PrintExecuteShellcode(task *sliverpb.Task, con *console.SliverConsoleClient
}
}
func executeInteractive(cmd *cobra.Command, hostProc string, shellcode []byte, rwxPages bool, con *console.SliverConsoleClient) {
func executeInteractive(cmd *cobra.Command, hostProc string, shellcode []byte, rwxPages bool, con *console.SliverClient) {
// Check active session
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
+12 -14
View File
@@ -23,18 +23,16 @@ import (
"strings"
"time"
"google.golang.org/protobuf/proto"
"github.com/spf13/cobra"
"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/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// ExecuteCmd - Run a command on the remote system
func ExecuteCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExecuteCmd - Run a command on the remote system.
func ExecuteCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -113,7 +111,7 @@ func ExecuteCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []str
}
}
func HandleExecuteResponse(exec *sliverpb.Execute, cmdPath string, hostName string, cmd *cobra.Command, con *console.SliverConsoleClient) {
func HandleExecuteResponse(exec *sliverpb.Execute, cmdPath string, hostName string, cmd *cobra.Command, con *console.SliverClient) {
var lootedOutput []byte
stdout, _ := cmd.Flags().GetString("stdout")
saveLoot, _ := cmd.Flags().GetBool("loot")
@@ -136,8 +134,8 @@ func HandleExecuteResponse(exec *sliverpb.Execute, cmdPath string, hostName stri
PrintExecute(exec, cmd, con)
}
// PrintExecute - Print the output of an executed command
func PrintExecute(exec *sliverpb.Execute, cmd *cobra.Command, con *console.SliverConsoleClient) {
// PrintExecute - Print the output of an executed command.
func PrintExecute(exec *sliverpb.Execute, cmd *cobra.Command, con *console.SliverClient) {
ignoreStderr, _ := cmd.Flags().GetBool("ignore-stderr")
stdout, _ := cmd.Flags().GetString("stdout")
stderr, _ := cmd.Flags().GetString("stderr")
@@ -210,7 +208,7 @@ func combineCommandOutput(exec *sliverpb.Execute, combineStdOut bool, combineStd
return []byte(outputString)
}
func LootExecute(commandOutput []byte, lootName string, sliverCmdName string, cmdName string, hostName string, con *console.SliverConsoleClient) {
func LootExecute(commandOutput []byte, lootName string, sliverCmdName string, cmdName string, hostName string, con *console.SliverClient) {
if len(commandOutput) == 0 {
con.PrintInfof("There was no output from execution, so there is nothing to loot.\n")
return
@@ -225,11 +223,11 @@ func LootExecute(commandOutput []byte, lootName string, sliverCmdName string, cm
lootName = fmt.Sprintf("[%s] %s on %s (%s)", sliverCmdName, shortCommandName, hostName, timeNow)
}
lootMessage := loot.CreateLootMessage(fileName, lootName, clientpb.FileType_TEXT, commandOutput)
lootMessage := loot.CreateLootMessage(con.ActiveTarget.GetHostUUID(), fileName, lootName, clientpb.FileType_TEXT, commandOutput)
loot.SendLootMessage(lootMessage, con)
}
func PrintExecutionOutput(executionOutput string, saveOutput bool, commandName string, hostName string, con *console.SliverConsoleClient) {
func PrintExecutionOutput(executionOutput string, saveOutput bool, commandName string, hostName string, con *console.SliverClient) {
con.PrintInfof("Output:\n%s", executionOutput)
if saveOutput {
@@ -237,7 +235,7 @@ func PrintExecutionOutput(executionOutput string, saveOutput bool, commandName s
}
}
func SaveExecutionOutput(executionOutput string, commandName string, hostName string, con *console.SliverConsoleClient) {
func SaveExecutionOutput(executionOutput string, commandName string, hostName string, con *console.SliverClient) {
var outFilePath *os.File
var err error
@@ -258,7 +256,7 @@ func SaveExecutionOutput(executionOutput string, commandName string, hostName st
}
if outFilePath != nil {
outFilePath.Write([]byte(executionOutput))
outFilePath.WriteString(executionOutput)
con.PrintInfof("Output saved to %s\n", outFilePath.Name())
}
}
+53 -38
View File
@@ -21,19 +21,18 @@ package exec
import (
"context"
"fmt"
"strings"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
)
// MigrateCmd - Windows only, inject an implant into another process
func MigrateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
session := con.ActiveTarget.GetSession()
if session == nil {
func MigrateCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
@@ -43,44 +42,37 @@ func MigrateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []str
con.PrintErrorf("Error: Must specify either a PID or process name\n")
return
}
if procName != "" {
procCtrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("Searching for %s ...", procName), procCtrl)
proc, err := con.Rpc.Ps(context.Background(), &sliverpb.PsReq{
Request: con.ActiveTarget.Request(cmd),
})
if err != nil {
con.PrintErrorf("Error: %v\n", err)
return
}
procCtrl <- true
<-procCtrl
for _, p := range proc.GetProcesses() {
if strings.EqualFold(p.Executable, procName) {
pid = uint32(p.Pid)
break
}
}
if pid == 0 {
con.PrintErrorf("Error: Could not find process %s\n", procName)
return
}
con.PrintInfof("Process name specified, overriding PID with %d\n", pid)
var config *clientpb.ImplantConfig
var implantName string
if session != nil {
config = con.GetActiveSessionConfig()
implantName = session.Name
} else {
config = con.GetActiveBeaconConfig()
implantName = beacon.Name
}
config := con.GetActiveSessionConfig()
encoder := clientpb.ShellcodeEncoder_SHIKATA_GA_NAI
if disableSgn, _ := cmd.Flags().GetBool("disable-sgn"); disableSgn {
encoder = clientpb.ShellcodeEncoder_NONE
}
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("Migrating into %d ...", pid), ctrl)
if pid != 0 {
con.SpinUntil(fmt.Sprintf("Migrating into %d ...", pid), ctrl)
} else {
con.SpinUntil(fmt.Sprintf("Migrating into %s...", procName), ctrl)
}
migrate, err := con.Rpc.Migrate(context.Background(), &clientpb.MigrateReq{
Pid: pid,
Config: config,
Request: con.ActiveTarget.Request(cmd),
Encoder: encoder,
Pid: pid,
Config: config,
Request: con.ActiveTarget.Request(cmd),
Encoder: encoder,
Name: implantName,
ProcName: procName,
})
ctrl <- true
<-ctrl
@@ -88,9 +80,32 @@ func MigrateCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []str
con.PrintErrorf("Error: %v", err)
return
}
if !migrate.Success {
con.PrintErrorf("%s\n", migrate.GetResponse().GetErr())
return
if migrate.Response != nil && migrate.Response.Async {
con.AddBeaconCallback(migrate.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, migrate)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
}
if !migrate.Success {
if migrate.GetResponse().GetErr() != "" {
con.PrintErrorf("%s\n", migrate.GetResponse().GetErr())
} else {
con.PrintErrorf("Could not migrate into a new process. Check the PID or name.")
}
return
}
con.PrintInfof("Successfully migrated to %d\n", migrate.Pid)
})
con.PrintAsyncResponse(migrate.Response)
} else {
if !migrate.Success {
if migrate.GetResponse().GetErr() != "" {
con.PrintErrorf("%s\n", migrate.GetResponse().GetErr())
} else {
con.PrintErrorf("Could not migrate into a new process. Check the PID or name.")
}
return
}
con.PrintInfof("Successfully migrated to %d\n", migrate.Pid)
}
con.PrintInfof("Successfully migrated to %d\n", pid)
}
+6 -8
View File
@@ -22,18 +22,16 @@ import (
"context"
"fmt"
"google.golang.org/protobuf/proto"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// MsfInjectCmd - Inject a metasploit payload into a remote process
func MsfInjectCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// MsfInjectCmd - Inject a metasploit payload into a remote process.
func MsfInjectCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -99,8 +97,8 @@ func MsfInjectCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []s
}
}
// PrintMsfRemote - Print the results of the remote injection attempt
func PrintMsfRemote(msfRemote *sliverpb.Task, con *console.SliverConsoleClient) {
// PrintMsfRemote - Print the results of the remote injection attempt.
func PrintMsfRemote(msfRemote *sliverpb.Task, con *console.SliverClient) {
if msfRemote.Response == nil {
con.PrintErrorf("Empty response from msf payload injection task")
return
+4 -6
View File
@@ -22,17 +22,15 @@ import (
"context"
"fmt"
"google.golang.org/protobuf/proto"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// MsfCmd - Inject a metasploit payload into the current remote process
func MsfCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// MsfCmd - Inject a metasploit payload into the current remote process.
func MsfCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
+3 -5
View File
@@ -21,14 +21,11 @@ package exec
import (
"context"
"fmt"
insecureRand "math/rand"
"os"
"strings"
"time"
insecureRand "math/rand"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/command/generate"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
@@ -36,10 +33,11 @@ import (
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util/encoders"
"github.com/spf13/cobra"
)
// PsExecCmd - psexec command implementation.
func PsExecCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func PsExecCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
+5 -7
View File
@@ -25,17 +25,15 @@ import (
"path/filepath"
"strings"
"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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// SideloadCmd - Sideload a shared library on the remote system
func SideloadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// SideloadCmd - Sideload a shared library on the remote system.
func SideloadCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -96,7 +94,7 @@ func SideloadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
}
}
func HandleSideloadResponse(sideload *sliverpb.Sideload, binPath string, hostName string, cmd *cobra.Command, con *console.SliverConsoleClient) {
func HandleSideloadResponse(sideload *sliverpb.Sideload, binPath string, hostName string, cmd *cobra.Command, con *console.SliverClient) {
saveLoot, _ := cmd.Flags().GetBool("loot")
lootName, _ := cmd.Flags().GetString("name")
+5 -7
View File
@@ -24,17 +24,15 @@ import (
"os"
"strings"
"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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// SpawnDllCmd - Spawn execution of a DLL on the remote system
func SpawnDllCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// SpawnDllCmd - Spawn execution of a DLL on the remote system.
func SpawnDllCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -85,7 +83,7 @@ func SpawnDllCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
}
}
func HandleSpawnDLLResponse(spawndll *sliverpb.SpawnDll, binPath string, hostName string, cmd *cobra.Command, con *console.SliverConsoleClient) {
func HandleSpawnDLLResponse(spawndll *sliverpb.SpawnDll, binPath string, hostName string, cmd *cobra.Command, con *console.SliverClient) {
saveLoot, _ := cmd.Flags().GetBool("loot")
lootName, _ := cmd.Flags().GetString("name")
+7 -8
View File
@@ -24,16 +24,15 @@ import (
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"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"
)
// SSHCmd - A built-in SSH client command for the remote system (doesn't shell out)
func SSHCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// SSHCmd - A built-in SSH client command for the remote system (doesn't shell out).
func SSHCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
var (
privKey []byte
err error
@@ -120,8 +119,8 @@ func SSHCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
}
}
// PrintSSHCmd - Print the ssh command response
func PrintSSHCmd(sshCmd *sliverpb.SSHCommand, con *console.SliverConsoleClient) {
// PrintSSHCmd - Print the ssh command response.
func PrintSSHCmd(sshCmd *sliverpb.SSHCommand, con *console.SliverClient) {
if sshCmd.Response != nil && sshCmd.Response.Err != "" {
con.PrintErrorf("Error: %s\n", sshCmd.Response.Err)
if sshCmd.StdErr != "" {
@@ -139,7 +138,7 @@ func PrintSSHCmd(sshCmd *sliverpb.SSHCommand, con *console.SliverConsoleClient)
}
}
func tryCredsFromLoot(con *console.SliverConsoleClient) (string, string, []byte) {
func tryCredsFromLoot(con *console.SliverClient) (string, string, []byte) {
var (
username string
password string
+15 -2
View File
@@ -25,12 +25,13 @@ import (
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/spf13/cobra"
)
// ExitCmd - Exit the console
func ExitCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExitCmd - Exit the console.
func ExitCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
fmt.Println("Exiting...")
if con.IsServer {
sessions, err := con.Rpc.GetSessions(context.Background(), &commonpb.Empty{})
@@ -53,3 +54,15 @@ func ExitCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string
}
os.Exit(0)
}
// Commands returns the `exit` command.
func Command(con *console.SliverClient) []*cobra.Command {
return []*cobra.Command{{
Use: "exit",
Short: "Exit the program",
Run: func(cmd *cobra.Command, args []string) {
ExitCmd(cmd, con, args)
},
GroupID: constants.GenericHelpGroup,
}}
}
+68
View File
@@ -0,0 +1,68 @@
package extensions
import (
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
extensionCmd := &cobra.Command{
Use: consts.ExtensionsStr,
Short: "Manage extensions",
Long: help.GetHelpFor([]string{consts.ExtensionsStr}),
GroupID: consts.ExecutionHelpGroup,
Run: func(cmd *cobra.Command, _ []string) {
ExtensionsCmd(cmd, con)
},
}
extensionCmd.AddCommand(&cobra.Command{
Use: consts.ListStr,
Short: "List extensions loaded in the current session or beacon",
Long: help.GetHelpFor([]string{consts.ExtensionsStr, consts.ListStr}),
Run: func(cmd *cobra.Command, args []string) {
ExtensionsListCmd(cmd, con, args)
},
})
extensionLoadCmd := &cobra.Command{
Use: consts.LoadStr,
Short: "Temporarily load an extension from a local directory",
Long: help.GetHelpFor([]string{consts.ExtensionsStr, consts.LoadStr}),
Run: func(cmd *cobra.Command, args []string) {
ExtensionLoadCmd(cmd, con, args)
},
}
extensionCmd.AddCommand(extensionLoadCmd)
carapace.Gen(extensionLoadCmd).PositionalCompletion(carapace.ActionDirectories().Usage("path to the extension directory"))
extensionInstallCmd := &cobra.Command{
Use: consts.InstallStr,
Short: "Install an extension from a local directory or .tar.gz file",
Long: help.GetHelpFor([]string{consts.ExtensionsStr, consts.InstallStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ExtensionsInstallCmd(cmd, con, args)
},
}
extensionCmd.AddCommand(extensionInstallCmd)
carapace.Gen(extensionInstallCmd).PositionalCompletion(carapace.ActionFiles().Usage("path to the extension .tar.gz or directory"))
extensionRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove an installed extension",
Args: cobra.ExactArgs(1),
Long: help.GetHelpFor([]string{consts.ExtensionsStr, consts.RmStr}),
Run: func(cmd *cobra.Command, args []string) {
ExtensionsRemoveCmd(cmd, con, args)
},
}
extensionCmd.AddCommand(extensionRmCmd)
carapace.Gen(extensionRmCmd).PositionalCompletion(ExtensionsCommandNameCompleter(con).Usage("the command name of the extension to remove"))
return []*cobra.Command{extensionCmd}
}
+31 -20
View File
@@ -24,18 +24,17 @@ import (
"os"
"strings"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/settings"
"github.com/bishopfox/sliver/client/console"
)
// ExtensionsCmd - List information about installed extensions
func ExtensionsCmd(cmd *cobra.Command, con *console.SliverConsoleClient) {
// ExtensionsCmd - List information about installed extensions.
func ExtensionsCmd(cmd *cobra.Command, con *console.SliverClient) {
if 0 < len(getInstalledManifests()) {
PrintExtensions(con)
} else {
@@ -43,8 +42,8 @@ func ExtensionsCmd(cmd *cobra.Command, con *console.SliverConsoleClient) {
}
}
// PrintExtensions - Print a list of loaded extensions
func PrintExtensions(con *console.SliverConsoleClient) {
// PrintExtensions - Print a list of loaded extensions.
func PrintExtensions(con *console.SliverClient) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
@@ -66,25 +65,27 @@ func PrintExtensions(con *console.SliverConsoleClient) {
installedManifests := getInstalledManifests()
for _, extension := range loadedExtensions {
//for _, extension := range extensionm.ExtCommand {
installed := ""
if _, ok := installedManifests[extension.CommandName]; ok {
if _, ok := installedManifests[extension.Manifest.Name]; ok {
installed = "✅"
}
tw.AppendRow(table.Row{
extension.Name,
extension.Manifest.Name,
extension.CommandName,
strings.Join(extensionPlatforms(extension), ",\n"),
extension.Version,
extension.Manifest.Version,
installed,
extension.ExtensionAuthor,
extension.OriginalAuthor,
extension.RepoURL,
extension.Manifest.ExtensionAuthor,
extension.Manifest.OriginalAuthor,
extension.Manifest.RepoURL,
})
//}
}
con.Println(tw.Render())
}
func extensionPlatforms(extension *ExtensionManifest) []string {
func extensionPlatforms(extension *ExtCommand) []string {
platforms := map[string]string{}
for _, entry := range extension.Files {
platforms[fmt.Sprintf("%s/%s", entry.OS, entry.Arch)] = ""
@@ -109,17 +110,17 @@ func getInstalledManifests() map[string]*ExtensionManifest {
if err != nil {
continue
}
installedManifests[manifest.CommandName] = manifest
installedManifests[manifest.Name] = manifest
}
return installedManifests
}
// ExtensionsCommandNameCompleter - Completer for installed extensions command names
func ExtensionsCommandNameCompleter(con *console.SliverConsoleClient) carapace.Action {
// ExtensionsCommandNameCompleter - Completer for installed extensions command names.
func ExtensionsCommandNameCompleter(con *console.SliverClient) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
installedManifests := getInstalledManifests()
//installedManifests := getInstalledManifests()
results := []string{}
for _, manifest := range installedManifests {
for _, manifest := range loadedExtensions {
results = append(results, manifest.CommandName)
results = append(results, manifest.Help)
}
@@ -127,3 +128,13 @@ func ExtensionsCommandNameCompleter(con *console.SliverConsoleClient) carapace.A
return carapace.ActionValuesDescribed(results...).Tag("extension commands")
})
}
func ManifestCompleter() carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
results := []string{}
for k := range loadedManifests {
results = append(results, k)
}
return carapace.ActionValues(results...).Tag("extensions")
})
}
+150 -75
View File
@@ -1,5 +1,10 @@
package extensions
import (
"encoding/json"
"testing"
)
/*
Sliver Implant Framework
Copyright (C) 2021 Bishop Fox
@@ -18,26 +23,25 @@ package extensions
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"encoding/json"
"testing"
)
const (
sample1 = `{
"name": "test1",
"command_name": "test1",
"version": "1.0.0",
"extension_author": "test",
"original_author": "test",
"repo_url": "https://example.com/",
"help": "some help",
"files": [
{
"os": "windows",
"arch": "amd64",
"path": "foo/test1.dll"
}
"commands":[
{
"command_name": "test1",
"help": "some help",
"files": [
{
"os": "windows",
"arch": "amd64",
"path": "foo/test1.dll"
}
]
}
]
}`
@@ -53,6 +57,60 @@ const (
}
]
}`
sample3 = `{
"name": "test3",
"version": "1.0.0",
"extension_author": "test",
"original_author": "test",
"repo_url": "https://example.com/",
"commands": [
{
"command_name": "test3",
"help": "some help",
"files": [
{
"os": "windows",
"arch": "amd64",
"path": "foo/test1.dll"
}
]
}
]
}`
multicmd = `{
"name": "example-multientry",
"version": "0.0.0",
"extension_author": "cs",
"original_author": "cs",
"repo_url": "no",
"commands": [
{
"command_name": "startw",
"help": "startw",
"entrypoint": "StartW",
"files": [
{
"os": "windows",
"arch": "amd64",
"path": "ex.dll"
}
]
},
{
"command_name": "Test2",
"help": "startw",
"entrypoint": "Test2",
"files": [
{
"os": "windows",
"arch": "amd64",
"path": "ex.dll"
}
]
}
]
}`
)
func TestParseExtensionManifest(t *testing.T) {
@@ -63,9 +121,7 @@ func TestParseExtensionManifest(t *testing.T) {
if extManifest.Name != "test1" {
t.Errorf("Expected extension name 'test1', got '%s'", extManifest.Name)
}
if extManifest.CommandName != "test1" {
t.Errorf("Expected extension command name 'test1', got '%s'", extManifest.CommandName)
}
if extManifest.Version != "1.0.0" {
t.Errorf("Expected extension version '1.0.0', got '%s'", extManifest.Version)
}
@@ -78,67 +134,86 @@ func TestParseExtensionManifest(t *testing.T) {
if extManifest.RepoURL != "https://example.com/" {
t.Errorf("Expected repo URL 'https://example.com/', got '%s'", extManifest.RepoURL)
}
if extManifest.Help != "some help" {
t.Errorf("Expected help 'some help', got '%s'", extManifest.Help)
}
if len(extManifest.Files) != 1 {
t.Errorf("Expected 1 file, got %d", len(extManifest.Files))
}
if extManifest.Files[0].OS != "windows" {
t.Errorf("Expected OS 'windows', got '%s'", extManifest.Files[0].OS)
}
if extManifest.Files[0].Arch != "amd64" {
t.Errorf("Expected Arch 'amd64', got '%s'", extManifest.Files[0].Arch)
}
if extManifest.Files[0].Path != "/foo/test1.dll" {
t.Errorf("Expected path '/foo/test1.dll', got '%s'", extManifest.Files[0].Path)
for _, extCmd := range extManifest.ExtCommand { //should only be a single manfiest here, so should pass
if extCmd.CommandName != "test1" {
t.Errorf("Expected extension command name 'test1', got '%s'", extCmd.CommandName)
}
if extCmd.Help != "some help" {
t.Errorf("Expected help 'some help', got '%s'", extCmd.Help)
}
if len(extCmd.Files) != 1 {
t.Errorf("Expected 1 file, got %d", len(extCmd.Files))
}
if extCmd.Files[0].OS != "windows" {
t.Errorf("Expected OS 'windows', got '%s'", extCmd.Files[0].OS)
}
if extCmd.Files[0].Arch != "amd64" {
t.Errorf("Expected Arch 'amd64', got '%s'", extCmd.Files[0].Arch)
}
if extCmd.Files[0].Path != "/foo/test1.dll" {
t.Errorf("Expected path '/foo/test1.dll', got '%s'", extCmd.Files[0].Path)
}
}
extManifest2, err := ParseExtensionManifest([]byte(sample2))
mextManifest2, err := ParseExtensionManifest([]byte(sample2)) //checking old manifests work good too
if err != nil {
t.Fatalf("Error parsing extension manifest (2): %s", err)
}
if extManifest2.Name != "test2" {
t.Errorf("Expected extension name 'test2', got '%s'", extManifest2.Name)
if mextManifest2.Name != "test2" {
t.Errorf("Expected extension name 'test2', got '%s'", mextManifest2.Name)
}
if extManifest2.CommandName != "test2" {
t.Errorf("Expected extension command name 'test2', got '%s'", extManifest2.CommandName)
}
if extManifest2.Help != "some help" {
t.Errorf("Expected help 'some help', got '%s'", extManifest2.Help)
}
if len(extManifest2.Files) != 1 {
t.Errorf("Expected 1 file, got %d", len(extManifest2.Files))
}
if extManifest2.Files[0].OS != "windows" {
t.Errorf("Expected OS 'windows', got '%s'", extManifest2.Files[0].OS)
}
if extManifest2.Files[0].Arch != "amd64" {
t.Errorf("Expected Arch 'amd64', got '%s'", extManifest2.Files[0].Arch)
}
if extManifest2.Files[0].Path != "/foo/test1.dll" {
t.Errorf("Expected path '/foo/test1.dll', got '%s'", extManifest2.Files[0].Path)
for _, extManifest2 := range mextManifest2.ExtCommand {
if extManifest2.CommandName != "test2" {
t.Errorf("Expected extension command name 'test2', got '%s'", extManifest2.CommandName)
}
if extManifest2.Help != "some help" {
t.Errorf("Expected help 'some help', got '%s'", extManifest2.Help)
}
if len(extManifest2.Files) != 1 {
t.Errorf("Expected 1 file, got %d", len(extManifest2.Files))
}
if extManifest2.Files[0].OS != "windows" {
t.Errorf("Expected OS 'windows', got '%s'", extManifest2.Files[0].OS)
}
if extManifest2.Files[0].Arch != "amd64" {
t.Errorf("Expected Arch 'amd64', got '%s'", extManifest2.Files[0].Arch)
}
if extManifest2.Files[0].Path != "/foo/test1.dll" {
t.Errorf("Expected path '/foo/test1.dll', got '%s'", extManifest2.Files[0].Path)
}
}
}
const (
sample3 = `{
"name": "test3",
"command_name": "test3",
"version": "1.0.0",
"extension_author": "test",
"original_author": "test",
"repo_url": "https://example.com/",
"help": "some help",
"files": [
{
"os": "windows",
"arch": "amd64",
"path": "foo/test1.dll"
}
]
}`
)
func TestParseMultipleCmdManifest(t *testing.T) {
mextManifest, err := ParseExtensionManifest([]byte(multicmd))
if err != nil {
t.Errorf("error parsing manifest: %s", err)
}
if mextManifest.Name != "example-multientry" {
t.Errorf("expected name example-multientry, got %s", mextManifest.Name)
}
if mextManifest.ExtCommand[0].CommandName != "startw" {
t.Errorf("expected commandname startw, got %s", mextManifest.ExtCommand[0].CommandName)
}
if mextManifest.ExtCommand[1].CommandName != "Test2" {
t.Errorf("expected commandname Test2, got %s", mextManifest.ExtCommand[1].CommandName)
}
if mextManifest.ExtCommand[0].Entrypoint != "StartW" {
t.Errorf("expected entrypoint StartW, got %s", mextManifest.ExtCommand[0].Entrypoint)
}
if mextManifest.ExtCommand[1].Entrypoint != "Test2" {
t.Errorf("expected entrypoint Test2, got %s", mextManifest.ExtCommand[1].Entrypoint)
}
if mextManifest.ExtCommand[0].Files[0].Path != "/ex.dll" { //path cleaning adds a root path here? I am not sure if this should be a bug or not... works fine in prod
t.Errorf("expected path ex.dll, got %s", mextManifest.ExtCommand[0].Files[0].Path)
}
if mextManifest.ExtCommand[1].Files[0].Path != "/ex.dll" { //path cleaning adds a root path here? I am not sure if this should be a bug or not... works fine in prod
t.Errorf("expected path ex.dll, got %s", mextManifest.ExtCommand[0].Files[0].Path)
}
//maybe some more? args?
}
func TestParseExtensionManifestErrors(t *testing.T) {
sample3, err := ParseExtensionManifest([]byte(sample3))
@@ -155,7 +230,7 @@ func TestParseExtensionManifestErrors(t *testing.T) {
}
missingCmdName := (*sample3)
missingCmdName.CommandName = ""
missingCmdName.ExtCommand[0].CommandName = ""
data, _ = json.Marshal(missingCmdName)
_, err = ParseExtensionManifest(data)
if err == nil {
@@ -163,7 +238,7 @@ func TestParseExtensionManifestErrors(t *testing.T) {
}
missingHelp := (*sample3)
missingHelp.Help = ""
missingHelp.ExtCommand[0].Help = ""
data, _ = json.Marshal(missingHelp)
_, err = ParseExtensionManifest(data)
if err == nil {
@@ -171,7 +246,7 @@ func TestParseExtensionManifestErrors(t *testing.T) {
}
missingFiles := (*sample3)
missingFiles.Files = []*extensionFile{}
missingFiles.ExtCommand[0].Files = []*extensionFile{}
data, _ = json.Marshal(missingFiles)
_, err = ParseExtensionManifest(data)
if err == nil {
@@ -179,7 +254,7 @@ func TestParseExtensionManifestErrors(t *testing.T) {
}
missingFileOS := (*sample3)
missingFileOS.Files = []*extensionFile{
missingFileOS.ExtCommand[0].Files = []*extensionFile{
{
OS: "",
Arch: "amd64",
@@ -193,7 +268,7 @@ func TestParseExtensionManifestErrors(t *testing.T) {
}
missingFileArch := (*sample3)
missingFileArch.Files = []*extensionFile{
missingFileArch.ExtCommand[0].Files = []*extensionFile{
{
OS: "windows",
Arch: "",
@@ -207,7 +282,7 @@ func TestParseExtensionManifestErrors(t *testing.T) {
}
missingFilePath := (*sample3)
missingFilePath.Files = []*extensionFile{
missingFilePath.ExtCommand[0].Files = []*extensionFile{
{
OS: "windows",
Arch: "amd64",
@@ -228,7 +303,7 @@ func TestParseExtensionManifestErrors(t *testing.T) {
}
for _, invalidPath := range invalidPaths {
missingFilePath2 := (*sample3)
missingFilePath2.Files = []*extensionFile{
missingFilePath2.ExtCommand[0].Files = []*extensionFile{
{
OS: "windows",
Arch: "amd64",
+53 -84
View File
@@ -22,135 +22,104 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
)
// ExtensionsInstallCmd - Install an extension
func ExtensionsInstallCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExtensionsInstallCmd - Install an extension.
func ExtensionsInstallCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
extLocalPath := args[0]
fi, err := os.Stat(extLocalPath)
_, err := os.Stat(extLocalPath)
if os.IsNotExist(err) {
con.PrintErrorf("Extension path '%s' does not exist", extLocalPath)
return
}
if !fi.IsDir() {
InstallFromFilePath(extLocalPath, false, con)
} else {
installFromDir(extLocalPath, con)
}
InstallFromDir(extLocalPath, con, strings.HasSuffix(extLocalPath, ".tar.gz"))
}
// Install an extension from a directory
func installFromDir(extLocalPath string, con *console.SliverConsoleClient) {
manifestData, err := os.ReadFile(filepath.Join(extLocalPath, ManifestFileName))
func InstallFromDir(extLocalPath string, con *console.SliverClient, isGz bool) {
var manifestData []byte
var err error
if isGz {
manifestData, err = util.ReadFileFromTarGz(extLocalPath, fmt.Sprintf("./%s", ManifestFileName))
} else {
manifestData, err = os.ReadFile(filepath.Join(extLocalPath, ManifestFileName))
}
if err != nil {
con.PrintErrorf("Error reading %s: %s", ManifestFileName, err)
return
}
manifest, err := ParseExtensionManifest(manifestData)
manifestF, err := ParseExtensionManifest(manifestData)
if err != nil {
con.PrintErrorf("Error parsing %s: %s", ManifestFileName, err)
return
}
installPath := filepath.Join(assets.GetExtensionsDir(), filepath.Base(manifest.CommandName))
if _, err := os.Stat(installPath); !os.IsNotExist(err) {
con.PrintInfof("Extension '%s' already exists", manifest.CommandName)
//create repo path
minstallPath := filepath.Join(assets.GetExtensionsDir(), filepath.Base(manifestF.Name))
if _, err := os.Stat(minstallPath); !os.IsNotExist(err) {
con.PrintInfof("Extension '%s' already exists", manifestF.Name)
confirm := false
prompt := &survey.Confirm{Message: "Overwrite current install?"}
survey.AskOne(prompt, &confirm)
if !confirm {
return
}
forceRemoveAll(installPath)
forceRemoveAll(minstallPath)
}
con.PrintInfof("Installing extension '%s' (%s) ... ", manifest.CommandName, manifest.Version)
err = os.MkdirAll(installPath, 0o700)
con.PrintInfof("Installing extension '%s' (%s) ... \n", manifestF.Name, manifestF.Version)
err = os.MkdirAll(minstallPath, 0o700)
if err != nil {
con.PrintErrorf("Error creating extension directory: %s\n", err)
return
}
err = os.WriteFile(filepath.Join(installPath, ManifestFileName), manifestData, 0o600)
err = os.WriteFile(filepath.Join(minstallPath, ManifestFileName), manifestData, 0o600)
if err != nil {
con.PrintErrorf("Failed to write %s: %s\n", ManifestFileName, err)
forceRemoveAll(installPath)
forceRemoveAll(minstallPath)
return
}
for _, manifestFile := range manifest.Files {
if manifestFile.Path != "" {
src := filepath.Join(extLocalPath, util.ResolvePath(manifestFile.Path))
dst := filepath.Join(installPath, util.ResolvePath(manifestFile.Path))
err := util.CopyFile(src, dst)
if err != nil {
con.PrintErrorf("Error copying file '%s' -> '%s': %s\n", src, dst, err)
forceRemoveAll(installPath)
return
for _, manifest := range manifestF.ExtCommand {
installPath := filepath.Join(minstallPath)
for _, manifestFile := range manifest.Files {
if manifestFile.Path != "" {
if isGz {
err = installArtifact(extLocalPath, installPath, manifestFile.Path, con)
} else {
src := filepath.Join(extLocalPath, util.ResolvePath(manifestFile.Path))
dst := filepath.Join(installPath, util.ResolvePath(manifestFile.Path))
err = os.MkdirAll(filepath.Dir(dst), 0o700) //required for extensions with multiple dirs between the .o file and the manifest
if err != nil {
con.PrintErrorf("\nError creating extension directory: %s\n", err)
forceRemoveAll(installPath)
return
}
err = util.CopyFile(src, dst)
if err != nil {
err = fmt.Errorf("error copying file '%s' -> '%s': %s\n", src, dst, err)
}
}
if err != nil {
con.PrintErrorf("Error installing command: %s\n", err)
forceRemoveAll(installPath)
return
}
}
}
}
}
// InstallFromFilePath - Install an extension from a .tar.gz file
func InstallFromFilePath(extLocalPath string, autoOverwrite bool, con *console.SliverConsoleClient) *string {
manifestData, err := util.ReadFileFromTarGz(extLocalPath, fmt.Sprintf("./%s", ManifestFileName))
if err != nil {
con.PrintErrorf("Failed to read %s from '%s': %s\n", ManifestFileName, extLocalPath, err)
return nil
}
manifest, err := ParseExtensionManifest(manifestData)
if err != nil {
con.PrintErrorf("Failed to parse %s: %s\n", ManifestFileName, err)
return nil
}
installPath := filepath.Join(assets.GetExtensionsDir(), filepath.Base(manifest.CommandName))
if _, err := os.Stat(installPath); !os.IsNotExist(err) {
if !autoOverwrite {
con.PrintInfof("Extension '%s' already exists\n", manifest.CommandName)
confirm := false
prompt := &survey.Confirm{Message: "Overwrite current install?"}
survey.AskOne(prompt, &confirm)
if !confirm {
return nil
}
}
forceRemoveAll(installPath)
}
con.PrintInfof("Installing extension '%s' (%s) ... ", manifest.CommandName, manifest.Version)
err = os.MkdirAll(installPath, 0o700)
if err != nil {
con.PrintErrorf("Failed to create extension directory: %s\n", err)
return nil
}
err = os.WriteFile(filepath.Join(installPath, ManifestFileName), manifestData, 0o600)
if err != nil {
con.PrintErrorf("Failed to write %s: %s\n", ManifestFileName, err)
forceRemoveAll(installPath)
return nil
}
for _, manifestFile := range manifest.Files {
if manifestFile.Path != "" {
err = installArtifact(extLocalPath, installPath, manifestFile.Path, con)
if err != nil {
con.PrintErrorf("Failed to install file: %s\n", err)
forceRemoveAll(installPath)
return nil
}
}
}
con.Printf("done!\n")
return &installPath
}
func installArtifact(extGzFilePath string, installPath string, artifactPath string, con *console.SliverConsoleClient) error {
func installArtifact(extGzFilePath string, installPath string, artifactPath string, con *console.SliverClient) error {
data, err := util.ReadFileFromTarGz(extGzFilePath, "."+filepath.ToSlash(artifactPath))
if err != nil {
return err
+3 -4
View File
@@ -21,14 +21,13 @@ package extensions
import (
"context"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/spf13/cobra"
)
// ExtensionsListCmd - List all extension loaded on the active session/beacon
func ExtensionsListCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExtensionsListCmd - List all extension loaded on the active session/beacon.
func ExtensionsListCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
return
+242 -86
View File
@@ -24,18 +24,14 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"os"
"path"
"path/filepath"
"strconv"
"strings"
appConsole "github.com/reeflective/console"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/protobuf/proto"
"github.com/AlecAivazis/survey/v2"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
@@ -44,18 +40,24 @@ import (
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
appConsole "github.com/reeflective/console"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/protobuf/proto"
)
const (
defaultTimeout = 60
// ManifestFileName - Extension manifest file name
// ManifestFileName - Extension manifest file name.
ManifestFileName = "extension.json"
)
var loadedExtensions = map[string]*ExtensionManifest{}
var loadedExtensions = map[string]*ExtCommand{}
var loadedManifests = map[string]*ExtensionManifest{}
type ExtensionManifest struct {
type ExtensionManifest_ struct {
Name string `json:"name"`
CommandName string `json:"command_name"`
Version string `json:"version"`
@@ -73,6 +75,32 @@ type ExtensionManifest struct {
RootPath string `json:"-"`
}
type ExtensionManifest struct {
Name string `json:"name"`
Version string `json:"version"`
ExtensionAuthor string `json:"extension_author"`
OriginalAuthor string `json:"original_author"`
RepoURL string `json:"repo_url"`
ExtCommand []*ExtCommand `json:"commands"`
RootPath string `json:"-"`
}
type ExtCommand struct {
CommandName string `json:"command_name"`
Help string `json:"help"`
LongHelp string `json:"long_help"`
Files []*extensionFile `json:"files"`
Arguments []*extensionArgument `json:"arguments"`
Entrypoint string `json:"entrypoint"`
DependsOn string `json:"depends_on"`
Manifest *ExtensionManifest
}
//type MultiManifest []*ExtensionManifest
type extensionFile struct {
OS string `json:"os"`
Arch string `json:"arch"`
@@ -86,11 +114,11 @@ type extensionArgument struct {
Optional bool `json:"optional"`
}
func (e *ExtensionManifest) getFileForTarget(cmdName string, targetOS string, targetArch string) (string, error) {
func (e *ExtCommand) getFileForTarget(targetOS string, targetArch string) (string, error) {
filePath := ""
for _, extFile := range e.Files {
if targetOS == extFile.OS && targetArch == extFile.Arch {
filePath = path.Join(assets.GetExtensionsDir(), e.CommandName, extFile.Path)
filePath = path.Join(assets.GetExtensionsDir(), e.Manifest.Name, extFile.Path)
break
}
}
@@ -105,90 +133,196 @@ func (e *ExtensionManifest) getFileForTarget(cmdName string, targetOS string, ta
return filePath, nil
}
// ExtensionLoadCmd - Load extension command
func ExtensionLoadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExtensionLoadCmd - Load extension command.
func ExtensionLoadCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
dirPath := args[0]
// dirPath := ctx.Args.String("dir-path")
extCmd, err := LoadExtensionManifest(filepath.Join(dirPath, ManifestFileName))
manyfest, err := LoadExtensionManifest(filepath.Join(dirPath, ManifestFileName))
if err != nil {
return
}
// do not add if the command already exists
sliverMenu := con.App.Menu("implant")
if CmdExists(extCmd.CommandName, sliverMenu.Command) {
con.PrintErrorf("%s command already exists\n", extCmd.CommandName)
return
for _, extCmd := range manyfest.ExtCommand {
if CmdExists(extCmd.CommandName, sliverMenu.Command) {
con.PrintErrorf("%s command already exists\n", extCmd.CommandName)
confirm := false
prompt := &survey.Confirm{Message: "Overwrite current command?"}
survey.AskOne(prompt, &confirm)
if !confirm {
return
}
}
ExtensionRegisterCommand(extCmd, cmd.Root(), con)
con.PrintInfof("Added %s command: %s\n", extCmd.CommandName, extCmd.Help)
}
ExtensionRegisterCommand(extCmd, cmd.Root(), con)
con.PrintInfof("Added %s command: %s\n", extCmd.CommandName, extCmd.Help)
}
// LoadExtensionManifest - Parse extension files
// LoadExtensionManifest - Parse extension files.
func LoadExtensionManifest(manifestPath string) (*ExtensionManifest, error) {
data, err := os.ReadFile(manifestPath)
if err != nil {
return nil, err
}
extManifest, err := ParseExtensionManifest(data)
manifest, err := ParseExtensionManifest(data)
if err != nil {
return nil, err
}
extManifest.RootPath = filepath.Dir(manifestPath)
loadedExtensions[extManifest.CommandName] = extManifest
return extManifest, nil
manifest.RootPath = filepath.Dir(manifestPath)
for _, extManifest := range manifest.ExtCommand {
loadedExtensions[extManifest.CommandName] = extManifest
}
loadedManifests[manifest.Name] = manifest
return manifest, nil
}
// ParseExtensionManifest - Parse extension manifest from buffer
func convertOldManifest(old *ExtensionManifest_) *ExtensionManifest {
ret := &ExtensionManifest{
Name: old.CommandName, //treating old commandname as the manifest name to avoid weird chars mostly
Version: old.Version,
ExtensionAuthor: old.ExtensionAuthor,
OriginalAuthor: old.OriginalAuthor,
RepoURL: old.RepoURL,
RootPath: old.RootPath,
//only one command exists in the old manifest, so we can 'confidently' create it here
ExtCommand: []*ExtCommand{
{
CommandName: old.CommandName,
DependsOn: old.DependsOn,
Help: old.Help,
LongHelp: old.LongHelp,
Entrypoint: old.Entrypoint,
Files: old.Files,
Arguments: old.Arguments,
},
},
}
//Manifest ref is done in the parser that calls this
return ret
}
// parseExtensionManifest - Parse extension manifest from buffer (legacy, only parses one)
func ParseExtensionManifest(data []byte) (*ExtensionManifest, error) {
extManifest := &ExtensionManifest{}
err := json.Unmarshal(data, &extManifest)
if err != nil {
return nil, err
}
if extManifest.Name == "" {
return nil, errors.New("missing `name` field in extension manifest")
}
if extManifest.CommandName == "" {
return nil, errors.New("missing `command_name` field in extension manifest")
}
if len(extManifest.Files) == 0 {
return nil, errors.New("missing `files` field in extension manifest")
}
for _, extFiles := range extManifest.Files {
if extFiles.OS == "" {
return nil, errors.New("missing `files.os` field in extension manifest")
if err != nil || len(extManifest.ExtCommand) == 0 { //extensions must have at least one command to be sensible
//maybe it's an old manifest
log.Println(err)
oldmanifest := &ExtensionManifest_{}
err := json.Unmarshal(data, &oldmanifest)
if err != nil {
//nope, just broken
return nil, err
}
if extFiles.Arch == "" {
return nil, errors.New("missing `files.arch` field in extension manifest")
}
extFiles.Path = util.ResolvePath(extFiles.Path)
if extFiles.Path == "" || extFiles.Path == "/" {
return nil, errors.New("missing `files.path` field in extension manifest")
}
extFiles.OS = strings.ToLower(extFiles.OS)
extFiles.Arch = strings.ToLower(extFiles.Arch)
//yes, ok, lets jigger it to a new manifest
extManifest = convertOldManifest(oldmanifest)
}
if extManifest.Help == "" {
return nil, errors.New("missing `help` field in extension manifest")
//pass ref to manifest to each command
for i := range extManifest.ExtCommand {
extManifest.ExtCommand[i].Manifest = extManifest
}
return extManifest, nil
return extManifest, validManifest(extManifest)
}
func validManifest(manifest *ExtensionManifest) error {
if manifest.Name == "" {
return errors.New("missing `name` field in extension manifest")
}
for _, extManifest := range manifest.ExtCommand {
if extManifest.CommandName == "" {
return errors.New("missing `command_name` field in extension manifest")
}
if len(extManifest.Files) == 0 {
return errors.New("missing `files` field in extension manifest")
}
for _, extFiles := range extManifest.Files {
if extFiles.OS == "" {
return errors.New("missing `files.os` field in extension manifest")
}
if extFiles.Arch == "" {
return errors.New("missing `files.arch` field in extension manifest")
}
extFiles.Path = util.ResolvePath(extFiles.Path)
if extFiles.Path == "" || extFiles.Path == "/" {
return errors.New("missing `files.path` field in extension manifest")
}
extFiles.OS = strings.ToLower(extFiles.OS)
extFiles.Arch = strings.ToLower(extFiles.Arch)
}
if extManifest.Help == "" {
return errors.New("missing `help` field in extension manifest")
}
}
return nil
}
// ExtensionRegisterCommand - Register a new extension command
func ExtensionRegisterCommand(extCmd *ExtensionManifest, cmd *cobra.Command, con *console.SliverConsoleClient) {
func ExtensionRegisterCommand(extCmd *ExtCommand, cmd *cobra.Command, con *console.SliverClient) {
if errInvalidArgs := checkExtensionArgs(extCmd); errInvalidArgs != nil {
con.PrintErrorf(errInvalidArgs.Error())
return
}
loadedExtensions[extCmd.CommandName] = extCmd
helpMsg := extCmd.Help
//helpMsg := extCmd.Help
usage := strings.Builder{}
usage.WriteString(extCmd.CommandName)
//build usage including args
for _, arg := range extCmd.Arguments {
usage.WriteString(" ")
if arg.Optional {
usage.WriteString("[")
}
usage.WriteString(strings.ToUpper(arg.Name))
if arg.Optional {
usage.WriteString("]")
}
}
longHelp := strings.Builder{}
//prepend the help value, because otherwise I don't see where it is meant to be shown
//build the command ref
longHelp.WriteString("[[.Bold]]Command:[[.Normal]]")
longHelp.WriteString(usage.String())
longHelp.WriteString("\n")
if len(extCmd.Help) > 0 || len(extCmd.LongHelp) > 0 {
longHelp.WriteString("[[.Bold]]About:[[.Normal]]")
if len(extCmd.Help) > 0 {
longHelp.WriteString(extCmd.Help)
longHelp.WriteString("\n")
}
if len(extCmd.LongHelp) > 0 {
longHelp.WriteString(extCmd.LongHelp)
longHelp.WriteString("\n")
}
}
if len(extCmd.Arguments) > 0 {
longHelp.WriteString("[[.Bold]]Arguments:[[.Normal]]")
}
//if more than 0 args specified, describe each arg at the bottom of the long help text (incase the manifest doesn't include it)
for _, arg := range extCmd.Arguments {
longHelp.WriteString("\n\t")
optStr := ""
if arg.Optional {
optStr = "[OPTIONAL]"
}
aType := arg.Type
if aType == "wstring" {
aType = "string" //avoid confusion, as this is mostly for telling operator what to shove into the args
}
//idk how to make this look nice, tabs don't work especially good - maybe should use the table stuff other things do? Pls help.
longHelp.WriteString(fmt.Sprintf("%s (%s):\t%s%s", strings.ToUpper(arg.Name), aType, optStr, arg.Desc))
}
// Command
extensionCmd := &cobra.Command{
Use: extCmd.CommandName,
Short: helpMsg,
Long: help.FormatHelpTmpl(extCmd.LongHelp),
Use: usage.String(), //extCmd.CommandName,
//Short: helpMsg.String(), doesn't appear to be used?
Long: help.FormatHelpTmpl(longHelp.String()),
Run: func(cmd *cobra.Command, args []string) {
runExtensionCmd(cmd, con, args)
},
@@ -197,7 +331,7 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, cmd *cobra.Command, con
}
// Flags
f := pflag.NewFlagSet(extCmd.Name, pflag.ContinueOnError)
f := pflag.NewFlagSet(extCmd.CommandName, pflag.ContinueOnError)
f.BoolP("save", "s", false, "Save output to disk")
f.IntP("timeout", "t", defaultTimeout, "command timeout in seconds")
extensionCmd.Flags().AddFlagSet(f)
@@ -210,9 +344,9 @@ func ExtensionRegisterCommand(extCmd *ExtensionManifest, cmd *cobra.Command, con
cmd.AddCommand(extensionCmd)
}
func loadExtension(goos string, goarch string, checkCache bool, ext *ExtensionManifest, cmd *cobra.Command, con *console.SliverConsoleClient) error {
func loadExtension(goos string, goarch string, checkCache bool, ext *ExtCommand, cmd *cobra.Command, con *console.SliverClient) error {
var extensionList []string
binPath, err := ext.getFileForTarget(cmd.Name(), goos, goarch)
binPath, err := ext.getFileForTarget(goos, goarch)
if err != nil {
return err
}
@@ -233,10 +367,12 @@ func loadExtension(goos string, goarch string, checkCache bool, ext *ExtensionMa
}
depLoaded := false
for _, extName := range extensionList {
if !depLoaded && extName == ext.DependsOn {
depLoaded = true
if !depLoaded {
if extN, ok := loadedExtensions[cmd.Name()]; ok && extName == extN.DependsOn {
depLoaded = true
}
}
if ext.CommandName == extName {
if extN, ok := loadedExtensions[cmd.Name()]; ok && extN.CommandName == extName {
return nil
}
}
@@ -261,12 +397,12 @@ func loadExtension(goos string, goarch string, checkCache bool, ext *ExtensionMa
return nil
}
func registerExtension(goos string, ext *ExtensionManifest, binData []byte, cmd *cobra.Command, con *console.SliverConsoleClient) error {
func registerExtension(goos string, ext *ExtCommand, binData []byte, cmd *cobra.Command, con *console.SliverClient) error {
registerResp, err := con.Rpc.RegisterExtension(context.Background(), &sliverpb.RegisterExtensionReq{
Name: ext.CommandName,
Data: binData,
OS: goos,
Init: ext.Init,
Name: ext.CommandName,
Data: binData,
OS: goos,
//Init: ext.Init, ?
Request: con.ActiveTarget.Request(cmd),
})
if err != nil {
@@ -278,10 +414,10 @@ func registerExtension(goos string, ext *ExtensionManifest, binData []byte, cmd
return nil
}
func loadDep(goos string, goarch string, depName string, cmd *cobra.Command, con *console.SliverConsoleClient) error {
func loadDep(goos string, goarch string, depName string, cmd *cobra.Command, con *console.SliverClient) error {
depExt, ok := loadedExtensions[depName]
if ok {
depBinPath, err := depExt.getFileForTarget(depExt.CommandName, goos, goarch)
depBinPath, err := depExt.getFileForTarget(goos, goarch)
if err != nil {
return err
}
@@ -294,7 +430,7 @@ func loadDep(goos string, goarch string, depName string, cmd *cobra.Command, con
return fmt.Errorf("missing dependency %s", depName)
}
func runExtensionCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func runExtensionCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
var (
err error
extensionArgs []byte
@@ -327,7 +463,7 @@ func runExtensionCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
return
}
binPath, err := ext.getFileForTarget(cmd.Name(), goos, goarch)
binPath, err := ext.getFileForTarget(goos, goarch)
if err != nil {
con.PrintErrorf("Failed to read extension file: %s\n", err)
return
@@ -351,8 +487,17 @@ func runExtensionCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
entryPoint = loadedExtensions[extName].Entrypoint // should exist at this point
} else {
// Regular DLL
extArgs := strings.Join(args, " ")
extensionArgs = []byte(extArgs)
// extArgs := strings.Join(args, " ")
//legacy case - single string arg
if len(ext.Arguments) == 1 && ext.Arguments[0].Type == "string" {
extensionArgs = []byte(strings.Join(args, " "))
} else {
extensionArgs, err = getExtArgs(cmd, args, binPath, ext)
if err != nil {
con.PrintErrorf("ext args error: %s\n", err)
return
}
}
extName = ext.CommandName
entryPoint = ext.Entrypoint
}
@@ -388,8 +533,8 @@ func runExtensionCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
// PrintExtOutput - Print the ext execution output
func PrintExtOutput(extName string, commandName string, callExtension *sliverpb.CallExtension, con *console.SliverConsoleClient) {
// PrintExtOutput - Print the ext execution output.
func PrintExtOutput(extName string, commandName string, callExtension *sliverpb.CallExtension, con *console.SliverClient) {
if extName == commandName {
con.PrintInfof("Successfully executed %s", extName)
} else {
@@ -404,12 +549,8 @@ func PrintExtOutput(extName string, commandName string, callExtension *sliverpb.
}
}
func getBOFArgs(cmd *cobra.Command, args []string, binPath string, ext *ExtensionManifest) ([]byte, error) {
var extensionArgs []byte
binData, err := os.ReadFile(binPath)
if err != nil {
return nil, err
}
func getExtArgs(cmd *cobra.Command, args []string, binPath string, ext *ExtCommand) ([]byte, error) {
var err error
argsBuffer := core.BOFArgsBuffer{
Buffer: new(bytes.Buffer),
}
@@ -486,6 +627,17 @@ func getBOFArgs(cmd *cobra.Command, args []string, binPath string, ext *Extensio
if err != nil {
return nil, err
}
return parsedArgs, nil
}
func getBOFArgs(cmd *cobra.Command, args []string, binPath string, ext *ExtCommand) ([]byte, error) {
var extensionArgs []byte
binData, err := os.ReadFile(binPath)
if err != nil {
return nil, err
}
// Now build the extension's argument buffer
extensionArgsBuffer := core.BOFArgsBuffer{
Buffer: new(bytes.Buffer),
@@ -498,6 +650,10 @@ func getBOFArgs(cmd *cobra.Command, args []string, binPath string, ext *Extensio
if err != nil {
return nil, err
}
parsedArgs, err := getExtArgs(cmd, args, binPath, ext)
if err != nil {
return nil, err
}
err = extensionArgsBuffer.AddData(parsedArgs)
if err != nil {
return nil, err
@@ -509,7 +665,7 @@ func getBOFArgs(cmd *cobra.Command, args []string, binPath string, ext *Extensio
return extensionArgs, nil
}
// CmdExists - checks if a command exists
// CmdExists - checks if a command exists.
func CmdExists(name string, cmd *cobra.Command) bool {
for _, c := range cmd.Commands() {
if name == c.Name() {
@@ -520,7 +676,7 @@ func CmdExists(name string, cmd *cobra.Command) bool {
}
// makeExtensionArgParser builds the valid positional arguments cobra handler for the extension.
func checkExtensionArgs(extCmd *ExtensionManifest) error {
func checkExtensionArgs(extCmd *ExtCommand) error {
if 0 < len(extCmd.Arguments) {
for _, arg := range extCmd.Arguments {
switch arg.Type {
@@ -536,7 +692,7 @@ func checkExtensionArgs(extCmd *ExtensionManifest) error {
}
// makeExtensionArgCompleter builds the positional arguments completer for the extension.
func makeExtensionArgCompleter(extCmd *ExtensionManifest, _ *cobra.Command, comps *carapace.Carapace) {
func makeExtensionArgCompleter(extCmd *ExtCommand, _ *cobra.Command, comps *carapace.Carapace) {
var actions []carapace.Action
for _, arg := range extCmd.Arguments {
@@ -558,7 +714,7 @@ func makeExtensionArgCompleter(extCmd *ExtensionManifest, _ *cobra.Command, comp
comps.PositionalCompletion(actions...)
}
func makeCommandPlatformFilters(extCmd *ExtensionManifest) map[string]string {
func makeCommandPlatformFilters(extCmd *ExtCommand) map[string]string {
filtersOS := make(map[string]bool)
filtersArch := make(map[string]bool)
+40 -9
View File
@@ -25,15 +25,14 @@ import (
"path/filepath"
"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/bishopfox/sliver/client/assets"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
)
// ExtensionsRemoveCmd - Remove an extension
func ExtensionsRemoveCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ExtensionsRemoveCmd - Remove an extension.
func ExtensionsRemoveCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
name := args[0]
if name == "" {
con.PrintErrorf("Extension name is required\n")
@@ -45,17 +44,27 @@ func ExtensionsRemoveCmd(cmd *cobra.Command, con *console.SliverConsoleClient, a
if !confirm {
return
}
err := RemoveExtensionByCommandName(name, con)
found, err := RemoveExtensionByManifestName(name, con)
if err != nil {
con.PrintErrorf("Error removing extension: %s\n", err)
con.PrintErrorf("Error removing extensions: %s\n", err)
return
}
if !found {
err = RemoveExtensionByCommandName(name, con)
if err != nil {
con.PrintErrorf("Error removing extension: %s\n", err)
return
} else {
con.PrintInfof("Extension '%s' removed\n", name)
}
} else {
con.PrintInfof("Extension '%s' removed\n", name)
//found, and no error, manifest must have removed good
con.PrintInfof("Extensions from %s removed\n", name)
}
}
// RemoveExtensionByCommandName - Remove an extension by command name
func RemoveExtensionByCommandName(commandName string, con *console.SliverConsoleClient) error {
// RemoveExtensionByCommandName - Remove an extension by command name.
func RemoveExtensionByCommandName(commandName string, con *console.SliverClient) error {
if commandName == "" {
return errors.New("command name is required")
}
@@ -71,6 +80,28 @@ func RemoveExtensionByCommandName(commandName string, con *console.SliverConsole
return nil
}
// RemoveExtensionByManifestName - remove by the named manifest, returns true if manifest was removed, false if no manifest with that name was found
func RemoveExtensionByManifestName(manifestName string, con *console.SliverClient) (bool, error) {
if manifestName == "" {
return false, errors.New("command name is required")
}
if man, ok := loadedManifests[manifestName]; ok {
//foudn the manifest
//delet it
extPath := filepath.Join(assets.GetExtensionsDir(), filepath.Base(manifestName))
if _, err := os.Stat(extPath); os.IsNotExist(err) {
return true, nil
}
forceRemoveAll(extPath)
delete(loadedManifests, manifestName)
for _, cmd := range man.ExtCommand {
delete(loadedExtensions, cmd.CommandName)
}
return true, nil
}
return false, nil
}
func forceRemoveAll(rootPath string) {
util.ChmodR(rootPath, 0o600, 0o700)
os.RemoveAll(rootPath)
+6 -7
View File
@@ -27,18 +27,17 @@ import (
"github.com/alecthomas/chroma/formatters"
"github.com/alecthomas/chroma/lexers"
"github.com/alecthomas/chroma/styles"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"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/bishopfox/sliver/util/encoders"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// CatCmd - Display the contents of a remote file
func CatCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CatCmd - Display the contents of a remote file.
func CatCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -81,8 +80,8 @@ func CatCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
}
}
// PrintCat - Print the download to stdout
func PrintCat(download *sliverpb.Download, cmd *cobra.Command, con *console.SliverConsoleClient) {
// PrintCat - Print the download to stdout.
func PrintCat(download *sliverpb.Download, cmd *cobra.Command, con *console.SliverClient) {
var (
lootDownload bool = true
err error
+4 -6
View File
@@ -21,17 +21,15 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// CdCmd - Change directory on the remote system
func CdCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CdCmd - Change directory on the remote system.
func CdCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
+6 -8
View File
@@ -20,17 +20,15 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// ChmodCmd - Change the permissions of a file on the remote file system
func ChmodCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ChmodCmd - Change the permissions of a file on the remote file system.
func ChmodCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -77,8 +75,8 @@ func ChmodCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []strin
}
}
// PrintChmod - Print the chmod response
func PrintChmod(chmod *sliverpb.Chmod, con *console.SliverConsoleClient) {
// PrintChmod - Print the chmod response.
func PrintChmod(chmod *sliverpb.Chmod, con *console.SliverClient) {
if chmod.Response != nil && chmod.Response.Err != "" {
con.PrintErrorf("%s\n", chmod.Response.Err)
return
+6 -8
View File
@@ -20,17 +20,15 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// ChownCmd - Change the owner of a file on the remote file system
func ChownCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ChownCmd - Change the owner of a file on the remote file system.
func ChownCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -85,8 +83,8 @@ func ChownCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []strin
}
}
// PrintChown - Print the chown response
func PrintChown(chown *sliverpb.Chown, con *console.SliverConsoleClient) {
// PrintChown - Print the chown response.
func PrintChown(chown *sliverpb.Chown, con *console.SliverClient) {
if chown.Response != nil && chown.Response.Err != "" {
con.PrintErrorf("%s\n", chown.Response.Err)
return
+6 -8
View File
@@ -21,17 +21,15 @@ import (
"context"
"time"
"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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// ChtimesCmd - Change the access and modified time of a file on the remote file system
func ChtimesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// ChtimesCmd - Change the access and modified time of a file on the remote file system.
func ChtimesCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -98,8 +96,8 @@ func ChtimesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []str
}
}
// PrintChtimes - Print the Chtimes response
func PrintChtimes(chtimes *sliverpb.Chtimes, con *console.SliverConsoleClient) {
// PrintChtimes - Print the Chtimes response.
func PrintChtimes(chtimes *sliverpb.Chtimes, con *console.SliverClient) {
if chtimes.Response != nil && chtimes.Response.Err != "" {
con.PrintErrorf("%s\n", chtimes.Response.Err)
return
+246
View File
@@ -0,0 +1,246 @@
package filesystem
import (
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/command/loot"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
mvCmd := &cobra.Command{
Use: consts.MvStr,
Short: "Move or rename a file",
Long: help.GetHelpFor([]string{consts.MvStr}),
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
MvCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, mvCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(mvCmd).PositionalCompletion(
carapace.ActionValues().Usage("path to source file (required)"),
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) {
CpCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, cpCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.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",
Long: help.GetHelpFor([]string{consts.LsStr}),
Args: cobra.RangeArgs(0, 1),
Run: func(cmd *cobra.Command, args []string) {
LsCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, lsCmd, func(f *pflag.FlagSet) {
f.BoolP("reverse", "r", false, "reverse sort order")
f.BoolP("modified", "m", false, "sort by modified time")
f.BoolP("size", "s", false, "sort by size")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(lsCmd).PositionalCompletion(carapace.ActionValues().Usage("path to enumerate (optional)"))
rmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a file or directory",
Long: help.GetHelpFor([]string{consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
RmCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, rmCmd, func(f *pflag.FlagSet) {
f.BoolP("recursive", "r", false, "recursively remove files")
f.BoolP("force", "F", false, "ignore safety and forcefully remove files")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(rmCmd).PositionalCompletion(carapace.ActionValues().Usage("path to the file to remove"))
mkdirCmd := &cobra.Command{
Use: consts.MkdirStr,
Short: "Make a directory",
Long: help.GetHelpFor([]string{consts.MkdirStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
MkdirCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, mkdirCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(mkdirCmd).PositionalCompletion(carapace.ActionValues().Usage("path to the directory to create"))
cdCmd := &cobra.Command{
Use: consts.CdStr,
Short: "Change directory",
Long: help.GetHelpFor([]string{consts.CdStr}),
Args: cobra.RangeArgs(0, 1),
Run: func(cmd *cobra.Command, args []string) {
CdCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, cdCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(cdCmd).PositionalCompletion(carapace.ActionValues().Usage("path to the directory"))
pwdCmd := &cobra.Command{
Use: consts.PwdStr,
Short: "Print working directory",
Long: help.GetHelpFor([]string{consts.PwdStr}),
Run: func(cmd *cobra.Command, args []string) {
PwdCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, pwdCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
catCmd := &cobra.Command{
Use: consts.CatStr,
Short: "Dump file to stdout",
Long: help.GetHelpFor([]string{consts.CatStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
CatCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, catCmd, 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", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(catCmd).PositionalCompletion(carapace.ActionValues().Usage("path to the file to print"))
downloadCmd := &cobra.Command{
Use: consts.DownloadStr,
Short: "Download a file",
Long: help.GetHelpFor([]string{consts.DownloadStr}),
Args: cobra.RangeArgs(1, 2),
Run: func(cmd *cobra.Command, args []string) {
DownloadCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, downloadCmd, func(f *pflag.FlagSet) {
f.BoolP("loot", "X", false, "save output as loot")
f.StringP("type", "T", "", "force a specific loot type (file/cred) if looting")
f.StringP("file-type", "F", "", "force a specific file type (binary/text) if looting")
f.StringP("name", "n", "", "name to assign the download if looting")
f.BoolP("recurse", "r", false, "recursively download all files in a directory")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
flags.BindFlagCompletions(downloadCmd, func(comp *carapace.ActionMap) {
(*comp)["type"] = loot.LootTypeCompleter(con)
(*comp)["file-type"] = loot.FileTypeCompleter(con)
})
carapace.Gen(downloadCmd).PositionalCompletion(
carapace.ActionValues().Usage("path to the file or directory to download"),
carapace.ActionFiles().Usage("local path where the downloaded file will be saved (optional)"),
)
uploadCmd := &cobra.Command{
Use: consts.UploadStr,
Short: "Upload a file",
Long: help.GetHelpFor([]string{consts.UploadStr}),
Args: cobra.RangeArgs(1, 2),
Run: func(cmd *cobra.Command, args []string) {
UploadCmd(cmd, con, args)
},
GroupID: consts.FilesystemHelpGroup,
}
flags.Bind("", false, uploadCmd, func(f *pflag.FlagSet) {
f.BoolP("ioc", "i", false, "track uploaded file as an ioc")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
carapace.Gen(uploadCmd).PositionalCompletion(
carapace.ActionFiles().Usage("local path to the file to upload"),
carapace.ActionValues().Usage("path to the file or directory to upload to (optional)"),
)
memfilesCmd := &cobra.Command{
Use: consts.MemfilesStr,
Short: "List current memfiles",
Long: help.GetHelpFor([]string{consts.MemfilesStr}),
GroupID: consts.FilesystemHelpGroup,
Run: func(cmd *cobra.Command, args []string) {
MemfilesListCmd(cmd, con, args)
},
}
flags.Bind("", true, memfilesCmd, func(f *pflag.FlagSet) {
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
memfilesAddCmd := &cobra.Command{
Use: consts.AddStr,
Short: "Add a memfile",
Long: help.GetHelpFor([]string{consts.MemfilesStr, consts.AddStr}),
Run: func(cmd *cobra.Command, args []string) {
MemfilesAddCmd(cmd, con, args)
},
}
memfilesCmd.AddCommand(memfilesAddCmd)
memfilesRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a memfile",
Long: help.GetHelpFor([]string{consts.MemfilesStr, consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
MemfilesRmCmd(cmd, con, args)
},
}
memfilesCmd.AddCommand(memfilesRmCmd)
carapace.Gen(memfilesRmCmd).PositionalCompletion(carapace.ActionValues().Usage("memfile file descriptor"))
return []*cobra.Command{
mvCmd,
cpCmd,
lsCmd,
rmCmd,
mkdirCmd,
pwdCmd,
catCmd,
cdCmd,
downloadCmd,
uploadCmd,
memfilesCmd,
}
}
+4 -6
View File
@@ -21,16 +21,14 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
func CpCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) (err error) {
func CpCmd(cmd *cobra.Command, con *console.SliverClient, args []string) (err error) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -72,7 +70,7 @@ func CpCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
return
}
func PrintCp(cp *sliverpb.Cp, con *console.SliverConsoleClient) {
func PrintCp(cp *sliverpb.Cp, con *console.SliverClient) {
if cp.Response != nil && cp.Response.Err != "" {
con.PrintErrorf("%s\n", cp.Response.Err)
return
+5 -6
View File
@@ -28,18 +28,17 @@ import (
"strings"
"time"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"gopkg.in/AlecAivazis/survey.v1"
"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/bishopfox/sliver/util/encoders"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"gopkg.in/AlecAivazis/survey.v1"
)
func DownloadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func DownloadCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -105,7 +104,7 @@ func prettifyDownloadName(path string) string {
return filteredString
}
func HandleDownloadResponse(download *sliverpb.Download, cmd *cobra.Command, args []string, con *console.SliverConsoleClient) {
func HandleDownloadResponse(download *sliverpb.Download, cmd *cobra.Command, args []string, con *console.SliverClient) {
var err error
if download.Response != nil && download.Response.Err != "" {
con.PrintErrorf("%s\n", download.Response.Err)
+2 -2
View File
@@ -83,7 +83,7 @@ func processFlags(searchPattern string, insensitive bool, exact bool) string {
return processedSearchPattern
}
func GrepCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func GrepCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -152,7 +152,7 @@ func GrepCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string
}
// 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) {
func printGrep(grep *sliverpb.Grep, searchPattern string, searchPath string, cmd *cobra.Command, con *console.SliverClient) {
saveLoot, _ := cmd.Flags().GetBool("loot")
lootName, _ := cmd.Flags().GetString("name")
colorize, _ := cmd.Flags().GetBool("colorize-output")
+1 -1
View File
@@ -29,7 +29,7 @@ import (
"google.golang.org/protobuf/proto"
)
func HeadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string, head bool) {
func HeadCmd(cmd *cobra.Command, con *console.SliverClient, args []string, head bool) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
+7 -9
View File
@@ -27,19 +27,17 @@ import (
"text/tabwriter"
"time"
"google.golang.org/protobuf/proto"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/protobuf/proto"
)
// LsCmd - List the contents of a remote directory
func LsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// LsCmd - List the contents of a remote directory.
func LsCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -75,8 +73,8 @@ func LsCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
}
}
// PrintLs - Display an sliverpb.Ls object
func PrintLs(ls *sliverpb.Ls, flags *pflag.FlagSet, con *console.SliverConsoleClient) {
// PrintLs - Display an sliverpb.Ls object.
func PrintLs(ls *sliverpb.Ls, flags *pflag.FlagSet, con *console.SliverClient) {
if ls.Response != nil && ls.Response.Err != "" {
con.PrintErrorf("%s\n", ls.Response.Err)
return
+6 -7
View File
@@ -20,16 +20,15 @@ package filesystem
import (
"context"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"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"
)
// MemfilesAddCmd - Add memfile
func MemfilesAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// MemfilesAddCmd - Add memfile.
func MemfilesAddCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -57,8 +56,8 @@ func MemfilesAddCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args [
}
}
// PrintAddMemfile - Print the memfiles response
func PrintAddMemfile(memfilesAdd *sliverpb.MemfilesAdd, con *console.SliverConsoleClient) {
// PrintAddMemfile - Print the memfiles response.
func PrintAddMemfile(memfilesAdd *sliverpb.MemfilesAdd, con *console.SliverClient) {
if memfilesAdd.Response != nil && memfilesAdd.Response.Err != "" {
con.PrintErrorf("%s\n", memfilesAdd.Response.Err)
return
+6 -7
View File
@@ -25,17 +25,16 @@ import (
"text/tabwriter"
"time"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// MemfilesListCmd - List memfiles
func MemfilesListCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// MemfilesListCmd - List memfiles.
func MemfilesListCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -63,8 +62,8 @@ func MemfilesListCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args
}
}
// PrintMemfiles - Display an sliverpb.Ls object
func PrintMemfiles(ls *sliverpb.Ls, con *console.SliverConsoleClient) {
// PrintMemfiles - Display an sliverpb.Ls object.
func PrintMemfiles(ls *sliverpb.Ls, con *console.SliverClient) {
if ls.Response != nil && ls.Response.Err != "" {
con.PrintErrorf("%s\n", ls.Response.Err)
return
+6 -7
View File
@@ -21,16 +21,15 @@ import (
"context"
"strconv"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"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"
)
// MemfilesRmCmd - Remove a memfile
func MemfilesRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// MemfilesRmCmd - Remove a memfile.
func MemfilesRmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -70,8 +69,8 @@ func MemfilesRmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []
}
}
// PrintRmMemfile - Remove a memfile
func PrintRmMemfile(memfilesList *sliverpb.MemfilesRm, con *console.SliverConsoleClient) {
// PrintRmMemfile - Remove a memfile.
func PrintRmMemfile(memfilesList *sliverpb.MemfilesRm, con *console.SliverClient) {
if memfilesList.Response != nil && memfilesList.Response.Err != "" {
con.PrintErrorf("%s\n", memfilesList.Response.Err)
return
+6 -8
View File
@@ -21,17 +21,15 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// MkdirCmd - Make a remote directory
func MkdirCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// MkdirCmd - Make a remote directory.
func MkdirCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -68,8 +66,8 @@ func MkdirCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []strin
}
}
// PrintMkdir - Print make directory
func PrintMkdir(mkdir *sliverpb.Mkdir, con *console.SliverConsoleClient) {
// PrintMkdir - Print make directory.
func PrintMkdir(mkdir *sliverpb.Mkdir, con *console.SliverClient) {
if mkdir.Response != nil && mkdir.Response.Err != "" {
con.PrintErrorf("%s\n", mkdir.Response.Err)
return
+5 -7
View File
@@ -21,16 +21,14 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
func MvCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) (err error) {
func MvCmd(cmd *cobra.Command, con *console.SliverClient, args []string) (err error) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -77,8 +75,8 @@ func MvCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
return
}
// PrintMv - Print the renamed file
func PrintMv(mv *sliverpb.Mv, con *console.SliverConsoleClient) {
// PrintMv - Print the renamed file.
func PrintMv(mv *sliverpb.Mv, con *console.SliverClient) {
if mv.Response != nil && mv.Response.Err != "" {
con.PrintErrorf("%s\n", mv.Response.Err)
return
+6 -8
View File
@@ -21,17 +21,15 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// PwdCmd - Print the remote working directory
func PwdCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// PwdCmd - Print the remote working directory.
func PwdCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -58,8 +56,8 @@ func PwdCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
}
}
// PrintPwd - Print the remote working directory
func PrintPwd(pwd *sliverpb.Pwd, con *console.SliverConsoleClient) {
// PrintPwd - Print the remote working directory.
func PrintPwd(pwd *sliverpb.Pwd, con *console.SliverClient) {
if pwd.Response != nil && pwd.Response.Err != "" {
con.PrintErrorf("%s\n", pwd.Response.Err)
return
+6 -8
View File
@@ -21,17 +21,15 @@ package filesystem
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"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
// RmCmd - Remove a directory from the remote file system
func RmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// RmCmd - Remove a directory from the remote file system.
func RmCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -73,8 +71,8 @@ func RmCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string)
}
}
// PrintRm - Print the rm response
func PrintRm(rm *sliverpb.Rm, con *console.SliverConsoleClient) {
// PrintRm - Print the rm response.
func PrintRm(rm *sliverpb.Rm, con *console.SliverClient) {
if rm.Response != nil && rm.Response.Err != "" {
con.PrintErrorf("%s\n", rm.Response.Err)
return
+354 -26
View File
@@ -19,23 +19,259 @@ package filesystem
*/
import (
"archive/tar"
"bytes"
"context"
"errors"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"google.golang.org/protobuf/proto"
"github.com/spf13/cobra"
"strings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/implant/sliver/handlers/matcher"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util/encoders"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
)
func determineDirPathFilter(targetPath string) (string, string) {
// The filter
filter := ""
// The path the filter applies to
path := ""
/*
Check to see if the remote path is a filter or contains a filter.
If the path passes the test to be a filter, then it is a filter
because paths are not valid filters.
*/
if targetPath != "." {
// Check if the path contains a filter
// Test on a standardized version of the path (change any \ to /)
testPath := strings.Replace(targetPath, "\\", "/", -1)
/*
Cannot use the path or filepath libraries because the OS
of the client does not necessarily match the OS of the
implant
*/
lastSeparatorOccurrence := strings.LastIndex(testPath, "/")
if lastSeparatorOccurrence == -1 {
// Then this is only a filter
filter = targetPath
path = "."
} else {
// Then we need to test for a filter on the end of the string
// The indices should be the same because we did not change the length of the string
path = targetPath[:lastSeparatorOccurrence+1]
filter = targetPath[lastSeparatorOccurrence+1:]
}
} else {
path = targetPath
// filter remains blank
}
return path, filter
}
func standarizeArchiveFileName(path string, uploadPathSpecified string) string {
// Change all backslashes to forward slashes
var standardFilePath string = strings.ReplaceAll(path, "\\", "/")
var standardUploadPath string = strings.ReplaceAll(uploadPathSpecified, "\\", "/")
/*
Remove the volume / root from the directory
path. This makes it so that files on the
system where the archive is extracted to
will not be clobbered.
Tried with filepath.VolumeName, but that function
does not work reliably with Windows paths
*/
if strings.HasPrefix(standardFilePath, "//") {
// If this a UNC path, filepath.Rel is not going to work
return standardFilePath[2:]
} else {
beginningOfUploadPath, _, _ := strings.Cut(standardUploadPath, "/")
if index := strings.Index(standardFilePath, beginningOfUploadPath); index != -1 {
// Add a / in front to make the specified upload path the root
standardFilePath = "/" + standardFilePath[index:]
}
// Calculate a path relative to the root
pathParts := strings.SplitN(standardFilePath, "/", 2)
if len(pathParts) < 2 {
// Then something is wrong with this path
return standardFilePath
}
basePath := pathParts[0]
fileRelPath := pathParts[1]
if basePath == "" {
// If base path is blank, that means it started with / and / is the root
return fileRelPath
} else {
/*
Then this is almost certainly Windows, and we will set the archive up
so that it preserves the path but without the colon.
Something like:
c/windows/system32/file.whatever
Colons are not legal in Windows filenames, so let's get rid of them.
*/
basePath = strings.ReplaceAll(basePath, ":", "")
basePath = strings.ToLower(basePath)
return basePath + "/" + fileRelPath
}
}
}
func tarDirectory(sourcePath string, pathAsSpecified string, sourceFilter string, recurse bool, preserveDirStructure bool) ([]byte, int, int, error) {
readFiles := 0
unreadableFiles := 0
var matchingFiles []string
var buffer bytes.Buffer
tarWriter := tar.NewWriter(&buffer)
/*
Build the list of files to include in the archive.
Walking the directory can take a long time and do a lot of unnecessary work
if we do not need to recurse through subdirectories.
If we are not recursing, then read the directory without worrying about
subdirectories.
*/
if !recurse {
testPath := strings.ReplaceAll(sourcePath, "\\", "/")
directory, err := os.Open(sourcePath)
if err != nil {
return nil, readFiles, unreadableFiles, err
}
directoryFiles, err := directory.Readdirnames(0)
directory.Close()
if err != nil {
return nil, readFiles, unreadableFiles, err
}
for _, fileName := range directoryFiles {
standardFileName := strings.ReplaceAll(testPath+fileName, "\\", "/")
if sourceFilter != "" {
match, err := matcher.Match(sourcePath+sourceFilter, standardFileName)
if err == nil && match {
matchingFiles = append(matchingFiles, standardFileName)
}
} else {
matchingFiles = append(matchingFiles, standardFileName)
}
}
} else {
filepath.WalkDir(sourcePath, func(file string, d os.DirEntry, err error) error {
filePath := strings.ReplaceAll(file, "\\", "/")
if sourceFilter != "" {
// Normalize paths
testPath := strings.ReplaceAll(filepath.Dir(file), "\\", "/") + "/"
match, matchErr := matcher.Match(testPath+sourceFilter, filePath)
if !match || matchErr != nil {
// If there is an error, it is because the filter is bad, so it is not a match
return nil
}
matchingFiles = append(matchingFiles, file)
} else {
matchingFiles = append(matchingFiles, file)
}
return nil
})
}
var fileName string
for _, file := range matchingFiles {
fi, err := os.Stat(file)
if err != nil {
// Cannot get info on the file, so skip it
unreadableFiles += 1
continue
}
if preserveDirStructure {
fileName = standarizeArchiveFileName(file, pathAsSpecified)
} else {
fileName = fi.Name()
}
// 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 {
unreadableFiles += 1
continue
}
fi, err = os.Lstat(file)
if err != nil {
unreadableFiles += 1
continue
}
}
header, err := tar.FileInfoHeader(fi, file)
if err != nil {
unreadableFiles += 1
continue
}
// Keep the symlink file path for the header name.
header.Name = filepath.ToSlash(fileName)
// Check that we can open the file before we try to write it to the archive
if !fi.IsDir() {
data, err := os.Open(file)
if err != nil {
// Skip this file and do not write it to the archive.
unreadableFiles += 1
continue
}
if err := tarWriter.WriteHeader(header); err != nil {
unreadableFiles += 1
data.Close()
continue
}
if _, err := io.Copy(tarWriter, data); err != nil {
unreadableFiles += 1
data.Close()
continue
}
data.Close()
readFiles += 1
} else {
if err := tarWriter.WriteHeader(header); err != nil {
unreadableFiles += 1
continue
}
}
}
if err := tarWriter.Close(); err != nil {
return buffer.Bytes(), readFiles, unreadableFiles, err
}
return buffer.Bytes(), readFiles, unreadableFiles, nil
}
// UploadCmd - Upload a file to the remote system
func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
func UploadCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
readFiles := 0
unreadableFiles := 0
var isDirectory bool
var fileName string
var sourceInfomation fs.FileInfo
var uploadData []byte
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
@@ -48,9 +284,10 @@ func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
remotePath = args[1]
}
// localPath := ctx.Args.String("local-path")
// remotePath := ctx.Args.String("remote-path")
recurse, _ := cmd.Flags().GetBool("recurse")
preserve, _ := cmd.Flags().GetBool("preserve")
isIOC, _ := cmd.Flags().GetBool("ioc")
overwrite, _ := cmd.Flags().GetBool("overwrite")
if localPath == "" {
con.PrintErrorf("Missing parameter, see `help upload`\n")
@@ -58,12 +295,6 @@ func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
}
src, _ := filepath.Abs(localPath)
_, err := os.Stat(src)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
fileName := filepath.Base(src)
if remotePath == "" {
remotePath = fileName
@@ -71,22 +302,103 @@ func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
dst := remotePath
fileBuf, err := os.ReadFile(src)
// Get information on the source - is it a directory?
srcPath, srcFilter := determineDirPathFilter(src)
sourceInfomation, err := os.Stat(src)
if err == nil && sourceInfomation.IsDir() {
if !strings.HasSuffix(src, string(os.PathSeparator)) {
src += string(os.PathSeparator)
}
srcPath = src
srcFilter = ""
}
if err != nil {
con.PrintErrorf("%s\n", err)
if errors.Is(err, fs.ErrNotExist) {
// Check to see if src ends with a filter
sourceInfomation, err = os.Stat(srcPath)
if errors.Is(err, fs.ErrNotExist) {
con.PrintErrorf("The source %s does not exist.\n", src)
return
} else if errors.Is(err, fs.ErrPermission) {
con.PrintErrorf("Permissions error when trying to read %s.\n", src)
return
}
}
if errors.Is(err, fs.ErrPermission) {
con.PrintErrorf("Permissions error when trying to read %s.\n", src)
return
}
}
// If we still do not have information about the source at this point, bail.
if sourceInfomation == nil {
con.PrintErrorf("Could not get information about the upload source %s\n", src)
return
}
uploadGzip, _ := new(encoders.Gzip).Encode(fileBuf)
if sourceInfomation.IsDir() {
// tar the directory and send it over
uploadData, readFiles, unreadableFiles, err = tarDirectory(srcPath, localPath, srcFilter, recurse, preserve)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if readFiles == 0 {
con.PrintErrorf("Could not find any files matching %s\n", src)
return
}
isDirectory = true
fileName = ""
} else {
uploadData, err = os.ReadFile(src)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
readFiles = 1
unreadableFiles = 0
isDirectory = false
fileName = filepath.Base(src)
}
uploadGzip, _ := new(encoders.Gzip).Encode(uploadData)
var readFilesQualifier string
var unsuccessfulFiles string
if readFiles == 1 {
readFilesQualifier = ""
} else {
readFilesQualifier = "s"
}
if unreadableFiles > 0 {
if unreadableFiles == 1 {
unsuccessfulFiles = fmt.Sprintf(" (could not read %d file)", unreadableFiles)
} else {
unsuccessfulFiles = fmt.Sprintf(" (could not read %d files)", unreadableFiles)
}
} else {
unsuccessfulFiles = ""
}
ctrl := make(chan bool)
con.SpinUntil(fmt.Sprintf("%s -> %s", src, dst), ctrl)
con.SpinUntil(fmt.Sprintf("Uploading %d file%s %sfrom %s to %s", readFiles,
readFilesQualifier,
unsuccessfulFiles,
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,
FileName: fileName,
Request: con.ActiveTarget.Request(cmd),
Path: dst,
Data: uploadGzip,
Encoder: "gzip",
IsIOC: isIOC,
FileName: fileName,
IsDirectory: isDirectory,
Overwrite: overwrite,
})
ctrl <- true
<-ctrl
@@ -109,11 +421,27 @@ func UploadCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []stri
}
}
// PrintUpload - Print the result of the upload command
func PrintUpload(upload *sliverpb.Upload, con *console.SliverConsoleClient) {
// PrintUpload - Print the result of the upload command.
func PrintUpload(upload *sliverpb.Upload, con *console.SliverClient) {
if upload.Response != nil && upload.Response.Err != "" {
con.PrintErrorf("%s\n", upload.Response.Err)
return
}
con.PrintInfof("Wrote file to %s\n", upload.Path)
writtenFileQualifier := "s"
if upload.WrittenFiles == 1 {
writtenFileQualifier = ""
}
unwrittenFileQualifier := "s"
if upload.UnwriteableFiles == 1 {
unwrittenFileQualifier = ""
}
if upload.WrittenFiles > 0 {
if upload.UnwriteableFiles > 0 {
con.PrintInfof("Wrote %d file%s successfully (%d file%s not written) to %s\n", upload.WrittenFiles, writtenFileQualifier, upload.UnwriteableFiles, unwrittenFileQualifier, upload.Path)
} else {
con.PrintInfof("Wrote %d file%s successfully to %s\n", upload.WrittenFiles, writtenFileQualifier, upload.Path)
}
} else {
con.PrintInfof("Could not write %d file%s to %s: the files already exist on the target\n", upload.UnwriteableFiles, unwrittenFileQualifier, upload.Path)
}
}
+75
View File
@@ -0,0 +1,75 @@
package flags
import (
"strings"
"github.com/reeflective/console"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
const (
DefaultTimeout = 60
)
// Bind is a convenience function to bind flags to a command, through newly created
// pflag.Flagset type. This function can be called any number of times for any command.
// desc - An optional name for the flag set (can be empty, but might end up useful).
// persistent - If true, the flags bound will apply to all subcommands of this command.
// cmd - The pointer to the command the flags should be bound to.
// flags - A function using this flag set as parameter, for you to register flags.
func Bind(desc string, persistent bool, cmd *cobra.Command, flags func(f *pflag.FlagSet)) {
flagSet := pflag.NewFlagSet(desc, pflag.ContinueOnError)
flags(flagSet)
if persistent {
cmd.PersistentFlags().AddFlagSet(flagSet)
} else {
cmd.Flags().AddFlagSet(flagSet)
}
}
// RestrictTargets generates a cobra annotation map with a single console.CommandHiddenFilter key
// to a comma-separated list of filters to use in order to expose/hide commands based on requirements.
// Ex: cmd.Annotations = RestrictTargets("windows") will only show the command if the target is Windows.
// Ex: cmd.Annotations = RestrictTargets("windows", "beacon") show the command if target is a beacon on Windows.
func RestrictTargets(filters ...string) map[string]string {
if len(filters) == 0 {
return nil
}
if len(filters) == 1 {
return map[string]string{
console.CommandFilterKey: filters[0],
}
}
filts := strings.Join(filters, ",")
return map[string]string{
console.CommandFilterKey: filts,
}
}
// NewCompletions registers the command to the application completion engine and returns
// you a type through which you can register all sorts of completions for this command,
// from flag arguments, positional ones, per index or remaining, etc.
//
// See https://rsteube.github.io/carapace/ for a complete documentation of carapace completions.
func NewCompletions(cmd *cobra.Command) *carapace.Carapace {
return carapace.Gen(cmd)
}
// BindFlagCompletions is a convenience function for binding completers to flags requiring arguments.
// (It wraps a few steps to be used through the *carapace.Carapace type so you don't have to bother).
// cmd - The target command/subcommand which flags to be completed.
// bind - A function using a map "flag-name":carapace.Action for you to bind completions to the flag.
//
// See https://rsteube.github.io/carapace/ for a complete documentation of carapace completions.
func BindFlagCompletions(cmd *cobra.Command, bind func(comp *carapace.ActionMap)) {
comps := make(carapace.ActionMap)
bind(&comps)
carapace.Gen(cmd).FlagCompletion(comps)
}
+6 -7
View File
@@ -4,17 +4,16 @@ import (
"context"
"fmt"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
"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"
)
// CanariesCmd - Display canaries from the database and their status
func CanariesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []string) {
// CanariesCmd - Display canaries from the database and their status.
func CanariesCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
canaries, err := con.Rpc.Canaries(context.Background(), &commonpb.Empty{})
if err != nil {
con.PrintErrorf("Failed to list canaries %s", err)
@@ -28,8 +27,8 @@ func CanariesCmd(cmd *cobra.Command, con *console.SliverConsoleClient, args []st
}
}
// PrintCanaries - Print the canaries tracked by the server
func PrintCanaries(con *console.SliverConsoleClient, canaries []*clientpb.DNSCanary, burnedOnly bool) {
// PrintCanaries - Print the canaries tracked by the server.
func PrintCanaries(con *console.SliverClient, canaries []*clientpb.DNSCanary, burnedOnly bool) {
tw := table.NewWriter()
tw.SetStyle(settings.GetTableStyle(con))
tw.AppendHeader(table.Row{
+369
View File
@@ -0,0 +1,369 @@
package generate
import (
"github.com/bishopfox/sliver/client/command/flags"
"github.com/bishopfox/sliver/client/command/help"
"github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// Commands returns the “ command and its subcommands.
func Commands(con *console.SliverClient) []*cobra.Command {
// [ Generate ] --------------------------------------------------------------
generateCmd := &cobra.Command{
Use: consts.GenerateStr,
Short: "Generate an implant binary",
Long: help.GetHelpFor([]string{consts.GenerateStr}),
Run: func(cmd *cobra.Command, args []string) {
GenerateCmd(cmd, con, args)
},
GroupID: consts.PayloadsHelpGroup,
}
flags.Bind("generate", true, generateCmd, func(f *pflag.FlagSet) {
f.IntP("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
// Session flags and completions.
coreImplantFlags("session", generateCmd)
compileImplantFlags("session", generateCmd)
coreImplantFlagCompletions(generateCmd, con)
generateBeaconCmd := &cobra.Command{
Use: consts.BeaconStr,
Short: "Generate a beacon binary",
Long: help.GetHelpFor([]string{consts.GenerateStr, consts.BeaconStr}),
Run: func(cmd *cobra.Command, args []string) {
GenerateBeaconCmd(cmd, con, args)
},
}
// Beacon flags and completions.
coreImplantFlags("beacon", generateBeaconCmd)
compileImplantFlags("beacon", generateBeaconCmd)
coreBeaconFlags("beacon", generateBeaconCmd)
coreImplantFlagCompletions(generateBeaconCmd, con)
generateCmd.AddCommand(generateBeaconCmd)
generateStagerCmd := &cobra.Command{
Use: consts.MsfStagerStr,
Short: "Generate a stager using Metasploit (requires local Metasploit installation)",
Long: help.GetHelpFor([]string{consts.MsfStagerStr}),
Run: func(cmd *cobra.Command, args []string) {
GenerateStagerCmd(cmd, con, args)
},
}
flags.Bind("stager", false, generateStagerCmd, func(f *pflag.FlagSet) {
f.StringP("os", "o", "windows", "operating system")
f.StringP("arch", "a", "amd64", "cpu architecture")
f.StringP("lhost", "L", "", "Listening host")
f.Uint32P("lport", "l", 8443, "Listening port")
f.StringP("protocol", "r", "tcp", "Staging protocol (tcp/http/https)")
f.StringP("format", "f", "raw", "Output format (msfvenom formats, see help generate msf-stager for the list)")
f.StringP("badchars", "b", "", "bytes to exclude from stage shellcode")
f.StringP("save", "s", "", "directory to save the generated stager to")
f.StringP("advanced", "d", "", "Advanced options for the stager using URI query syntax (option1=value1&option2=value2...)")
})
flags.BindFlagCompletions(generateStagerCmd, func(comp *carapace.ActionMap) {
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
})
generateCmd.AddCommand(generateStagerCmd)
generateInfoCmd := &cobra.Command{
Use: consts.CompilerInfoStr,
Short: "Get information about the server's compiler",
Long: help.GetHelpFor([]string{consts.CompilerInfoStr}),
Run: func(cmd *cobra.Command, args []string) {
GenerateInfoCmd(cmd, con, args)
},
}
generateCmd.AddCommand(generateInfoCmd)
// Traffic Encoder SubCommands
trafficEncodersCmd := &cobra.Command{
Use: consts.TrafficEncodersStr,
Short: "Manage implant traffic encoders",
Long: help.GetHelpFor([]string{consts.GenerateStr, consts.TrafficEncodersStr}),
Run: func(cmd *cobra.Command, args []string) {
TrafficEncodersCmd(cmd, con, args)
},
}
generateCmd.AddCommand(trafficEncodersCmd)
trafficEncodersAddCmd := &cobra.Command{
Use: consts.AddStr,
Short: "Add a new traffic encoder to the server from the local file system",
Long: help.GetHelpFor([]string{consts.GenerateStr, consts.TrafficEncodersStr, consts.AddStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
TrafficEncodersAddCmd(cmd, con, args)
},
}
flags.Bind("", false, trafficEncodersAddCmd, func(f *pflag.FlagSet) {
f.BoolP("skip-tests", "s", false, "skip testing the traffic encoder (not recommended)")
})
carapace.Gen(trafficEncodersAddCmd).PositionalCompletion(carapace.ActionFiles("wasm").Tag("wasm files").Usage("local file path (expects .wasm)"))
trafficEncodersCmd.AddCommand(trafficEncodersAddCmd)
trafficEncodersRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a traffic encoder from the server",
Long: help.GetHelpFor([]string{consts.GenerateStr, consts.TrafficEncodersStr, consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
TrafficEncodersRemoveCmd(cmd, con, args)
},
}
carapace.Gen(trafficEncodersRmCmd).PositionalCompletion(TrafficEncodersCompleter(con).Usage("traffic encoder to remove"))
trafficEncodersCmd.AddCommand(trafficEncodersRmCmd)
// [ Regenerate ] --------------------------------------------------------------
regenerateCmd := &cobra.Command{
Use: consts.RegenerateStr,
Short: "Regenerate an implant",
Long: help.GetHelpFor([]string{consts.RegenerateStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
RegenerateCmd(cmd, con, args)
},
GroupID: consts.PayloadsHelpGroup,
}
flags.Bind("regenerate", false, regenerateCmd, func(f *pflag.FlagSet) {
f.StringP("save", "s", "", "directory/file to the binary to")
})
flags.BindFlagCompletions(regenerateCmd, func(comp *carapace.ActionMap) {
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
})
carapace.Gen(regenerateCmd).PositionalCompletion(ImplantBuildNameCompleter(con))
// [ Profiles ] --------------------------------------------------------------
profilesCmd := &cobra.Command{
Use: consts.ProfilesStr,
Short: "List existing profiles",
Long: help.GetHelpFor([]string{consts.ProfilesStr}),
Run: func(cmd *cobra.Command, args []string) {
ProfilesCmd(cmd, con, args)
},
GroupID: consts.PayloadsHelpGroup,
}
flags.Bind("profiles", true, profilesCmd, func(f *pflag.FlagSet) {
f.IntP("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
profilesGenerateCmd := &cobra.Command{
Use: consts.GenerateStr,
Short: "Generate implant from a profile",
Long: help.GetHelpFor([]string{consts.ProfilesStr, consts.GenerateStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ProfilesGenerateCmd(cmd, con, args)
},
}
flags.Bind("profiles", false, profilesGenerateCmd, func(f *pflag.FlagSet) {
f.StringP("save", "s", "", "directory/file to the binary to")
f.BoolP("disable-sgn", "G", false, "disable shikata ga nai shellcode encoder")
})
flags.BindFlagCompletions(profilesGenerateCmd, func(comp *carapace.ActionMap) {
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
})
carapace.Gen(profilesGenerateCmd).PositionalCompletion(ProfileNameCompleter(con))
profilesCmd.AddCommand(profilesGenerateCmd)
profilesNewCmd := &cobra.Command{
Use: consts.NewStr,
Short: "Create a new implant profile (interactive session)",
Long: help.GetHelpFor([]string{consts.ProfilesStr, consts.NewStr}),
Run: func(cmd *cobra.Command, args []string) {
ProfilesNewCmd(cmd, con, args)
},
}
profilesCmd.AddCommand(profilesNewCmd)
// Session flags and completions.
coreImplantFlags("session", profilesNewCmd)
compileImplantFlags("session", profilesNewCmd)
coreImplantFlagCompletions(profilesNewCmd, con)
profilesNewBeaconCmd := &cobra.Command{
Use: consts.BeaconStr,
Short: "Create a new implant profile (beacon)",
Long: help.GetHelpFor([]string{consts.ProfilesStr, consts.NewStr, consts.BeaconStr}),
Run: func(cmd *cobra.Command, args []string) {
ProfilesNewBeaconCmd(cmd, con, args)
},
}
profilesNewCmd.AddCommand(profilesNewBeaconCmd)
// Beacon flags and completions.
coreImplantFlags("beacon", profilesNewBeaconCmd)
compileImplantFlags("beacon", profilesNewBeaconCmd)
coreBeaconFlags("beacon", profilesNewBeaconCmd)
coreImplantFlagCompletions(profilesNewBeaconCmd, con)
profilesRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove a profile",
Long: help.GetHelpFor([]string{consts.ProfilesStr, consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ProfilesRmCmd(cmd, con, args)
},
}
carapace.Gen(profilesRmCmd).PositionalCompletion(ProfileNameCompleter(con))
profilesCmd.AddCommand(profilesRmCmd)
profilesInfoCmd := &cobra.Command{
Use: consts.InfoStr,
Short: "Details about a profile",
Long: help.GetHelpFor([]string{consts.ProfilesStr, consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
PrintProfileInfo(args[0], con)
},
}
carapace.Gen(profilesInfoCmd).PositionalCompletion(ProfileNameCompleter(con))
profilesCmd.AddCommand(profilesInfoCmd)
// [ Implants ] --------------------------------------------------------------
implantBuildsCmd := &cobra.Command{
Use: consts.ImplantBuildsStr,
Short: "List implant builds",
Long: help.GetHelpFor([]string{consts.ImplantBuildsStr}),
Run: func(cmd *cobra.Command, args []string) {
ImplantsCmd(cmd, con, args)
},
GroupID: consts.PayloadsHelpGroup,
}
flags.Bind("implants", true, implantBuildsCmd, func(f *pflag.FlagSet) {
f.IntP("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
flags.Bind("implants", false, implantBuildsCmd, func(f *pflag.FlagSet) {
f.StringP("os", "o", "", "filter builds by operating system")
f.StringP("arch", "a", "", "filter builds by cpu architecture")
f.StringP("format", "f", "", "filter builds by artifact format")
f.BoolP("only-sessions", "s", false, "filter interactive sessions")
f.BoolP("only-beacons", "b", false, "filter beacons")
f.BoolP("no-debug", "d", false, "filter builds by debug flag")
})
flags.BindFlagCompletions(implantBuildsCmd, func(comp *carapace.ActionMap) {
(*comp)["os"] = OSCompleter(con)
(*comp)["arch"] = ArchCompleter(con)
(*comp)["format"] = FormatCompleter()
})
implantsRmCmd := &cobra.Command{
Use: consts.RmStr,
Short: "Remove implant build",
Long: help.GetHelpFor([]string{consts.ImplantBuildsStr, consts.RmStr}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ImplantsRmCmd(cmd, con, args)
},
}
carapace.Gen(implantsRmCmd).PositionalCompletion(ImplantBuildNameCompleter(con))
implantBuildsCmd.AddCommand(implantsRmCmd)
canariesCmd := &cobra.Command{
Use: consts.CanariesStr,
Short: "List previously generated canaries",
Long: help.GetHelpFor([]string{consts.CanariesStr}),
Run: func(cmd *cobra.Command, args []string) {
CanariesCmd(cmd, con, args)
},
GroupID: consts.PayloadsHelpGroup,
}
flags.Bind("canaries", false, canariesCmd, func(f *pflag.FlagSet) {
f.BoolP("burned", "b", false, "show only triggered/burned canaries")
f.Int64P("timeout", "t", flags.DefaultTimeout, "grpc timeout in seconds")
})
return []*cobra.Command{generateCmd, regenerateCmd, profilesCmd, implantBuildsCmd}
}
// coreImplantFlags binds all flags common to all sliver implant types.
// This is used by all sliver compilation and profiles generation commands.
func coreImplantFlags(name string, cmd *cobra.Command) {
flags.Bind(name, false, cmd, func(f *pflag.FlagSet) {
// Core compile
f.StringP("os", "o", "windows", "operating system")
f.StringP("arch", "a", "amd64", "cpu architecture")
f.StringP("name", "N", "", "agent name") //
f.BoolP("debug", "d", false, "enable debug features")
f.StringP("debug-file", "O", "", "path to debug output")
f.BoolP("evasion", "e", false, "enable evasion features (e.g. overwrite user space hooks)")
f.BoolP("skip-symbols", "l", false, "skip symbol obfuscation")
f.BoolP("disable-sgn", "G", false, "disable shikata ga nai shellcode encoder")
f.StringP("canary", "c", "", "canary domain(s)")
// C2 channels
f.StringP("mtls", "m", "", "mtls connection strings")
f.StringP("wg", "g", "", "wg connection strings")
f.StringP("http", "b", "", "http(s) connection strings")
f.StringP("dns", "n", "", "dns connection strings")
f.StringP("named-pipe", "p", "", "named-pipe connection strings")
f.StringP("tcp-pivot", "i", "", "tcp-pivot connection strings")
f.Uint32P("key-exchange", "X", DefaultWGKeyExPort, "wg key-exchange port")
f.Uint32P("tcp-comms", "T", DefaultWGNPort, "wg c2 comms port")
f.BoolP("run-at-load", "R", false, "run the implant entrypoint from DllMain/Constructor (shared library only)")
f.BoolP("netgo", "q", false, "force the use of netgo")
f.StringP("traffic-encoders", "A", "", "comma separated list of traffic encoders to enable")
f.StringP("strategy", "Z", "", "specify a connection strategy (r = random, rd = random domain, s = sequential)")
f.Int64P("reconnect", "j", DefaultReconnect, "attempt to reconnect every n second(s)")
f.Int64P("poll-timeout", "P", DefaultPollTimeout, "long poll request timeout")
f.Uint32P("max-errors", "k", DefaultMaxErrors, "max number of connection errors")
// Limits
f.StringP("limit-datetime", "w", "", "limit execution to before datetime")
f.BoolP("limit-domainjoined", "x", false, "limit execution to domain joined machines")
f.StringP("limit-username", "y", "", "limit execution to specified username")
f.StringP("limit-hostname", "z", "", "limit execution to specified hostname")
f.StringP("limit-fileexists", "F", "", "limit execution to hosts with this file in the filesystem")
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)")
})
}
// coreImplantFlagCompletions binds completions to flags registered in coreImplantFlags.
func coreImplantFlagCompletions(cmd *cobra.Command, con *console.SliverClient) {
flags.BindFlagCompletions(cmd, func(comp *carapace.ActionMap) {
(*comp)["debug-file"] = carapace.ActionFiles()
(*comp)["os"] = OSCompleter(con)
(*comp)["arch"] = ArchCompleter(con)
(*comp)["strategy"] = carapace.ActionValuesDescribed([]string{"r", "random", "rd", "random domain", "s", "sequential"}...).Tag("C2 strategy")
(*comp)["format"] = FormatCompleter()
(*comp)["save"] = carapace.ActionFiles().Tag("directory/file to save implant")
(*comp)["traffic-encoders"] = TrafficEncodersCompleter(con).UniqueList(",")
})
}
// coreBeaconFlags binds all flags specific to beacon implants (profiles or compiled).
func coreBeaconFlags(name string, cmd *cobra.Command) {
flags.Bind(name, false, cmd, func(f *pflag.FlagSet) {
f.Int64P("days", "D", 0, "beacon interval days")
f.Int64P("hours", "H", 0, "beacon interval hours")
f.Int64P("minutes", "M", 0, "beacon interval minutes")
f.Int64P("seconds", "S", 60, "beacon interval seconds")
f.Int64P("jitter", "J", 30, "beacon interval jitter in seconds")
})
}
// compileImplantFlags binds all flags used when actually compiling an implant (not when creating a profile).
func compileImplantFlags(name string, cmd *cobra.Command) {
flags.Bind(name, false, cmd, func(f *pflag.FlagSet) {
f.StringP("name", "N", "", "agent name")
f.StringP("template", "I", "sliver", "implant code template")
f.BoolP("external-builder", "E", false, "use an external builder")
f.StringP("save", "s", "", "directory/file to the binary to")
})
}
Loaded 100 of 763 files, more files were not shown because too many files have changed in this diff. Show more