blob: be8c12f235502ea3f6b15b5537f8c31d8cb0f48b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
import io
import zipfile
from pychrysalide.analysis.scan import ScanRegisteredItem
from pychrysalide.analysis.scan.exprs import ScanLiteralExpression
from pychrysalide.core import get_rost_root_namespace
from pychrysalide.plugins import PluginModule
class ZipBombKeyword(ScanRegisteredItem):
"""Introduce a new keyword in the ROST grammar."""
_name = 'is_zip_bomb'
def _reduce(self, ctx, scope):
expr = None
try:
has_bomb = False
# compress < 10% plain => bomb
ZIP_BOMB_RATIO = 0.01
data = io.BytesIO(ctx.content.data)
zf = zipfile.ZipFile(data)
info = zf.infolist()
for i in info:
ratio = i.compress_size / i.file_size
has_bomb = ratio < ZIP_BOMB_RATIO
if has_bomb:
break
expr = ScanLiteralExpression(has_bomb)
except:
pass
return expr
class ZipBombChecker(PluginModule):
"""Check for ZIP bombs."""
_name = 'ZipBombChecker'
_desc = 'Check if a ZIP archive may contain heavy files on extraction'
_version = '0.1'
_url = 'https://www.chrysalide.re/'
_actions = ( )
def __init__(self):
"""Create a ZipBombChecker plugin instance."""
super().__init__()
ns = get_rost_root_namespace()
kw = ZipBombKeyword()
ns.register_item(kw)
|