mirror of
https://github.com/optim-enterprises-bv/Mailu.git
synced 2025-11-01 10:37:49 +00:00
Implement oletools to filter out bad macros
This commit is contained in:
4
.github/workflows/build_test_deploy.yml
vendored
4
.github/workflows/build_test_deploy.yml
vendored
@@ -394,7 +394,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx"]
|
target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "oletools", "postfix", "dovecot", "unbound", "nginx"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Retrieve global variables
|
- name: Retrieve global variables
|
||||||
@@ -439,7 +439,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx"]
|
target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "oletools", "postfix", "dovecot", "unbound", "nginx"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Retrieve global variables
|
- name: Retrieve global variables
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ watchdog
|
|||||||
# core/postfix
|
# core/postfix
|
||||||
postfix-mta-sts-resolver
|
postfix-mta-sts-resolver
|
||||||
|
|
||||||
|
# core/oletools
|
||||||
|
python-magic
|
||||||
|
oletools
|
||||||
|
|
||||||
# optional/fetchmail
|
# optional/fetchmail
|
||||||
requests
|
requests
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ marshmallow==3.18.0
|
|||||||
marshmallow-sqlalchemy==0.28.1
|
marshmallow-sqlalchemy==0.28.1
|
||||||
multidict==6.0.2
|
multidict==6.0.2
|
||||||
mysql-connector-python==8.0.31
|
mysql-connector-python==8.0.31
|
||||||
|
oletools==0.60.1
|
||||||
packaging==21.3
|
packaging==21.3
|
||||||
passlib==1.7.4
|
passlib==1.7.4
|
||||||
podop @ file:///app/libs/podop
|
podop @ file:///app/libs/podop
|
||||||
@@ -52,7 +53,9 @@ pycares==4.2.2
|
|||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
Pygments==2.13.0
|
Pygments==2.13.0
|
||||||
pyOpenSSL==22.1.0
|
pyOpenSSL==22.1.0
|
||||||
pyparsing==3.0.9
|
pyparsing==2.4.7
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
python-magic==0.4.27
|
||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
pytz==2022.6
|
pytz==2022.6
|
||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
|
|||||||
31
core/oletools/Dockerfile
Normal file
31
core/oletools/Dockerfile
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# syntax=docker/dockerfile-upstream:1.4.3
|
||||||
|
|
||||||
|
# oletools image
|
||||||
|
FROM base
|
||||||
|
|
||||||
|
ARG VERSION=local
|
||||||
|
LABEL version=$VERSION
|
||||||
|
|
||||||
|
RUN set -euxo pipefail \
|
||||||
|
; apk add --no-cache netcat-openbsd libmagic libffi \
|
||||||
|
; curl -sLo olefy.py https://raw.githubusercontent.com/HeinleinSupport/olefy/f8aac6cc55283886d153e89c8f27fae66b1c24e2/olefy.py \
|
||||||
|
; chmod 755 olefy.py
|
||||||
|
|
||||||
|
RUN echo $VERSION >/version
|
||||||
|
|
||||||
|
HEALTHCHECK --start-period=60s CMD echo PING|nc -q1 127.0.0.1 11343|grep "PONG"
|
||||||
|
EXPOSE 11343/tcp
|
||||||
|
|
||||||
|
USER nobody:nobody
|
||||||
|
|
||||||
|
ENV \
|
||||||
|
OLEFY_BINDADDRESS="0.0.0.0" \
|
||||||
|
OLEFY_BINDPORT="11343" \
|
||||||
|
OLEFY_OLEVBA_PATH="/app/venv/bin/olevba" \
|
||||||
|
OLEFY_PYTHON_PATH="/app/venv/bin/python3" \
|
||||||
|
OLEFY_TMPDIR="/dev/shm/" \
|
||||||
|
OLEFY_MINLENGTH="300" \
|
||||||
|
OLEFY_DEL_TMP="1" \
|
||||||
|
OLEFY_DEL_TMP_FAILED="1"
|
||||||
|
|
||||||
|
CMD /app/olefy.py
|
||||||
12
core/rspamd/conf/composites.conf
Normal file
12
core/rspamd/conf/composites.conf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
OLETOOLS_MACRO_MRAPTOR {
|
||||||
|
expression = "(OLETOOLS_A & OLETOOLS_W) | (OLETOOLS_A & OLETOOLS_X) | (OLETOOLS_W & OLETOOLS_X)";
|
||||||
|
message = "Rejected (malicious macro - mraptor)";
|
||||||
|
policy = "leave";
|
||||||
|
score = 20.0;
|
||||||
|
}
|
||||||
|
OLETOOLS_MACRO_SUSPICIOUS {
|
||||||
|
expression = "OLETOOLS & OLETOOLS_SUSPICIOUS";
|
||||||
|
message = "Rejected (malicious macro)";
|
||||||
|
policy = "leave";
|
||||||
|
score = 20.0;
|
||||||
|
}
|
||||||
61
core/rspamd/conf/external_services.conf
Normal file
61
core/rspamd/conf/external_services.conf
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
oletools {
|
||||||
|
# default olefy settings
|
||||||
|
servers = "{{ OLETOOLS_ADDRESS }}"
|
||||||
|
|
||||||
|
# needs to be set explicitly for Rspamd < 1.9.5
|
||||||
|
scan_mime_parts = true;
|
||||||
|
extended = true;
|
||||||
|
max_size = 3145728;
|
||||||
|
timeout = 20.0;
|
||||||
|
retransmits = 1;
|
||||||
|
|
||||||
|
patterns {
|
||||||
|
OLETOOLS_MACRO = '^.....M..$';
|
||||||
|
OLETOOLS_AUTOEXEC = '^A....M..$';
|
||||||
|
OLETOOLS_SUSPICIOUS = '^.....MS.$';
|
||||||
|
# see https://github.com/decalage2/oletools/blob/master/oletools/mraptor.py
|
||||||
|
OLETOOLS_A = '(?i)\b(?:Auto(?:Exec|_?Open|_?Close|Exit|New)|Document(?:_?Open|_Close|_?BeforeClose|Change|_New)|NewDocument|Workbook(?:_Open|_Activate|_Close|_BeforeClose)|\w+_(?:Painted|Painting|GotFocus|LostFocus|MouseHover|Layout|Click|Change|Resize|BeforeNavigate2|BeforeScriptExecute|DocumentComplete|DownloadBegin|DownloadComplete|FileDownload|NavigateComplete2|NavigateError|ProgressChange|PropertyChange|SetSecureLockIcon|StatusTextChange|TitleChange|MouseMove|MouseEnter|MouseLeave|OnConnecting))|Auto_Ope\b';
|
||||||
|
OLETOOLS_W = '(?i)\b(?:FileCopy|CopyFile|Kill|CreateTextFile|VirtualAlloc|RtlMoveMemory|URLDownloadToFileA?|AltStartupPath|WriteProcessMemory|ADODB\.Stream|WriteText|SaveToFile|SaveAs|SaveAsRTF|FileSaveAs|MkDir|RmDir|SaveSetting|SetAttr)\b|(?:\bOpen\b[^\n]+\b(?:Write|Append|Binary|Output|Random)\b)';
|
||||||
|
OLETOOLS_X = '(?i)\b(?:Shell|CreateObject|GetObject|SendKeys|RUN|CALL|MacScript|FollowHyperlink|CreateThread|ShellExecuteA?|ExecuteExcel4Macro|EXEC|REGISTER|SetTimer)\b|(?:\bDeclare\b[^\n]+\bLib\b)';
|
||||||
|
}
|
||||||
|
|
||||||
|
# mime-part regex matching in content-type or filename
|
||||||
|
mime_parts_filter_regex {
|
||||||
|
#UNKNOWN = "application\/octet-stream";
|
||||||
|
DOC2 = "application\/msword";
|
||||||
|
DOC3 = "application\/vnd\.ms-word.*";
|
||||||
|
XLS = "application\/vnd\.ms-excel.*";
|
||||||
|
PPT = "application\/vnd\.ms-powerpoint.*";
|
||||||
|
GENERIC = "application\/vnd\.openxmlformats-officedocument.*";
|
||||||
|
}
|
||||||
|
# mime-part filename extension matching (no regex)
|
||||||
|
mime_parts_filter_ext {
|
||||||
|
doc = "doc";
|
||||||
|
dot = "dot";
|
||||||
|
docx = "docx";
|
||||||
|
dotx = "dotx";
|
||||||
|
docm = "docm";
|
||||||
|
dotm = "dotm";
|
||||||
|
xls = "xls";
|
||||||
|
xlt = "xlt";
|
||||||
|
xla = "xla";
|
||||||
|
xlsx = "xlsx";
|
||||||
|
xltx = "xltx";
|
||||||
|
xlsm = "xlsm";
|
||||||
|
xltm = "xltm";
|
||||||
|
xlam = "xlam";
|
||||||
|
xlsb = "xlsb";
|
||||||
|
ppt = "ppt";
|
||||||
|
pot = "pot";
|
||||||
|
pps = "pps";
|
||||||
|
ppa = "ppa";
|
||||||
|
pptx = "pptx";
|
||||||
|
potx = "potx";
|
||||||
|
ppsx = "ppsx";
|
||||||
|
ppam = "ppam";
|
||||||
|
pptm = "pptm";
|
||||||
|
potm = "potm";
|
||||||
|
ppsm = "ppsm";
|
||||||
|
slk = "slk";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
|
|||||||
|
|
||||||
os.environ["REDIS_ADDRESS"] = system.get_host_address_from_environment("REDIS", "redis")
|
os.environ["REDIS_ADDRESS"] = system.get_host_address_from_environment("REDIS", "redis")
|
||||||
os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin")
|
os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin")
|
||||||
|
os.environ["OLETOOLS_ADDRESS"] = system.get_host_address_from_environment("OLETOOLS", "oletools:11343")
|
||||||
|
|
||||||
if os.environ.get("ANTIVIRUS") == 'clamav':
|
if os.environ.get("ANTIVIRUS") == 'clamav':
|
||||||
os.environ["ANTIVIRUS_ADDRESS"] = system.get_host_address_from_environment("ANTIVIRUS", "antivirus:3310")
|
os.environ["ANTIVIRUS_ADDRESS"] = system.get_host_address_from_environment("ANTIVIRUS", "antivirus:3310")
|
||||||
|
|||||||
@@ -103,16 +103,33 @@ services:
|
|||||||
- {{ dns }}
|
- {{ dns }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
oletools:
|
||||||
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}oletools:${MAILU_VERSION:-{{ version }}}
|
||||||
|
hostname: oletools
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- noinet
|
||||||
|
depends_on:
|
||||||
|
{% if resolver_enabled %}
|
||||||
|
- resolver
|
||||||
|
dns:
|
||||||
|
- {{ dns }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
antispam:
|
antispam:
|
||||||
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-{{ version }}}
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-{{ version }}}
|
||||||
hostname: antispam
|
hostname: antispam
|
||||||
restart: always
|
restart: always
|
||||||
env_file: {{ env }}
|
env_file: {{ env }}
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- noinet
|
||||||
volumes:
|
volumes:
|
||||||
- "{{ root }}/filter:/var/lib/rspamd"
|
- "{{ root }}/filter:/var/lib/rspamd"
|
||||||
- "{{ root }}/overrides/rspamd:/etc/rspamd/override.d:ro"
|
- "{{ root }}/overrides/rspamd:/etc/rspamd/override.d:ro"
|
||||||
depends_on:
|
depends_on:
|
||||||
- front
|
- front
|
||||||
|
- oletools
|
||||||
{% if resolver_enabled %}
|
{% if resolver_enabled %}
|
||||||
- resolver
|
- resolver
|
||||||
dns:
|
dns:
|
||||||
@@ -199,3 +216,6 @@ networks:
|
|||||||
{% if ipv6_enabled %}
|
{% if ipv6_enabled %}
|
||||||
- subnet: {{ subnet6 }}
|
- subnet: {{ subnet6 }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
noinet:
|
||||||
|
driver: bridge
|
||||||
|
internal: true
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ group "default" {
|
|||||||
"antispam",
|
"antispam",
|
||||||
"front",
|
"front",
|
||||||
"imap",
|
"imap",
|
||||||
|
"oletools",
|
||||||
"smtp",
|
"smtp",
|
||||||
|
|
||||||
"webmail",
|
"webmail",
|
||||||
@@ -152,6 +153,15 @@ target "front" {
|
|||||||
tags = tag("nginx")
|
tags = tag("nginx")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target "oletools" {
|
||||||
|
inherits = ["defaults"]
|
||||||
|
context = "core/oletools/"
|
||||||
|
contexts = {
|
||||||
|
base = "target:base"
|
||||||
|
}
|
||||||
|
tags = tag("oletools")
|
||||||
|
}
|
||||||
|
|
||||||
target "imap" {
|
target "imap" {
|
||||||
inherits = ["defaults"]
|
inherits = ["defaults"]
|
||||||
context = "core/dovecot/"
|
context = "core/dovecot/"
|
||||||
|
|||||||
@@ -65,10 +65,20 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- front
|
- front
|
||||||
|
|
||||||
|
oletools:
|
||||||
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}oletools:${MAILU_VERSION:-local}
|
||||||
|
hostname: oletools
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- noinet
|
||||||
|
|
||||||
antispam:
|
antispam:
|
||||||
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
||||||
restart: always
|
restart: always
|
||||||
env_file: mailu.env
|
env_file: mailu.env
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- noinet
|
||||||
volumes:
|
volumes:
|
||||||
- "/mailu/filter:/var/lib/rspamd"
|
- "/mailu/filter:/var/lib/rspamd"
|
||||||
- "/mailu/dkim:/dkim"
|
- "/mailu/dkim:/dkim"
|
||||||
@@ -96,3 +106,6 @@ networks:
|
|||||||
driver: default
|
driver: default
|
||||||
config:
|
config:
|
||||||
- subnet: 192.168.203.0/24
|
- subnet: 192.168.203.0/24
|
||||||
|
noinet:
|
||||||
|
driver: bridge
|
||||||
|
internal: true
|
||||||
|
|||||||
@@ -65,10 +65,20 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- front
|
- front
|
||||||
|
|
||||||
|
oletools:
|
||||||
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}oletools:${MAILU_VERSION:-local}
|
||||||
|
hostname: oletools
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- noinet
|
||||||
|
|
||||||
antispam:
|
antispam:
|
||||||
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
||||||
restart: always
|
restart: always
|
||||||
env_file: mailu.env
|
env_file: mailu.env
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- noinet
|
||||||
volumes:
|
volumes:
|
||||||
- "/mailu/filter:/var/lib/rspamd"
|
- "/mailu/filter:/var/lib/rspamd"
|
||||||
- "/mailu/dkim:/dkim"
|
- "/mailu/dkim:/dkim"
|
||||||
@@ -103,3 +113,6 @@ networks:
|
|||||||
driver: default
|
driver: default
|
||||||
config:
|
config:
|
||||||
- subnet: 192.168.203.0/24
|
- subnet: 192.168.203.0/24
|
||||||
|
noinet:
|
||||||
|
driver: bridge
|
||||||
|
internal: true
|
||||||
|
|||||||
@@ -65,10 +65,20 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- front
|
- front
|
||||||
|
|
||||||
|
oletools:
|
||||||
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}oletools:${MAILU_VERSION:-local}
|
||||||
|
hostname: oletools
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- noinet
|
||||||
|
|
||||||
antispam:
|
antispam:
|
||||||
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
||||||
restart: always
|
restart: always
|
||||||
env_file: mailu.env
|
env_file: mailu.env
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- noinet
|
||||||
volumes:
|
volumes:
|
||||||
- "/mailu/filter:/var/lib/rspamd"
|
- "/mailu/filter:/var/lib/rspamd"
|
||||||
- "/mailu/dkim:/dkim"
|
- "/mailu/dkim:/dkim"
|
||||||
@@ -102,3 +112,6 @@ networks:
|
|||||||
driver: default
|
driver: default
|
||||||
config:
|
config:
|
||||||
- subnet: 192.168.203.0/24
|
- subnet: 192.168.203.0/24
|
||||||
|
noinet:
|
||||||
|
driver: bridge
|
||||||
|
internal: true
|
||||||
|
|||||||
@@ -65,10 +65,20 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- front
|
- front
|
||||||
|
|
||||||
|
oletools:
|
||||||
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}oletools:${MAILU_VERSION:-local}
|
||||||
|
hostname: oletools
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- noinet
|
||||||
|
|
||||||
antispam:
|
antispam:
|
||||||
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
||||||
restart: always
|
restart: always
|
||||||
env_file: mailu.env
|
env_file: mailu.env
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- noinet
|
||||||
volumes:
|
volumes:
|
||||||
- "/mailu/filter:/var/lib/rspamd"
|
- "/mailu/filter:/var/lib/rspamd"
|
||||||
- "/mailu/dkim:/dkim"
|
- "/mailu/dkim:/dkim"
|
||||||
@@ -103,3 +113,6 @@ networks:
|
|||||||
driver: default
|
driver: default
|
||||||
config:
|
config:
|
||||||
- subnet: 192.168.203.0/24
|
- subnet: 192.168.203.0/24
|
||||||
|
noinet:
|
||||||
|
driver: bridge
|
||||||
|
internal: true
|
||||||
|
|||||||
@@ -65,10 +65,20 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- front
|
- front
|
||||||
|
|
||||||
|
oletools:
|
||||||
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}oletools:${MAILU_VERSION:-local}
|
||||||
|
hostname: oletools
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- noinet
|
||||||
|
|
||||||
antispam:
|
antispam:
|
||||||
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local}
|
||||||
restart: always
|
restart: always
|
||||||
env_file: mailu.env
|
env_file: mailu.env
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- noinet
|
||||||
volumes:
|
volumes:
|
||||||
- "/mailu/filter:/var/lib/rspamd"
|
- "/mailu/filter:/var/lib/rspamd"
|
||||||
- "/mailu/dkim:/dkim"
|
- "/mailu/dkim:/dkim"
|
||||||
@@ -104,3 +114,6 @@ networks:
|
|||||||
driver: default
|
driver: default
|
||||||
config:
|
config:
|
||||||
- subnet: 192.168.203.0/24
|
- subnet: 192.168.203.0/24
|
||||||
|
noinet:
|
||||||
|
driver: bridge
|
||||||
|
internal: true
|
||||||
|
|||||||
1
towncrier/newsfragments/2510.feature
Normal file
1
towncrier/newsfragments/2510.feature
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Implement OLETools and block bad macros in office documents
|
||||||
Reference in New Issue
Block a user