渗透基础 —— 利用 IMAP 协议读取邮件

发布于 2024-11-02 02:38:49 字数 8416 浏览 13 评论 0

0x00 前言

在渗透测试中,当我们获得了用户的邮箱凭据,需要对邮箱内容进行分析时,可以选择通过 IMAP 协议实现自动化来提高效率。

本文以 Exchange 为例,介绍通过 IMAP 协议下载邮件和附件的方法,开源代码,分享脚本编写细节。

0x01 简介

本文将要介绍以下内容:

  • 基础知识
  • Exchange 开启 IMAP 功能和登录日志
  • Python3 实现细节
  • 开源代码

0x02 基础知识

1.IMAP

全称是 Internet Mail Access Protocol,即交互式邮件存取协议

是一种邮件获取协议,可以从邮件服务器上获取邮件的信息

使用端口 143

2.IMAP4_SSL

全称是 IMAP over SSL,是 IMAP 协议基于 SSL 安全协议之上的一种变种协议

继承了 SSL 安全协议的非对称加密的高度安全可靠性,可防止邮件泄露,也是用来接收邮件的

使用端口 993

3.Python3 imaplib 库

官方文档:https://docs.python.org/3/library/imaplib.html

该模块定义了三个类,IMAP4,IMAP4_SSL 和 IMAP4_stream

为了提高安全性,我们通常使用用于安全连接的子类 IMAP4_SSL

4.Python3 email 库

官方文档:https://docs.python.org/3/library/email.html

当我们使用 imaplib 库读取邮件时,需要使用 email 库将接收的消息转换为 EmailMessage 对象,可以更加方便的对邮件内容进行处理

0x03 Exchange 开启 IMAP 功能和登录日志

默认情况下,Exchange 中未启用 IMAP4 客户端连接

参考资料:https://docs.microsoft.com/en-us/exchange/clients/pop3-and-imap4/configure-imap4?view=exchserver-2019

开启方法如下:

1.启动 IMAP4 服务,并将服务配置为自动启动

Powershell 命令如下:

Start-Service MSExchangeIMAP4; Start-Service MSExchangeIMAP4BE
Set-Service MSExchangeIMAP4 -StartupType Automatic; Set-Service MSExchangeIMAP4BE -StartupType Automatic

2.配置 IMAP4 设置

格式如下:

Set-ImapSettings -ExternalConnectionSettings "<FQDN1>:<TCPPort1>:<SSL | TLS | blank>", "<FQDN2>:<TCPPort2>:<SSL | TLS | blank>"...  -X509CertificateName <FQDN> [-SSLBindings "<IPv4Orv6Address1>:<TCPPort1>","<IPv4Orv6Address2>:<TCPPort2>"...] [-UnencryptedOrTLSBindings "<IPv4Orv6Address1>:<TCPPort1>","<IPv4Orv6Address2>:<TCPPort2>"...]

Powershell 命令实例:

Set-ImapSettings -ExternalConnectionSettings "mail.test.com:993:SSL","mail.test.com:143:TLS" -X509CertificateName mail.test.com

3.重新启动 IMAP4 服务

Powershell 命令如下:

Restart-Service MSExchangeIMAP4; Restart-Service MSExchangeIMAP4BE

4.查看配置:

Powershell 命令如下:

Get-Service MSExchangeIMAP4; Get-Service MSExchangeIMAP4BE
Get-ImapSettings | Format-List *ConnectionSettings,*Bindings,X509CertificateName

使用邮箱用户登录 OWA,选择 Settings -> Options ,能够看到 IMAP 配置,如下图

Alt text

默认情况下,Exchange 中未启用日志功能

参考资料:https://docs.microsoft.com/en-us/exchange/configure-protocol-logging-for-pop3-and-imap4-exchange-2013-help

开启方法如下:

1.开启日志功能

Powershell 命令如下:

Set-ImapSettings -Server "CAS01" -ProtocolLogEnabled $true

2.重启服务

重新启动 IMAP4 服务,Powershell 命令如下:

Restart-Service MSExchangeIMAP4; Restart-Service MSExchangeIMAP4BE

3.查看配置信息:

Powershell 命令如下:

Get-ImapSettings | Format-List ProtocolLogEnabled,LogFileLocation,LogPerFileSizeQuota,LogFileRollOverSettings

默认的日志保存路径为: C:\Program Files\Microsoft\Exchange Server\V15\Logging\Imap4

0x04 Python3 实现细节

测试代码 1

import imaplib
M = imaplib.IMAP4_SSL('192.168.1.1','993')
M.login('User1', 'Password')
data = M.list()
print(data)
M.logout()

以上代码用来获得所有邮箱文件夹对应的名称

(1) M.list() 用来列出邮箱文件夹的名称

注:不同的邮件系统只有收件箱名称统一默认为 INBOX,发件箱的名称一般不同,例如 Exchange 的发件箱名称为 "Sent Items"

测试代码 2

import imaplib
M = imaplib.IMAP4_SSL('192.168.1.1','993')
M.login('User1', 'Password')
M.select('INBOX')
typ, data = M.search(None, 'ALL')
for num in data[0].split():
    typ, data = M.fetch(num, '(RFC822)')
    print('Message %s\n%s\n' % (num, data[0][1]))
M.close()
M.logout()

