7

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

 3 years ago
source link: https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%9F%BA%E7%A1%80-%E5%88%A9%E7%94%A8IMAP%E5%8D%8F%E8%AE%AE%E8%AF%BB%E5%8F%96%E9%82%AE%E4%BB%B6
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

22 Jan 2021

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)')用来提取邮件消息

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

参数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()

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

(1)msg = email.message_from_bytes(data[0][1])用来将数据转换为email对象

(2)msg.walk()用来遍历邮件对象的所有部分

(3)part.get('Content-Disposition')用来获得对应字段名Content-Disposition的字段值

如果邮件包含附件,将会带有字段Content-Disposition,通过这个判断邮件是否包含附件

(4)part.get_filename()用来获得信息头当中Content-Disposition字段当中名为filename的参数值,对应附件的名称

(5)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,分享脚本编写细节。对于其他邮件系统,可以参照此代码只需要修改发件箱的名称即可。


LEAVE A REPLY


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK