Commit graph

28 commits

Author SHA1 Message Date
Val Snyder
7ff29b8c37
Bump copyright dates for 2025 2025-02-14 10:24:30 -05:00
Andy Ragusa
666e047f2b
Store URLs from HTML when recording scan metadata json
Store URLs found in HTML `<a>` and `<form>` tags during scan of HTML files
when recording scan metadata.

HTML URL recording will be ON by default, but is a part of the
generate-metadata-json feature.
The generate-metadata-json feature is OFF by default.

This introduces a new general scan option:
- libclamav: `CL_SCAN_GENERAL_STORE_HTML_URLS`.
- ClamD: `JsonStoreHTMLUrls`.
- ClamScan: `--json-store-html-urls`

Thank you Matt Jolly for the helpful comment on the pull request.
2024-09-11 13:40:29 -04:00
Micah Snyder
2cc47c83ac Make image fuzzy hashing optional
Image fuzzy hashing is enabled by default. The following options have
been added to allow users to disable it, if desired.

New clamscan options:

  --scan-image[=yes(*)/no]

  --scan-image-fuzzy-hash[=yes(*)/no]

New clamd config options:

  ScanImage yes(*)/no

  ScanImageFuzzyHash yes(*)/no

New libclamav scan options:

  options.parse &= ~CL_SCAN_PARSE_IMAGE;

  options.parse &= ~CL_SCAN_PARSE_IMAGE_FUZZY_HASH;

This commit also changes scan behavior to disable image fuzzy hashing
for specific types when the DCONF (.cfg) signatures disable those types.
That is, if DCONF disables the PNG parser, it should not only disable
the CVE/format checker for PNG files, but also disable image fuzzy
hashing for PNG files.

Also adds a DCONF option to disable image fuzzy hashing:
  OTHER_CONF_IMAGE_FUZZY_HASH

DCONF allows scanning features to be disabled using a configuration
"signature".
2024-03-14 16:57:48 -04:00
Micah Snyder
2f6b71eb98 ClamD: Disable VirusEvent '%f' feature, use environment var instead
The '%f' filename format character has been disabled and will no longer
be replaced with the file name, due to command injection security concerns.
Use the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead.

For the same reason, you should NOT use the environment variables in the
command directly, but should use it carefully from your executed script.
2024-02-05 11:39:02 -05:00
Micah Snyder
9cb28e51e6 Bump copyright dates for 2024 2024-01-22 11:27:17 -05:00
Micah Snyder
3b2f8c044a Support for extracting attachments from OneNote section files
Includes rudimentary support for getting slices from FMap's and for
interacting with libclamav's context structure.

For now will use a Cisco-Talos org fork of the onenote_parser
until the feature to read open a onenote section from a slice (instead
of from a filepath) is added to the upstream.
2023-12-11 15:18:41 -05:00
RainRat
caf324e544
Fix typos (no functional changes) 2023-11-26 18:01:19 -05:00
ChrisWi
ed630ab5a9 harmonize socket/pid file path to those used in Docker 2023-08-03 09:23:29 -07:00
Matthias Fratz
2962509609 Raise artificial 4G limit for MaxScanSize
This limit is internally "long long", so >=64-bit even on 32-bit platforms.
Also fixes a related issue where limits could have been set to negative
values on 64-bit platforms where setting a "long long" (64-bit signed) can
overflow if assigned from an "unsigned long" (64-bit unsigned).

Resolves: https://github.com/Cisco-Talos/clamav/issues/809
2023-08-03 00:23:38 -07:00
Craig Andrews
e70493cf61 Add options: --cache-size, CacheSize
* Add new clamd and clamscan option --cache-size

This option allows you to set the number of entries the cache can store.

Additionally, introduce CacheSize as a clamd.conf
synonym for --cache-size.

Fixes #867
2023-05-16 19:18:30 -07:00
Andy Ragusa
f683571de5 Sigtool: Add vba macro support for OOXML files
Add a new cl_engine_set_clcb_vba() function to set a cb_vba callback
function and add clcb_generic_data handler prototype to the clamav.h
public API.

The cb_vba callback function will be run whenever VBA is extracted from
office documents. The provided data will be a normalized copy of the
original VBA. This callback is added to support Sigtool so it can use
the same VBA extraction logic as when scanning documents.

Change the Sigtool temp directory creation for any commands that use
temp directories so that you can select a custom temp directory with the
`--tempdir=PATH` option, and can retain the temp files with the
`--leave-temps` option.

