Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anti-virus support without need to run external programs #1986

Closed
wants to merge 9 commits into from
Closed

Anti-virus support without need to run external programs #1986

wants to merge 9 commits into from

Conversation

azurit
Copy link
Member

@azurit azurit commented Jan 24, 2021

Adding anti-virus support implemented in pure Lua. The only external requirement is lua-socket library (should be part of all major distros). Currently, only ClamAV is supported. All configuration can be done in crs-setup.conf. This feature is disabled by default.

Feature is implemented using INSTREAM ClamAV command, so:

  • no external program/script is running (no forking, no need of extended permissions and so on)
  • ClamAV doesn't need to be run as root to have access to scanned files as data is send through socket (both TCP/IP and unix socket files are supported)
  • should be fully multiplatform

Thing to consider: Requests containing virus should be hard-blocked, current implementation is only adding score (CRITICAL severity).

ClamAV signatures for PHP malware (tested, both are good):
https://www.rfxn.com/projects/linux-malware-detect/ (free of charge)
https://malware.expert/signatures/ (commercial)

@azurit azurit added the 🚀 enhancement New feature or request label Jan 24, 2021
@azurit azurit self-assigned this Jan 24, 2021
@dune73
Copy link
Member

dune73 commented Jan 25, 2021

Hey @azurit, thank you for this contribution.

I can not get it to work so far, but I have some preliminary feedback:

  • The log action missing in rule 925100
  • I like your handling of virus name in 925100
  • Please rename av.lua to anti-virus.lua
  • I get the feeling you would like to generalize this, but the var names link it to clamav. Can you generalize them, or will a different backend need different variables? If yes, then better leave it as is.
  • I enabled the rules without compiling lua into ModSec, but no warning. I know, this is not your fault, but it's a problem.
    (As soon as lua is installed, apache complains when it does not find the script.)
  • No comments whatsoever in av.lua script. Most is self-explanatory, but not everything.
  • Documentation should reference the need for testing with the eicar file:
    curl http://localhost --form "[email protected]"
    Get eicar test file from https://www.eicar.org
  • Remark to run lua script from the command line while testing would also be helpful
    lua5.3 av.lua
    (If that is meant to work at all)
  • No complaint that lua-socket is not installed
    But error message:
    [2021-01-25 15:31:53.679752] [-:error] 127.0.0.1:44956 YA7WWVYoCzdOV1uTMfDC7AAAAAA [client 127.0.0.1] ModSecurity: Rule processing failed (id=, msg=). [hostname "localhost"] [uri "/"] [unique_id "YA7WWVYoCzdOV1uTMfDC7AAAAAA"]
  • configuration comments reference connection type socket and tcp, but script checks for socket and else.
    Also not sure that
    module_name = "socket"
    is correct for connection type "tcp". Or is it?
  • What is require("m") meant to load? I fail with this. And I never got it to log anything.

@azurit
Copy link
Member Author

azurit commented Jan 25, 2021

Hey @azurit, thank you for this contribution.

I can not get it to work so far, but I have some preliminary feedback:

Thanks for reviewing! Strange, it's fully working for me. Also see comments below.

* The log action missing in rule 925100

Fixed.

* I like your handling of virus name in 925100

* Please rename av.lua to anti-virus.lua

Done.

* I get the feeling you would like to generalize this, but the var names link it to clamav. Can you generalize them, or will a different backend need different variables? If yes, then better leave it as is.

I was planning to add support also for other anti-virus software and allow activation of multiple anti-viruses simultaneously - it makes sense as various AVs are able to detect different viruses.

* I enabled the rules without compiling lua into ModSec, but no warning. I know, this is not your fault, but it's a problem.
  (As soon as lua is installed, apache complains when it does not find the script.)

Now i noticed that @inspectFile is not giving a warning about this - in other cases like SecRuleScript, modsecurity is printing a warning on web server startup:
Ignoring SecRuleScript "response_body_decompress.lua" directive (/usr/share/modsecurity-crs-new/rules/REQUEST-901-INITIALIZATION.conf:502): No Lua scripting support.

Probably a modsecurity bug, I will look into this.

* No comments whatsoever in av.lua script. Most is self-explanatory, but not everything.

I already added few but was not pushing it only because of this. But ok, i will add more.

* Documentation should reference the need for testing with the eicar file:
  curl http://localhost --form "[email protected]"
  Get eicar test file from https://www.eicar.org

