spoa-modsecurity icon indicating copy to clipboard operation
spoa-modsecurity copied to clipboard

when will does a new release with modsecurity v3 ?

Open El977 opened this issue 2 years ago • 11 comments

El977 avatar Mar 27 '23 22:03 El977

Try my fork. The work was done by @uubk I added a few commits to make it work for me

FireBurn avatar Apr 17 '23 16:04 FireBurn

Try my fork. The work was done by @uubk I added a few commits to make it work for me

Thanks , and do you have modsec v3 on container docker image ? Because I need it , i now using modsec V2 on docker container

El977 avatar Apr 18 '23 06:04 El977

Nope, I've not needed it for docker

FireBurn avatar Apr 18 '23 08:04 FireBurn

Thank for talking about it

El977 avatar Apr 18 '23 11:04 El977

hi @FireBurn , i've been trying to compile your version but i'm stuck in this step:

make -C standalone install make: *** standalone: No such file or directory

have you faced this issue? thanks in advance

adsorrentino avatar Jun 16 '23 16:06 adsorrentino

@adsorrentino Here's the complete script I use in jenkins, it's designed to build on RHEL6, 7 & 8, a lot of it can be stripped away and you probably don't need to mess with -march etc

Parameters:

MODSECURITY_VERSION=3.0.9
LUA_VERSION-3.4.4

# Keep a note of the current working directory

export JENKINS_DIR=$(pwd)
export PREFIX=${JENKINS_DIR}/apps/was/modsecurity

export OS_MAJOR_VERSION=`sed -rn 's/.*([0-9])\.[0-9].*/\1/p' /etc/redhat-release`

if [[ "${OS_MAJOR_VERSION}" == "8" ]]; then
  MARCH="haswell"
  PCRE="--with-pcre2"
  PCRE_LIB="-lpcre2-8"
fi
if [[ "${OS_MAJOR_VERSION}" == "7" ]]; then
  MARCH="corei7-avx"
  PCRE=""
  PCRE_LIB="-lpcre"
fi
if [[ "${OS_MAJOR_VERSION}" == "6" ]]; then
  MARCH="core2"
  PCRE=""
  PCRE_LIB="-lpcre"
fi

export CFLAGS="-O3 -march=${MARCH} -fPIE -fstack-protector-all -D_FORTIFY_SOURCE=2 -fno-strict-aliasing"
export CXXFLAGS=${CFLAGS}
export LDFLAGS="-Wl,-z,now -Wl,-z,relro"

# Download source files

wget --no-check-certificate -nv https://dev.gentoo.org/~soap/distfiles/lua-${LUA_VERSION}.tar.xz
git clone https://github.com/lloyd/yajl
git clone https://github.com/ssdeep-project/ssdeep
git clone https://github.com/LMDB/lmdb
git clone --recurse-submodules https://github.com/maxmind/libmaxminddb
git clone --recurse-submodules https://github.com/SpiderLabs/ModSecurity -b v${MODSECURITY_VERSION}
git clone https://github.com/FireBurn/spoa-modsecurity

# Compile LUA

cd ${JENKINS_DIR}

tar xf lua-${LUA_VERSION}.tar.xz

cd ${JENKINS_DIR}/lua-${LUA_VERSION}

./configure \
 --enable-static \
 --without-readline \
 --prefix ${PREFIX}

make -j10

make install

# Compile Yajl

cd ${JENKINS_DIR}/yajl

./configure \
 --prefix ${PREFIX}

make install

# Compile SSDeep

cd ${JENKINS_DIR}/ssdeep

./bootstrap

./configure \
 --prefix=${PREFIX}

make -j10

make install

# Compile LMDB

cd ${JENKINS_DIR}/lmdb/libraries/liblmdb

sed -i "s#-O2 -g#${CFLAGS}#g" Makefile
sed -i "s#/usr/local#${PREFIX}#g" Makefile

make -j10

make install

# Compile libMaxMindDB

cd ${JENKINS_DIR}/libmaxminddb

./bootstrap

./configure \
 --disable-tests \
 --disable-shared \
 --prefix=${PREFIX}

make -j10

make install

# Compile Modsecurity

cd ${JENKINS_DIR}/ModSecurity

./build.sh