以上代码用来读取收件箱所有邮件的内容

(1) M.select('INBOX') 表示选择收件箱

如果换成读取 Exchange 的发件箱,对应的代码为 M.select('"Sent Items"')

如果添加参数 2 为 False,表示设置了只读标志,不允许修改邮箱,示例: M.select('"Sent Items"',False)

(2) typ, data = M.search(None, 'ALL') 中, None 表示使用默认的 ASCII 编码, ALL 表示搜索条件为所有邮件

如果想要筛选出发件人为 user2 的邮件,对应语句为 typ, msgnums = M.search(None, '(FROM "user2")')

M.search() 返回的结果为邮件的序列号,例如我的测试环境下,收件箱有 9 个邮件,此时返回的结果为:

[b'1 2 3 4 5 6 7 8 9']

注:这里需要区分邮件序列号和 UID,邮件序列号为从 1 开始累加的数列,UID 是区分邮件的唯一标识,获得邮件序列号同 UID 对应关系可使用以下代码:

import imaplib
M = imaplib.IMAP4_SSL('192.168.1.1','993')
M.login('User1', 'Password')
M.select('INBOX')
typ, data = M.search(None, 'ALL')
for num in data[0].split():
    typ, data = M.fetch(num, 'UID')
    print(data)
M.close()
M.logout()

(3) M.fetch(num, '(RFC822)') 用来提取邮件消息

参数 1 num 表示提取的邮件序列号

参数 1 支持同时提取多个连续邮件消息,例如同时提取邮件序列号为 2-5 的邮件命令为 M.fetch('2:5', '(RFC822)')

参数 2 '(RFC822)' 表示数据项名称,这里'(RFC822)'等同于 BODY[] ,只返回邮件体文本格式和大小的摘要信息

如果只想获得邮件头部的内容,可以使用以下代码:

M.fetch(num, 'BODY[HEADER]')

如果只想获得邮件体的内容,可以使用以下代码:

M.fetch(num, 'BODY[TEXT]')

(4) M.close() 用来关闭当前选择的邮箱

在执行完 M.select() 后使用

测试代码 3

import imaplib
import email
M = imaplib.IMAP4_SSL('192.168.1.1','993')
M.login('User1', 'Password')
M.select('INBOX')
typ, data = M.search(None, 'ALL')
for num in data[0].split():
    typ, data = M.fetch(num, '(RFC822)')
    msg = email.message_from_bytes(data[0][1])
    for part in msg.walk():
        if part.get('Content-Disposition'):
            fileName = part.get_filename()
            if bool(fileName):
                with open(fileName,'wb') as f:
                    f.write(part.get_payload(decode=True))
M.close()
M.logout()

以上代码用来保存收件箱所有邮件的附件

  • msg = email.message_from_bytes(data[0][1]) 用来将数据转换为 email 对象
  • msg.walk() 用来遍历邮件对象的所有部分
  • part.get('Content-Disposition') 用来获得对应字段名 Content-Disposition 的字段值,如果邮件包含附件,将会带有字段 Content-Disposition ,通过这个判断邮件是否包含附件
  • part.get_filename() 用来获得信息头当中 Content-Disposition 字段当中名为 filename 的参数值,对应附件的名称
  • part.get_payload(decode=True) 用来获得附件内容

由于附件内容是以 Base64 编码的形式存储,所以在读取时需要加入参数 decode=True 作 Base64 解码

测试代码 4

import imaplib
import email
M = imaplib.IMAP4_SSL('192.168.1.1','993')
M.login('User1', 'Password')
M.select('INBOX')
typ, data = M.search(None, 'ALL')
for num in data[0].split():
    typ, data = M.fetch(num, '(RFC822)')
    msg = email.message_from_bytes(data[0][1])
    with open(num.decode('utf8') + '.eml','wb') as f:
        f.write(bytes(msg))
M.close()
M.logout()

以上代码用来逐个保存收件箱的所有邮件,以邮件序列号为名称,后缀名为 eml,可以使用 Outlook 打开

0x05 开源代码

我已经将完整的代码上传至 github,地址如下:https://github.com/3gstudent/Homework-of-Python/blob/master/imapManage.py

代码支持以下功能:

  • 查看文件夹配置
  • 从收件箱下载所有附件
  • 从发件箱下载所有附件
  • 从收件箱下载所有邮件
  • 从发件箱下载所有邮件

在下载文件时,首先以邮箱用户名创建文件夹,保存对应用户下载的文件

默认支持通过 IMAP4_SSL 访问 Exchange 邮件,对于不同的邮件系统,收件箱没有区别,发件箱的名称有所不同。发件箱的名称可以通过 CheckConfig 命令查询文件夹对应的名称进行修改。

代码修复了附件名称因为编码问题无法识别的 bug,为了便于记录邮件访问过程,加入了日志记录功能

0x06 小结

本文以 Exchange 为例,介绍通过 IMAP 协议下载邮件和附件的方法,开源代码 imapManage.py,分享脚本编写细节。对于其他邮件系统,可以参照此代码只需要修改发件箱的名称即可。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

生来就爱笑

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

lee_heart

文章 0 评论 0

往事如风

文章 0 评论 0

春风十里

文章 0 评论 0

纸短情长

文章 0 评论 0

qq_pdEUFz

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文