Added `--tempdir` and `--leave-temps` to the Sigtool `--help` output.
Added `--tempdir` and `--leave-temps` to the Sigtool manpage.
2023-03-29 22:21:37 -07:00
Răzvan Cojocaru
e4fe6654c1
Add options: --fail-if-cvd-older-than, FailIfCvdOlderThan
* Add a new function cl_cvdgetage() to the libclamav API. 

This function will retrieve the age of the youngest file in a
database directory, or the age of a single CVD (or CLD) file.

* Add new clamscan option --fail-if-cvd-older-than=days

When passed, causes clamscan to exit with a non-zero return code
if the virus database is older than the specified number of days.

* Add new clamd option --fail-if-cvd-older-than=days

When passed, causes clamd to exit on start-up with a non-zero
return code if the virus database is older than the specified
number of days.

Additionally, we introduce FailIfCvdOlderThan as a clamd.conf
synonym for --fail-if-cvd-older-than.

Fixes #820
2023-03-28 14:22:48 -07:00
Micah Snyder
6eebecc303 Bump copyright for 2023 2023-02-12 11:20:22 -08:00
Micah Snyder
89b72cb002
Sigtool: Add --fuzzy-img option to generate image fuzzy hash
Add `sigtool --fuzzy-img` option to generate image fuzzy hash.

Also fix assorted warnings, mostly ensuring enough buffer space so format
strings aren't truncated.

For the dsig change: the returned string is allocated and is not const.
The caller will have to free it.
2022-03-24 16:11:50 -07:00
Micah Snyder
d1656ee241 Increase default file maximums
MaxFileSize        25M  -> 100M
MaxScanSize        100M -> 400M
StreamMaxLength    25M  -> 100M
MaxEmbeddedPE      10M  -> 40M
MaxHTMLNormalize   10M  -> 40M
MaxHTMLNoTags      2M   -> 8M
MaxScriptNormalize 5M   -> 20M
PCREMaxFileSIze    25M  -> 100M
2022-03-09 16:47:44 -08:00
mko-x
a21cc6dcd7
Add explicit log level parameter to application logging API
* Added loglevel parameter to logg()

* Fix logg and mprintf internals with new loglevels

* Update all logg calls to set loglevel

* Update all mprintf calls to set loglevel

* Fix hidden logg calls

* Executed clam-format
2022-02-15 15:13:55 -08:00
micasnyd
140c88aa4e Bump copyright for 2022
Includes minor format corrections.
2022-01-09 14:23:25 -07:00
micasnyd
cca5f489b0 freshclam, clamd: Increase max config line length
ClamAV's option parser, used for `freshclam.conf`, `clamd.conf`,
and `clamav-milter.conf` has a max line length of 512 characters.

By request, this commit increases the line length to 1024 to accommodate
very long `DatabaseMirror` options when using access tokens in the URI.

Resolves: https://github.com/Cisco-Talos/clamav/issues/281
2022-01-06 15:31:34 -07:00
Micah Snyder
0a24f70218 Rename Heuristics.Email.ExceedsMax alerts
Rename Heuristics.Email.ExceedsMax alerts to start with
Heuristics.Limits.Exceeded.Email instead, so that all heuristic alerts
for exceeded scan limits have the same prefix.
2021-10-29 15:01:25 -07:00
Micah Snyder
db013a2bfd libclamav: Fix scan recursion tracking
Scan recursion is the process of identifying files embedded in other
files and then scanning them, recursively.

Internally this process is more complex than it may sound because a file
may have multiple layers of types before finding a new "file".

At present we treat the recursion count in the scanning context as an
index into both our fmap list AND our container list. These two lists
are conceptually a part of the same thing and should be unified.

But what's concerning is that the "recursion level" isn't actually
incremented or decremented at the same time that we add a layer to the
fmap or container lists but instead is more touchy-feely, increasing
when we find a new "file".

To account for this shadiness, the size of the fmap and container lists
has always been a little longer than our "max scan recursion" limit so
we don't accidentally overflow the fmap or container arrays (!).

I've implemented a single recursion-stack as an array, similar to before,
which includes a pointer to each fmap at each layer, along with the size
and type. Push and pop functions add and remove layers whenever a new
fmap is added. A boolean argument when pushing indicates if the new layer
represents a new buffer or new file (descriptor). A new buffer will reset
the "nested fmap level" (described below).

This commit also provides a solution for an issue where we detect
embedded files more than once during scan recursion.

