summaryrefslogtreecommitdiff
path: root/tests/analysis/scan/fuzzing.py
blob: c38b25c92ad786b2344055514fb5b586c72ac3eb (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

from common import RostTestClass
from pychrysalide.analysis.contents import MemoryContent
from pychrysalide.analysis.scan import ContentScanner
from pychrysalide.analysis.scan import ScanOptions
from pychrysalide.analysis.scan.patterns.backends import AcismBackend
from pychrysalide.analysis.scan.patterns.backends import BitapBackend


class TestRostFuzzingFixes(RostTestClass):
    """TestCases to remember all the fixes for crashes identified by fuzzing."""

    def testEmptyPatternListWithContent(self):
        """Check no backend is run if there is no pattern to look for."""

        content = MemoryContent(b'\n')

        rule = '''
'''

        backends = [
            AcismBackend, # This one was segfaulting
            BitapBackend,
        ]

        for b in backends:

            options = ScanOptions()
            options.backend_for_data = b

            scanner = ContentScanner(rule)
            ctx = scanner.analyze(options, content)

            self.assertIsNotNone(ctx)


    def testMandatoryCondition(self):
        """Ensure a condition section exists in a rule."""

        rule = '''
rule test {

}
'''

        with self.assertRaisesRegex(ValueError, 'Unable to create content scanner'):

            scanner = ContentScanner(rule)


    def testNonExistingPattern(self):
        """Avoid to count the matches of a non-existing pattern."""

        rule = '''
rule test {

   condition:
      #badid

}
'''

        with self.assertRaisesRegex(ValueError, 'Unable to create content scanner'):

            scanner = ContentScanner(rule)


    def testNamespacesWithoutReductionCode(self):
        """Clean the code for ROST namespaces."""

        rule = '''
rule test {

   condition:
      console

}
'''

        self.check_rule_failure(rule)


    def testCallOnNonCallable(self):
        """Reject calls on non callable expressions softly."""

        rule = '''
rule test {

   condition:
      console.log().log()

}
'''

        self.check_rule_failure(rule)


    def testSelfReferencingRule(self):
        """Reject any rule referencing itself as match condition."""

        rule = '''
rule test {

   condition:
      test

}
'''

        self.check_rule_failure(rule)


    def testSelfReferencingRule(self):
        """Expect only one argument for the not operator, even in debug mode."""

        rule = '''
rule test {

   condition:
      not(0)

}
'''

        self.check_rule_success(rule)


    def testNoCommon(self):
        """Handle the case where no common item is found from an empty set."""

        rule = '''
rule test {

   bytes:
        $a = "a"

   condition:
      maxcommon($a) == 0

}
'''

        self.check_rule_success(rule)


    def testAAsAcharacter(self):
        """Consider the 'a' character as a valid lowercase character."""

        rule = '''
rule test {

   bytes:
        $a = "0000a0I0" nocase

   condition:
      $a

}
'''

        self.check_rule_failure(rule)