This artifact enables running Yara on embeded compressed files.
The artifact:
The artifact is optimised to recursively search through embedded zip, jar,war and ear files by extracting any discovered containers. Select UploadHits to upload Discovered file for further analysis. It is recommended to increase default artifact timeout for large servers or target glob.
Some examples of path glob may include:
/path/here/file.zip
/var/www/*.{jar,war,ear}
/var/www/**/*.jar
C:/**/*.zip
NOTE: this artifact runs the glob plugin with the nosymlink switch turned on. This will NOT follow any symlinks and may cause unexpected results if unknowingly targeting a folder with symlinks. Yara is not applied to the containers, only contained contents that are not containers.
name: Generic.Detection.Yara.Zip
author: "Matt Green - @mgreen27"
description: |
This artifact enables running Yara on embeded compressed files.
The artifact:
* firstly searches for compressed zip files (PK header)
* then applies yara on files inside.
* files matching ZipFilenameRegex are recursively searched as above.
The artifact is optimised to recursively search through embedded zip,
jar,war and ear files by extracting any discovered containers.
Select UploadHits to upload Discovered file for further analysis. It is
recommended to increase default artifact timeout for large servers or target
glob.
Some examples of path glob may include:
* Specific container: `/path/here/file.zip`
* Wildcards: `/var/www/*.{jar,war,ear}`
* More wildcards: `/var/www/**/*.jar`
* Windows: `C:/**/*.zip`
NOTE: this artifact runs the glob plugin with the nosymlink switch
turned on. This will NOT follow any symlinks and may cause
unexpected results if unknowingly targeting a folder with
symlinks. Yara is not applied to the containers, only contained contents
that are not containers.
parameters:
- name: TargetGlob
default: "**/*.{zip,jar,war,ear}"
- name: ZipFilenameRegex
default: ".(zip|jar|war|ear)$"
description: Regex of FileName inside container files we would like to recursively scan.
- name: MaxRecursions
description: Number of recursions to allow checking inside archives. Default is 10 layers.
default: 10
type: int
- name: UploadHits
description: Select to upload hits to server.
type: bool
- name: YaraRule
type: yara
description: Final Yara option and the default if no other options provided.
default: |
rule IsPE:TestRule {
meta:
author = "the internet"
date = "2021-03-04"
description = "A simple PE rule to test yara features"
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550
}
- name: NumberOfHits
description: THis artifact will stop by default at one hit. This setting allows additional hits
default: 1
type: int
- name: ContextBytes
description: Include this amount of bytes around hit as context.
default: 0
type: int
sources:
- query: |
-- this section glob searches and confirms we are looking at zip container
LET target_files = SELECT *,
read_file(filename=OSPath,offset=0,length=2) as _Header
FROM glob(globs=TargetGlob,nosymlink=True)
WHERE _Header = 'PK'
-- recursive search function
LET Recurse(Container, File, Accessor, RecursionRounds) = SELECT * FROM if(
condition=RecursionRounds < MaxRecursions,
then={
SELECT * FROM foreach(
row={
SELECT *
FROM glob(accessor='zip',
root=pathspec(DelegatePath=File, DelegateAccessor=Accessor),
globs='**')
WHERE NOT IsDir AND Size > 0
},
query={
SELECT *
FROM if(condition=Name =~ ZipFilenameRegex,
then={
SELECT *
FROM Recurse(
Container = Container,
File=OSPath,
Accessor="zip",
RecursionRounds = RecursionRounds + 1)
},
else={
SELECT
Container,
OSPath.HumanString as ExtractedPath,
OSPath.Path as FilePath,
hash(accessor='zip',path=OSPath) as Hash,
File.Size AS Size,
Mtime, Atime, Ctime, Btime,
Rule, Tags, Meta,
String.Name as YaraString,
String.Offset as HitOffset,
upload( accessor='scope',
file='String.Data',
name=format(format="%v_%v",
args=[ OSPath.HumanString, String.Offset ]
)) as HitContext
FROM yara(accessor='zip',files=OSPath,rules=YaraRule,
context=ContextBytes, number=NumberOfHits)
})
})
})
LET hits = SELECT * FROM foreach(row=target_files,
query={
SELECT *
FROM Recurse(Container=OSPath,File=OSPath, Accessor="auto", RecursionRounds=0)
})
-- upload files that have hit
LET upload_hits = SELECT *, upload(file=Container) as ContainerUpload FROM hits
-- display rows
SELECT * FROM if(condition=UploadHits,
then= upload_hits,
else= hits)
column_types:
- name: HitContext
type: preview_upload