For illustration, imagine a tarball named foo.tar.gz with this structure:
| description               | type  | rec level | nested fmap level |
| ------------------------- | ----- | --------- | ----------------- |
| foo.tar.gz                | GZ    | 0         | 0                 |
| └── foo.tar               | TAR   | 1         | 0                 |
|     ├── bar.zip           | ZIP   | 2         | 1                 |
|     │   └── hola.txt      | ASCII | 3         | 0                 |
|     └── baz.exe           | PE    | 2         | 1                 |

But suppose baz.exe embeds a ZIP archive and a 7Z archive, like this:
| description               | type  | rec level | nested fmap level |
| ------------------------- | ----- | --------- | ----------------- |
| baz.exe                   | PE    | 0         | 0                 |
| ├── sfx.zip               | ZIP   | 1         | 1                 |
| │   └── hello.txt         | ASCII | 2         | 0                 |
| └── sfx.7z                | 7Z    | 1         | 1                 |
|     └── world.txt         | ASCII | 2         | 0                 |

(A) If we scan for embedded files at any layer, we may detect:
| description               | type  | rec level | nested fmap level |
| ------------------------- | ----- | --------- | ----------------- |
| foo.tar.gz                | GZ    | 0         | 0                 |
| ├── foo.tar               | TAR   | 1         | 0                 |
| │   ├── bar.zip           | ZIP   | 2         | 1                 |
| │   │   └── hola.txt      | ASCII | 3         | 0                 |
| │   ├── baz.exe           | PE    | 2         | 1                 |
| │   │   ├── sfx.zip       | ZIP   | 3         | 1                 |
| │   │   │   └── hello.txt | ASCII | 4         | 0                 |
| │   │   └── sfx.7z        | 7Z    | 3         | 1                 |
| │   │       └── world.txt | ASCII | 4         | 0                 |
| │   ├── sfx.zip           | ZIP   | 2         | 1                 |
| │   │   └── hello.txt     | ASCII | 3         | 0                 |
| │   └── sfx.7z            | 7Z    | 2         | 1                 |
| │       └── world.txt     | ASCII | 3         | 0                 |
| ├── sfx.zip               | ZIP   | 1         | 1                 |
| └── sfx.7z                | 7Z    | 1         | 1                 |

(A) is bad because it scans content more than once.

Note that for the GZ layer, it may detect the ZIP and 7Z if the
signature hits on the compressed data, which it might, though
extracting the ZIP and 7Z will likely fail.

The reason the above doesn't happen now is that we restrict embedded
type scans for a bunch of archive formats to include GZ and TAR.

(B) If we scan for embedded files at the foo.tar layer, we may detect:
| description               | type  | rec level | nested fmap level |
| ------------------------- | ----- | --------- | ----------------- |
| foo.tar.gz                | GZ    | 0         | 0                 |
| └── foo.tar               | TAR   | 1         | 0                 |
|     ├── bar.zip           | ZIP   | 2         | 1                 |
|     │   └── hola.txt      | ASCII | 3         | 0                 |
|     ├── baz.exe           | PE    | 2         | 1                 |
|     ├── sfx.zip           | ZIP   | 2         | 1                 |
|     │   └── hello.txt     | ASCII | 3         | 0                 |
|     └── sfx.7z            | 7Z    | 2         | 1                 |
|         └── world.txt     | ASCII | 3         | 0                 |

(B) is almost right. But we can achieve it easily enough only scanning for
embedded content in the current fmap when the "nested fmap level" is 0.
The upside is that it should safely detect all embedded content, even if
it may think the sfz.zip and sfx.7z are in foo.tar instead of in baz.exe.

The biggest risk I can think of affects ZIPs. SFXZIP detection
is identical to ZIP detection, which is why we don't allow SFXZIP to be
detected if insize of a ZIP. If we only allow embedded type scanning at
fmap-layer 0 in each buffer, this will fail to detect the embedded ZIP
if the bar.exe was not compressed in foo.zip and if non-compressed files
extracted from ZIPs aren't extracted as new buffers:
| description               | type  | rec level | nested fmap level |
| ------------------------- | ----- | --------- | ----------------- |
| foo.zip                   | ZIP   | 0         | 0                 |
| └── bar.exe               | PE    | 1         | 1                 |
|     └── sfx.zip           | ZIP   | 2         | 2                 |

Provided that we ensure all files extracted from zips are scanned in
new buffers, option (B) should be safe.

(C) If we scan for embedded files at the baz.exe layer, we may detect:
| description               | type  | rec level | nested fmap level |
| ------------------------- | ----- | --------- | ----------------- |
| foo.tar.gz                | GZ    | 0         | 0                 |
| └── foo.tar               | TAR   | 1         | 0                 |
|     ├── bar.zip           | ZIP   | 2         | 1                 |
|     │   └── hola.txt      | ASCII | 3         | 0                 |
|     └── baz.exe           | PE    | 2         | 1                 |
|         ├── sfx.zip       | ZIP   | 3         | 1                 |
|         │   └── hello.txt | ASCII | 4         | 0                 |
|         └── sfx.7z        | 7Z    | 3         | 1                 |
|             └── world.txt | ASCII | 4         | 0                 |

(C) is right. But it's harder to achieve. For this example we can get it by
restricting 7ZSFX and ZIPSFX detection only when scanning an executable.
But that may mean losing detection of archives embedded elsewhere.
And we'd have to identify allowable container types for each possible
embedded type, which would be very difficult.

So this commit aims to solve the issue the (B)-way.

Note that in all situations, we still have to scan with file typing
enabled to determine if we need to reassign the current file type, such
as re-identifying a Bzip2 archive as a DMG that happens to be Bzip2-
compressed. Detection of DMG and a handful of other types rely on
finding data partway through or near the ned of a file before
reassigning the entire file as the new type.

Other fixes and considerations in this commit:

- The utf16 HTML parser has weak error handling, particularly with respect
  to creating a nested fmap for scanning the ascii decoded file.
  This commit cleans up the error handling and wraps the nested scan with
  the recursion-stack push()/pop() for correct recursion tracking.

  Before this commit, each container layer had a flag to indicate if the
  container layer is valid.
  We need something similar so that the cli_recursion_stack_get_*()
  functions ignore normalized layers. Details...

  Imagine an LDB signature for HTML content that specifies a ZIP
  container. If the signature actually alerts on the normalized HTML and
  you don't ignore normalized layers for the container check, it will
  appear as though the alert is in an HTML container rather than a ZIP
  container.

  This commit accomplishes this with a boolean you set in the scan context
  before scanning a new layer. Then when the new fmap is created, it will
  use that flag to set similar flag for the layer. The context flag is
  reset those that anything after this doesn't have that flag.
  The flag allows the new recursion_stack_get() function to ignore
  normalized layers when iterating the stack to return a layer at a
  requested index, negative or positive.

  Scanning normalized extracted/normalized javascript and VBA should also
  use the 'layer is normalized' flag.

- This commit also fixes Heuristic.Broken.Executable alert for ELF files
  to make sure that:

  A) these only alert if cli_append_virus() returns CL_VIRUS (aka it
  respects the FP check).

  B) all broken-executable alerts for ELF only happen if the
  SCAN_HEURISTIC_BROKEN option is enabled.

- This commit also cleans up the error handling in cli_magic_scan_dir().
  This was needed so we could correctly apply the layer-is-normalized-flag
  to all VBA macros extracted to a directory when scanning the directory.

- Also fix an issue where exceeding scan maximums wouldn't cause embedded
  file detection scans to abort. Granted we don't actually want to abort
  if max filesize or max recursion depth are exceeded... only if max
  scansize, max files, and max scantime are exceeded.

  Add 'abort_scan' flag to scan context, to protect against depending on
  correct error propagation for fatal conditions. Instead, setting this
  flag in the scan context should guarantee that a fatal condition deep in
  scan recursion isn't lost which result in more stuff being scanned
  instead of aborting. This shouldn't be necessary, but some status codes
  like CL_ETIMEOUT never used to be fatal and it's easier to do this than
  to verify every parser only returns CL_ETIMEOUT and other "fatal
  status codes" in fatal conditions.

- Remove duplicate is_tar() prototype from filestypes.c and include
  is_tar.h instead.

- Presently we create the fmap hash when creating the fmap.
  This wastes a bit of CPU if the hash is never needed.
  Now that we're creating fmap's for all embedded files discovered with
  file type recognition scans, this is a much more frequent occurence and
  really slows things down.

  This commit fixes the issue by only creating fmap hashes as needed.
  This should not only resolve the perfomance impact of creating fmap's
  for all embedded files, but also should improve performance in general.

- Add allmatch check to the zip parser after the central-header meta
  match. That way we don't multiple alerts with the same match except in
  allmatch mode. Clean up error handling in the zip parser a tiny bit.

- Fixes to ensure that the scan limits such as scansize, filesize,
  recursion depth, # of embedded files, and scantime are always reported
  if AlertExceedsMax (--alert-exceeds-max) is enabled.