Added.

* Remark to run lua script from the command line while testing would also be helpful
  lua5.3 av.lua
  (If that is meant to work at all)

This is not supposed to work.

* No complaint that lua-socket is not installed
  But error message:
  [2021-01-25 15:31:53.679752] [-:error] 127.0.0.1:44956 YA7WWVYoCzdOV1uTMfDC7AAAAAA [client 127.0.0.1] ModSecurity: Rule processing failed (id=, msg=). [hostname "localhost"] [uri "/"] [unique_id "YA7WWVYoCzdOV1uTMfDC7AAAAAA"]

It's working for me, modsec2, apache 2.4, lua 5.1. What version of modsec are you testing on? Which web server software?

[Mon Jan 25 17:06:01.153312 2021] [:error] [pid 14721] [client ...] [client ...] ModSecurity: ClamAV: lua-socket library not installed, please install it or disable 'tx.crs_anti-virus_protection_enable' in crs-setup.conf [hostname "..."] [uri "/"] [unique_id "YA7saWbMVoYLfTj0kRzgpAAAAGA"]

* configuration comments reference connection type socket and tcp, but script checks for socket and else.

Yes, do you find this not correct? I can add additional check.

  Also not sure that
  module_name = "socket"
  is correct for connection type "tcp". Or is it?

This is ok.

* What is require("m") meant to load? I fail with this. And I never got it to log anything.

It's a special modsecurity Lua library shipped with modsecurity and always available to all Lua scripts executed internally, using it, Lua scripts has access to modsecurity internals (for example TX variable).

@dune73
Copy link
Member

dune73 commented Jan 25, 2021

Thank you for petting me. I have lua 5.3 installed. Does it work for you on lua 5.3 as well?

Definitely no "m" to load / require here. :(

@azurit
Copy link
Member Author

azurit commented Jan 25, 2021

Are you sure your modsecurity is compiled with Lua 5.3? Is it modsec 2 or 3? The whole modsecurity 2.x documentation is mentioning only Lua version 5.1. Newer Lua versions are available only with modsec 3 (as far as i understand it).

@dune73
Copy link
Member

dune73 commented Jan 25, 2021

Ah, my bad. Have not worked with Lua in quite a long time. No problem during compilation, but if that is a constraint, I need to downgrade and try it out anew.

@azurit
Copy link
Member Author

azurit commented Jan 25, 2021

I just pushed mentioned fixies.

@azurit
Copy link
Member Author

azurit commented Jan 25, 2021

Were you able to make it work?

@dune73
Copy link
Member

dune73 commented Jan 25, 2021

Have not tried it yet.

@franbuehler
Copy link
Contributor

Meeting decision March: #2008 (comment):
@airween volunteers to review this PR.

@dune73
Copy link
Member

dune73 commented Apr 2, 2021

Hey @airween: You promised to review this PR. Did you have the time to look into it?

@airween
Copy link
Contributor

airween commented Apr 2, 2021

Hey @airween: You promised to review this PR. Did you have the time to look into it?

Yes, I already did it - found some issue in case of libmodsecurity3, see this report. Noticed @azurit about partially results.

Btw: in case of Apache2 - mod_security everything worked as well.

@airween
Copy link
Contributor

airween commented Apr 4, 2021

I reviewed this PR, see my comments between lines.

There is one more note: libmodsecurity3 has a known bug: variable REQUEST_BODY always presents, even if the Content-Type is not www-url-form-encoded nor ctl:forceRequestBodyVariable isn't used. Therefore it has an unexpected side effect: when upload a file, libmodsecurity3 uses the REQUEST_BODY at all rules where it uses, and there are two false positive rule: 920272 and 920273.

2021/04/04 21:23:19 [info] 12723#12723: *3 ModSecurity: Warning. Matched "Operator `ValidateByteRange' with parameter `32-36,38-126' against variable `REQUEST_BODY' (Value: `--------------------------cbd70b742c11bc6b\x0d\x0aContent-Disposition: form-data; name="userfile"; f (556 characters omitted)' ) [file "/usr/share/modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1361"] [id "920272"] [rev ""] [msg "Invalid character in request (outside of printable chars below ascii 127)"] [data "REQUEST_BODY=--------------------------cbd70b742c11bc6b\x0d\x0aContent-Disposition: form-data; name="userfile"; filename="eicar.com"\x0d\x0aContent-Type: application/octet-stream\x0d\x0a\x0d\x0aPK\x03\x04\x0a\x00\x00\x00\x00\x00\xe0\x98\xb8(<\xcfQhD\x00\x00\x00D\x00\x00\x00\x09\x00\x00\x00 (202 characters omitted)"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "paranoia-level/3"] [hostname "::1"] [uri "/index.php"] [unique_id "1617564199"] [ref "o42,1o43,1o113,1o114,1o153,1o154,1o155,1o156,1o159,1o160,1o161,1o162,1o163,1o164,1o165,1o166,1o167,1o168,1o169,1o172,1o176,1o177,1o178,1o180,1o181,1o182,1o183,1o184,1o185,1o186,1o201,1o266,1o267,1o268 (360 characters omitted)"], client: ::1, server: _, request: "POST /index.php HTTP/1.1", host: "localhost"

2021/04/04 21:23:19 [info] 12723#12723: *3 ModSecurity: Warning. Matched "Operator `ValidateByteRange' with parameter `38,44-46,48-58,61,65-90,95,97-122' against variable `REQUEST_BODY' (Value: `--------------------------cbd70b742c11bc6b\x0d\x0aContent-Disposition: form-data; name="userfile"; f (556 characters omitted)' ) [file "/usr/share/modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1500"] [id "920273"] [rev ""] [msg "Invalid character in request (outside of very strict set)"] [data "REQUEST_BODY=--------------------------cbd70b742c11bc6b\x0d\x0aContent-Disposition: form-data; name="userfile"; filename="eicar.com"\x0d\x0aContent-Type: application/octet-stream\x0d\x0a\x0d\x0aPK\x03\x04\x0a\x00\x00\x00\x00\x00\xe0\x98\xb8(<\xcfQhD\x00\x00\x00D\x00\x00\x00\x09\x00\x00\x00 (202 characters omitted)"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "paranoia-level/4"] [hostname "::1"] [uri "/index.php"] [unique_id "1617564199"] [ref "o42,1o43,1o64,1o74,1o75,1o81,1o90,1o91,1o92,1o102,1o112,1o113,1o114,1o128,1o140,1o153,1o154,1o155,1o156,1o159,1o160,1o161,1o162,1o163,1o164,1o165,1o166,1o167,1o168,1o169,1o170,1o171,1o172,1o176,1o177, (533 characters omitted)"], client: ::1, server: _, request: "POST /index.php HTTP/1.1", host: "localhost"

These FP's always triggered, no matter the anti-virus feature is on or off, but the anomaly score value will be distorted.

And finally: in case of Apache2 + mod_security everything is fine.

Copy link
Contributor

@airween airween left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comments between the lines.

crs-setup.conf.example Show resolved Hide resolved
crs-setup.conf.example Outdated Show resolved Hide resolved
rules/anti-virus.lua Outdated Show resolved Hide resolved
# setvar:'tx.crs_anti-virus_clamav_port=3310',\
# setvar:'tx.crs_anti-virus_clamav_chunk_size=4096',\
# setvar:'tx.crs_anti-virus_clamav_network_timeout_seconds=2',\
# setvar:'tx.crs_anti-virus_clamav_max_file_size_bytes=1048576'"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid the FP's in case of libmodsecurity3 (because the REQUEST_BODY is always presented), we should add these actions:

  ctl:ruleRemoveById=920272,\
  ctl:ruleRemoveById=920273"

or we can combine these exceptions with checking of CT header.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not count on CT as it can be faked to bypass anti-virus check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be we should discuss this on monthly chat. I tried this rule in crs-setup.conf:

SecRule REQUEST_HEADERS:Content-Type "(?:multipart/form-data)" \
    "id:'900801',\
    phase:1,\
    t:none,t:lowercase,\
    pass,\
    nolog,\
    ctl:ruleRemoveTargetById=920272;REQUEST_BODY,\
    ctl:ruleRemoveTargetById=920273;REQUEST_BODY"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will keep this open, i think we need to discuss it with others.

@azurit
Copy link
Member Author

azurit commented Apr 5, 2021

Simple way of testing anti-virus:
python -c 'import requests; print(requests.post("http://example.com/", files={"virus": "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"}))'

@azurit
Copy link
Member Author

azurit commented Apr 5, 2021

@airween Thanks A LOT for a detailed review!

@azurit
Copy link
Member Author

azurit commented Apr 6, 2021

Just a note: I will rewrite this into plugin after plugin infrastructure is merged.

@emphazer
Copy link
Contributor

emphazer commented Apr 9, 2021

lua: test.lua:2: attempt to index local 'socket' (a function value)
stack traceback:
        test.lua:2: in main chunk
        [C]: ?

@azurit
Copy link
Member Author

azurit commented Apr 9, 2021

Try this one:

local ok, socket2 = pcall(require, "socket.unix")
sck = socket2.tcp()
status, error = sck:connect("/var/run/clamd.scan/clamd.sock")
print(status)
print(error)
sck:close()

@emphazer
Copy link
Contributor

emphazer commented Apr 9, 2021

lua: test2.lua:2: attempt to index local 'socket2' (a function value)
stack traceback:
        test2.lua:2: in main chunk
        [C]: ?

@azurit
Copy link
Member Author

azurit commented Apr 9, 2021

That's really weird, everything is fully working with same versions of the software on Debian 10.

What about this:

local ok, socket = pcall(require, "socket.unix")
print(ok)
print(type(socket))
print(socket)
sck = socket.tcp()
status, error = sck:connect("/var/run/clamd.scan/clamd.sock")
print(status)
print(error)
sck:close()

@emphazer
Copy link
Contributor

emphazer commented Apr 9, 2021

i don't understand it too. the lua-socket module is from epel repository.
and lua from official rhel7 repo...

true
function
function: 0x60c080
lua: test3.lua:5: attempt to index local 'socket' (a function value)
stack traceback:
        test3.lua:5: in main chunk
        [C]: ?

@azurit
Copy link
Member Author

azurit commented Apr 9, 2021

Can you point me to the repository page of the lua-socket you are using? Looks like you have something different than i have. You need this library:
http://w3.impa.br/~diego/software/luasocket/

@emphazer
Copy link
Contributor

emphazer commented Apr 9, 2021

Installed Packages
Name        : lua-socket
Arch        : x86_64
Version     : 3.0
Release     : 0.17.rc1.el7
Size        : 671 k
Repo        : installed
From repo   : rhel-server-7-epel
Summary     : Network support for the Lua language
URL         : http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/
License     : MIT
Description : LuaSocket is a Lua extension library that is composed by two parts: a C core
            : that provides support for the TCP and UDP transport layers, and a set of Lua
            : modules that add support for functionality commonly needed by applications
            : that deal with the Internet.
            :
            : Among the support modules, the most commonly used implement the SMTP, HTTP
            : and FTP. In addition there are modules for MIME, URL handling and LTN12.

here the link to the source package. last update was 2018
https://ftp.fau.de/epel/7/SRPMS/Packages/l/lua-socket-3.0-0.17.rc1.el7.src.rpm

@emphazer
Copy link
Contributor

emphazer commented Apr 9, 2021

@azurit you use v3.0 too right?

@azurit
Copy link
Member Author

azurit commented Apr 9, 2021

@emphazer Yes, 3.0 rc1, same as you.

@emphazer
Copy link
Contributor

emphazer commented Apr 9, 2021

well, i could recompile the src package without the 3 included patches and see if it works...
or else im out of ideas.

@azurit
Copy link
Member Author

azurit commented Apr 9, 2021

No, wait with that please, i will try to look at it again probably tomorrow (i'm out of energy for today). Thank you!

@emphazer
Copy link
Contributor

emphazer commented Apr 9, 2021

no problemo ;-)

@airween
Copy link
Contributor

airween commented Apr 11, 2021

I don't know why, but looks like the RH and for eg. Debian Luasocket are different (I've tested both of them).

