Skip to main content

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