将包含算法、密钥长度、IV 长度和密码的密钥字节流,作为 Java 程序标准输入传递。
xjar.go代码
package main
import (
"bytes"
"crypto/md5"
"crypto/sha1"
"errors"
"hash"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
)
var xJar = XJar{
md5: []byte{9, 15, 233, 88, 9, 60, 80, 217, 189, 204, 223, 35, 62, 229, 255, 80},
sha1: []byte{63, 97, 90, 64, 90, 144, 174, 79, 13, 192, 250, 105, 89, 114, 78, 133, 4, 170, 2, 30},
}
var xKey = XKey{
algorithm: []byte{65, 69, 83, 47, 67, 66, 67, 47, 80, 75, 67, 83, 53, 80, 97, 100, 100, 105, 110, 103},
keysize: []byte{49, 50, 56},
ivsize: []byte{49, 50, 56},
password: []byte{49, 50, 51, 52, 53, 54, 119, 119},
}
func main() {
// search the jar to start
jar, err := JAR(os.Args)
if err != nil {
panic(err)
}
// parse jar name to absolute path
path, err := filepath.Abs(jar)
if err != nil {
panic(err)
}
// verify jar with MD5
MD5, err := MD5(path)
if err != nil {
panic(err)
}
if bytes.Compare(MD5, xJar.md5) != 0 {
panic(errors.New("invalid jar with MD5"))
}
// verify jar with SHA-1
SHA1, err := SHA1(path)
if err != nil {
panic(err)
}
if bytes.Compare(SHA1, xJar.sha1) != 0 {
panic(errors.New("invalid jar with SHA-1"))
}
// check agent forbid
{
args := os.Args
l := len(args)
for i := 0; i < l; i++ {
arg := args[i]
if strings.HasPrefix(arg, "-javaagent:") {
panic(errors.New("agent forbidden"))
}
}
}
// start java application
java := os.Args[1]
args := os.Args[2:]
key := bytes.Join([][]byte{
xKey.algorithm, {13, 10},
xKey.keysize, {13, 10},
xKey.ivsize, {13, 10},
xKey.password, {13, 10},
}, []byte{})
cmd := exec.Command(java, args...)
cmd.Stdin = bytes.NewReader(key)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
panic(err)
}
}
// find jar name from args
func JAR(args []string) (string, error) {
var jar string
l := len(args)
for i := 1; i < l-1; i++ {
arg := args[i]
if arg == "-jar" {
jar = args[i+1]
}
}
if jar == "" {
return "", errors.New("unspecified jar name")
}
return jar, nil
}
// calculate file's MD5
func MD5(path string) ([]byte, error) {
return HASH(path, md5.New())
}
// calculate file's SHA-1
func SHA1(path string) ([]byte, error) {
return HASH(path, sha1.New())
}
// calculate file's HASH value with specified HASH Algorithm
func HASH(path string, hash hash.Hash) ([]byte, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
_, _err := io.Copy(hash, file)
if _err != nil {
return nil, _err
}
sum := hash.Sum(nil)
return sum, nil
}
type XJar struct {
md5 []byte
sha1 []byte
}
type XKey struct {
algorithm []byte
keysize []byte
ivsize []byte
password []byte
}
3.3、获取密钥
(1)拿到密钥
启动器需要接收参数,可以直接编写一个 Go 程序输出传入的 stdin。
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
input := bufio.NewScanner(os.Stdin) //初始化一个扫表对象
for input.Scan() { //扫描输入内容
line := input.Text() //把输入内容转换为字符串
fmt.Println(line) //输出到标准输出
}
}
拿到密钥