Here is a snippet which worked on both system:

socket = require("socket")
socket.unix = require("socket.unix")
c = socket.unix()
local ok = c:connect("/var/run/clamav/clamd.ctl")
print(ok)

Also it's interesting that on Debian the result will 1, on RH will 1.0.

@azurit
Copy link
Member Author

azurit commented Apr 12, 2021

@airween Thanks!

@emphazer Can you try current version? Pls test both socket and tcp.

@emphazer
Copy link
Contributor

yeeeeeehaaaa, work perfect! :-)
good job!

@azurit
Copy link
Member Author

azurit commented Apr 13, 2021

Does ANYONE see any problems or have feature requests?

@airween
Copy link
Contributor

airween commented Apr 13, 2021

Does ANYONE see any problems or have feature requests?

I think it's really nice work, congratulation!

I'd check the whole cumulated patch again both on Apache and Nginx, but may be I just can do that tomorrow.

@dune73
Copy link
Member

dune73 commented Apr 14, 2021

This is coming along nicely. Thank you all for your work and looking fwd to @airween's review.

@airween
Copy link
Contributor

airween commented Apr 17, 2021

@azurit, @emphazer - can you help me how can I emulate the POST request with x-www-form-urlencoded CT?

After the first tests, this implementation works with the "regular" file upload:

