01 IMAP的TLS抓包
1中间人拦截TCP报文方式
1.1 说明
只要是长连接的tcp/ip
连接基于TLS
加密,想要解密,除非有服务端的私钥和证书,或是对客户端能直接
侵入式植入代码调试,不然,很难的了。 但也有可能中间人进行介入。 比如,本地的邮件服务的imsp
的数据
走的是TLS
层加密的,这样客户端和服务的数据基本很难被抓到。不过,本地的邮件客户端提供代理功能,可以从
代理入手,来捕获加密的数据。
方式大概就是
imsp客户端 ---TLS---> 代理层 ----TLS---> 服务端
准备工作就是:
- 准备好一个域名,并准备这个域名的证书的私钥,要
CI
证书机构的签发的那种。 - 然后再把域名解析来本机
ip
127.0.0.1
,这个修改下/etc/hosts
文件就可以实现了。 - 最后把邮件客户端的端口配置为自己指向本地的域名。
- 做好这些,就可以写代理了。
1.2 代理层的转发代码实现
package main
import (
"bufio"
"crypto/rand"
"crypto/tls"
"log"
"net"
"time"
)
func main() {
cert, err := tls.LoadX509KeyPair(
"certs/client.pem",
"certs/private.key",
)
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates: []tls.Certificate{cert}}
config.Rand = rand.Reader
service := "0.0.0.0:993"
listener, err := tls.Listen("tcp", service, &config)
if err != nil {
log.Fatalf("server: listen: %s", err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Println(err)
continue
}
go handleConn(conn)
}
}
func handleConn(conn net.Conn) {
defer conn.Close()
cert, err := tls.LoadX509KeyPair(
"certs/client.pem",
"certs/private.key",
)
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
imspConn, err := tls.Dial("tcp", "imsp.qq.com:993", &config)
if err != nil {
log.Fatalf("client: dial: %s", err)
}
go handleImapConn(imspConn, conn)
r := bufio.NewReader(conn)
for {
msg, err := r.ReadString('\n')
if err != nil {
log.Println(err)
return
}
t := time.Now()
println("-> " + t.Format("2006-01-02 15:04:05") + " " + msg)
n, err := imspConn.Write([]byte(msg))
if err != nil {
log.Println(n, err)
return
}
}
}
func handleImapConn(imspConn net.Conn, parenConn net.Conn) {
r := bufio.NewReader(imspConn)
for {
msg, err := r.ReadString('\n')
if err != nil {
log.Println(err)
return
}
t := time.Now()
println("<- " + t.Format("2006-01-02 15:04:05") + " " + msg)
n, err := parenConn.Write([]byte(msg))
if err != nil {
log.Println(n, err)
return
}
}
}
代理的思路很简单的,就是以TLS
方式监听本地的933
端口,由于本地的邮件的imsp
的代理就域名就是指向本地,
且本地的证书是合法的,自然就能解密发向这里的数据,然后把数据导向服务端,让本地的邮件客户端数据回到该去的地方
,同理,服务端的数据发向邮件客户端也是要经过代理服务的, 自然也能解开。
至此,被加密的数据已经完整被打印出来了。
2 使用终端连接工具直连接IMAP服务
2.1 telnet方式连接
$ telnet <ip> <143>
这种方式不走TLS
通道,所以不安全,现在143
端口多数心STARTTLS
为主,所以多数不支持
2.2 TLS 的telnet 方式连接
$ openssl s_client -connect <ip>:993 -crlf -quiet
The option “-crlf” just means to issue a carriage return and a line feed on enter and “-quiet” means not to spit out a bunch of details about the encrypted channel. Feel free to drop “-quiet” to view the output, or if you are keen, add “-debug” for even more detail. More detail
如果想使用
STARTTLS
连接143
端口,则:$ openssl s_client -connect <ip>:143 -crlf -quiet -starttls imap