sed -i "s#/usr/lib /usr/local/lib /usr/local/fuzzy /usr/local/libfuzzy /usr/local /opt /usr /usr/lib64 /opt/local#${PREFIX}#g" configure
sed -i "s#/usr/lib /usr/local/lib /usr/local/lib64 /usr/local/lua /usr/local/liblua /usr/local /opt /usr /usr/lib64 /opt/local /usr/lib/lua5.3/liblua /usr/lib/lua5.2/liblua#${PREFIX}#g" configure
#sed -i 's#LUA_POSSIBLE_EXTENSIONS="so la sl dll dylib"#LUA_POSSIBLE_EXTENSIONS="a"#g' configure

./configure \
 ${PCRE} \
 --with-lmdb=${PREFIX} \
 --with-lua=yes \
 --with-maxmind=${PREFIX} \
 --with-ssdeep=yes \
 --with-yajl=${PREFIX} \
 --prefix=${PREFIX}

make -j10

make install

# Compile SPOA-Modsecurity

cd ${JENKINS_DIR}/spoa-modsecurity

sed -i "s#ModSecurity-v3.0.5/INSTALL/usr/local/modsecurity#${PREFIX}#g" Makefile
sed -i "s#-Wall -Werror -pthread -O2 -g -fsanitize=address -fno-omit-frame-pointer#${CFLAGS}#g" Makefile
sed -i "s#-lasan##g" Makefile
sed -i 's#$(MODSEC_LIB)/libmodsecurity.so#-Wl,-Bstatic $(MODSEC_LIB)/libmodsecurity.a $(MODSEC_LIB)/libyajl_s.a $(MODSEC_LIB)/liblmdb.a $(MODSEC_LIB)/libmaxminddb.a $(MODSEC_LIB)/liblua5.4.a $(MODSEC_LIB)/libfuzzy.a -Wl,-Bdynamic#g' Makefile
sed -i "s#-Wl,-Bdynamic#-Wl,-Bdynamic -lgcc_s -lstdc++ -lm -ldl -lxml2 -lcurl ${PCRE_LIB}#g" Makefile

make

strip modsecurity || true

./modsecurity -h

tar czSf ${JENKINS_DIR}/apps/was/modsecurity-${MODSECURITY_VERSION}.tar.gz modsecurity

FireBurn avatar Jun 16 '23 19:06 FireBurn

@FireBurn , Thanks! your script worked perfectly. What i'm finding odd is that ModSecurity logs a 200 response code in the audit log, eventhough it returns the correct 403 code to the client, probably a bug in ModSecurity ModSecurity: Access denied with code 200 (phase 2)

adsorrentino avatar Jun 29 '23 13:06 adsorrentino

Looks like this line of code https://github.com/SpiderLabs/ModSecurity/blob/2cb6344bf8a1f7d564d45d6d6a3745212abdd37f/src/rule_message.cc#L75

Are you getting an access denied? Or maybe running without enforcement?

FireBurn avatar Jun 29 '23 14:06 FireBurn

Yeah, i'm getting the denied message, it's in the auditlog where it shows the response code 200. I've tried different CRS versions and it's the same, that's why i think the issue might be in ModSecurity.

403 Forbidden

Request forbidden by administrative rules.

{"transaction":{"client_ip":"1.2.3.4","time_stamp":"Thu Jun 29 14:22:55 2023","server_id":"8a33dde95a00a805a77d2a05f90d040f325af25e","client_port":60319,"host_ip":"5.6.7.8","host_port":443,"unique_id":"168805937549.649067","request":{"method":"GET","http_version":1.1,"uri":"http://my.domain.com/\?x\=/etc/passwd","headers":{"host":"my.domain.com","user-agent":"curl/8.0.1","accept":"/"}},"response":{"body":"","http_code":200,"headers":{}},"producer":{"modsecurity":"ModSecurity v3.0.9 (Linux)","connector":"spoa-modsec-my.domain.com","secrules_engine":"Enabled","components":["OWASP_CRS/3.3.2""]},"messages":[{"message":"OS File Access Attempt","details":{"match":"Matched "Operator PmFromFile' with parameter lfi-os-files.data' against variable ARGS:x\\' (Value: /etc/passwd' )","reference":"o1,10v47,11t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase","ruleId":"930120","file":"/opt/owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf","lineNumber":"78","data":"Matched Data: etc/passwd found within ARGS:x\: /etc/passwd","severity":"2","ver":"OWASP_CRS/3.3.2","rev":"","tags":["application-multi","language-multi","platform-multi","attack-lfi","paranoia-level/1","OWASP_CRS","capec/1000/255/153/126","PCI/6.5.4"],"maturity":"0","accuracy":"0"}}]}}

