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

[Bug] regex library on Alpine causes NASL script to fail #288

Closed
karlffox opened this issue Oct 7, 2021 · 9 comments
Closed

[Bug] regex library on Alpine causes NASL script to fail #288

karlffox opened this issue Oct 7, 2021 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@karlffox
Copy link

karlffox commented Oct 7, 2021

Describe the bug
The GVM plugin

/var/lib/openvas/plugins/2012/secpod_apache_http_srv_cookie_info_disc_vuln.nasl

throws the following error every time it is run from the securecompliance/gvm:21.4.3-v1-data container:

lib nasl:MESSAGE:2021-09-20 16h36.25 utc:4470: 4470 nasl_exec: bad regex at or near line 93 lib nasl:MESSAGE:2021-09-20 16h41.00 utc:11405: 1…

I filed this with Greenbone and they sent the following reply:

AFAICT this is a limitation of the regex library used by the scanner host (in this case Alpine linux running within the docker container or more specifically the mus libc of Alpine).

Currently there are a few options:

  1. switching the underlying operating system to a Debian / Ubuntu based system where this doesn’t occur
  2. ignoring the log entries as that limitation of musl libc is only affecting a VT from 2012
  3. a third party patch (tested on Alpine and Debian) by the community (posted at https://community.greenbone.net/c/vulnerability-tests/7) to work around this limitation on the regex library side of Apline (if this is possible at all) while keeping compatibility with our reference system (which is Debian).

To Reproduce
Steps to reproduce the behavior:

  1. Run a vulnerability scan that includes the above-mentioned plugin
  2. Search the OpenVAS log file for regex errors:
docker exec gvm bash -c 'grep bad.regex /var/log/gvm/openvas.log'
  1. See errors

Expected behavior
The regular expression should be parsed and the plugin should complete without error.

Host Device:
Host:

  • OS: Ubuntu 18.04.6 LTS
  • Docker 20.10.7, build 20.10.7-0ubuntu1~18.04.2

Image in use:

# docker image inspect securecompliance/gvm:21.4.3-v1-data
[
    {
        "Id": "sha256:c1b8fb4147c6111631d906db0d4fa98585ef16d20ba621f70f35af4d4a697a9c",
        "RepoTags": [
            "securecompliance/gvm:21.4.3-v1-data"
        ],
        "RepoDigests": [
            "securecompliance/gvm@sha256:8d00f21ea9808c89ef5623ce7a29217b60d71c447b6b4b697d95877642768cb8"
        ],
        "Parent": "",
        "Comment": "buildkit.dockerfile.v0",
        "Created": "2021-08-08T20:39:17.163431132Z",
        "Container": "",
        "ContainerConfig": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": null,
            "Cmd": null,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "DockerVersion": "",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "22/tcp": {},
                "5432/tcp": {},
                "8081/tcp": {},
                "9392/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "SUPVISD=supervisorctl",
                "USERNAME=admin",
                "PASSWORD=adminpassword",
                "PASSWORD_FILE=none",
                "TIMEOUT=15",
                "DEBUG=N",
                "RELAYHOST=smtp",
                "SMTPPORT=25",
                "AUTO_SYNC=true",
                "HTTPS=true",
                "CERTIFICATE=none",
                "CERTIFICATE_KEY=none",
                "TZ=Etc/UTC",
                "SSHD=false",
                "DB_PASSWORD=none",
                "DB_PASSWORD_FILE=none",
                "LANG=en_US.UTF-8",
                "LANGUAGE=en_US.UTF-8",
                "LC_ALL=en_US.UTF-8",
                "MUSL_LOCPATH=/usr/share/i18n/locales/musl",
                "SETUP=0",
                "OPT_PDF=0"
            ],
            "Cmd": [
                "/usr/bin/supervisord",
                "-n",
                "-c",
                "/etc/supervisord.conf"
            ],
            "ArgsEscaped": true,
            "Image": "",
            "Volumes": {
                "/etc/ssh": {},
                "/opt/database": {},
                "/var/lib/gvm": {},
                "/var/lib/openvas/plugins": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "/entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "org.opencontainers.image.created": "2021-08-08T20:34:33.356Z",
                "org.opencontainers.image.description": "Greenbone Vulnerability Management Docker Image with OpenVAS",
                "org.opencontainers.image.licenses": "MIT",
                "org.opencontainers.image.revision": "45166f1b9bc1c5314303b99ee1a94bb7552bc153",
                "org.opencontainers.image.source": "https://github.com/Secure-Compliance-Solutions-LLC/GVM-Docker",
                "org.opencontainers.image.title": "GVM-Docker",
                "org.opencontainers.image.url": "https://github.com/Secure-Compliance-Solutions-LLC/GVM-Docker",
                "org.opencontainers.image.version": "21.4.3-v1-data"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 2216784430,
        "VirtualSize": 2216784430,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/248778d6ed08ec5a0e597eb04b69cc21655f4c40518ed6d75254ad66d42186c5/diff:/var/lib/docker/overlay2/ebf213220e2f16907e0d528ef0241dc542a6631cab4787df63cbba5d09e6f8c6/diff:/var/lib/docker/overlay2/b570476f3a8ed5565ce75f9027c67b621554b387b57747eaf4d0b8b4438c1c9b/diff:/var/lib/docker/overlay2/514e63bc38502ca0110b8005be96abd656f581a09f6a388015cae7dd36c25d05/diff:/var/lib/docker/overlay2/069e0bc406716c550b2f1e8dbec63662bdcfc574aebbb70c04038184a04515ba/diff:/var/lib/docker/overlay2/af7f5c86eab82e24033f448e7f391e59b46a80ebce83e3c69de643ee6693eeb9/diff:/var/lib/docker/overlay2/1bda4775298658e23911435d88323328530c2d262211a58af5578f2c95f13280/diff:/var/lib/docker/overlay2/45d4c9a75bef8c655fc5adfc8fbe68f6385d73db506e49df47f77ad7a314a32b/diff:/var/lib/docker/overlay2/d030dad3fa6cb22c0422e52688f348f9f8b7fb67091f72c15ead13941c4804d3/diff:/var/lib/docker/overlay2/d44e30cd9ed380b07728ae442b1a7b743381b84ec69fea6b2d363464bb4e637c/diff:/var/lib/docker/overlay2/7634702b7deecfcf8d2a50450924ea8465ba0b92eb289b277a4ada307be6d9c6/diff:/var/lib/docker/overlay2/301e801d8c4fa0a78e428d66adb558fa66a46b152d298c5e671b40dcc75afe25/diff:/var/lib/docker/overlay2/b199614b69e1a315ae785e8ac63ec8f30556f78fea3e499bd6673e6c25121aea/diff",
                "MergedDir": "/var/lib/docker/overlay2/7d7bad7584ad94af33f4bf652c7e0edf76fe23bf5ce09b2111a1202476b50f98/merged",
                "UpperDir": "/var/lib/docker/overlay2/7d7bad7584ad94af33f4bf652c7e0edf76fe23bf5ce09b2111a1202476b50f98/diff",
                "WorkDir": "/var/lib/docker/overlay2/7d7bad7584ad94af33f4bf652c7e0edf76fe23bf5ce09b2111a1202476b50f98/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:bc276c40b172b1c5467277d36db5308a203a48262d5f278766cf083947d05466",
                "sha256:0c4ac070c4f03cca7c16a747fd9d467b485c061795399010bd3100581ec41c0a",
                "sha256:5d6bbd2dcce5feb5424d1e3ee6b44049d37071d175d18eb303a73a79916848d8",
                "sha256:16695a3a00062961220ed6f18b64cfd35358523af07e29a8883d0cafa5c96527",
                "sha256:a59e5a6ab44c1b2ed1afea4e2f931ef547f4bf63c6fdd8285b67fe8a5a2ce99f",
                "sha256:9036d1e8e0173202f37107495ca936ea7212936b6ee822bc0b9382e486a99e3d",
                "sha256:ee290c784570e9d71576d06e5c05cb1174d72c1c2b280d4cfa8018ccda0fed88",
                "sha256:b0a7804131f6cd5ae9b6527379c0a374fa76e960f2201e4d3dd2df94bb3cdde6",
                "sha256:2e640983d7088266c796b233ed6c949e118a8b043108b1e3c98e74413fec2383",
                "sha256:a9ae95a9e54ee4eeb73c72bf88e5d799274f94daa6f984924531d12633469129",
                "sha256:02b18ec11a49495185b7cef99d3ed5a332123c17fd699a460cbd7bfda57d0cae",
                "sha256:1a0a0799c42ce65f726c5454d3d6656b80dd854dbb05747e6d43f497e124535a",
                "sha256:93ce1cb27fbd99165639d00f5b8626d938ccf9de99aecbddb21c9a474eede731",
                "sha256:e2ac0ff4bc79aaaddd97f9f1cb5fd0083b1fa8cbc2c095a720e7bca57d467d99"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

Additional context
The code in secpod_apache_http_srv_cookie_info_disc_vuln.nasl that fails:

res = http_keepalive_send_recv(port:port, data:req, bodyonly:TRUE);

if(res && "400 Bad Request" >< res &&
   res =~ "Cookie: c[0-9]=X{820}; path=/;" &&
   "Size of a request header field exceeds server limit" >< res){
  security_message(port:port);
  exit(0);
}
@karlffox karlffox added the bug Something isn't working label Oct 7, 2021
@cfi-gb
Copy link

cfi-gb commented Oct 12, 2021

As researched in greenbone/gvmd#1667 this seems to be coming from a limitation in the musl libc of Alpine related to this:

X{820}

It seems that there is a limitation in the regex library used on Alpine which can't handle such a huge number of repetitions in {}.

Maybe some one having such an Alpine setup can try something like e.g. the following:

(X{82}){10}

https://regexper.com/#%28X%7B82%7D%29%7B10%7D

which could work around this limitation.

@austinsonger
Copy link
Contributor

We are currently working on a new Debian version on the dev branch, if you have a workaround this limitation of alpine, then please fork and submit a pull request.

@cfi-gb
Copy link

cfi-gb commented Oct 12, 2021

A workaround would be required to be submitted to the Greenbone feed side. If some one is able to test and confirm the previously mentioned suggestion i'm happy to push a fix on Greenbone feed side.

@Dexus
Copy link
Contributor

Dexus commented Oct 12, 2021 via email

@karlffox
Copy link
Author

I just updated my ticket with Greenbone, suggesting making the X{820} -> (X{82}){10} change to their plugin. I have implemented a filter to my Greenbone plugin feed that does exactly that edit, and it does indeed prevent the error message. I have no way to test whether it is actually working properly, though.

I consider this issue closed. Thank you for providing me what I needed.

Karl

@austinsonger
Copy link
Contributor

@karlffox can you add the ticket link in this issue?

@karlffox
Copy link
Author

Certainly.

https://community.greenbone.net/t/openvas-is-throwing-this-regex-error/10217/3

@Dexus
Copy link
Contributor

Dexus commented Oct 12, 2021

As researched in greenbone/gvmd#1667 this seems to be coming from a limitation in the musl libc of Alpine related to this:


X{820}

It seems that there is a limitation in the regex library used on Alpine which can't handle such a huge number of repetitions in {}.

Maybe some one having such an Alpine setup can try something like e.g. the following:


(X{82}){10}

https://regexper.com/#%28X%7B82%7D%29%7B10%7D

which could work around this limitation.

https://regexper.com/#%28X%7B82%7D%29%7B10%7D%20X%7B820%7D

But this would not be the same result!

Or do I'm currently see this wrong?

@Dexus Dexus reopened this Oct 12, 2021
@cfi-gb
Copy link

cfi-gb commented Oct 13, 2021

The regex should work the same way:

Basically X{820} says that X needs to be included 820 times in the response.

The same should work for (X{82}){10} because it says X should be included 82 times ((X{82}) in the response multiplied by 10 ({10}).

Below is a reproducing .nasl script, maybe some one with an Alpine docker installation and having access to openvas-nasl in that environment can check that:

res = "Cookie: c1=" + crap( 820 ) + "; path=/; ";
res += '\n400 Bad Request';
res += '\nSize of a request header field exceeds server limit';

# nb: The default regex
if(res && "400 Bad Request" >< res &&
   res =~ "Cookie: c[0-9]=X{820}; path=/;" &&
   "Size of a request header field exceeds server limit" >< res)
  display("Default regex works / matches");

# nb: Workaround regex for Alpine
if(res && "400 Bad Request" >< res &&
   res =~ "Cookie: c[0-9]=(X{82}){10}; path=/;" &&
   "Size of a request header field exceeds server limit" >< res)
  display("Workaround regex for Alpine works / matches");

This can be launched like e.g.:

openvas-nasl -X regex.nasl

and gives the following on my Debian system:

lib  nasl-Message: 10:52:38.646: Default regex works / matches
lib  nasl-Message: 10:52:38.647: Workaround regex for Alpine works / matches

and on Alpine it probably throws the previously mentioned error for the first regex but the second string should be included.

@Dexus Dexus closed this as completed Nov 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants