azul-runner 9.0.38__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- azul_runner-9.0.38/.github/CODEOWNERS +1 -0
- azul_runner-9.0.38/.gitignore +247 -0
- azul_runner-9.0.38/PKG-INFO +178 -0
- azul_runner-9.0.38/README.md +131 -0
- azul_runner-9.0.38/azul_runner/__init__.py +58 -0
- azul_runner-9.0.38/azul_runner/binary_plugin.py +22 -0
- azul_runner-9.0.38/azul_runner/coordinator.py +387 -0
- azul_runner-9.0.38/azul_runner/local.py +102 -0
- azul_runner-9.0.38/azul_runner/log_setup.py +61 -0
- azul_runner-9.0.38/azul_runner/main.py +442 -0
- azul_runner-9.0.38/azul_runner/models.py +574 -0
- azul_runner-9.0.38/azul_runner/monitor.py +635 -0
- azul_runner-9.0.38/azul_runner/network.py +191 -0
- azul_runner-9.0.38/azul_runner/network_transform.py +294 -0
- azul_runner-9.0.38/azul_runner/plugin.py +210 -0
- azul_runner-9.0.38/azul_runner/plugin_executor.py +223 -0
- azul_runner-9.0.38/azul_runner/pusher.py +268 -0
- azul_runner-9.0.38/azul_runner/settings.py +257 -0
- azul_runner-9.0.38/azul_runner/storage.py +527 -0
- azul_runner-9.0.38/azul_runner/storage_spooled.py +24 -0
- azul_runner-9.0.38/azul_runner/test_utils/__init__.py +8 -0
- azul_runner-9.0.38/azul_runner/test_utils/test_template.py +633 -0
- azul_runner-9.0.38/azul_runner.egg-info/PKG-INFO +178 -0
- azul_runner-9.0.38/azul_runner.egg-info/SOURCES.txt +82 -0
- azul_runner-9.0.38/azul_runner.egg-info/dependency_links.txt +1 -0
- azul_runner-9.0.38/azul_runner.egg-info/requires.txt +19 -0
- azul_runner-9.0.38/azul_runner.egg-info/top_level.txt +1 -0
- azul_runner-9.0.38/debian.txt +1 -0
- azul_runner-9.0.38/docs/coding/children.md +45 -0
- azul_runner-9.0.38/docs/coding/config.md +66 -0
- azul_runner-9.0.38/docs/coding/features.md +90 -0
- azul_runner-9.0.38/docs/coding/index.md +184 -0
- azul_runner-9.0.38/docs/coding/info.md +25 -0
- azul_runner-9.0.38/docs/coding/logging.md +13 -0
- azul_runner-9.0.38/docs/coding/runtime.md +26 -0
- azul_runner-9.0.38/docs/coding/security.md +26 -0
- azul_runner-9.0.38/docs/coding/status.md +83 -0
- azul_runner-9.0.38/docs/coding/streams.md +102 -0
- azul_runner-9.0.38/docs/coding/tests.md +100 -0
- azul_runner-9.0.38/docs/features.md +161 -0
- azul_runner-9.0.38/docs/index.md +394 -0
- azul_runner-9.0.38/docs/migration.md +126 -0
- azul_runner-9.0.38/docs/monitor.md +63 -0
- azul_runner-9.0.38/docs/structure.md +151 -0
- azul_runner-9.0.38/license.md +9 -0
- azul_runner-9.0.38/pipeline-mirror.yaml +25 -0
- azul_runner-9.0.38/pipeline.yaml +34 -0
- azul_runner-9.0.38/pyproject.toml +39 -0
- azul_runner-9.0.38/requirements.txt +8 -0
- azul_runner-9.0.38/requirements_tests.txt +9 -0
- azul_runner-9.0.38/setup.cfg +4 -0
- azul_runner-9.0.38/setup.py +45 -0
- azul_runner-9.0.38/tests/__init__.py +13 -0
- azul_runner-9.0.38/tests/binary_plugin/__init__.py +0 -0
- azul_runner-9.0.38/tests/binary_plugin/test_dataless.py +40 -0
- azul_runner-9.0.38/tests/binary_plugin/test_dynamic.py +187 -0
- azul_runner-9.0.38/tests/binary_plugin/test_static.py +163 -0
- azul_runner-9.0.38/tests/data/binary_event_message.json +70 -0
- azul_runner-9.0.38/tests/data/peanut.txt +11 -0
- azul_runner-9.0.38/tests/data/u_testfile.cart +0 -0
- azul_runner-9.0.38/tests/example_plugins.py +112 -0
- azul_runner-9.0.38/tests/mock_dispatcher.py +257 -0
- azul_runner-9.0.38/tests/plugin_support.py +97 -0
- azul_runner-9.0.38/tests/test_delete_temp.py +71 -0
- azul_runner-9.0.38/tests/test_main.py +1052 -0
- azul_runner-9.0.38/tests/test_mock_dispatcher.py +139 -0
- azul_runner-9.0.38/tests/test_models.py +35 -0
- azul_runner-9.0.38/tests/test_models_network.py +27 -0
- azul_runner-9.0.38/tests/test_network_transform.py +1009 -0
- azul_runner-9.0.38/tests/test_plugin_children.py +339 -0
- azul_runner-9.0.38/tests/test_plugin_execution.py +877 -0
- azul_runner-9.0.38/tests/test_plugin_grandchildren.py +380 -0
- azul_runner-9.0.38/tests/test_plugin_live.py +1959 -0
- azul_runner-9.0.38/tests/test_plugin_misc.py +410 -0
- azul_runner-9.0.38/tests/test_plugin_multi.py +491 -0
- azul_runner-9.0.38/tests/test_plugin_oom.py +245 -0
- azul_runner-9.0.38/tests/test_plugin_pusher.py +559 -0
- azul_runner-9.0.38/tests/test_plugin_sigterm.py +180 -0
- azul_runner-9.0.38/tests/test_plugin_static.py +381 -0
- azul_runner-9.0.38/tests/test_plugin_timeout.py +313 -0
- azul_runner-9.0.38/tests/test_plugin_watch.py +165 -0
- azul_runner-9.0.38/tests/test_storage.py +319 -0
- azul_runner-9.0.38/tests/test_structures.py +108 -0
- azul_runner-9.0.38/tox.ini +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @AustralianCyberSecurityCentre/azul-admins
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
docker/tmp/
|
|
2
|
+
|
|
3
|
+
# Created by https://www.gitignore.io/api/vim,python,pycharm
|
|
4
|
+
# Edit at https://www.gitignore.io/?templates=vim,python,pycharm
|
|
5
|
+
|
|
6
|
+
### PyCharm ###
|
|
7
|
+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
|
8
|
+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
9
|
+
.idea
|
|
10
|
+
|
|
11
|
+
# User-specific stuff
|
|
12
|
+
.idea/**/workspace.xml
|
|
13
|
+
.idea/**/tasks.xml
|
|
14
|
+
.idea/**/usage.statistics.xml
|
|
15
|
+
.idea/**/dictionaries
|
|
16
|
+
.idea/**/shelf
|
|
17
|
+
|
|
18
|
+
# Generated files
|
|
19
|
+
.idea/**/contentModel.xml
|
|
20
|
+
|
|
21
|
+
# Sensitive or high-churn files
|
|
22
|
+
.idea/**/dataSources/
|
|
23
|
+
.idea/**/dataSources.ids
|
|
24
|
+
.idea/**/dataSources.local.xml
|
|
25
|
+
.idea/**/sqlDataSources.xml
|
|
26
|
+
.idea/**/dynamic.xml
|
|
27
|
+
.idea/**/uiDesigner.xml
|
|
28
|
+
.idea/**/dbnavigator.xml
|
|
29
|
+
|
|
30
|
+
# Gradle
|
|
31
|
+
.idea/**/gradle.xml
|
|
32
|
+
.idea/**/libraries
|
|
33
|
+
|
|
34
|
+
# Gradle and Maven with auto-import
|
|
35
|
+
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
36
|
+
# since they will be recreated, and may cause churn. Uncomment if using
|
|
37
|
+
# auto-import.
|
|
38
|
+
# .idea/modules.xml
|
|
39
|
+
# .idea/*.iml
|
|
40
|
+
# .idea/modules
|
|
41
|
+
|
|
42
|
+
# CMake
|
|
43
|
+
cmake-build-*/
|
|
44
|
+
|
|
45
|
+
# Mongo Explorer plugin
|
|
46
|
+
.idea/**/mongoSettings.xml
|
|
47
|
+
|
|
48
|
+
# File-based project format
|
|
49
|
+
*.iws
|
|
50
|
+
|
|
51
|
+
# IntelliJ
|
|
52
|
+
out/
|
|
53
|
+
|
|
54
|
+
# mpeltonen/sbt-idea plugin
|
|
55
|
+
.idea_modules/
|
|
56
|
+
|
|
57
|
+
# JIRA plugin
|
|
58
|
+
atlassian-ide-plugin.xml
|
|
59
|
+
|
|
60
|
+
# Cursive Clojure plugin
|
|
61
|
+
.idea/replstate.xml
|
|
62
|
+
|
|
63
|
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
64
|
+
com_crashlytics_export_strings.xml
|
|
65
|
+
crashlytics.properties
|
|
66
|
+
crashlytics-build.properties
|
|
67
|
+
fabric.properties
|
|
68
|
+
|
|
69
|
+
# Editor-based Rest Client
|
|
70
|
+
.idea/httpRequests
|
|
71
|
+
|
|
72
|
+
# Android studio 3.1+ serialized cache file
|
|
73
|
+
.idea/caches/build_file_checksums.ser
|
|
74
|
+
|
|
75
|
+
### PyCharm Patch ###
|
|
76
|
+
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
|
77
|
+
|
|
78
|
+
# *.iml
|
|
79
|
+
# modules.xml
|
|
80
|
+
# .idea/misc.xml
|
|
81
|
+
# *.ipr
|
|
82
|
+
|
|
83
|
+
# Sonarlint plugin
|
|
84
|
+
.idea/sonarlint
|
|
85
|
+
|
|
86
|
+
### Python ###
|
|
87
|
+
# Byte-compiled / optimized / DLL files
|
|
88
|
+
__pycache__/
|
|
89
|
+
*.py[cod]
|
|
90
|
+
*$py.class
|
|
91
|
+
|
|
92
|
+
# C extensions
|
|
93
|
+
*.so
|
|
94
|
+
|
|
95
|
+
# Distribution / packaging
|
|
96
|
+
.Python
|
|
97
|
+
build/
|
|
98
|
+
develop-eggs/
|
|
99
|
+
dist/
|
|
100
|
+
downloads/
|
|
101
|
+
eggs/
|
|
102
|
+
.eggs/
|
|
103
|
+
lib/
|
|
104
|
+
lib64/
|
|
105
|
+
parts/
|
|
106
|
+
sdist/
|
|
107
|
+
var/
|
|
108
|
+
wheels/
|
|
109
|
+
pip-wheel-metadata/
|
|
110
|
+
share/python-wheels/
|
|
111
|
+
*.egg-info/
|
|
112
|
+
.installed.cfg
|
|
113
|
+
*.egg
|
|
114
|
+
MANIFEST
|
|
115
|
+
|
|
116
|
+
# PyInstaller
|
|
117
|
+
# Usually these files are written by a python script from a template
|
|
118
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
119
|
+
*.manifest
|
|
120
|
+
*.spec
|
|
121
|
+
|
|
122
|
+
# Installer logs
|
|
123
|
+
pip-log.txt
|
|
124
|
+
pip-delete-this-directory.txt
|
|
125
|
+
|
|
126
|
+
# Unit test / coverage reports
|
|
127
|
+
htmlcov/
|
|
128
|
+
.tox/
|
|
129
|
+
.nox/
|
|
130
|
+
.coverage
|
|
131
|
+
.coverage.*
|
|
132
|
+
.cache
|
|
133
|
+
nosetests.xml
|
|
134
|
+
coverage.xml
|
|
135
|
+
*.cover
|
|
136
|
+
.hypothesis/
|
|
137
|
+
.pytest_cache/
|
|
138
|
+
|
|
139
|
+
# Translations
|
|
140
|
+
*.mo
|
|
141
|
+
*.pot
|
|
142
|
+
|
|
143
|
+
# Django stuff:
|
|
144
|
+
*.log
|
|
145
|
+
local_settings.py
|
|
146
|
+
db.sqlite3
|
|
147
|
+
|
|
148
|
+
# Flask stuff:
|
|
149
|
+
instance/
|
|
150
|
+
.webassets-cache
|
|
151
|
+
|
|
152
|
+
# Scrapy stuff:
|
|
153
|
+
.scrapy
|
|
154
|
+
|
|
155
|
+
# Sphinx documentation
|
|
156
|
+
docs/_build/
|
|
157
|
+
|
|
158
|
+
# PyBuilder
|
|
159
|
+
target/
|
|
160
|
+
|
|
161
|
+
# Jupyter Notebook
|
|
162
|
+
.ipynb_checkpoints
|
|
163
|
+
|
|
164
|
+
# IPython
|
|
165
|
+
profile_default/
|
|
166
|
+
ipython_config.py
|
|
167
|
+
|
|
168
|
+
# pyenv
|
|
169
|
+
.python-version
|
|
170
|
+
|
|
171
|
+
# celery beat schedule file
|
|
172
|
+
celerybeat-schedule
|
|
173
|
+
|
|
174
|
+
# SageMath parsed files
|
|
175
|
+
*.sage.py
|
|
176
|
+
|
|
177
|
+
# Environments
|
|
178
|
+
.env
|
|
179
|
+
.venv
|
|
180
|
+
env/
|
|
181
|
+
venv/
|
|
182
|
+
ENV/
|
|
183
|
+
env.bak/
|
|
184
|
+
venv.bak/
|
|
185
|
+
|
|
186
|
+
# Spyder project settings
|
|
187
|
+
.spyderproject
|
|
188
|
+
.spyproject
|
|
189
|
+
|
|
190
|
+
# Rope project settings
|
|
191
|
+
.ropeproject
|
|
192
|
+
|
|
193
|
+
# mkdocs documentation
|
|
194
|
+
/site
|
|
195
|
+
|
|
196
|
+
# mypy
|
|
197
|
+
.mypy_cache/
|
|
198
|
+
.dmypy.json
|
|
199
|
+
dmypy.json
|
|
200
|
+
|
|
201
|
+
# Pyre type checker
|
|
202
|
+
.pyre/
|
|
203
|
+
|
|
204
|
+
### Python Patch ###
|
|
205
|
+
.venv/
|
|
206
|
+
|
|
207
|
+
### Vim ###
|
|
208
|
+
# Swap
|
|
209
|
+
[._]*.s[a-v][a-z]
|
|
210
|
+
[._]*.sw[a-p]
|
|
211
|
+
[._]s[a-rt-v][a-z]
|
|
212
|
+
[._]ss[a-gi-z]
|
|
213
|
+
[._]sw[a-p]
|
|
214
|
+
|
|
215
|
+
# Session
|
|
216
|
+
Session.vim
|
|
217
|
+
|
|
218
|
+
# Temporary
|
|
219
|
+
.netrwhist
|
|
220
|
+
*~
|
|
221
|
+
# Auto-generated tag files
|
|
222
|
+
tags
|
|
223
|
+
# Persistent undo
|
|
224
|
+
[._]*.un~
|
|
225
|
+
|
|
226
|
+
# End of https://www.gitignore.io/api/vim,python,pycharm
|
|
227
|
+
|
|
228
|
+
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode
|
|
229
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode
|
|
230
|
+
|
|
231
|
+
### VisualStudioCode ###
|
|
232
|
+
.vscode/*
|
|
233
|
+
#!.vscode/settings.json
|
|
234
|
+
#!.vscode/tasks.json
|
|
235
|
+
#!.vscode/launch.json
|
|
236
|
+
#!.vscode/extensions.json
|
|
237
|
+
*.code-workspace
|
|
238
|
+
|
|
239
|
+
# Local History for Visual Studio Code
|
|
240
|
+
.history/
|
|
241
|
+
|
|
242
|
+
### VisualStudioCode Patch ###
|
|
243
|
+
# Ignore all local history of files
|
|
244
|
+
.history
|
|
245
|
+
.ionide
|
|
246
|
+
|
|
247
|
+
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: azul-runner
|
|
3
|
+
Version: 9.0.38
|
|
4
|
+
Summary: Core framework for writing Python plugins for Azul.
|
|
5
|
+
Home-page: https://www.asd.gov.au/
|
|
6
|
+
Author: Azul
|
|
7
|
+
Author-email: azul@asd.gov.au
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: azul-bedrock
|
|
20
|
+
Requires-Dist: bitarray>=0.9
|
|
21
|
+
Requires-Dist: cart
|
|
22
|
+
Requires-Dist: httpx
|
|
23
|
+
Requires-Dist: pydantic>2
|
|
24
|
+
Requires-Dist: pydantic-settings
|
|
25
|
+
Requires-Dist: watchdog
|
|
26
|
+
Requires-Dist: psutil
|
|
27
|
+
Provides-Extra: test-utils
|
|
28
|
+
Requires-Dist: azul-bedrock[test_utils]; extra == "test-utils"
|
|
29
|
+
Requires-Dist: black; extra == "test-utils"
|
|
30
|
+
Requires-Dist: fastapi; extra == "test-utils"
|
|
31
|
+
Requires-Dist: pytest; extra == "test-utils"
|
|
32
|
+
Requires-Dist: tox; extra == "test-utils"
|
|
33
|
+
Requires-Dist: uvicorn[standard]; extra == "test-utils"
|
|
34
|
+
Requires-Dist: pytest-timeout; extra == "test-utils"
|
|
35
|
+
Requires-Dist: yara-x; extra == "test-utils"
|
|
36
|
+
Requires-Dist: urllib3; extra == "test-utils"
|
|
37
|
+
Dynamic: author
|
|
38
|
+
Dynamic: author-email
|
|
39
|
+
Dynamic: classifier
|
|
40
|
+
Dynamic: description
|
|
41
|
+
Dynamic: description-content-type
|
|
42
|
+
Dynamic: home-page
|
|
43
|
+
Dynamic: provides-extra
|
|
44
|
+
Dynamic: requires-dist
|
|
45
|
+
Dynamic: requires-python
|
|
46
|
+
Dynamic: summary
|
|
47
|
+
|
|
48
|
+
# Azul Runner
|
|
49
|
+
|
|
50
|
+
Core framework for writing Python plugins for Azul.
|
|
51
|
+
|
|
52
|
+
It handles filtering and fetching events, setting up data streams, and
|
|
53
|
+
parsing and validating plugin results before posting output events
|
|
54
|
+
back to the dispatcher.
|
|
55
|
+
|
|
56
|
+
Additionally, it allows plugins to be run
|
|
57
|
+
locally from the commandline, with local files or folders as input data.
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
To run a plugin (after installing azul-runner and the plugin as Python packages):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# against local samples
|
|
65
|
+
$ azul-plugin-(name) local_file.bin
|
|
66
|
+
$ azul-plugin-(name) local_folder/
|
|
67
|
+
|
|
68
|
+
# against remote dispatcher
|
|
69
|
+
$ azul-plugin-(name) --server http://server.address/path
|
|
70
|
+
|
|
71
|
+
# with custom config
|
|
72
|
+
$ azul-plugin-(name) -c KEY VALUE -c KEY2 VALUE2
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Plugins may define multiple entrypoints, check the plugins setup.py for details.
|
|
76
|
+
|
|
77
|
+
Plugin configuration may be passed in as environment variables.
|
|
78
|
+
|
|
79
|
+
Check ./azul_runner/settings.py for specific options
|
|
80
|
+
|
|
81
|
+
- PLUGIN_RUN_TIMEOUT=600
|
|
82
|
+
- PLUGIN_SERVER=http://widgets.co.internal
|
|
83
|
+
|
|
84
|
+
## Plugin Development
|
|
85
|
+
|
|
86
|
+
Use the project `azure-generator` to generate boilerplate code for a new plugin.
|
|
87
|
+
|
|
88
|
+
For most common use cases, inherit from `azul_runner.BinaryPlugin` and implement the `execute` method.
|
|
89
|
+
It is recommended to look at existing plugins in order to implement your plugin.
|
|
90
|
+
You can also check binary_plugin.py and plugin.py for more properties that can be configured.
|
|
91
|
+
|
|
92
|
+
Advanced use cases may inherit from `azul_runner.Plugin` instead.
|
|
93
|
+
|
|
94
|
+
For more documentation on development process, see [here](./docs/index.md)
|
|
95
|
+
|
|
96
|
+
For more documentation on specific api usage and plugin code, see [here](./docs/coding/index.md)
|
|
97
|
+
|
|
98
|
+
See [structure](./docs/structure.md) for more information about the structure of azul-runner.
|
|
99
|
+
|
|
100
|
+
See [migration guide](./docs/migration.md) to update your plugin in line with api changes in azul-runner.
|
|
101
|
+
|
|
102
|
+
## Example Plugin
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from azul_runner import BinaryPlugin, Feature, Job, cmdline_run, State, FeatureType
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class LookForThings(BinaryPlugin):
|
|
109
|
+
"""Look for things."""
|
|
110
|
+
|
|
111
|
+
VERSION = "1.0"
|
|
112
|
+
SETTINGS = add_settings(
|
|
113
|
+
# You can filter assemblyline file types as below.
|
|
114
|
+
# These are the files that your plugin will process.
|
|
115
|
+
# Note: you can filter by prefix (document/).
|
|
116
|
+
# Check azul-bedrock/identify.yaml for valid file types.
|
|
117
|
+
filter_data_types={
|
|
118
|
+
"content": [
|
|
119
|
+
"text/plain",
|
|
120
|
+
"document/",
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
FEATURES = [
|
|
125
|
+
Feature("tag", "Custom tag", FeatureType.String),
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
def execute(self, job: Job):
|
|
129
|
+
"""Find peanuts."""
|
|
130
|
+
data = job.get_data()
|
|
131
|
+
# 'data' is a file-like object that supports seeking and being read from
|
|
132
|
+
# (The content may be retrieved in parts if the file is large and non-local)
|
|
133
|
+
header: bytes = data.read(7)
|
|
134
|
+
if header == b"PEANUT:":
|
|
135
|
+
# create a tag
|
|
136
|
+
self.add_feature_values("tag", "may contain nuts")
|
|
137
|
+
# add the next 24 bytes as a child
|
|
138
|
+
c = self.add_child_with_data(
|
|
139
|
+
relationship={"label": "peanut"},
|
|
140
|
+
data=data.read(24),
|
|
141
|
+
)
|
|
142
|
+
c.add_feature_values("tag", "may be hard to crack")
|
|
143
|
+
else:
|
|
144
|
+
return State.Label.OPT_OUT
|
|
145
|
+
|
|
146
|
+
if __name__ == '__main__':
|
|
147
|
+
cmdline_run(plugin=LookForThings)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Execution
|
|
151
|
+
|
|
152
|
+
As the example plugin was not constructed in `azure-generator`, running them requires directly executing
|
|
153
|
+
the script they are contained in. A copy can be found in `tests/example_plugins.py`.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
azul-runner$ python tests/example_plugins.py tests/data/peanut.txt
|
|
157
|
+
----- LookForThings results -----
|
|
158
|
+
COMPLETED
|
|
159
|
+
|
|
160
|
+
events (2)
|
|
161
|
+
|
|
162
|
+
event for cmdline_entity:None
|
|
163
|
+
{}
|
|
164
|
+
output features:
|
|
165
|
+
tag: may contain nuts
|
|
166
|
+
|
|
167
|
+
event for 7c4cd5274277dde41aa3f5e06cfca8c6cc703951a642b6c268cb43a2b345780a:None
|
|
168
|
+
{'label': 'peanut'}
|
|
169
|
+
child of cmdline_entity
|
|
170
|
+
output data streams (1):
|
|
171
|
+
24 bytes - EventData(hash='7c4cd5274277dde41aa3f5e06cfca8c6cc703951a642b6c268cb43a2b345780a', label='content')
|
|
172
|
+
output features:
|
|
173
|
+
tag: may be hard to crack
|
|
174
|
+
|
|
175
|
+
Feature key:
|
|
176
|
+
tag: Custom tag
|
|
177
|
+
|
|
178
|
+
```
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Azul Runner
|
|
2
|
+
|
|
3
|
+
Core framework for writing Python plugins for Azul.
|
|
4
|
+
|
|
5
|
+
It handles filtering and fetching events, setting up data streams, and
|
|
6
|
+
parsing and validating plugin results before posting output events
|
|
7
|
+
back to the dispatcher.
|
|
8
|
+
|
|
9
|
+
Additionally, it allows plugins to be run
|
|
10
|
+
locally from the commandline, with local files or folders as input data.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
To run a plugin (after installing azul-runner and the plugin as Python packages):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# against local samples
|
|
18
|
+
$ azul-plugin-(name) local_file.bin
|
|
19
|
+
$ azul-plugin-(name) local_folder/
|
|
20
|
+
|
|
21
|
+
# against remote dispatcher
|
|
22
|
+
$ azul-plugin-(name) --server http://server.address/path
|
|
23
|
+
|
|
24
|
+
# with custom config
|
|
25
|
+
$ azul-plugin-(name) -c KEY VALUE -c KEY2 VALUE2
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Plugins may define multiple entrypoints, check the plugins setup.py for details.
|
|
29
|
+
|
|
30
|
+
Plugin configuration may be passed in as environment variables.
|
|
31
|
+
|
|
32
|
+
Check ./azul_runner/settings.py for specific options
|
|
33
|
+
|
|
34
|
+
- PLUGIN_RUN_TIMEOUT=600
|
|
35
|
+
- PLUGIN_SERVER=http://widgets.co.internal
|
|
36
|
+
|
|
37
|
+
## Plugin Development
|
|
38
|
+
|
|
39
|
+
Use the project `azure-generator` to generate boilerplate code for a new plugin.
|
|
40
|
+
|
|
41
|
+
For most common use cases, inherit from `azul_runner.BinaryPlugin` and implement the `execute` method.
|
|
42
|
+
It is recommended to look at existing plugins in order to implement your plugin.
|
|
43
|
+
You can also check binary_plugin.py and plugin.py for more properties that can be configured.
|
|
44
|
+
|
|
45
|
+
Advanced use cases may inherit from `azul_runner.Plugin` instead.
|
|
46
|
+
|
|
47
|
+
For more documentation on development process, see [here](./docs/index.md)
|
|
48
|
+
|
|
49
|
+
For more documentation on specific api usage and plugin code, see [here](./docs/coding/index.md)
|
|
50
|
+
|
|
51
|
+
See [structure](./docs/structure.md) for more information about the structure of azul-runner.
|
|
52
|
+
|
|
53
|
+
See [migration guide](./docs/migration.md) to update your plugin in line with api changes in azul-runner.
|
|
54
|
+
|
|
55
|
+
## Example Plugin
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from azul_runner import BinaryPlugin, Feature, Job, cmdline_run, State, FeatureType
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class LookForThings(BinaryPlugin):
|
|
62
|
+
"""Look for things."""
|
|
63
|
+
|
|
64
|
+
VERSION = "1.0"
|
|
65
|
+
SETTINGS = add_settings(
|
|
66
|
+
# You can filter assemblyline file types as below.
|
|
67
|
+
# These are the files that your plugin will process.
|
|
68
|
+
# Note: you can filter by prefix (document/).
|
|
69
|
+
# Check azul-bedrock/identify.yaml for valid file types.
|
|
70
|
+
filter_data_types={
|
|
71
|
+
"content": [
|
|
72
|
+
"text/plain",
|
|
73
|
+
"document/",
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
FEATURES = [
|
|
78
|
+
Feature("tag", "Custom tag", FeatureType.String),
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
def execute(self, job: Job):
|
|
82
|
+
"""Find peanuts."""
|
|
83
|
+
data = job.get_data()
|
|
84
|
+
# 'data' is a file-like object that supports seeking and being read from
|
|
85
|
+
# (The content may be retrieved in parts if the file is large and non-local)
|
|
86
|
+
header: bytes = data.read(7)
|
|
87
|
+
if header == b"PEANUT:":
|
|
88
|
+
# create a tag
|
|
89
|
+
self.add_feature_values("tag", "may contain nuts")
|
|
90
|
+
# add the next 24 bytes as a child
|
|
91
|
+
c = self.add_child_with_data(
|
|
92
|
+
relationship={"label": "peanut"},
|
|
93
|
+
data=data.read(24),
|
|
94
|
+
)
|
|
95
|
+
c.add_feature_values("tag", "may be hard to crack")
|
|
96
|
+
else:
|
|
97
|
+
return State.Label.OPT_OUT
|
|
98
|
+
|
|
99
|
+
if __name__ == '__main__':
|
|
100
|
+
cmdline_run(plugin=LookForThings)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Execution
|
|
104
|
+
|
|
105
|
+
As the example plugin was not constructed in `azure-generator`, running them requires directly executing
|
|
106
|
+
the script they are contained in. A copy can be found in `tests/example_plugins.py`.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
azul-runner$ python tests/example_plugins.py tests/data/peanut.txt
|
|
110
|
+
----- LookForThings results -----
|
|
111
|
+
COMPLETED
|
|
112
|
+
|
|
113
|
+
events (2)
|
|
114
|
+
|
|
115
|
+
event for cmdline_entity:None
|
|
116
|
+
{}
|
|
117
|
+
output features:
|
|
118
|
+
tag: may contain nuts
|
|
119
|
+
|
|
120
|
+
event for 7c4cd5274277dde41aa3f5e06cfca8c6cc703951a642b6c268cb43a2b345780a:None
|
|
121
|
+
{'label': 'peanut'}
|
|
122
|
+
child of cmdline_entity
|
|
123
|
+
output data streams (1):
|
|
124
|
+
24 bytes - EventData(hash='7c4cd5274277dde41aa3f5e06cfca8c6cc703951a642b6c268cb43a2b345780a', label='content')
|
|
125
|
+
output features:
|
|
126
|
+
tag: may be hard to crack
|
|
127
|
+
|
|
128
|
+
Feature key:
|
|
129
|
+
tag: Custom tag
|
|
130
|
+
|
|
131
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# flake8: noqa - Flake8 doesn't detect these exported functions and classes properly.
|
|
2
|
+
import contextlib
|
|
3
|
+
|
|
4
|
+
from azul_bedrock.models_network import DataLabel, FeatureType
|
|
5
|
+
from azul_bedrock.models_network import FeatureValue as APIFeatureValue
|
|
6
|
+
|
|
7
|
+
from .binary_plugin import BinaryPlugin
|
|
8
|
+
from .main import cmdline_run
|
|
9
|
+
from .models import (
|
|
10
|
+
FV,
|
|
11
|
+
Event,
|
|
12
|
+
EventData,
|
|
13
|
+
EventParent,
|
|
14
|
+
Feature,
|
|
15
|
+
FeatureValue,
|
|
16
|
+
Filepath,
|
|
17
|
+
Job,
|
|
18
|
+
JobResult,
|
|
19
|
+
State,
|
|
20
|
+
Uri,
|
|
21
|
+
)
|
|
22
|
+
from .plugin import Plugin
|
|
23
|
+
from .settings import add_settings
|
|
24
|
+
from .storage import DATA_HASH, DATA_HASH_NAME, StorageProxyFile
|
|
25
|
+
|
|
26
|
+
append_all: list[str] = []
|
|
27
|
+
with contextlib.suppress(ImportError):
|
|
28
|
+
from .test_utils import test_template
|
|
29
|
+
from .test_utils.test_template import TestPlugin
|
|
30
|
+
|
|
31
|
+
print("You have the azul-runner[test_utils] installed, this should only be used for development or testing.")
|
|
32
|
+
append_all = ["TestPlugin", "test_template"]
|
|
33
|
+
|
|
34
|
+
EXPORTS = append_all + [
|
|
35
|
+
"add_settings",
|
|
36
|
+
"APIFeatureValue",
|
|
37
|
+
"BinaryPlugin",
|
|
38
|
+
"cmdline_run",
|
|
39
|
+
"DATA_HASH_NAME",
|
|
40
|
+
"DATA_HASH",
|
|
41
|
+
"DataLabel",
|
|
42
|
+
"Event",
|
|
43
|
+
"EventData",
|
|
44
|
+
"EventParent",
|
|
45
|
+
"Feature",
|
|
46
|
+
"FeatureType",
|
|
47
|
+
"FeatureValue",
|
|
48
|
+
"Filepath",
|
|
49
|
+
"FV",
|
|
50
|
+
"Job",
|
|
51
|
+
"JobResult",
|
|
52
|
+
"Plugin",
|
|
53
|
+
"State",
|
|
54
|
+
"StorageProxyFile",
|
|
55
|
+
"Uri",
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
__all__ = list(EXPORTS)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Subclass of Plugin designed for processing binary files."""
|
|
2
|
+
|
|
3
|
+
from azul_bedrock import models_network
|
|
4
|
+
|
|
5
|
+
from . import plugin, settings
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BinaryPlugin(plugin.Plugin):
|
|
9
|
+
"""Base class for plugins that want to run on new sightings of a binary.
|
|
10
|
+
|
|
11
|
+
See readme.md for usage information.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
SETTINGS = settings.add_settings(
|
|
15
|
+
# plugin code generally assumes it can access data
|
|
16
|
+
assume_streams_available=True,
|
|
17
|
+
# event must be a new sighting of a label='content' binary
|
|
18
|
+
filter_allow_event_types=[
|
|
19
|
+
models_network.BinaryAction.Sourced,
|
|
20
|
+
models_network.BinaryAction.Extracted,
|
|
21
|
+
],
|
|
22
|
+
)
|