curl -v http://localhost/index.php -F "[email protected]"
2021/04/17 13:42:10 [info] 17102#17102: *11 ModSecurity: Warning. Matched "Operator `StrEq' with parameter `' against variable `TX:VIRUS_NAME' (Value: `Win.Test.EICAR_HDB-1' ) [file "/usr/share/modsecurity-crs/rules/REQUEST-925-ANTIVIRUS.conf"] [line "30"] [id "925110"] [rev ""] [msg "Virus detected in uploaded file: Win.Test.EICAR_HDB-1"] [data "Virus detected in uploaded file: Win.Test.EICAR_HDB-1"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/262/441/442"] [hostname "::1"] [uri "/index.php"] [unique_id "1618659730"] [ref "v286,63"], client: ::1, server: _, request: "POST /index.php HTTP/1.1", host: "localhost"

2021/04/17 13:42:10 [info] 17102#17102: *11 ModSecurity: Warning. Matched "Operator `StrEq' with parameter `' against variable `TX:VIRUS_NAME' (Value: `Win.Test.EICAR_HDB-1' ) [file "/usr/share/modsecurity-crs/rules/REQUEST-925-ANTIVIRUS.conf"] [line "46"] [id "925120"] [rev ""] [msg "Virus detected in request body: Win.Test.EICAR_HDB-1"] [data "Virus detected in request body: Win.Test.EICAR_HDB-1"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/262/441/442"] [hostname "::1"] [uri "/index.php"] [unique_id "1618659730"] [ref "v182,389"], client: ::1, server: _, request: "POST /index.php HTTP/1.1", host: "localhost"

and PUT method:

curl -v -T "eicar.com" "http://localhost/index.php"
2021/04/17 13:39:00 [info] 17102#17102: *9 ModSecurity: Warning. Matched "Operator `StrEq' with parameter `' against variable `TX:VIRUS_NAME' (Value: `Win.Test.EICAR_HDB-1' ) [file "/usr/share/modsecurity-crs/rules/REQUEST-925-ANTIVIRUS.conf"] [line "46"] [id "925120"] [rev ""] [msg "Virus detected in request body: Win.Test.EICAR_HDB-1"] [data "Virus detected in request body: Win.Test.EICAR_HDB-1"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/262/441/442"] [hostname "::1"] [uri "/index.php"] [unique_id "1618659540"] [ref "v117,184"], client: ::1, server: _, request: "PUT /index.php HTTP/1.1", host: "localhost"

But the rule 925120 didn't triggered with the request was like this:

curl -X POST -d @eicar.com http://localhost/index.php

And my 2 cents: in case of first case (regular file upload) there are two blocking rules. It's no problem, just saying.

@azurit
Copy link
Member Author

azurit commented Apr 17, 2021

But the rule 925120 didn't triggered with the request was like this:

It works for me. Is that modsec3? Have you set tx.crs_anti-virus_protection_scan_request_body to 1 in crs-setup.conf?

And my 2 cents: in case of first case (regular file upload) there are two blocking rules. It's no problem, just saying.

modsec3?

@airween
Copy link
Contributor

airween commented Apr 17, 2021

It works for me.

Can you share with me the curl request for this test?

Is that modsec3? Have you set tx.crs_anti-virus_protection_scan_request_body to 1 in crs-setup.conf?

yes, and yes :)

But I also tested with mod_security2 with same result.

And my 2 cents: in case of first case (regular file upload) there are two blocking rules. It's no problem, just saying.

modsec3?

yes, but in case of mod_security2, the PUT request doesn't work at there too. Can you share that request too?

@azurit
Copy link
Member Author

azurit commented Apr 17, 2021

I used the same command as you:
curl -X POST -d @eicar.com http://localhost/index.php