- Fixed an issue where non-fatal alerts for exceeding scan maximums may
  mask signature matches later on. I changed it so these alerts use the
  "possibly unwanted" alert-type and thus only alert if no other alerts
  were found or if all-match or heuristic-precedence are enabled.

- Added the "Heuristics.Limits.Exceeded.*" events to the JSON metadata
  when the --gen-json feature is enabled. These will show up once under
  "ParseErrors" the first time a limit is exceeded. In the present
  implementation, only one limits-exceeded events will be added, so as to
  prevent a malicious or malformed sample from filling the JSON buffer
  with millions of events and using a tonne of RAM.
2021-10-25 16:02:29 -07:00
Micah Snyder
d8dc3f00f9 ClamD: Add GenerateMetadataJson option, like clamscan --gen-json
Adds an equivalent functionality to ClamScan's --gen-json option to
ClamD.

Behavior for GenerateMetadataJson is the same as with --gen-json.
If Debug is enabled, it will print out the JSON after each scan.
If LeaveTemporaryFiles is enabled, it will drop a metadat.json file
in the scan temp directory, which of course may be customized using
the TemporaryDirectory option.
2021-10-11 11:32:06 -07:00
kang-grace
23dfe8fc4c
ClamScan, ClamDScan: process memory scanning (Windows)
Add the process memory scanning feature from ClamWin's ClamScan.
This commit extends that feature to make it available in ClamDScan 
as well.

This adds three new options to ClamScan and ClamDScan on Windows:
* --memory
* --kill
* --unload

--allmatch and --stream are available for ClamDScan.

To reduce code duplication, this refactors clamd related code
used in both scanmem.c and proto.c into clamdcom. 
Moved send_fdpass(), send_stream(), chkpath(), dconnect(), and
dsresult(); as well as some type definitions.

Special thanks to Gianluigi Tiesi for allowing us to integrate the 
Windows process memory scanning feature from ClamWin into the ClamAV.
2021-08-27 09:14:45 -07:00
Simon Arlott
1b276dbe93 Change ReceiveTimeout to use CURLOPT_LOW_SPEED_TIME
Currently ReceiveTimeout sets CURLOPT_TIMEOUT which is an absolute timeout
on the HTTP download and not particularly useful without knowing the size
of the file or the throughput available to download it.

Change it to use CURLOPT_LOW_SPEED_TIME instead, and set the related low
speed limit (CURLOPT_LOW_SPEED_LIMIT) to 1 byte per second. This will allow
the ReceiveTimeout to abort the attempt if the download is not making
any significant progress.

Restore the documentation, default and sample options back to before
2fd28e1d09 and
f5d465a864.

This fixes #266 and avoids problems caused by the Ubuntu default
ReceiveTimeout of 30 seconds.
2021-08-26 16:17:17 -07:00
Micah Snyder
d46832d5cf clamav.net URL update for new docs, github issues
Replace new bugzilla ticket links with links to github issues.
Replace clamav.net/documentation links with docs.clamav.net equivalents.
2021-07-17 15:28:02 -07:00
kang-grace
27d51762b3
Added Windows services for clamd and freshclam
Added feature to start FreshClam & Clamd as Windows services

Special thanks to Gianluigi Tiesi for allowing us to integrate this
feature from ClamWin directly into ClamAV.

Added internal --service-mode option for FreshClam and ClamD
This is used when Windows starts FreshClam or ClamD as a service so
that they will register with the service manager.

Code found in service.c.
2021-07-13 12:31:20 -07:00
Micah Snyder (micasnyd)
4f51994fad FreshClam: Fix tests, configs for IPv6-only systems
Some config settings and some tests hardcoded 127.0.0.1. This switches
to localhost, they'll work for systems that don't support IPv4.
2021-05-27 16:52:58 -07:00
Micah Snyder
0255f29a72 Blacklist & Whitelist verbiage
Improvements to use modern block list and allow list verbiage.

blacklist -> block list
whitelist -> allow listed
blacklisted -> blocked
whitelisted -> allowed

In the case of certificate verification, use "trust" or "verify" when
something is allowed.

Also changed domainlist -> domain list (or DomainList) to match.
2021-05-27 14:16:00 -07:00
Micah Snyder
c025afd683 Rename "shared" library to "common"
The named "shared" is confusing, especially now that these features are
built as a static library instead of being directly compiled into the
various applications.
2021-04-20 17:31:19 -07:00
Renamed from shared/optparser.c (Browse further)