thanks

adsorrentino avatar Jun 29 '23 17:06 adsorrentino

@adsorrentino, @FireBurn

Hello, i'm currently running into the same trouble as @adsorrentino , the audit log is always showing 200 regardless of the actual backend server response status code. Here is an example of my case: Haproxy log:

2024-12-13T17:02:48.915655+07:00 test test[145282]: client-ip [13/Dec/2024:17:02:48.893] http_front_default BE_Default 16/0/0/5/21 404 1401 - - ---- 117/117/ 0/0/0 0/0 "GET https://mydomain/index.php?lang=../../../../../../../../secret/file HTTP/2.0" \71146DFE:8587_C0A84264:01BB_675C0648_145029:23782

in the haproxy log, it show a path traversal attack to a "secret file" which then the backend return it with a 404 error. However in the auditlog, it log the request as a status 200:

{
  "transaction": {
    "client_ip": "client-ip",
    "time_stamp": "Fri Dec 13 17:02:48 2024",
    "client_port": 12345,
    "host_ip": "my-ip",
    "host_port": 443,
    "request": {
      "method": "GET",
      "http_version": 2.0,
      "uri": "http://mydomain/index.php?lang=../../../../../../../../secret/file",
      "headers": {
        "sec-fetch-user": "?1",
        "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
        "sec-fetch-site": "none",
        "sec-ch-ua-platform": "\"Windows\"",
        "upgrade-insecure-requests": "1",
        "if-none-match": "\"9f727fd2c7c6da1:0\"",
        "sec-ch-ua-mobile": "?0",
        "if-modified-since": "Tue, 25 Jun 2024 06:20:49 GMT",
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "cache-control": "max-age=0",
        "sec-fetch-mode": "navigate",
        "host": "mydomain",
        "sec-fetch-dest": "document",
        "accept-encoding": "gzip, deflate, br",
        "accept-language": "en-US,en;q=0.9",
        "priority": "u=0, i"
      }
    },
    "response": {
      "body": "",
      "http_code": 200,
      "headers": {}
    },
    "producer": {
      "modsecurity": "ModSecurity v3.0.9 (Linux)",
      "connector": "spoa-modsecurity",
      "secrules_engine": "DetectionOnly",
      "components": [
        "OWASP_CRS/4.8.0\""
      ]
    },
    "messages": [
      {
        "message": "Path Traversal Attack (/../) or (/.../)",
        "details": {
          "match": "Matched \"Operator `Rx' with parameter `(?i)(?:[/\\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[56]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1 (394 characters omitted)' against variable `ARGS:lang' (Value: `../../../../../../../../secret/file' )",
          "reference": "o44,4v4,76o2,4v46,34",
          "ruleId": "930100",
          "file": "/etc/haproxy/modsec/crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf",
          "lineNumber": "35",
          "data": "Matched Data: /../ found within ARGS:lang: ../../../../../../../../secret/file",
          "severity": "2",
          "ver": "OWASP_CRS/4.8.0",
          "rev": "",
          "tags": [
            "application-multi",
            "language-multi",
            "platform-multi",
            "attack-lfi",
            "paranoia-level/1",
            "OWASP_CRS",
            "capec/1000/255/153/126"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      }
	}
}

This has been the case for every single request. I was wondering if you have found a solution to this yet? If you have, may i know how you did it. Thank you in advanced.

I'm using modsecurity v3.0.9 with CRS v4.8.0 connected using this repo https://github.com/FireBurn/spoa-modsecurity.git

UPDATE: i have try to upgrade modsecurity to the newest version 3.0.13 but the problem still persist

m0nK3man avatar Dec 14 '24 01:12 m0nK3man

hi, i found a project to use CRS rules with native haproxy ACLs, maybe it's an valid option https://github.com/fabriziosalmi/patterns

best regards

adsorrentino avatar Feb 19 '25 15:02 adsorrentino