Wireshark对IMAP抓包分析

本文最后更新于:May 13, 2020 am

本文主要使用Wireshark对邮件客户端使用IMAP协议接收邮件的过程进行抓包分析并使用telnet命令进行简单操作。

1、IMAP简介

IMAP和POP3两个协议基本上是目前支持和使用最广泛的邮件接收协议,IMAP和POP3相比有着许多优点,参考wiki和后面的抓包结果进行分析,这里列出一些后面抓包的时候可以验证的优点:

  • 支持连接和断开两种操作模式

    和POP3协议在接收完邮件之后就和服务器断开连接不同,IMAP协议可以一直和服务器保持连接从而使得接收新邮件的延迟大大降低。

  • 支持多个客户同时连接到一个邮箱

    POP3协议假定邮箱当前的连接是唯一的连接。相反,IMAP4协议允许多个用户同时访问邮箱同时提供一种机制让客户能够感知其他当前连接到这个邮箱的用户所做的操作。

  • 支持在服务器保留消息状态信息

    通过使用在IMAP4协议中定义的标志客户端可以跟踪消息状态,例如邮件是否被读取,回复,或者删除。这些标识存储在服务器,所以多个客户在不同时间访问一个邮箱可以感知其他用户所做的操作。

  • 支持在服务器上访问多个邮箱

    IMAP4客户端可以在服务器上创建,重命名,或删除邮箱(通常以文件夹形式显现给用户)。支持多个邮箱还允许服务器提供对于共享和公共文件夹的访问。

  • 支持访问消息中的MIME部分和部分获取。

    几乎所有的Internet邮件都是以MIME格式传输的。MIME允许消息包含一个树型结构,这个树型结构的叶子节点都是单一内容类型而非叶子节点都是多块类型的组合。IMAP4协议允许客户端获取任何独立的MIME部分和获取信息的一部分或者全部。这些机制使得用户无需下载附件就可以浏览消息内容或者在获取内容的同时浏览。

2、抓包分析

MUA中的设置如下,同样不使用加密协议方便分析数据。

配置完成开始抓包之后发现邮箱大师有多线程并发收件的操作,这也算是利用了IMAP协议的能够允许多个客户端连接到同一个服务器的特点,但是显然不利于我们分析串行模式下单个连接收件的完整过程,不过也可以对比多个连接之间的差异。

由于建立IMAP通信连接必须要登录,所以我们只需要查看报文就可以知道一共并行发起了多少个连接,在这次的报文中一共发现了有三个LOGIN的请求报文,因此可以判断应该一共先后发起了三个连接,其中第三个连接是在第一个连接结束之后发起的,具体分析如下:

可以看到最开始几乎同时发起了两个IMAP连接:

2.1 第一个连接

我们先来对第一个连接进行分析:

首先我们可以确定IMAP的传输层协议也是使用的TCP协议,同样这里略去TCP三握四挥的分析,直接看IMAP相关部分的报文:

  • 客户端与IMAP服务器在TCP三次握手之后建立连接

  • IMAP服务器返回OK信息,并说明自身邮件系统的类型为coremail

  • 客户端发送CAPABILITY命令查询可用的命令,这个和POP3中的CAPA命令功能相同

  • IMAP服务器返回可以执行的命令

  • 客户端发送ID命令,附带了MUA和OS的相关信息

  • IMAP服务器返回ID字符串,同样附带了邮件服务器的相关信息

  • 客户端发送LOGIN命令进行登录,双引号内的为邮箱账号,后面加一个空格然后紧跟着的是密码

  • IMAP服务器返回OK指令提示登录成功

  • 客户端发送LIST命令查询该账号内的邮件信息,但是可能命令的格式不对,并没有查询到任何有用的信息

  • IMAP服务器返回查询结果为空:

    如果把查询命令换为LIST "" "*"则可以查询到该账号的所有邮箱文件夹:

  • 客户端发送NOOP指令,与之前的POP3协议类似,NOOP指令的作用应该是用于保持连接,默认相当于无操作,但是在此次连接还没使用过SELECT命令并且是第一次发送NOOP指令的时候,IMAP服务器会返回该账号下所有目录的邮件总数

  • IMAP服务器返回OK指令并且返回了邮件总数、

  • 客户端使用SELECT指令,并且选中了INBOX文件夹(一般对应收件箱),相当于在数据库中选中了一个数据表

  • 然后连接就莫名没了

2.2 第二个连接

第二次连接的数据包较长,我们截取部分客户端发送的请求:

对比第一次连接,主要有以下不同点:

  • 使用了XLIST "" "*"查询到了邮件账号下的所有文件夹(收件箱、发件箱、草稿箱、垃圾箱、垃圾邮件等)
  • 依次使用SELECT命令和UID SEARCH UID 命令来对每个文件夹进行操作,进而获取到该账号对应的文件夹下的所有邮件的总数和对应的UID

2.3 第三个连接

从wireshark上对数据包标记的序号来看,第三个连接是在第一个连接结束之后才发起的。对应的客户端主要操作如下:

上面的内容重复操作较多,主要就是对每个文件夹都进行SELECT,然后获取里面的邮件具体内容,主要的核心操作有以下两个

  • UID FETCH 1557156839:1557156846 (UID FLAGS RFC822.SIZE BODYSTRUCTURE INTERNALDATE BODY.PEEK[HEADER.FIELDS (Date Subject From Sender Reply-To To Cc Bcc Message-ID References In-Reply-To X-MailMaster-ShowOneRcpt X-CUSTOM-MAIL-MASTER-SENT-ID Disposition-Notification-To X-CM-CTRLMSGS)])
  • UID FETCH 1557156844 BODY.PEEK[1]

