├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── bpf.go
├── ebpf
├── bpf
│ └── execsnoop.c
├── bpf_bpfeb.go
├── bpf_bpfeb.o
├── bpf_bpfel.go
├── bpf_bpfel.o
├── ebpf.go
└── include
│ ├── bpf_helper_defs.h
│ ├── bpf_helpers.h
│ ├── common.h
│ └── update.sh
├── go.mod
├── go.sum
├── main.go
├── rules
├── c2_earthworm.yml
├── credential_access_collection_sensitive_files.yml
├── credential_access_ssh_backdoor_log.yml
├── defense_evasion_attempt_to_disable_iptables_or_firewall.yml
├── defense_evasion_attempt_to_disable_syslog_service.yml
├── defense_evasion_base16_or_base32_encoding_or_decoding_activity.yml
├── defense_evasion_deletion_of_bash_command_line_history.yml
├── defense_evasion_disable_selinux_attempt.yml
├── defense_evasion_file_deletion_via_shred.yml
├── defense_evasion_file_mod_writable_dir.yml
├── defense_evasion_hidden_file_dir_tmp.yml
├── defense_evasion_kernel_module_removal.yml
├── defense_evasion_log_files_deleted.yml
├── discovery_kernel_module_enum.yml
├── discovery_virtual_machine_fingerprinting.yml
├── execution_perl_tty_shell.yml
├── execution_python_tty_shell.yml
├── lateral_movement_telnet_network_activity_internal.yml
├── linux_iodine_activity.yml
└── privilege_escalation_ld_preload_shared_object_modif.yml
├── sigma.go
├── static
└── bee-transparent.png
└── types.go
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build Test
2 |
3 | on:
4 | push:
5 | workflow_dispatch:
6 |
7 | jobs:
8 |
9 | build:
10 | name: Build
11 | runs-on: ubuntu-20.04
12 | steps:
13 |
14 | - name: Set up Go 1.x
15 | uses: actions/setup-go@v2
16 | with:
17 | go-version: ^1.18
18 |
19 | - name: Check out code into the Go module directory
20 | uses: actions/checkout@v2
21 |
22 | - name: Install Clang
23 | run: sudo apt install -y clang-11 --install-suggests
24 |
25 | - name: llvm-strip symlink
26 | run: sudo ln -s /usr/bin/llvm-strip-11 /usr/bin/llvm-strip
27 |
28 | - name: Get dependencies
29 | run: go get -v
30 | working-directory: "."
31 |
32 | - name: Build
33 | run: make
34 | working-directory: "./"
35 |
36 | - uses: actions/upload-artifact@v2
37 | with:
38 | name: huakiwi.bin
39 | path: ./huakiwi.bin
40 |
41 | - name: Upload Linux binary to release
42 | if: startsWith(github.ref, 'refs/tags/v')
43 | uses: svenstaro/upload-release-action@v2
44 | with:
45 | repo_token: ${{ secrets.GITHUB_TOKEN }}
46 | file: ./huakiwi.bin
47 | asset_name: huakiwi.bin
48 | tag: ${{ github.ref }}
49 | overwrite: true
50 | body: ""
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 | *.bin
8 |
9 | # Test binary, built with `go test -c`
10 | *.test
11 |
12 | # Output of the go coverage tool, specifically when used with LiteIDE
13 | *.out
14 |
15 | # Dependency directories (remove the comment below to include it)
16 | # vendor/
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | OUTPUTFILE=huakiwi.bin
2 | GO_ENV := BPF_CLANG=clang BPF_CFLAGS=""
3 | SOURCES = $(wildcard *.go) $(wildcard */*.go)
4 |
5 | $(OUTPUTFILE): $(SOURCES)
6 | $(GO_ENV) go generate ./...
7 | $(GO_ENV) go build -o $(OUTPUTFILE) .
8 |
9 | clean:
10 | -rm $(OUTPUTFILE)
11 | -find . -iname "*.o" -delete
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Huakiwi
2 | Huwkiwi is an EDR powered by eBPF and Sigma.
3 |
4 | # Name
5 |
6 | Huakiwi is named after [Leioproctus huakiwi](https://en.wikipedia.org/wiki/Leioproctus_huakiwi), a species of bee Endemic to New Zealand.
7 |
8 |
9 |
10 |
11 |
12 | credit: [hasherezade](https://github.com/hasherezade/drawings)
13 |
14 | # Requirements
15 | - kernel 4.4+ [go-ebf requirement](https://github.com/cilium/ebpf#requirements)
16 | - LLVM/Clang
17 |
18 |
19 | # Build
20 | Simply run `make` after cloning the repo. it should generate a portable statically-linked binary.
21 |
22 | ```sh
23 | git clone https://github.com/bm9w/huakiwi
24 | cd huakiwi
25 | make
26 | ```
27 |
28 |
29 | # Rules
30 |
31 | current rules (almost all of them are borrowed from Elastic's public repo on SIEM rules)
32 |
33 | - Potential Protocol Tunneling via EarthWorm
34 | - Compression of Sensitive Files
35 | - Potential OpenSSH Backdoor Logging Activity
36 | - Attempt to Disable IPTables or Firewall
37 | - Attempt to Disable Logging
38 | - Base16 or Base32 Encoding/Decoding Activity
39 | - Tampering of Bash Command-Line History
40 | - Potential Disabling of SELinux
41 | - File Deletion via Shred
42 | - Removing a kernel module
43 | - System Log File Deletion
44 | - Interactive Terminal Spawned via Perl
45 | - Interactive Terminal Spawned via Python
46 | - Modification of Dynamic Linker Preload Shared Object
47 | - Use of raw networking tools
48 | - Use of iodine DNS tunnel
49 | - Modification of Dynamic Linker Preload Shared Object
50 |
51 | Contributions welcome!
52 |
--------------------------------------------------------------------------------
/bpf.go:
--------------------------------------------------------------------------------
1 | //go:build linux
2 | // +build linux
3 |
4 | // This program demonstrates attaching an eBPF program to a kernel symbol.
5 | // The eBPF program will be attached to the start of the sys_execve
6 | // kernel function and prints out the number of times it has been called
7 | // every second.
8 | package main
9 |
10 | import (
11 | "bytes"
12 | "encoding/binary"
13 | "errors"
14 | "os"
15 | "strings"
16 | "time"
17 |
18 | log "github.com/sirupsen/logrus"
19 |
20 | "github.com/cilium/ebpf/link"
21 | "github.com/cilium/ebpf/perf"
22 | "github.com/cilium/ebpf/rlimit"
23 | "golang.org/x/sys/unix"
24 |
25 | "github.com/mosajjal/ebpf-edr/ebpf"
26 | )
27 |
28 | func execsnoopTrace(stopper chan os.Signal) {
29 | const mapKey uint32 = 0
30 | // Name of the kernel function to trace.
31 | fn := "sys_execve"
32 |
33 | // Allow the current process to lock memory for eBPF resources.
34 | if err := rlimit.RemoveMemlock(); err != nil {
35 | log.Fatal(err)
36 | }
37 |
38 | // Load pre-compiled programs and maps into the kernel.
39 | objs := ebpf.CreateEmptyObject()
40 | if err := ebpf.LoadObjects(&objs, nil); err != nil {
41 | log.Fatalf("loading objects: %v", err)
42 | }
43 | defer objs.Close()
44 |
45 | // Open a Kprobe at the entry point of the kernel function and attach the
46 | // pre-compiled program. Each time the kernel function enters, the program
47 | // will increment the execution counter by 1. The read loop below polls this
48 | // map value once per second.
49 | kp, err := link.Kprobe(fn, objs.KprobeExecve, nil)
50 | if err != nil {
51 | log.Fatalf("opening kprobe: %s", err)
52 | }
53 | defer kp.Close()
54 |
55 | ticker := time.NewTicker(time.Second)
56 |
57 | for {
58 | select {
59 | case <-ticker.C:
60 | var value uint64
61 | if err := objs.KprobeMap.Lookup(mapKey, &value); err != nil {
62 | log.Fatalf("reading map: %v", err)
63 | }
64 | log.Printf("called %d times\n", value)
65 | case <-stopper:
66 | return
67 | }
68 | }
69 | }
70 |
71 | func eventExecv(stopper chan os.Signal, events chan EventStream) {
72 | // Name of the kernel function to trace.
73 | fn := "sys_enter_execve"
74 |
75 | // Allow the current process to lock memory for eBPF resources.
76 | if err := rlimit.RemoveMemlock(); err != nil {
77 | log.Fatal(err)
78 | }
79 |
80 | // Load pre-compiled programs and maps into the kernel.
81 | objs := ebpf.CreateEmptyObject()
82 | if err := ebpf.LoadObjects(&objs, nil); err != nil {
83 | log.Fatalf("loading objects: %v", err)
84 | }
85 | defer objs.Close()
86 |
87 | // Open a Kprobe at the entry point of the kernel function and attach the
88 | // pre-compiled program. Each time the kernel function enters, the program
89 | // will increment the execution counter by 1. The read loop below polls this
90 | // map value once per second.
91 | kp, err := link.Tracepoint("syscalls", fn, objs.TraceExecveEvent, nil)
92 | if err != nil {
93 | log.Fatalf("opening kprobe: %s", err)
94 | }
95 | defer kp.Close()
96 |
97 | rd, _ := perf.NewReader(objs.Events, os.Getpagesize())
98 | defer rd.Close()
99 | var event InputEvent
100 |
101 | for {
102 | var output EventStream
103 | output.Env = make(map[string]string)
104 |
105 | record, err := rd.Read()
106 | if err != nil {
107 | if errors.Is(err, perf.ErrClosed) {
108 | return
109 | }
110 | log.Printf("reading from perf event reader: %s", err)
111 | continue
112 | }
113 |
114 | if record.LostSamples != 0 {
115 | log.Printf("perf event ring buffer full, dropped %d samples", record.LostSamples)
116 | continue
117 | }
118 |
119 | // Parse the perf event entry into an Event structure.
120 | if err := binary.Read(bytes.NewBuffer(record.RawSample), binary.LittleEndian, &event); err != nil {
121 | log.Printf("parsing perf event: %s", err)
122 | continue
123 | }
124 | var i uint32
125 | for i = 0; i < event.ArgLen; i++ {
126 | argv, err := objs.Argvs.LookupBytes(i)
127 | if err != nil {
128 | log.Printf("reading argv: %s", err)
129 | break
130 | }
131 | if argv != nil {
132 | output.Args = append(output.Args, string(unix.ByteSliceToString(argv[:])))
133 | }
134 | }
135 | for i = 0; i < event.EnvLen; i++ {
136 | var env []byte
137 | env, err = objs.Envs.LookupBytes(i)
138 | if err != nil {
139 | log.Printf("reading argv: %s", err)
140 | break
141 | }
142 | if env != nil {
143 | envString := string(string(unix.ByteSliceToString(env[:])))
144 | k, v := strings.Split(envString, "=")[0], strings.Split(envString, "=")[1]
145 | output.Env[k] = v
146 | }
147 | }
148 | output.Pid = event.Pid
149 | output.Gid = event.Gid
150 | output.Cmd = string(unix.ByteSliceToString(event.Cmd[:]))
151 |
152 | events <- output
153 |
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/ebpf/bpf/execsnoop.c:
--------------------------------------------------------------------------------
1 | #include "common.h"
2 | #include "bpf_helpers.h"
3 |
4 | char __license[] SEC("license") = "Dual MIT/GPL";
5 |
6 | struct bpf_map_def SEC("maps") kprobe_map = {
7 | .type = BPF_MAP_TYPE_ARRAY,
8 | .key_size = sizeof(u32),
9 | .value_size = sizeof(u64),
10 | .max_entries = 1,
11 | };
12 |
13 | SEC("kprobe/sys_execve")
14 | int kprobe_execve()
15 | {
16 | u32 key = 0;
17 | u64 initval = 1, *valp;
18 |
19 | valp = bpf_map_lookup_elem(&kprobe_map, &key);
20 | if (!valp)
21 | {
22 | bpf_map_update_elem(&kprobe_map, &key, &initval, BPF_ANY);
23 | return 0;
24 | }
25 | __sync_fetch_and_add(valp, 1);
26 |
27 | return 0;
28 | }
29 |
30 | // SECOND ONE
31 | struct event_t
32 | {
33 | u32 pid;
34 | u32 gid;
35 | char str[80];
36 | };
37 |
38 | struct
39 | {
40 | __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
41 | } events SEC(".maps");
42 |
43 | SEC("uretprobe/bash_readline")
44 | int uretprobe_bash_readline(struct pt_regs *ctx)
45 | {
46 | struct event_t event;
47 |
48 | event.pid = bpf_get_current_pid_tgid();
49 | event.gid = bpf_get_current_uid_gid();
50 | bpf_probe_read(&event.str, sizeof(event.str), (void *)PT_REGS_RC(ctx));
51 |
52 | bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
53 |
54 | return 0;
55 | }
56 |
57 | // THIRD ONE
58 |
59 | const u32 MAX_ARGV = 128;
60 |
61 | struct bpf_map_def SEC("maps") argvs = {
62 | .type = BPF_MAP_TYPE_ARRAY,
63 | .key_size = sizeof(u32),
64 | .value_size = sizeof(char[128]),
65 | .max_entries = 256,
66 | };
67 |
68 | struct bpf_map_def SEC("maps") envs = {
69 | .type = BPF_MAP_TYPE_ARRAY,
70 | .key_size = sizeof(u32),
71 | .value_size = sizeof(char[128]),
72 | .max_entries = 256,
73 | };
74 |
75 | struct event_execv
76 | {
77 | u32 pid;
78 | u32 gid;
79 | u32 arg_length;
80 | u32 env_length;
81 | char cmd[80];
82 | //todo: time packets in packets out
83 | };
84 |
85 | struct execve_args
86 | {
87 | short common_type;
88 | char common_flags;
89 | char common_preempt_count;
90 | int common_pid;
91 | int __syscall_nr;
92 | char *filename;
93 | const char *const *argv;
94 | const char *const *envp;
95 | };
96 |
97 | SEC("tracepoint/syscalls/sys_enter_execve")
98 | int trace_execve_event(struct execve_args *ctx)
99 | {
100 | struct event_execv event;
101 |
102 | event.pid = bpf_get_current_pid_tgid();
103 | event.gid = bpf_get_current_uid_gid();
104 |
105 | int comm = bpf_get_current_comm(&event.cmd, sizeof(event.cmd));
106 | if (comm != 0)
107 | {
108 | return -1;
109 | }
110 |
111 | u32 cnt = 0;
112 | for (u32 i = 0; i < MAX_ARGV; i++) {
113 | char *first_var;
114 | char value[300] = "";
115 | if (!bpf_probe_read(&first_var, sizeof(first_var), &ctx->argv[cnt])) {
116 | if (bpf_probe_read_str(value, sizeof(value), first_var) > 0)
117 | bpf_map_update_elem(&argvs, &cnt, &value, BPF_ANY);
118 | else break;
119 | } else break;
120 | cnt++;
121 | }
122 | event.arg_length = cnt;
123 |
124 | cnt = 0;
125 | for (u32 i = 0; i < MAX_ARGV; i++) {
126 | char *first_var;
127 | char value[300] = "";
128 | if (!bpf_probe_read(&first_var, sizeof(first_var), &ctx->envp[cnt])) {
129 | if (bpf_probe_read_str(value, sizeof(value), first_var) > 0)
130 | bpf_map_update_elem(&envs, &cnt, &value, BPF_ANY);
131 | else break;
132 | } else break;
133 | cnt++;
134 | }
135 | event.env_length = cnt;
136 |
137 | // bpf_probe_read_str(&event.args, sizeof(event.args), first_env_var);
138 | bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
139 |
140 | return 0;
141 | }
142 |
--------------------------------------------------------------------------------
/ebpf/bpf_bpfeb.go:
--------------------------------------------------------------------------------
1 | // Code generated by bpf2go; DO NOT EDIT.
2 | //go:build mips || mips64 || ppc64 || s390x
3 |
4 | package ebpf
5 |
6 | import (
7 | "bytes"
8 | _ "embed"
9 | "fmt"
10 | "io"
11 |
12 | "github.com/cilium/ebpf"
13 | )
14 |
15 | // loadBpf returns the embedded CollectionSpec for bpf.
16 | func loadBpf() (*ebpf.CollectionSpec, error) {
17 | reader := bytes.NewReader(_BpfBytes)
18 | spec, err := ebpf.LoadCollectionSpecFromReader(reader)
19 | if err != nil {
20 | return nil, fmt.Errorf("can't load bpf: %w", err)
21 | }
22 |
23 | return spec, err
24 | }
25 |
26 | // loadBpfObjects loads bpf and converts it into a struct.
27 | //
28 | // The following types are suitable as obj argument:
29 | //
30 | // *bpfObjects
31 | // *bpfPrograms
32 | // *bpfMaps
33 | //
34 | // See ebpf.CollectionSpec.LoadAndAssign documentation for details.
35 | func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error {
36 | spec, err := loadBpf()
37 | if err != nil {
38 | return err
39 | }
40 |
41 | return spec.LoadAndAssign(obj, opts)
42 | }
43 |
44 | // bpfSpecs contains maps and programs before they are loaded into the kernel.
45 | //
46 | // It can be passed ebpf.CollectionSpec.Assign.
47 | type bpfSpecs struct {
48 | bpfProgramSpecs
49 | bpfMapSpecs
50 | }
51 |
52 | // bpfSpecs contains programs before they are loaded into the kernel.
53 | //
54 | // It can be passed ebpf.CollectionSpec.Assign.
55 | type bpfProgramSpecs struct {
56 | KprobeExecve *ebpf.ProgramSpec `ebpf:"kprobe_execve"`
57 | TraceExecveEvent *ebpf.ProgramSpec `ebpf:"trace_execve_event"`
58 | UretprobeBashReadline *ebpf.ProgramSpec `ebpf:"uretprobe_bash_readline"`
59 | }
60 |
61 | // bpfMapSpecs contains maps before they are loaded into the kernel.
62 | //
63 | // It can be passed ebpf.CollectionSpec.Assign.
64 | type bpfMapSpecs struct {
65 | Argvs *ebpf.MapSpec `ebpf:"argvs"`
66 | Envs *ebpf.MapSpec `ebpf:"envs"`
67 | Events *ebpf.MapSpec `ebpf:"events"`
68 | KprobeMap *ebpf.MapSpec `ebpf:"kprobe_map"`
69 | }
70 |
71 | // bpfObjects contains all objects after they have been loaded into the kernel.
72 | //
73 | // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign.
74 | type bpfObjects struct {
75 | bpfPrograms
76 | bpfMaps
77 | }
78 |
79 | func (o *bpfObjects) Close() error {
80 | return _BpfClose(
81 | &o.bpfPrograms,
82 | &o.bpfMaps,
83 | )
84 | }
85 |
86 | // bpfMaps contains all maps after they have been loaded into the kernel.
87 | //
88 | // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign.
89 | type bpfMaps struct {
90 | Argvs *ebpf.Map `ebpf:"argvs"`
91 | Envs *ebpf.Map `ebpf:"envs"`
92 | Events *ebpf.Map `ebpf:"events"`
93 | KprobeMap *ebpf.Map `ebpf:"kprobe_map"`
94 | }
95 |
96 | func (m *bpfMaps) Close() error {
97 | return _BpfClose(
98 | m.Argvs,
99 | m.Envs,
100 | m.Events,
101 | m.KprobeMap,
102 | )
103 | }
104 |
105 | // bpfPrograms contains all programs after they have been loaded into the kernel.
106 | //
107 | // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign.
108 | type bpfPrograms struct {
109 | KprobeExecve *ebpf.Program `ebpf:"kprobe_execve"`
110 | TraceExecveEvent *ebpf.Program `ebpf:"trace_execve_event"`
111 | UretprobeBashReadline *ebpf.Program `ebpf:"uretprobe_bash_readline"`
112 | }
113 |
114 | func (p *bpfPrograms) Close() error {
115 | return _BpfClose(
116 | p.KprobeExecve,
117 | p.TraceExecveEvent,
118 | p.UretprobeBashReadline,
119 | )
120 | }
121 |
122 | func _BpfClose(closers ...io.Closer) error {
123 | for _, closer := range closers {
124 | if err := closer.Close(); err != nil {
125 | return err
126 | }
127 | }
128 | return nil
129 | }
130 |
131 | // Do not access this directly.
132 | //
133 | //go:embed bpf_bpfeb.o
134 | var _BpfBytes []byte
135 |
--------------------------------------------------------------------------------
/ebpf/bpf_bpfeb.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0x00000013/huakiwi/44ba973fe8ab50121476a67fabfb86742037fcbc/ebpf/bpf_bpfeb.o
--------------------------------------------------------------------------------
/ebpf/bpf_bpfel.go:
--------------------------------------------------------------------------------
1 | // Code generated by bpf2go; DO NOT EDIT.
2 | //go:build 386 || amd64 || arm || arm64 || loong64 || mips64le || mipsle || ppc64le || riscv64
3 |
4 | package ebpf
5 |
6 | import (
7 | "bytes"
8 | _ "embed"
9 | "fmt"
10 | "io"
11 |
12 | "github.com/cilium/ebpf"
13 | )
14 |
15 | // loadBpf returns the embedded CollectionSpec for bpf.
16 | func loadBpf() (*ebpf.CollectionSpec, error) {
17 | reader := bytes.NewReader(_BpfBytes)
18 | spec, err := ebpf.LoadCollectionSpecFromReader(reader)
19 | if err != nil {
20 | return nil, fmt.Errorf("can't load bpf: %w", err)
21 | }
22 |
23 | return spec, err
24 | }
25 |
26 | // loadBpfObjects loads bpf and converts it into a struct.
27 | //
28 | // The following types are suitable as obj argument:
29 | //
30 | // *bpfObjects
31 | // *bpfPrograms
32 | // *bpfMaps
33 | //
34 | // See ebpf.CollectionSpec.LoadAndAssign documentation for details.
35 | func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error {
36 | spec, err := loadBpf()
37 | if err != nil {
38 | return err
39 | }
40 |
41 | return spec.LoadAndAssign(obj, opts)
42 | }
43 |
44 | // bpfSpecs contains maps and programs before they are loaded into the kernel.
45 | //
46 | // It can be passed ebpf.CollectionSpec.Assign.
47 | type bpfSpecs struct {
48 | bpfProgramSpecs
49 | bpfMapSpecs
50 | }
51 |
52 | // bpfSpecs contains programs before they are loaded into the kernel.
53 | //
54 | // It can be passed ebpf.CollectionSpec.Assign.
55 | type bpfProgramSpecs struct {
56 | KprobeExecve *ebpf.ProgramSpec `ebpf:"kprobe_execve"`
57 | TraceExecveEvent *ebpf.ProgramSpec `ebpf:"trace_execve_event"`
58 | UretprobeBashReadline *ebpf.ProgramSpec `ebpf:"uretprobe_bash_readline"`
59 | }
60 |
61 | // bpfMapSpecs contains maps before they are loaded into the kernel.
62 | //
63 | // It can be passed ebpf.CollectionSpec.Assign.
64 | type bpfMapSpecs struct {
65 | Argvs *ebpf.MapSpec `ebpf:"argvs"`
66 | Envs *ebpf.MapSpec `ebpf:"envs"`
67 | Events *ebpf.MapSpec `ebpf:"events"`
68 | KprobeMap *ebpf.MapSpec `ebpf:"kprobe_map"`
69 | }
70 |
71 | // bpfObjects contains all objects after they have been loaded into the kernel.
72 | //
73 | // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign.
74 | type bpfObjects struct {
75 | bpfPrograms
76 | bpfMaps
77 | }
78 |
79 | func (o *bpfObjects) Close() error {
80 | return _BpfClose(
81 | &o.bpfPrograms,
82 | &o.bpfMaps,
83 | )
84 | }
85 |
86 | // bpfMaps contains all maps after they have been loaded into the kernel.
87 | //
88 | // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign.
89 | type bpfMaps struct {
90 | Argvs *ebpf.Map `ebpf:"argvs"`
91 | Envs *ebpf.Map `ebpf:"envs"`
92 | Events *ebpf.Map `ebpf:"events"`
93 | KprobeMap *ebpf.Map `ebpf:"kprobe_map"`
94 | }
95 |
96 | func (m *bpfMaps) Close() error {
97 | return _BpfClose(
98 | m.Argvs,
99 | m.Envs,
100 | m.Events,
101 | m.KprobeMap,
102 | )
103 | }
104 |
105 | // bpfPrograms contains all programs after they have been loaded into the kernel.
106 | //
107 | // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign.
108 | type bpfPrograms struct {
109 | KprobeExecve *ebpf.Program `ebpf:"kprobe_execve"`
110 | TraceExecveEvent *ebpf.Program `ebpf:"trace_execve_event"`
111 | UretprobeBashReadline *ebpf.Program `ebpf:"uretprobe_bash_readline"`
112 | }
113 |
114 | func (p *bpfPrograms) Close() error {
115 | return _BpfClose(
116 | p.KprobeExecve,
117 | p.TraceExecveEvent,
118 | p.UretprobeBashReadline,
119 | )
120 | }
121 |
122 | func _BpfClose(closers ...io.Closer) error {
123 | for _, closer := range closers {
124 | if err := closer.Close(); err != nil {
125 | return err
126 | }
127 | }
128 | return nil
129 | }
130 |
131 | // Do not access this directly.
132 | //
133 | //go:embed bpf_bpfel.o
134 | var _BpfBytes []byte
135 |
--------------------------------------------------------------------------------
/ebpf/bpf_bpfel.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0x00000013/huakiwi/44ba973fe8ab50121476a67fabfb86742037fcbc/ebpf/bpf_bpfel.o
--------------------------------------------------------------------------------
/ebpf/ebpf.go:
--------------------------------------------------------------------------------
1 | package ebpf
2 |
3 | import "github.com/cilium/ebpf"
4 |
5 | //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf ./bpf/execsnoop.c -- -I./include
6 |
7 | // export the useful functions out of the generated file
8 | func CreateEmptyObject() bpfObjects {
9 | return bpfObjects{}
10 | }
11 |
12 | func LoadObjects(obj interface{}, opts *ebpf.CollectionOptions) error {
13 | return loadBpfObjects(obj, opts)
14 | }
15 |
--------------------------------------------------------------------------------
/ebpf/include/bpf_helpers.h:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2 | #ifndef __BPF_HELPERS__
3 | #define __BPF_HELPERS__
4 |
5 | /*
6 | * Note that bpf programs need to include either
7 | * vmlinux.h (auto-generated from BTF) or linux/types.h
8 | * in advance since bpf_helper_defs.h uses such types
9 | * as __u64.
10 | */
11 | #include "bpf_helper_defs.h"
12 |
13 | #define __uint(name, val) int (*name)[val]
14 | #define __type(name, val) typeof(val) *name
15 | #define __array(name, val) typeof(val) *name[]
16 |
17 | /* Helper macro to print out debug messages */
18 | #define bpf_printk(fmt, ...) \
19 | ({ \
20 | char ____fmt[] = fmt; \
21 | bpf_trace_printk(____fmt, sizeof(____fmt), \
22 | ##__VA_ARGS__); \
23 | })
24 |
25 | /*
26 | * Helper macro to place programs, maps, license in
27 | * different sections in elf_bpf file. Section names
28 | * are interpreted by libbpf depending on the context (BPF programs, BPF maps,
29 | * extern variables, etc).
30 | * To allow use of SEC() with externs (e.g., for extern .maps declarations),
31 | * make sure __attribute__((unused)) doesn't trigger compilation warning.
32 | */
33 | #define SEC(name) \
34 | _Pragma("GCC diagnostic push") \
35 | _Pragma("GCC diagnostic ignored \"-Wignored-attributes\"") \
36 | __attribute__((section(name), used)) \
37 | _Pragma("GCC diagnostic pop") \
38 |
39 | /* Avoid 'linux/stddef.h' definition of '__always_inline'. */
40 | #undef __always_inline
41 | #define __always_inline inline __attribute__((always_inline))
42 |
43 | #ifndef __noinline
44 | #define __noinline __attribute__((noinline))
45 | #endif
46 | #ifndef __weak
47 | #define __weak __attribute__((weak))
48 | #endif
49 |
50 | /*
51 | * Use __hidden attribute to mark a non-static BPF subprogram effectively
52 | * static for BPF verifier's verification algorithm purposes, allowing more
53 | * extensive and permissive BPF verification process, taking into account
54 | * subprogram's caller context.
55 | */
56 | #define __hidden __attribute__((visibility("hidden")))
57 |
58 | /* When utilizing vmlinux.h with BPF CO-RE, user BPF programs can't include
59 | * any system-level headers (such as stddef.h, linux/version.h, etc), and
60 | * commonly-used macros like NULL and KERNEL_VERSION aren't available through
61 | * vmlinux.h. This just adds unnecessary hurdles and forces users to re-define
62 | * them on their own. So as a convenience, provide such definitions here.
63 | */
64 | #ifndef NULL
65 | #define NULL ((void *)0)
66 | #endif
67 |
68 | #ifndef KERNEL_VERSION
69 | #define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
70 | #endif
71 |
72 | /*
73 | * Helper macros to manipulate data structures
74 | */
75 | #ifndef offsetof
76 | #define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER)
77 | #endif
78 | #ifndef container_of
79 | #define container_of(ptr, type, member) \
80 | ({ \
81 | void *__mptr = (void *)(ptr); \
82 | ((type *)(__mptr - offsetof(type, member))); \
83 | })
84 | #endif
85 |
86 | /*
87 | * Helper macro to throw a compilation error if __bpf_unreachable() gets
88 | * built into the resulting code. This works given BPF back end does not
89 | * implement __builtin_trap(). This is useful to assert that certain paths
90 | * of the program code are never used and hence eliminated by the compiler.
91 | *
92 | * For example, consider a switch statement that covers known cases used by
93 | * the program. __bpf_unreachable() can then reside in the default case. If
94 | * the program gets extended such that a case is not covered in the switch
95 | * statement, then it will throw a build error due to the default case not
96 | * being compiled out.
97 | */
98 | #ifndef __bpf_unreachable
99 | # define __bpf_unreachable() __builtin_trap()
100 | #endif
101 |
102 | /*
103 | * Helper function to perform a tail call with a constant/immediate map slot.
104 | */
105 | #if __clang_major__ >= 8 && defined(__bpf__)
106 | static __always_inline void
107 | bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
108 | {
109 | if (!__builtin_constant_p(slot))
110 | __bpf_unreachable();
111 |
112 | /*
113 | * Provide a hard guarantee that LLVM won't optimize setting r2 (map
114 | * pointer) and r3 (constant map index) from _different paths_ ending
115 | * up at the _same_ call insn as otherwise we won't be able to use the
116 | * jmpq/nopl retpoline-free patching by the x86-64 JIT in the kernel
117 | * given they mismatch. See also d2e4c1e6c294 ("bpf: Constant map key
118 | * tracking for prog array pokes") for details on verifier tracking.
119 | *
120 | * Note on clobber list: we need to stay in-line with BPF calling
121 | * convention, so even if we don't end up using r0, r4, r5, we need
122 | * to mark them as clobber so that LLVM doesn't end up using them
123 | * before / after the call.
124 | */
125 | asm volatile("r1 = %[ctx]\n\t"
126 | "r2 = %[map]\n\t"
127 | "r3 = %[slot]\n\t"
128 | "call 12"
129 | :: [ctx]"r"(ctx), [map]"r"(map), [slot]"i"(slot)
130 | : "r0", "r1", "r2", "r3", "r4", "r5");
131 | }
132 | #endif
133 |
134 | /*
135 | * Helper structure used by eBPF C program
136 | * to describe BPF map attributes to libbpf loader
137 | */
138 | struct bpf_map_def {
139 | unsigned int type;
140 | unsigned int key_size;
141 | unsigned int value_size;
142 | unsigned int max_entries;
143 | unsigned int map_flags;
144 | };
145 |
146 | enum libbpf_pin_type {
147 | LIBBPF_PIN_NONE,
148 | /* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
149 | LIBBPF_PIN_BY_NAME,
150 | };
151 |
152 | enum libbpf_tristate {
153 | TRI_NO = 0,
154 | TRI_YES = 1,
155 | TRI_MODULE = 2,
156 | };
157 |
158 | #define __kconfig __attribute__((section(".kconfig")))
159 | #define __ksym __attribute__((section(".ksyms")))
160 |
161 | #endif
162 |
--------------------------------------------------------------------------------
/ebpf/include/common.h:
--------------------------------------------------------------------------------
1 | // This is a compact version of `vmlinux.h` to be used in the examples using C code.
2 |
3 | #ifndef __VMLINUX_H__
4 | #define __VMLINUX_H__
5 |
6 | typedef unsigned char __u8;
7 | typedef short int __s16;
8 | typedef short unsigned int __u16;
9 | typedef int __s32;
10 | typedef unsigned int __u32;
11 | typedef long long int __s64;
12 | typedef long long unsigned int __u64;
13 | typedef __u8 u8;
14 | typedef __s16 s16;
15 | typedef __u16 u16;
16 | typedef __s32 s32;
17 | typedef __u32 u32;
18 | typedef __s64 s64;
19 | typedef __u64 u64;
20 | typedef __u16 __le16;
21 | typedef __u16 __be16;
22 | typedef __u32 __be32;
23 | typedef __u64 __be64;
24 | typedef __u32 __wsum;
25 |
26 | enum bpf_map_type {
27 | BPF_MAP_TYPE_UNSPEC = 0,
28 | BPF_MAP_TYPE_HASH = 1,
29 | BPF_MAP_TYPE_ARRAY = 2,
30 | BPF_MAP_TYPE_PROG_ARRAY = 3,
31 | BPF_MAP_TYPE_PERF_EVENT_ARRAY = 4,
32 | BPF_MAP_TYPE_PERCPU_HASH = 5,
33 | BPF_MAP_TYPE_PERCPU_ARRAY = 6,
34 | BPF_MAP_TYPE_STACK_TRACE = 7,
35 | BPF_MAP_TYPE_CGROUP_ARRAY = 8,
36 | BPF_MAP_TYPE_LRU_HASH = 9,
37 | BPF_MAP_TYPE_LRU_PERCPU_HASH = 10,
38 | BPF_MAP_TYPE_LPM_TRIE = 11,
39 | BPF_MAP_TYPE_ARRAY_OF_MAPS = 12,
40 | BPF_MAP_TYPE_HASH_OF_MAPS = 13,
41 | BPF_MAP_TYPE_DEVMAP = 14,
42 | BPF_MAP_TYPE_SOCKMAP = 15,
43 | BPF_MAP_TYPE_CPUMAP = 16,
44 | BPF_MAP_TYPE_XSKMAP = 17,
45 | BPF_MAP_TYPE_SOCKHASH = 18,
46 | BPF_MAP_TYPE_CGROUP_STORAGE = 19,
47 | BPF_MAP_TYPE_REUSEPORT_SOCKARRAY = 20,
48 | BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE = 21,
49 | BPF_MAP_TYPE_QUEUE = 22,
50 | BPF_MAP_TYPE_STACK = 23,
51 | BPF_MAP_TYPE_SK_STORAGE = 24,
52 | BPF_MAP_TYPE_DEVMAP_HASH = 25,
53 | BPF_MAP_TYPE_STRUCT_OPS = 26,
54 | BPF_MAP_TYPE_RINGBUF = 27,
55 | BPF_MAP_TYPE_INODE_STORAGE = 28,
56 | };
57 |
58 | enum {
59 | BPF_ANY = 0,
60 | BPF_NOEXIST = 1,
61 | BPF_EXIST = 2,
62 | BPF_F_LOCK = 4,
63 | };
64 |
65 | /* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
66 | * BPF_FUNC_perf_event_read_value flags.
67 | */
68 | #define BPF_F_INDEX_MASK 0xffffffffULL
69 | #define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
70 |
71 | #define PT_REGS_RC(x) ((x)->rax)
72 | struct pt_regs {
73 | /*
74 | * C ABI says these regs are callee-preserved. They aren't saved on kernel entry
75 | * unless syscall needs a complete, fully filled "struct pt_regs".
76 | */
77 | unsigned long r15;
78 | unsigned long r14;
79 | unsigned long r13;
80 | unsigned long r12;
81 | unsigned long rbp;
82 | unsigned long rbx;
83 | /* These regs are callee-clobbered. Always saved on kernel entry. */
84 | unsigned long r11;
85 | unsigned long r10;
86 | unsigned long r9;
87 | unsigned long r8;
88 | unsigned long rax;
89 | unsigned long rcx;
90 | unsigned long rdx;
91 | unsigned long rsi;
92 | unsigned long rdi;
93 | /*
94 | * On syscall entry, this is syscall#. On CPU exception, this is error code.
95 | * On hw interrupt, it's IRQ number:
96 | */
97 | unsigned long orig_rax;
98 | /* Return frame for iretq */
99 | unsigned long rip;
100 | unsigned long cs;
101 | unsigned long eflags;
102 | unsigned long rsp;
103 | unsigned long ss;
104 | /* top of stack page */
105 | };
106 |
107 | #endif /* __VMLINUX_H__ */
108 |
--------------------------------------------------------------------------------
/ebpf/include/update.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Version of libbpf to fetch headers from
4 | LIBBPF_VERSION=0.4.0
5 |
6 | # The headers we want
7 | prefix=libbpf-"$LIBBPF_VERSION"
8 | headers=(
9 | "$prefix"/src/bpf_helper_defs.h
10 | "$prefix"/src/bpf_helpers.h
11 | )
12 |
13 | # Fetch libbpf release and extract the desired headers
14 | curl -sL "https://github.com/libbpf/libbpf/archive/refs/tags/v${LIBBPF_VERSION}.tar.gz" | \
15 | tar -xz --xform='s#.*/##' "${headers[@]}"
16 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/mosajjal/ebpf-edr
2 |
3 | go 1.23.0
4 |
5 | require (
6 | github.com/cilium/ebpf v0.16.0
7 | github.com/markuskont/go-sigma-rule-engine v0.3.0
8 | github.com/sirupsen/logrus v1.9.3
9 | golang.org/x/sys v0.24.0
10 | )
11 |
12 | require (
13 | github.com/gobwas/glob v0.2.3 // indirect
14 | github.com/stretchr/testify v1.7.1 // indirect
15 | golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect
16 | gopkg.in/yaml.v2 v2.4.0 // indirect
17 | )
18 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok=
2 | github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE=
3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 | github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
7 | github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
8 | github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
9 | github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
10 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
11 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
12 | github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
13 | github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
14 | github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM=
15 | github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE=
16 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
17 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
18 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
19 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
20 | github.com/markuskont/datamodels v0.0.1 h1:Pibmdtfp4hTypvmFmmCPIkSPxUZ6rpi/myd8U9F/5y4=
21 | github.com/markuskont/datamodels v0.0.1/go.mod h1:dyie+4X2Pmask9qB6PS89+Xq6v0Hjm+anprlucH1JcA=
22 | github.com/markuskont/go-sigma-rule-engine v0.3.0 h1:Jssjmbsaep2l9EuP+40/QLUwamZQYDYSJAfHY+mfCIE=
23 | github.com/markuskont/go-sigma-rule-engine v0.3.0/go.mod h1:121K3IHrnNQcxQt1ZjzgRHqBAJh9Vzd5PSRoqprAOS0=
24 | github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
25 | github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
26 | github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
27 | github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
28 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
29 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
30 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
31 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
32 | github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
33 | github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
34 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
35 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
36 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
37 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
38 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
39 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
40 | golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
41 | golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
42 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
43 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
44 | golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
45 | golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
46 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
47 | golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
48 | golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
49 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
50 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
51 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
52 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
53 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
54 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
55 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
56 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 | "os/signal"
6 | "syscall"
7 |
8 | log "github.com/sirupsen/logrus"
9 | )
10 |
11 | func main() {
12 | // Subscribe to signals for terminating the program.
13 | signal.Notify(GlobalQuit, os.Interrupt, syscall.SIGTERM)
14 | log.Println("Waiting for events..")
15 |
16 | events := make(chan EventStream)
17 | go eventExecv(GlobalQuit, events)
18 |
19 | // todo: transform the events to have group name and username as well as the IDs by grabbing the groups and users periodically
20 | sigmaInsert()
21 |
22 | for {
23 | select {
24 | case event := <-events:
25 | results, match := RuleSet.EvalAll(event)
26 | if match {
27 | log.Warnf("%+s", Alarm{Rule: results, Event: event}.Json())
28 | }
29 |
30 | case <-GlobalQuit:
31 | log.Println("Received SIGTERM, exiting..")
32 | return
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/rules/c2_earthworm.yml:
--------------------------------------------------------------------------------
1 | title: Potential Protocol Tunneling via EarthWorm
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: Identifies the execution of the EarthWorm tunneler. Adversaries may tunnel network communications to and from a victim
5 | references:
6 | - "http://rootkiter.com/EarthWorm/"
7 | - https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/"
8 | tags:
9 | - attack.T1572
10 | - attack.TA0011
11 | author: Ali Mosajjal
12 | date: 2022/04/04 # Rule date
13 | logsource:
14 | category: eventstream
15 | detection:
16 | command:
17 | - cmd|contains: rssocks
18 | - args|contains:
19 | -s
20 | -d
21 | condition: command
22 | fields:
23 | - fields in the log source that are important to investigate further
24 | falsepositives:
25 | - describe possible false positive conditions to help the analysts in their investigation
26 | level: medium
--------------------------------------------------------------------------------
/rules/credential_access_collection_sensitive_files.yml:
--------------------------------------------------------------------------------
1 | title: Sensitive Files Compression
2 | status: production
3 | description: |
4 | Identifies the use of a compression utility to collect known files containing sensitive information, such as credentials
5 | and system configurations.
6 | # references:
7 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
8 | tags:
9 | - attack.T1552
10 | - attack.T1552.001
11 | - attack.TA0006
12 | - attack.T1560
13 | - attack.T1560.001
14 | - attack.TA0009
15 |
16 | author: Ali Mosajjal
17 | date: 2022/04/04 # Rule date
18 | logsource:
19 | category: eventstream
20 | detection:
21 | arguments:
22 | - args|contains:
23 | - /root/.ssh/id_rsa
24 | - /root/.ssh/id_rsa.pub
25 | - /root/.ssh/id_ed25519
26 | - /root/.ssh/id_ed25519.pub
27 | - /root/.ssh/authorized_keys
28 | - /root/.ssh/authorized_keys2
29 | - /root/.ssh/known_hosts
30 | - /root/.bash_history
31 | - /etc/hosts
32 | - /home/*/.ssh/id_rsa
33 | - /home/*/.ssh/id_rsa.pub
34 | - /home/*/.ssh/id_ed25519
35 | - /home/*/.ssh/id_ed25519.pub
36 | - /home/*/.ssh/authorized_keys
37 | - /home/*/.ssh/authorized_keys2
38 | - /home/*/.ssh/known_hosts
39 | - /home/*/.bash_history
40 | - /root/.aws/credentials
41 | - /root/.aws/config
42 | - /home/*/.aws/credentials
43 | - /home/*/.aws/config
44 | - /root/.docker/config.json
45 | - /home/*/.docker/config.json
46 | - /etc/group
47 | - /etc/passwd
48 | - /etc/shadow
49 | - /etc/gshadow
50 | commands:
51 | - cmd|contains:
52 | - 'zip'
53 | - 'gzip'
54 | - 'tar'
55 | - 'cat'
56 | - 'hdiutil'
57 | - '7z'
58 | condition: 1 of commands and 1 of arguments
59 | fields:
60 | - fields in the log source that are important to investigate further
61 | falsepositives:
62 | - |
63 | Security tools and device drivers may run these programs in order to enumerate kernel modules. Use of these programs
64 | by ordinary users is uncommon. These can be exempted by process name or username.
65 | level: medium
--------------------------------------------------------------------------------
/rules/credential_access_ssh_backdoor_log.yml:
--------------------------------------------------------------------------------
1 | title: Potential OpenSSH Backdoor Logging Activity
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Identifies a Secure Shell (SSH) client or server process creating or writing to a known SSH backdoor log file.
6 | Adversaries may modify SSH related binaries for persistence or credential access via patching sensitive functions to
7 | enable unauthorized access or to log SSH credentials for exfiltration.
8 | # references:
9 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
10 | tags:
11 | - attack.T1556
12 | - attack.TA0006
13 | - attack.T1554
14 | - attack.TA0003
15 | author: Ali Mosajjal
16 | date: 2022/04/04 # Rule date
17 | logsource:
18 | category: eventstream
19 | detection:
20 | paths:
21 | - args|contains:
22 | - /private/etc/
23 | - /usr/share/
24 | - /usr/include/
25 | - /usr/local/include/
26 | - /private/tmp/
27 | - /private/var/tmp/
28 | - /usr/tmp/
29 | - /usr/share/man/
30 | - /usr/local/share/
31 | - /usr/lib/
32 | - /private/etc/ssh/.sshd_auth
33 | - /usr/bin/ssd
34 | - /private/var/opt/power
35 | - /private/etc/ssh/ssh_known_hosts
36 | - /private/var/html/lol
37 | - /private/var/log/utmp
38 | - /private/var/lib
39 | - /var/run/sshd/sshd.pid
40 | - /var/run/nscd/ns.pid
41 | - /var/run/udev/ud.pid
42 | - /var/run/udevd.pid
43 | extensions:
44 | - args|contains:
45 | - .sock
46 | - .ini
47 | - .in
48 | - .out
49 | condition: 1 of paths and 1 of extensions
50 | fields:
51 | - fields in the log source that are important to investigate further
52 | falsepositives:
53 | - |
54 | Security tools and device drivers may run these programs in order to enumerate kernel modules. Use of these programs
55 | by ordinary users is uncommon. These can be exempted by process name or username.
56 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_attempt_to_disable_iptables_or_firewall.yml:
--------------------------------------------------------------------------------
1 | title: Attempt to Disable IPTables or Firewall
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Adversaries may attempt to disable the iptables or firewall service in an attempt to affect how a host is allowed to receive or send network traffic.
6 | # references:
7 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
8 | tags:
9 | - attack.TA0005
10 | - attack.T1562.001
11 | - attack.T1562
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | service_controllers:
18 | - cmd|contains:
19 | - "systemctl"
20 | - "chkconfig"
21 | - "service"
22 | actions:
23 | - args|contains:
24 | - "kill"
25 | - "stop"
26 | - "disable"
27 | - "off"
28 | services:
29 | - args|contains:
30 | - "firewalld"
31 | - "ufw"
32 | - "ip6tables"
33 | - "iptables"
34 | condition: 1 of service_controllers and 1 of actions and 1 of services
35 | fields:
36 | - fields in the log source that are important to investigate further
37 | falsepositives:
38 | - |
39 | Security tools and device drivers may run these programs in order to enumerate kernel modules. Use of these programs
40 | by ordinary users is uncommon. These can be exempted by process name or username.
41 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_attempt_to_disable_syslog_service.yml:
--------------------------------------------------------------------------------
1 | title: Attempt to Disable Logging
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Adversaries may attempt to disable the syslog service in an attempt to an attempt to disrupt event logging and evade
6 | detection by security controls.
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.TA0005
11 | - attack.T1562.001
12 | - attack.T1562
13 | author: Ali Mosajjal
14 | date: 2022/04/04 # Rule date
15 | logsource:
16 | category: eventstream
17 | detection:
18 | service_controllers:
19 | - cmd|contains:
20 | - "systemctl"
21 | - "chkconfig"
22 | - "service"
23 | actions:
24 | - args|contains:
25 | - "kill"
26 | - "stop"
27 | - "disable"
28 | - "off"
29 | services:
30 | - args|contains:
31 | - "rsyslog"
32 | - "syslog-ng"
33 | - "syslog"
34 | - "auditd"
35 | - "systemd-journald"
36 | condition: 1 of service_controllers and 1 of actions and 1 of services
37 | fields:
38 | - fields in the log source that are important to investigate further
39 | falsepositives:
40 | - |
41 | Security tools and device drivers may run these programs in order to enumerate kernel modules. Use of these programs
42 | by ordinary users is uncommon. These can be exempted by process name or username.
43 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.yml:
--------------------------------------------------------------------------------
1 | title: Base16 or Base32 Encoding/Decoding Activity
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Adversaries may encode/decode data in an attempt to evade detection by host- or network-based security controls.
6 | # references:
7 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
8 | tags:
9 | - attack.T1027
10 | - attack.TA0005
11 | - attack.T1140
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | processes:
18 | - cmd|contains:
19 | - "base16"
20 | - "base32"
21 | - "base32plain"
22 | - "base32hex"
23 | condition: 1 of processes
24 | fields:
25 | - fields in the log source that are important to investigate further
26 | falsepositives:
27 | - |
28 | Automated tools such as Jenkins may encode or decode files as part of their normal behavior. These events can be filtered by the process executable or username values
29 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_deletion_of_bash_command_line_history.yml:
--------------------------------------------------------------------------------
1 |
2 | title: Tampering of Bash Command-Line History
3 | # id: generate one here https://www.uuidgenerator.net/version4
4 | status: experimental
5 | description: Adversaries may attempt to clear or disable the Bash command-line history in an attempt to evade detection or forensic investigations.
6 | # references:
7 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
8 | tags:
9 | - attack.T1070
10 | - attack.T1070.003
11 | - attack.TA0005
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | command1:
18 | - args|contains:
19 | - bash_history
20 | command2:
21 | - args|contains:
22 | - "history -c"
23 | command3:
24 | - args|contains:
25 | - "export HISTFILE"
26 | command4:
27 | - args|contains:
28 | - "unset HISTFILE"
29 | command5:
30 | - args|contains:
31 | - "export HISTFILESIZE"
32 | command6:
33 | - args|contains:
34 | - "history +o"
35 | condition: all of command1 or all of command2 or all of command3 or all of command4 or all of command5 or all of command6
36 | fields:
37 | - fields in the log source that are important to investigate further
38 | falsepositives:
39 | - |
40 | Security tools and device drivers may run these programs in order to enumerate kernel modules. Use of these programs
41 | by ordinary users is uncommon. These can be exempted by process name or username.
42 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_disable_selinux_attempt.yml:
--------------------------------------------------------------------------------
1 | title: Potential Disabling of SELinux
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Identifies potential attempts to disable Security-Enhanced Linux (SELinux), which is a Linux kernel security feature to
6 | support access control policies. Adversaries may disable security tools to avoid possible detection of their tools and activities.
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1562
11 | - attack.T1562.001
12 | - attack.TA0005
13 | author: Ali Mosajjal
14 | date: 2022/04/04 # Rule date
15 | logsource:
16 | category: eventstream
17 | detection:
18 | command:
19 | - cmd|contains:
20 | - "setenforce"
21 | arguments:
22 | - args|contains:
23 | - "0"
24 |
25 | condition: all of command and 1 of arguments
26 | fields:
27 | - fields in the log source that are important to investigate further
28 | falsepositives:
29 | - none
30 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_file_deletion_via_shred.yml:
--------------------------------------------------------------------------------
1 | title: File Deletion via Shred
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Malware or other files dropped or created on a system by an adversary may leave traces behind as to what was done within
6 | a network and how. Adversaries may remove these files over the course of an intrusion to keep their footprint low or
7 | remove them at the end as part of the post-intrusion cleanup process.
8 | # references:
9 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
10 | tags:
11 | - attack.T1070
12 | - attack.T1070.004
13 | - attack.TA0005
14 | author: Ali Mosajjal
15 | date: 2022/04/04 # Rule date
16 | logsource:
17 | category: eventstream
18 | detection:
19 | command:
20 | - cmd|contains:
21 | - "shred"
22 | arguments:
23 | - args|contains:
24 | - "-u"
25 | - "--remove"
26 | - "-z"
27 | - "--zero"
28 | condition: all of command and 1 of arguments
29 | fields:
30 | - fields in the log source that are important to investigate further
31 | falsepositives:
32 | - none
33 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_file_mod_writable_dir.yml:
--------------------------------------------------------------------------------
1 | title: File Permission Modification in Writable Directory
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Identifies file permission modifications in common writable directories by a non-root user. Adversaries often drop files
6 | or payloads into a writable directory and change permissions prior to execution.
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1222
11 | - attack.TA0005
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | command:
18 | - cmd|contains:
19 | - "chown"
20 | - "chattr"
21 | - "chgrp"
22 | directories:
23 | - pwd|contains:
24 | - "/tmp"
25 | - "/var/tmp"
26 | - "/dev/shm"
27 | condition: 1 of command and 1 of directories
28 | fields:
29 | - fields in the log source that are important to investigate further
30 | falsepositives:
31 | - Certain programs or applications may modify files or change ownership in writable directories. These can be exempted by username.
32 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_hidden_file_dir_tmp.yml:
--------------------------------------------------------------------------------
1 | title: Creation of Hidden Files and Directories
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Users can mark specific files as hidden simply by putting a "." as the first character in the file or folder name.
6 | Adversaries can use this to their advantage to hide files and folders on the system for persistence and defense evasion.
7 | This rule looks for hidden files or folders in common writable directories.
8 | # references:
9 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
10 | tags:
11 | - attack.TA0003
12 | - attack.TA0005
13 | - attack.T1564
14 | - attack.T1564.001
15 | author: Ali Mosajjal
16 | date: 2022/04/04 # Rule date
17 | logsource:
18 | category: eventstream
19 | detection:
20 | commands:
21 | - cmd|contains:
22 | - "touch"
23 | - "mkdir"
24 | directories:
25 | - pwd|contains:
26 | - "/tmp"
27 | - "/var/tmp"
28 | - "/dev/shm"
29 | condition: 1 of commands and 1 of directories
30 | fields:
31 | - fields in the log source that are important to investigate further
32 | falsepositives:
33 | - >
34 | Certain tools may create hidden temporary files or directories upon installation or as part of their normal behavior.
35 | These events can be filtered by the process arguments, username, or process name values.
36 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_kernel_module_removal.yml:
--------------------------------------------------------------------------------
1 | title: Kernel Module Removal
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Kernel modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the
6 | functionality of the kernel without the need to reboot the system. This rule identifies attempts to remove a kernel
7 | module.
8 | # references:
9 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
10 | tags:
11 | - attack.TA0003
12 | - attack.TA0005
13 | - attack.T1547
14 | - attack.T1547.006
15 | - attack.T1562
16 | - attack.T1562.001
17 | author: Ali Mosajjal
18 | date: 2022/04/04 # Rule date
19 | logsource:
20 | category: eventstream
21 | detection:
22 | command1:
23 | - cmd|contains:
24 | - "rmmod"
25 | command2:
26 | - cmd|contains:
27 | - "modprobe"
28 | command2_args:
29 | - args|contains:
30 | - "--remove"
31 | - "-r"
32 | condition: all of command1 or (all of command2 and 1 of command2_args)
33 | # condition: all of command1
34 | fields:
35 | - fields in the log source that are important to investigate further
36 | falsepositives:
37 | - >
38 | There is usually no reason to remove modules, but some buggy modules require it. These can be exempted by username.
39 | Note that some Linux distributions are not built to support the removal of modules at all.
40 | level: medium
--------------------------------------------------------------------------------
/rules/defense_evasion_log_files_deleted.yml:
--------------------------------------------------------------------------------
1 | title: System Log File Deletion
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Identifies the deletion of sensitive Linux system logs. This may indicate an attempt to evade detection or destroy
6 | forensic evidence on a system.
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1070
11 | - attack.TA0005
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | command:
18 | - cmd|contains:
19 | - "unlink"
20 | - "rm"
21 | - "shred"
22 | arguments:
23 | - args|contains:
24 | - /var/run/utmp
25 | - /var/log/wtmp
26 | - /var/log/btmp
27 | - /var/log/lastlog
28 | - /var/log/faillog
29 | - /var/log/syslog
30 | - /var/log/messages
31 | - /var/log/secure
32 | - /var/log/auth.log
33 | condition: 1 of command and 1 of arguments
34 | fields:
35 | - fields in the log source that are important to investigate further
36 | falsepositives:
37 | - >
38 | none
39 | level: medium
--------------------------------------------------------------------------------
/rules/discovery_kernel_module_enum.yml:
--------------------------------------------------------------------------------
1 | title: Enumeration of Kernel Modules
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Loadable Kernel Modules (or LKMs) are pieces of code that can be loaded and unloaded into the kernel upon demand. They
6 | extend the functionality of the kernel without the need to reboot the system. This identifies attempts to enumerate
7 | information about a kernel module.
8 | # references:
9 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
10 | tags:
11 | - attack.TA0007
12 | - attack.T1082
13 | author: Ali Mosajjal
14 | date: 2022/04/04 # Rule date
15 | logsource:
16 | category: eventstream
17 | detection:
18 | command1:
19 | - cmd|contains: kmod
20 | command1_args:
21 | - args|contains:
22 | - "list"
23 | command2:
24 | - cmd|contains:
25 | - depmod
26 | - lsmod
27 | - modinfo
28 | condition: 1 of command2 or (all of command1 and all of command1_args)
29 | fields:
30 | - fields in the log source that are important to investigate further
31 | falsepositives:
32 | - |
33 | Security tools and device drivers may run these programs in order to enumerate kernel modules. Use of these programs
34 | by ordinary users is uncommon. These can be exempted by process name or username.
35 | level: medium
--------------------------------------------------------------------------------
/rules/discovery_virtual_machine_fingerprinting.yml:
--------------------------------------------------------------------------------
1 | title: System Information Discovery
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | An adversary may attempt to get detailed information about the operating system and hardware. This rule identifies
6 | common locations used to discover virtual machine hardware by a non-root user. This technique has been used by the Pupy
7 | RAT and other malware.
8 | # references:
9 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
10 | tags:
11 | - attack.TA0007
12 | - attack.T1082
13 | author: Ali Mosajjal
14 | date: 2022/04/04 # Rule date
15 | logsource:
16 | category: eventstream
17 | detection:
18 | arguments:
19 | - args|contains:
20 | - "/sys/class/dmi/id/bios_version"
21 | - "/sys/class/dmi/id/product_name"
22 | - "/sys/class/dmi/id/chassis_vendor"
23 | - "/proc/scsi/scsi"
24 | - "/proc/ide/hd0/model"
25 | condition: 1 of arguments
26 | fields:
27 | - fields in the log source that are important to investigate further
28 | falsepositives:
29 | - |
30 | Certain tools or automated software may enumerate hardware information. These tools can be exempted via user name or
31 | process arguments to eliminate potential noise.
32 | level: medium
--------------------------------------------------------------------------------
/rules/execution_perl_tty_shell.yml:
--------------------------------------------------------------------------------
1 | title: Interactive Terminal Spawned via Perl
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Identifies when a terminal (tty) is spawned via Perl. Attackers may upgrade a simple reverse shell to a fully
6 | interactive tty after obtaining initial access to a host.
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1059
11 | - attack.TA0002
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | command:
18 | cmd|contains:
19 | - perl
20 | arguments:
21 | - args|contains:
22 | - "/bin/bash"
23 | - "/bin/sh"
24 | - "/bin/dash"
25 | condition: all of command and 1 of arguments
26 | fields:
27 | - fields in the log source that are important to investigate further
28 | falsepositives:
29 | - |
30 | none
31 | level: medium
--------------------------------------------------------------------------------
/rules/execution_python_tty_shell.yml:
--------------------------------------------------------------------------------
1 | title: Interactive Terminal Spawned via Python
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Identifies when a terminal (tty) is spawned via Python. Attackers may upgrade a simple reverse shell to a fully
6 | interactive tty after obtaining initial access to a host.
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1059
11 | - attack.TA0002
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | command:
18 | cmd|contains:
19 | - python
20 | arguments:
21 | - args|contains:
22 | - "/bin/bash"
23 | - "/bin/sh"
24 | - "/bin/dash"
25 | condition: all of command and 1 of arguments
26 | fields:
27 | - fields in the log source that are important to investigate further
28 | falsepositives:
29 | - |
30 | none
31 | level: medium
--------------------------------------------------------------------------------
/rules/lateral_movement_telnet_network_activity_internal.yml:
--------------------------------------------------------------------------------
1 |
2 | title: Use of raw networking tools
3 | # id: generate one here https://www.uuidgenerator.net/version4
4 | status: experimental
5 | description: |
6 | Identifies potential lateral movement or port scanning using common network tools
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1059
11 | - attack.TA0002
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | commands:
18 | cmd|contains:
19 | - "telnet"
20 | - "netcat"
21 | - "netcat.openbsd"
22 | - "hping"
23 | - "nping"
24 | - "nc.openbsd"
25 | - "netcat.traditional"
26 | condition: 1 of commands
27 | fields:
28 | - fields in the log source that are important to investigate further
29 | falsepositives:
30 | - |
31 | users making use of the tool to troubleshoot networking issues or conducting tests
32 | level: low
33 |
34 |
--------------------------------------------------------------------------------
/rules/linux_iodine_activity.yml:
--------------------------------------------------------------------------------
1 |
2 | title: Use of iodine DNS tunnel
3 | # id: generate one here https://www.uuidgenerator.net/version4
4 | status: experimental
5 | description: |
6 | Identifies potential use of iodine DNS tunnel
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1059
11 | - attack.TA0002
12 | author: Ali Mosajjal
13 | date: 2022/04/04 # Rule date
14 | logsource:
15 | category: eventstream
16 | detection:
17 | commands:
18 | cmd|contains:
19 | - "iodine"
20 | - "iodined"
21 | condition: 1 of commands
22 | fields:
23 | - fields in the log source that are important to investigate further
24 | falsepositives:
25 | - |
26 | should not be very noisy
27 | level: low
28 |
--------------------------------------------------------------------------------
/rules/privilege_escalation_ld_preload_shared_object_modif.yml:
--------------------------------------------------------------------------------
1 | title: Modification of Dynamic Linker Preload Shared Object
2 | # id: generate one here https://www.uuidgenerator.net/version4
3 | status: experimental
4 | description: |
5 | Identifies modification of the dynamic linker preload shared object (ld.so.preload). Adversaries may execute malicious
6 | payloads by hijacking the dynamic linker used to load libraries.
7 | # references:
8 | # - A list of all references that can help a reader or analyst understand the meaning of a triggered rule
9 | tags:
10 | - attack.T1574
11 | - attack.T1574.006
12 | - attack.TA0004
13 | author: Ali Mosajjal
14 | date: 2022/04/04 # Rule date
15 | logsource:
16 | category: eventstream
17 | detection:
18 | arguments:
19 | - args|contains:
20 | - "/etc/ld.so.preload"
21 | condition: all of arguments
22 | fields:
23 | - fields in the log source that are important to investigate further
24 | falsepositives:
25 | - |
26 | potential use by a background service
27 | level: medium
--------------------------------------------------------------------------------
/sigma.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | log "github.com/sirupsen/logrus"
5 |
6 | sigma "github.com/markuskont/go-sigma-rule-engine"
7 | )
8 |
9 | // load all the .yara rules inside the rules/ directory and register them to the stream they subscribe to
10 |
11 | // //go:embed rules/*.yml
12 | // var sigmaRules embed.FS
13 | var RuleSet *sigma.Ruleset
14 |
15 | func sigmaInsert() {
16 | var err error
17 | RuleSet, err = sigma.NewRuleset(sigma.Config{
18 | // todo: make this work with embedded FS so we build the rules at compile time rather than runtime (optional)
19 | Directory: []string{"./rules"},
20 | })
21 | if err != nil {
22 | log.Printf("failed reading rule: %s", err)
23 | }
24 | log.Printf("Found %d files, %d ok, %d failed, %d unsupported\n", RuleSet.Total, RuleSet.Ok, RuleSet.Failed, RuleSet.Unsupported)
25 | for i := 0; i < len(RuleSet.Rules); i++ {
26 | log.Printf("%v\n", RuleSet.Rules[i].Rule.Title)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/static/bee-transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0x00000013/huakiwi/44ba973fe8ab50121476a67fabfb86742037fcbc/static/bee-transparent.png
--------------------------------------------------------------------------------
/types.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "os"
6 | "strings"
7 |
8 | sigma "github.com/markuskont/go-sigma-rule-engine"
9 | )
10 |
11 | var GlobalQuit = make(chan os.Signal, 1)
12 |
13 | type Alarm struct {
14 | Rule sigma.Results
15 | Event EventStream
16 | }
17 |
18 | func (a Alarm) Json() string {
19 | event_json, _ := json.Marshal(a)
20 | return string(event_json)
21 | }
22 |
23 | type EventStream struct {
24 | Pid uint32 `json:"pid"`
25 | Gid uint32 `json:"gid"`
26 | Cmd string `json:"cmd"`
27 | Args []string `json:"args"`
28 | Env map[string]string `json:"env"`
29 | }
30 |
31 | // inputEvent comes from eBPF
32 | type InputEvent struct {
33 | Pid uint32
34 | Gid uint32
35 | ArgLen uint32
36 | EnvLen uint32
37 | Cmd [80]byte
38 | }
39 |
40 | func (e EventStream) Keywords() ([]string, bool) {
41 | return e.Args, true
42 | }
43 |
44 | func (e EventStream) Select(s string) (any, bool) {
45 | switch s {
46 | case "pid":
47 | return e.Pid, true
48 | case "gid":
49 | return e.Gid, true
50 | case "cmd":
51 | return e.Cmd + " " + e.Args[0], true
52 | case "args":
53 | return strings.Join(e.Args[:], " "), true
54 | case "env":
55 | return e.Env, true
56 | case "pwd":
57 | value, exists := e.Env["PWD"]
58 | if exists {
59 | return value, true
60 | }
61 | return "", false
62 | default:
63 | return nil, false
64 | }
65 | }
66 |
67 | func (e EventStream) Json() string {
68 | event_json, _ := json.Marshal(e)
69 | return string(event_json)
70 | }
71 |
--------------------------------------------------------------------------------