滲透基礎(chǔ)-利用IMAP協(xié)議讀取郵件
0x00 前言
在滲透測(cè)試中,當(dāng)我們獲得了用戶的郵箱憑據(jù),需要對(duì)郵箱內(nèi)容進(jìn)行分析時(shí),可以選擇通過(guò)IMAP協(xié)議實(shí)現(xiàn)自動(dòng)化來(lái)提高效率。
本文以Exchange為例,介紹通過(guò)IMAP協(xié)議下載郵件和附件的方法,開源代碼,分享腳本編寫細(xì)節(jié)。
0x01 簡(jiǎn)介
本文將要介紹以下內(nèi)容:
- 基礎(chǔ)知識(shí)
- Exchange開啟IMAP功能和登錄日志
- Python3實(shí)現(xiàn)細(xì)節(jié)
- 開源代碼
0x02 基礎(chǔ)知識(shí)
1.IMAP
- 全稱是Internet Mail Access Protocol,即交互式郵件存取協(xié)議
- 是一種郵件獲取協(xié)議,可以從郵件服務(wù)器上獲取郵件的信息
- 使用端口143
2.IMAP4_SSL
- 全稱是IMAP over SSL,是IMAP協(xié)議基于SSL安全協(xié)議之上的一種變種協(xié)議
- 繼承了SSL安全協(xié)議的非對(duì)稱加密的高度安全可靠性,可防止郵件泄露,也是用來(lái)接收郵件的
- 使用端口993
3.Python3 imaplib庫(kù)
官方文檔:
https://docs.python.org/3/library/imaplib.html
- 該模塊定義了三個(gè)類,IMAP4,IMAP4_SSL和 IMAP4_stream
- 為了提高安全性,我們通常使用用于安全連接的子類IMAP4_SSL
4.Python3 email庫(kù)
官方文檔:
https://docs.python.org/3/library/email.html
- 當(dāng)我們使用imaplib庫(kù)讀取郵件時(shí),需要使用email庫(kù)將接收的消息轉(zhuǎn)換為EmailMessage對(duì)象,可以更加方便的對(duì)郵件內(nèi)容進(jìn)行處理
0x03 Exchange開啟IMAP功能和登錄日志
默認(rèn)情況下,Exchange中未啟用IMAP4客戶端連接
參考資料:
https://docs.microsoft.com/en-us/exchange/clients/pop3-and-imap4/configure-imap4?view=exchserver-2019
開啟方法如下:
1.啟動(dòng)IMAP4服務(wù),并將服務(wù)配置為自動(dòng)啟動(dòng)
Powershell命令如下:
- Start-Service MSExchangeIMAP4; Start-Service MSExchangeIMAP4BESet-Service MSExchangeIMAP4 -StartupType Automatic; Set-Service MSExchangeIMAP4BE -StartupType Automatic
2.配置IMAP4設(shè)置
格式如下:
- Set-ImapSettings -ExternalConnectionSettings "::", "::"... -X509CertificateName [-SSLBindings ":",":"...] [-UnencryptedOrTLSBindings ":",":"...]
Powershell命令實(shí)例:
- Set-ImapSettings -ExternalConnectionSettings "mail.test.com:993:SSL","mail.test.com:143:TLS" -X509CertificateName mail.test.com
3.重新啟動(dòng)IMAP4服務(wù)
Powershell命令如下:
- Restart-Service MSExchangeIMAP4; Restart-Service MSExchangeIMAP4BE
4.查看配置:
Powershell命令如下:
- Get-Service MSExchangeIMAP4; Get-Service MSExchangeIMAP4BEGet-ImapSettings | Format-List *ConnectionSettings,*Bindings,X509CertificateName
使用郵箱用戶登錄OWA,選擇Settings->Options,能夠看到IMAP配置,如下圖:

默認(rèn)情況下,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.重啟服務(wù)
重新啟動(dòng)IMAP4服務(wù),Powershell命令如下:
- Restart-Service MSExchangeIMAP4; Restart-Service MSExchangeIMAP4BE
3.查看配置信息:
Powershell命令如下:
- Get-ImapSettings | Format-List ProtocolLogEnabled,LogFileLocation,LogPerFileSizeQuota,LogFileRollOverSettings
默認(rèn)的日志保存路徑為:C:\Program Files\Microsoft\Exchange Server\V15\Logging\Imap4
0x04 Python3實(shí)現(xiàn)細(xì)節(jié)
測(cè)試代碼1
- import imaplibM = imaplib.IMAP4_SSL('192.168.1.1','993')M.login('User1', 'Password')data = M.list()print(data)M.logout()
以上代碼用來(lái)獲得所有郵箱文件夾對(duì)應(yīng)的名稱
(1)M.list()用來(lái)列出郵箱文件夾的名稱
注:
不同的郵件系統(tǒng)只有收件箱名稱統(tǒng)一默認(rèn)為INBOX,發(fā)件箱的名稱一般不同,例如Exchange的發(fā)件箱名稱為"Sent Items"。
測(cè)試代碼2
- import imaplibM = 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()
以上代碼用來(lái)讀取收件箱所有郵件的內(nèi)容。
(1)M.select('INBOX')表示選擇收件箱
- 如果換成讀取Exchange的發(fā)件箱,對(duì)應(yīng)的代碼為M.select('"Sent Items"')
- 如果添加參數(shù)2為False,表示設(shè)置了只讀標(biāo)志,不允許修改郵箱,示例:M.select('"Sent Items"',False)
(2)typ, data = M.search(None, 'ALL')中,None表示使用默認(rèn)的ASCII編碼,ALL表示搜索條件為所有郵件
- 如果想要篩選出發(fā)件人為user2的郵件,對(duì)應(yīng)語(yǔ)句為typ, msgnums = M.search(None, '(FROM "user2")')
M.search()返回的結(jié)果為郵件的序列號(hào),例如我的測(cè)試環(huán)境下,收件箱有9個(gè)郵件,此時(shí)返回的結(jié)果為:
- [b'1 2 3 4 5 6 7 8 9']
注:
- 這里需要區(qū)分郵件序列號(hào)和UID
- 郵件序列號(hào)為從1開始累加的數(shù)列,UID是區(qū)分郵件的唯一標(biāo)識(shí)
獲得郵件序列號(hào)同UID對(duì)應(yīng)關(guān)系可使用以下代碼:
- import imaplibM = 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)')用來(lái)提取郵件消息
- 參數(shù)1num表示提取的郵件序列號(hào)
- 參數(shù)1支持同時(shí)提取多個(gè)連續(xù)郵件消息,例如同時(shí)提取郵件序列號(hào)為2-5的郵件命令為M.fetch('2:5', '(RFC822)')
- 參數(shù)2'(RFC822)'表示數(shù)據(jù)項(xiàng)名稱,這里’(RFC822)’等同于BODY[],只返回郵件體文本格式和大小的摘要信息
如果只想獲得郵件頭部的內(nèi)容,可以使用以下代碼:
- M.fetch(num, 'BODY[HEADER]')
如果只想獲得郵件體的內(nèi)容,可以使用以下代碼:
- M.fetch(num, 'BODY[TEXT]')
(4)M.close()用來(lái)關(guān)閉當(dāng)前選擇的郵箱
在執(zhí)行完M.select()后使用
測(cè)試代碼3
- import imaplibimport emailM = 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()
以上代碼用來(lái)保存收件箱所有郵件的附件
(1)msg = email.message_from_bytes(data[0][1])用來(lái)將數(shù)據(jù)轉(zhuǎn)換為email對(duì)象
(2)msg.walk()用來(lái)遍歷郵件對(duì)象的所有部分
(3)part.get('Content-Disposition')用來(lái)獲得對(duì)應(yīng)字段名Content-Disposition的字段值
如果郵件包含附件,將會(huì)帶有字段Content-Disposition,通過(guò)這個(gè)判斷郵件是否包含附件
(4)part.get_filename()用來(lái)獲得信息頭當(dāng)中Content-Disposition字段當(dāng)中名為filename的參數(shù)值,對(duì)應(yīng)附件的名稱
(5)part.get_payload(decode=True)用來(lái)獲得附件內(nèi)容
由于附件內(nèi)容是以Base64編碼的形式存儲(chǔ),所以在讀取時(shí)需要加入?yún)?shù)decode=True作Base64解碼。
測(cè)試代碼4
- import imaplibimport emailM = 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()
以上代碼用來(lái)逐個(gè)保存收件箱的所有郵件,以郵件序列號(hào)為名稱,后綴名為eml,可以使用Outlook打開。
0x05 開源代碼
我已經(jīng)將完整的代碼上傳至github,地址如下:
https://github.com/3gstudent/Homework-of-Python/blob/master/imapManage.py
代碼支持以下功能:
- 查看文件夾配置
- 從收件箱下載所有附件
- 從發(fā)件箱下載所有附件
- 從收件箱下載所有郵件
- 從發(fā)件箱下載所有郵件
在下載文件時(shí),首先以郵箱用戶名創(chuàng)建文件夾,保存對(duì)應(yīng)用戶下載的文件。
默認(rèn)支持通過(guò)IMAP4_SSL訪問(wèn)Exchange郵件,對(duì)于不同的郵件系統(tǒng),收件箱沒(méi)有區(qū)別,發(fā)件箱的名稱有所不同。發(fā)件箱的名稱可以通過(guò)。CheckConfig命令查詢文件夾對(duì)應(yīng)的名稱進(jìn)行修改。
代碼修復(fù)了附件名稱因?yàn)榫幋a問(wèn)題無(wú)法識(shí)別的bug。
為了便于記錄郵件訪問(wèn)過(guò)程,加入了日志記錄功能。
0x06 小結(jié)
本文以Exchange為例,介紹通過(guò)IMAP協(xié)議下載郵件和附件的方法,開源代碼imapManage.py,分享腳本編寫細(xì)節(jié)。對(duì)于其他郵件系統(tǒng),可以參照此代碼只需要修改發(fā)件箱的名稱即可。
本文為 3gstudent 原創(chuàng)稿件,授權(quán)嘶吼獨(dú)家發(fā)布,如若轉(zhuǎn)載,請(qǐng)注明原文地址。