上面两个请求命令中的1557156844就是在第一个连接中使用UID SEARCH命令查询到的邮件的UID,这里使用了UID FETCH命令来获取邮件的对应内容。由于前面我们提到邮件的格式是符合MIME标准的,而IMAP协议又是允许MUA下载符合MIME标准的部分邮件内容,因此这两条UID命令就是用于获取对应的邮件的特定部分的内容

2.4 小结

在换了另一个测试账号进行同样的抓包操作之后我发现两次的数据请求操作几乎是一模一样的,都是有三个连接,操作也和上面相同。由此可以分析IMAP协议的可操作性要比POP3强很多,因此在具体的功能实现上对于不同的MUA而言也有不同。

3、telnet操作

同样的我们也可以telnet到邮件服务器的143端口来进行命令操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[root@www coremail]# telnet localhost 143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK Coremail System IMap Server Ready(126com[c92b4e18679ada4069d0bde6e2528ad1])
C1 LOGIN "test02@coremail.cn" password
C1 OK LOGIN completed
C2 LIST "" ""
* LIST (\Noselect) "/" ""
C2 OK LIST Completed
C3 LIST "" "*"
* LIST () "/" "INBOX"
* LIST (\Drafts) "/" "Drafts"
* LIST (\Sent) "/" "Sent Items"
* LIST (\Trash) "/" "Trash"
* LIST (\Junk) "/" "Junk E-mail"
* LIST () "/" "Virus Items"
C3 OK LIST Completed
C4 SELECT INBOX
* 8 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1] UIDs valid
* FLAGS (\Answered \Seen \Deleted \Draft \Flagged)
* OK [PERMANENTFLAGS (\Answered \Seen \Deleted \Draft \Flagged)] Limited
C4 OK [READ-WRITE] SELECT completed
C5 UID SEARCH 1:*
* SEARCH 1557156839 1557156840 1557156841 1557156842 1557156843 1557156844 1557156845 1557156846
C5 OK SEARCH completed
C6 UID FETCH 1557156839
C6 BAD Parse command error
C7 UID FETCH 1557156839 FULL
* 1 FETCH (UID 1557156839 INTERNALDATE " 6-May-2019 23:33:59 +0800" FLAGS (\Seen) ENVELOPE ("Mon, 6 May 2019 23:33:59 +0800 (GMT+08:00)" "=?UTF-8?B?5qyi6L+O5L2/55SoQ29yZW1haWznlLXlrZDpgq7ku7bns7vnu58vV2VsY29tZSB0byB0aGUgQ29yZW1haWwgZS1tYWlsIHN5c3RlbQ==?=" ((NIL NIL "postmaster" "coremail.cn")) ((NIL NIL "postmaster" "coremail.cn")) ((NIL NIL "postmaster" "coremail.cn")) ((NIL NIL "test02" "coremail.cn")) NIL NIL NIL "<1106604853.1.1557156839490@www.example.com>") BODY (("text" "html" ("charset" "UTF-8") NIL NIL "quoted-printable" 7274 152) "related") RFC822.SIZE 7959)
C7 OK Fetch completed
C8 UID FETCH 1557156846 FULL
* 8 FETCH (UID 1557156846 INTERNALDATE " 8-May-2019 09:43:11 +0800" FLAGS (\Seen) ENVELOPE ("Wed, 8 May 2019 09:43:11 +0800 (CST)" "=?UTF-8?B?dGVsbmV0IHRlc3QgbWFpbCBBdXRoZW50aWNhdGVk?=" (("=?UTF-8?B?InRlc3QwMSI=?=" NIL "test01" "coremail.cn")) (("=?UTF-8?B?InRlc3QwMSI=?=" NIL "test01" "coremail.cn")) (("=?UTF-8?B?InRlc3QwMSI=?=" NIL "test01" "coremail.cn")) (("=?UTF-8?B?InRlc3QwMiI=?=" NIL "test02" "coremail.cn")) NIL NIL NIL "<5CD2342F.000006.02460@coremail.cn>") BODY ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 0 0) RFC822.SIZE 656)
C8 OK Fetch completed
C9 UID FETCH 1557156844 FULL
* 6 FETCH (UID 1557156844 INTERNALDATE " 8-May-2019 16:59:38 +0800" FLAGS (\Seen) ENVELOPE ("Wed, 8 May 2019 16:59:38 +0800 (CST)" "=?UTF-8?B?dGVsbmV0IHRlc3QgbWFpbA==?=" (("=?UTF-8?B?InRlc3QwMSI=?=" NIL "test01" "coremail.cn")) (("=?UTF-8?B?InRlc3QwMSI=?=" NIL "test01" "coremail.cn")) (("=?UTF-8?B?InRlc3QwMSI=?=" NIL "test01" "coremail.cn")) (("=?UTF-8?B?InRlc3QwMiI=?=" NIL "test02" "coremail.cn")) NIL NIL NIL "<5CD29A7A.000004.02460@coremail.cn>") BODY ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 0 0) RFC822.SIZE 642)
C9 OK Fetch completed