@azurit
Copy link
Member Author

azurit commented Apr 17, 2021

Apache or nginx?

@airween
Copy link
Contributor

airween commented Apr 17, 2021

I'm using Apache2 with mod_security2, and Nginx with libmodsecurity3.

Here is the debug log from Apache+mod_security2 and the request what you shared:

Recipe: Invoking rule 7f928abeec38; [file "/usr/share/modsecurity-crs/rules/REQUEST-925-ANTIVIRUS.conf"] [line "58"] [id "925120"].
Rule 7f928abeec38: SecRule "TX:CRS_ANTI-VIRUS_PROTECTION_SCAN_REQUEST_BODY" "@eq 1" "phase:2,log,auditlog,id:925120,block,t:none,msg:'Virus detected in request body: %{tx.virus_name}',logdata:'Virus detected in request body: %{tx.virus_name}',tag:paranoia-level/1,tag:OWASP_CRS,tag:capec/1000/262/441/442,ver:OWASP_CRS/3.3.0,severity:CRITICAL,chain"
Transformation completed in 1 usec.
Executing operator "eq" with param "1" against TX:crs_anti-virus_protection_scan_request_body.
Target value: "1"
Operator completed in 1 usec.
Rule returned 1.
Match -> mode NEXT_RULE.
Recipe: Invoking rule 7f928abe4a88; [file "/usr/share/modsecurity-crs/rules/REQUEST-925-ANTIVIRUS.conf"] [line "59"].
Rule 7f928abe4a88: SecRule "REQUEST_BODY" "@inspectFile anti-virus.lua" "chain"
Transformation completed in 1 usec.
Executing operator "inspectFile" with param "anti-virus.lua" against REQUEST_BODY.
Target value: "PK\x03\x04"
Lua: Executing script: /usr/share/modsecurity-crs/rules/anti-virus.lua
Lua: Script completed in 1600 usec, returning: (null).
Operator completed in 1622 usec.
Rule returned 0.

Of course, I upgraded the anti-virus.lua tool by your newest version.

But looks like curl sends only a part of the file:

--37d8e57b-C--
PK^C^D
--37d8e57b-F--

Thoughts?

@airween
Copy link
Contributor

airween commented Apr 19, 2021

I reviewed the whole PR again both on Apache2 + mod_security2 and Nginx and libmodsecurity3.

There were two files: eicar.com, which is a zip file, and eicar.txt the plain virus itself.

I tested the engines with these requests:

curl http://localhost/index.php -F "[email protected]"
curl http://localhost/index.php -F "[email protected]" 
curl http://localhost/index.php -X POST -d "@eicar.txt"
curl http://localhost/index.php -T "eicar.txt"

the requests:

  1. upload the zip file
  2. upload the plain virus
  3. send a POST request with CT x-www-form-urlencoded
  4. send a PUT request

All request were catched by both engine, the one and only side-effect is when I uploaded the zipped file to Nginx, it logged the both rule (925110 and 925120) - the reason is known (REQUEST_BODY is always exists in v3).

I asked @azurit that fix the prerequisites in case of v3 and nginx in comment - every other part of this PR is perfect :)

@azurit
Copy link
Member Author

azurit commented Apr 19, 2021

@airween Thank you very much!

Can you be so kind and test again - this time as a plugin, see:
https://github.com/coreruleset/antivirus-plugin

Don't forget to apply changes in includes needs for plugins to work:
https://github.com/coreruleset/coreruleset/blob/v3.4/dev/INSTALL

Almost nothing changed so do only quick test mainly on Nginx and modsec3 (i already tested modsec2 + apache).

@airween
Copy link
Contributor

airween commented Apr 19, 2021

@airween Thank you very much!

Can you be so kind and test again - this time as a plugin, see:
https://github.com/coreruleset/antivirus-plugin

Don't forget to apply changes in includes needs for plugins to work:
https://github.com/coreruleset/coreruleset/blob/v3.4/dev/INSTALL

Almost nothing changed so do only quick test mainly on Nginx and modsec3 (i already tested modsec2 + apache).

sure, I'll check it again soon.

@azurit
Copy link
Member Author

azurit commented Apr 23, 2021

Closing in favour of official Antivirus plugin, see:
https://github.com/coreruleset/antivirus-plugin

Thanks to everyone!

@azurit azurit closed this Apr 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚀 enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants