Merge #2528
2528: Implement #2510: oletools integration r=mergify[bot] a=nextgens ## What type of PR? Feature ## What does this PR do? OLETools now flags documents with macros and rejects suspicious ones. We also block executable file extensions by default (but don't perform inspection in archives: you can tell users to zip-up whatever needs sending). ### Related issue(s) - closes #2510 - closes #2511 ## Prerequisites Before we can consider review and merge, please make sure the following list is done and checked. If an entry in not applicable, you can check it or remove it from the list. - [ ] In case of feature or enhancement: documentation updated accordingly - [x] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file. Co-authored-by: Florent Daigniere <nextgens@freenetproject.org> Co-authored-by: Dimitri Huisman <diman@huisman.xyz>main
commit
8d2bd6d9ff
@ -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
|
@ -0,0 +1,14 @@
|
|||||||
|
{% if SCAN_MACROS == 'True' %}
|
||||||
|
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_FLAG | OLETOOLS_VBASTOMP | OLETOOLS_A";
|
||||||
|
message = "Rejected (malicious macro)";
|
||||||
|
policy = "leave";
|
||||||
|
score = 20.0;
|
||||||
|
}
|
||||||
|
{% endif %}
|
@ -0,0 +1,64 @@
|
|||||||
|
{% if SCAN_MACROS == 'True' %}
|
||||||
|
oletools {
|
||||||
|
# default olefy settings
|
||||||
|
servers = "{{ OLETOOLS_ADDRESS }}:11343"
|
||||||
|
|
||||||
|
# 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_FOUND= '^.....M..$';
|
||||||
|
OLETOOLS_AUTOEXEC = '^A....M..$';
|
||||||
|
OLETOOLS_FLAG = '^.....MS.$';
|
||||||
|
OLETOOLS_VBASTOMP = '^VBA Stomping$';
|
||||||
|
# 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))\b|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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
@ -0,0 +1,40 @@
|
|||||||
|
{% if SCAN_MACROS == 'True' %}
|
||||||
|
# local.d/external_services_group.conf
|
||||||
|
|
||||||
|
description = "Oletools content rules";
|
||||||
|
symbols = {
|
||||||
|
"OLETOOLS" {
|
||||||
|
weight = 1.0;
|
||||||
|
description = "OLETOOLS found a Macro";
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
"OLETOOLS_MACRO_FOUND" {
|
||||||
|
weight = 0.0;
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
"OLETOOLS_AUTOEXEC" {
|
||||||
|
weight = 0.0;
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
"OLETOOLS_FLAG" {
|
||||||
|
weight = 0.0;
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
"OLETOOLS_VBASTOMP" {
|
||||||
|
weight = 0.0;
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
"OLETOOLS_A" {
|
||||||
|
weight = 0.0;
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
"OLETOOLS_W" {
|
||||||
|
weight = 0.0;
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
"OLETOOLS_X" {
|
||||||
|
weight = 0.0;
|
||||||
|
one_shot = true;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
{% endif %}
|
@ -0,0 +1,68 @@
|
|||||||
|
ace
|
||||||
|
ade
|
||||||
|
adp
|
||||||
|
apk
|
||||||
|
appx
|
||||||
|
appxbundle
|
||||||
|
arj
|
||||||
|
bat
|
||||||
|
bin
|
||||||
|
cab
|
||||||
|
chm
|
||||||
|
class
|
||||||
|
cmd
|
||||||
|
com
|
||||||
|
cpl
|
||||||
|
diagcab
|
||||||
|
diagcfg
|
||||||
|
diagpack
|
||||||
|
dll
|
||||||
|
ex
|
||||||
|
ex_
|
||||||
|
exe
|
||||||
|
hlp
|
||||||
|
hta
|
||||||
|
img
|
||||||
|
ins
|
||||||
|
iso
|
||||||
|
isp
|
||||||
|
jar
|
||||||
|
jnlp
|
||||||
|
js
|
||||||
|
jse
|
||||||
|
lib
|
||||||
|
lnk
|
||||||
|
lzh
|
||||||
|
mde
|
||||||
|
msc
|
||||||
|
msi
|
||||||
|
msix
|
||||||
|
msixbundle
|
||||||
|
msp
|
||||||
|
mst
|
||||||
|
msu
|
||||||
|
nsh
|
||||||
|
ocx
|
||||||
|
ovl
|
||||||
|
pif
|
||||||
|
ps1
|
||||||
|
r01
|
||||||
|
r14
|
||||||
|
r18
|
||||||
|
r25
|
||||||
|
scr
|
||||||
|
sct
|
||||||
|
shb
|
||||||
|
shs
|
||||||
|
sys
|
||||||
|
vb
|
||||||
|
vbe
|
||||||
|
vbs
|
||||||
|
vbscript
|
||||||
|
vdl
|
||||||
|
vhd
|
||||||
|
vxd
|
||||||
|
wsc
|
||||||
|
wsf
|
||||||
|
wsh
|
||||||
|
xll
|
@ -1,6 +1,6 @@
|
|||||||
python3 tests/email_test.py message-virus "tests/compose/filters/eicar.com"
|
python3 tests/email_test.py message-virus "tests/compose/filters/eicar.com.txt"
|
||||||
if [ $? -eq 99 ]; then
|
if [ $? -eq 99 ]; then
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
# Malicious macros should be blocked
|
||||||
|
# see https://github.com/clr2of8/VBAstomp and https://github.com/decalage2/oletools/wiki/mraptor
|
||||||
|
python3 tests/email_test.py message-macro-stomp "tests/compose/filters/2003x32_word_msgbox_stomped_fakecode.doc"
|
||||||
|
if [ $? -ne 25 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# This does Auto_Open + Alert()
|
||||||
|
python3 tests/email_test.py message-autoexec-macro "tests/compose/filters/excel4_sample_macro.slk"
|
||||||
|
if [ $? -ne 25 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
Binary file not shown.
@ -0,0 +1,68 @@
|
|||||||
|
ID;PWXL;N;E
|
||||||
|
P;PGeneral
|
||||||
|
P;P0
|
||||||
|
P;P0.00
|
||||||
|
P;P#,##0
|
||||||
|
P;P#,##0.00
|
||||||
|
P;P#,##0;;\-#,##0
|
||||||
|
P;P#,##0;;[Red]\-#,##0
|
||||||
|
P;P#,##0.00;;\-#,##0.00
|
||||||
|
P;P#,##0.00;;[Red]\-#,##0.00
|
||||||
|
P;P#,##0\ "$";;\-#,##0\ "$"
|
||||||
|
P;P#,##0\ "$";;[Red]\-#,##0\ "$"
|
||||||
|
P;P#,##0.00\ "$";;\-#,##0.00\ "$"
|
||||||
|
P;P#,##0.00\ "$";;[Red]\-#,##0.00\ "$"
|
||||||
|
P;P0%
|
||||||
|
P;P0.00%
|
||||||
|
P;P0.00E+00
|
||||||
|
P;P##0.0E+0
|
||||||
|
P;P#" "?/?
|
||||||
|
P;P#" "??/??
|
||||||
|
P;Pdd/mm/yyyy
|
||||||
|
P;Pdd\-mmm\-yy
|
||||||
|
P;Pdd\-mmm
|
||||||
|
P;Pmmm\-yy
|
||||||
|
P;Ph:mm\ AM/PM
|
||||||
|
P;Ph:mm:ss\ AM/PM
|
||||||
|
P;Phh:mm
|
||||||
|
P;Phh:mm:ss
|
||||||
|
P;Pdd/mm/yyyy\ hh:mm
|
||||||
|
P;Pmm:ss
|
||||||
|
P;Pmm:ss.0
|
||||||
|
P;P@
|
||||||
|
P;P[h]:mm:ss
|
||||||
|
P;P_-* #,##0\ "$"_-;;\-* #,##0\ "$"_-;;_-* "-"\ "$"_-;;_-@_-
|
||||||
|
P;P_-* #,##0_-;;\-* #,##0_-;;_-* "-"_-;;_-@_-
|
||||||
|
P;P_-* #,##0.00\ "$"_-;;\-* #,##0.00\ "$"_-;;_-* "-"??\ "$"_-;;_-@_-
|
||||||
|
P;P_-* #,##0.00_-;;\-* #,##0.00_-;;_-* "-"??_-;;_-@_-
|
||||||
|
P;FCalibri;M220;L9
|
||||||
|
P;FCalibri;M220;L9
|
||||||
|
P;FCalibri;M220;L9
|
||||||
|
P;FCalibri;M220;L9
|
||||||
|
P;ECalibri;M220;L9
|
||||||
|
P;ECalibri Light;M360;L55
|
||||||
|
P;ECalibri;M300;SB;L55
|
||||||
|
P;ECalibri;M260;SB;L55
|
||||||
|
P;ECalibri;M220;SB;L55
|
||||||
|
P;ECalibri;M220;L18
|
||||||
|
P;ECalibri;M220;L21
|
||||||
|
P;ECalibri;M220;L61
|
||||||
|
P;ECalibri;M220;L63
|
||||||
|
P;ECalibri;M220;SB;L64
|
||||||
|
P;ECalibri;M220;SB;L53
|
||||||
|
P;ECalibri;M220;L53
|
||||||
|
P;ECalibri;M220;SB;L10
|
||||||
|
P;ECalibri;M220;L11
|
||||||
|
P;ECalibri;M220;SI;L24
|
||||||
|
P;ECalibri;M220;SB;L9
|
||||||
|
P;ECalibri;M220;L10
|
||||||
|
P;ESegoe UI;M200;L9
|
||||||
|
F;P0;DG0G8;E;M292
|
||||||
|
B;Y2;X1;D0 0 1 0
|
||||||
|
O;L;E;D;V0;K47;G100 0.001
|
||||||
|
F;W1 1 17
|
||||||
|
F;W2 16384 9
|
||||||
|
NN;NAuto_Open;ER1C1
|
||||||
|
C;Y1;X1;KFALSE;EALERT("This is a sample Excel 4 macro")
|
||||||
|
C;Y2;KTRUE;EHALT()
|
||||||
|
E
|
@ -0,0 +1 @@
|
|||||||
|
Implement OLETools and block bad macros in office documents
|
@ -0,0 +1 @@
|
|||||||
|
Block executable file formats by default. Ask your users to zip them up if required.
|
Loading…
Reference in New Issue