首页
社区
课程
招聘
[原创]基于Python的邮件快速检测工具库
发表于: 2021-1-3 10:43 6978

[原创]基于Python的邮件快速检测工具库

2021-1-3 10:43
6978

mmpi,是一款使用python实现的开源邮件快速检测工具库,基于community框架设计开发。mmpi支持对邮件头、邮件正文、邮件附件的解析检测,并输出json检测报告。

mmpi,代码项目地址:https://github.com/a232319779/mmpi,pypi项目地址https://pypi.org/project/mmpi/

mmpi,邮件快速检测工具库检测逻辑:

mmpi的分析判定检测前提:邮件系统环境。脱离邮件环境上下文,检测规则的依据就不可靠了。

备注:windows安装yara-python,可以从这里下载

mmpi完全基于python开发,使用python原生emailhtmlzip库进行解析,基于oletool做定制化修改,支持对office文档和rtf文档的解析,再结合yara实现对其他文件的检测。

检测规则:压缩包中文件名以.exe结尾,并且中间插入20个以上空格的

检测规则:压缩包中同时存在exe和dll文件

检测规则:RTF文档中存在OLE对象,并且class_name是OLE2Link或者以equation开头

结果说明:邮件包含漏洞利用的RTF文档,属于恶意邮件。

 
 
$ pip install mmpi
$ pip install mmpi
$ mmpi-run $email_path
$ mmpi-run $email_path
from mmpi import mmpi
 
 
def main():
    emp = mmpi()
    emp.parse('test.eml')
    report = emp.get_report()
    print(report)
 
 
if __name__ == "__main__":
    main()
from mmpi import mmpi
 
 
def main():
    emp = mmpi()
    emp.parse('test.eml')
    report = emp.get_report()
    print(report)
 
 
if __name__ == "__main__":
    main()
{
     // 固定字段
    "headers": [],
    "body": [],
    "attachments": [],
    "signatures": []
    // 动态字段
    "vba": [],
    "rtf": [],
}
{
     // 固定字段
    "headers": [],
    "body": [],
    "attachments": [],
    "signatures": []
    // 动态字段
    "vba": [],
    "rtf": [],
}
.
├── mmpi
│   ├── common
│   ├── core
│   ├── data
│   │   ├── signatures
│   │   │   ├── eml
│   │   │   ├── html
│   │   │   ├── ole
│   │   │   ├── other
│   │   │   ├── rtf
│   │   │   └── zip
│   │   ├── white
│   │   └── yara
│   │       ├── exe
│   │       ├── pdf
│   │       └── vba
│   └── processing
└── tests
    └── samples
.
├── mmpi
│   ├── common
│   ├── core
│   ├── data
│   │   ├── signatures
│   │   │   ├── eml
│   │   │   ├── html
│   │   │   ├── ole
│   │   │   ├── other
│   │   │   ├── rtf
│   │   │   └── zip
│   │   ├── white
│   │   └── yara
│   │       ├── exe
│   │       ├── pdf
│   │       └── vba
│   └── processing
└── tests
    └── samples
class PEFakeDocument(Signature):
    authors = ["ddvv"]
    sig_type = 'zip'
    name = "pe_fake_document"
    severity = 9
    description = "PE File Fake Document"
 
    def on_complete(self):
        results = self.get_results()
        for result in results:
            if result.get('type', '') == self.sig_type:
                infos = result.get('value', {}).get('infos', [])
                for info in infos:
                    file_type = info.get('type')
                    file_name = info.get('name')
                    space_count = file_name.count('  ')
                    if 'exe' == file_type and space_count > 20:
                        self.mark(type="zip", tag=self.name, data=info.get('name'))
                        return self.has_marks()
        return None
class PEFakeDocument(Signature):
    authors = ["ddvv"]
    sig_type = 'zip'
    name = "pe_fake_document"
    severity = 9
    description = "PE File Fake Document"
 
    def on_complete(self):
        results = self.get_results()
        for result in results:
            if result.get('type', '') == self.sig_type:
                infos = result.get('value', {}).get('infos', [])
                for info in infos:
                    file_type = info.get('type')
                    file_name = info.get('name')
                    space_count = file_name.count('  ')
                    if 'exe' == file_type and space_count > 20:
                        self.mark(type="zip", tag=self.name, data=info.get('name'))
                        return self.has_marks()
        return None
class DLLHijacking(Signature):
    authors = ["ddvv"]
    sig_type = 'zip'
    name = "dll_hijacking"
    severity = 9
    description = "DLL Hijacking"
 
    def on_complete(self):
        results = self.get_results()
        for result in results:
            if result.get('type', '') == self.sig_type:
                infos = result.get('value', {}).get('infos', [])
                file_types = [info.get('type') for info in infos]
                if set(['exe', 'dll']).issubset(file_types):
                    self.mark(type="zip", tag=self.name)
                    return self.has_marks()
        return None
class DLLHijacking(Signature):
    authors = ["ddvv"]
    sig_type = 'zip'
    name = "dll_hijacking"
    severity = 9
    description = "DLL Hijacking"
 
    def on_complete(self):
        results = self.get_results()
        for result in results:
            if result.get('type', '') == self.sig_type:
                infos = result.get('value', {}).get('infos', [])
                file_types = [info.get('type') for info in infos]
                if set(['exe', 'dll']).issubset(file_types):
                    self.mark(type="zip", tag=self.name)
                    return self.has_marks()
        return None
class RTFExploitDetected(Signature):
    authors = ["ddvv"]
    sig_type = 'rtf'
    name = "rtf_exploit_detected"
    severity = 9
    description = "RTF Exploit Detected"
 
    def on_complete(self):
        results = self.get_results()
        for result in results:
            if result.get('type', '') == self.sig_type:
                infos = result.get('value', {}).get('infos', [])
                for info in infos:
                    if info.get('is_ole', False):
                        class_name = info.get('class_name', '')
                        if class_name == 'OLE2Link' or class_name.lower().startswith('equation'):
                            self.mark(type="rtf", tag=self.name)
                            return self.has_marks()
        return None
class RTFExploitDetected(Signature):
    authors = ["ddvv"]
    sig_type = 'rtf'
    name = "rtf_exploit_detected"
    severity = 9
    description = "RTF Exploit Detected"
 
    def on_complete(self):
        results = self.get_results()
        for result in results:
            if result.get('type', '') == self.sig_type:
                infos = result.get('value', {}).get('infos', [])
                for info in infos:
                    if info.get('is_ole', False):
                        class_name = info.get('class_name', '')
                        if class_name == 'OLE2Link' or class_name.lower().startswith('equation'):

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 3496
活跃值: (749)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不错,谢谢分享。
2021-1-4 08:05
0
雪    币: 1887
活跃值: (2766)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
kxzpy 不错,谢谢分享。
感谢认同
2021-1-6 15:34
0
雪    币: 228
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
请问会根据oletools的升级而更新吗
2021-1-11 01:43
0
雪    币: 1887
活跃值: (2766)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
dbg_man 请问会根据oletools的升级而更新吗
会的,这个项目会长期维护。依赖的外部更新,都会同步过来。
2021-1-11 12:22
0
游客
登录 | 注册 方可回帖
返回
//