{"id":38120583,"url":"https://github.com/hvs-consulting/nfs-security-tooling","last_synced_at":"2026-01-16T22:28:44.339Z","repository":{"id":270263569,"uuid":"825795700","full_name":"hvs-consulting/nfs-security-tooling","owner":"hvs-consulting","description":"Detect common NFS server misconfigurations","archived":false,"fork":false,"pushed_at":"2025-05-27T09:03:26.000Z","size":472,"stargazers_count":70,"open_issues_count":0,"forks_count":7,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-11-20T14:37:44.684Z","etag":null,"topics":["nfs","security","security-tools"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hvs-consulting.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-08T14:09:56.000Z","updated_at":"2025-11-10T11:52:30.000Z","dependencies_parsed_at":"2024-12-29T21:17:19.918Z","dependency_job_id":"3aa22141-20b0-429e-87cf-c4e88e99abb2","html_url":"https://github.com/hvs-consulting/nfs-security-tooling","commit_stats":null,"previous_names":["hvs-consulting/nfs-security-tooling"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hvs-consulting/nfs-security-tooling","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvs-consulting%2Fnfs-security-tooling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvs-consulting%2Fnfs-security-tooling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvs-consulting%2Fnfs-security-tooling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvs-consulting%2Fnfs-security-tooling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hvs-consulting","download_url":"https://codeload.github.com/hvs-consulting/nfs-security-tooling/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hvs-consulting%2Fnfs-security-tooling/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28485337,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nfs","security","security-tools"],"created_at":"2026-01-16T22:28:44.237Z","updated_at":"2026-01-16T22:28:44.325Z","avatar_url":"https://github.com/hvs-consulting.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"This repository contains two tools, `nfs_analyze` and `fuse_nfs` that are released along with our [blog post](https://www.hvs-consulting.de/en/nfs-security-identifying-and-exploiting-misconfigurations/) on the NFS protocol from a pentester's perspective.\n\nThe tools can detect common misconfigurations on NFS servers that allow access to files outside the exported directories and privilege escalation.\n\nThe [wiki](https://github.com/hvs-consulting/nfs-security-tooling/wiki) contains technical background information.\n\n# Installation\nThese tools are designed for and tested on Linux. \nTo install, first make sure pkg-config, libfuse3-dev and python3-dev are installed.\nFor example, on Kali you can run \n\n~~~\nsudo apt update\nsudo apt install pkg-config libfuse3-dev python3-dev\n~~~\n\nto install the dependencies.\nAfterwards, you can install `nfs_analyze` and `fuse_nfs`, for example with [pipx](https://github.com/pypa/pipx), using:\n\n~~~\npipx install git+https://github.com/hvs-consulting/nfs-security-tooling.git\n~~~\n\nThe programs require ```cap_net_bind_service``` or root privileges to use privileged ports. On Kali this should work automatically because it does not have privileged ports, on other systems you may have to install and run the program as root or temporarily disable privileged ports by running ```sudo sysctl net.ipv4.ip_unprivileged_port_start=0```.\n\n# nfs_analyze\nThis script prints details about an NFS server and detects some potential misconfigurations which are highlighted in red.\nIt is based on a [modified version of pynfs](https://github.com/hvs-consulting/pynfs).\n\n**WARNING**: *This script leaves traces in logs and the rmtab on the server.*\n\n```\nusage: nfs_analyze [-h] [--check-no-root-squash] [--btrfs-subvolumes BTRFS_SUBVOLUMES] [--delay DELAY] [--timeout TIMEOUT] [--skip-version-check] [--no-color] [--no-ping] [--ping-timeout PING_TIMEOUT] [--v4-overview-depth V4_OVERVIEW_DEPTH] [--v4-show-exports-only] [--check-v4] [--charset CHARSET] [--json-file JSON_FILE] [--json-dir JSON_DIR] [--findings-file FINDINGS_FILE] [--verbose-errors] [--reload-pynfs] [target ...]\n\npositional arguments:\n  target                List of targets, each target can be an IP address, a hostname or a path to a file containing a host on each line (default: None)\n\noptions:\n  -h, --help            show this help message and exit\n  --check-no-root-squash\n                        Test if no_root_squash is enabled on the server which can be used for privilege escalation on clients. WARNING: THIS WRITES DATA ON THE SERVER (default: False)\n  --btrfs-subvolumes BTRFS_SUBVOLUMES\n                        Number of subvolumes to try to read when escaping a BTRFS export (default: 16)\n  --delay DELAY         Number of milliseconds to wait between connections. If this value is too low, connections might fail (default: 1000)\n  --timeout TIMEOUT     Socket timeout in milliseconds (default: 3000)\n  --skip-version-check  Skip version check to speed up the test (default: False)\n  --no-color            Disable colored output (default: False)\n  --no-ping             Do not ping clients reported by mount (default: False)\n  --ping-timeout PING_TIMEOUT\n                        Number of seconds before a ping times out (default: 1)\n  --v4-overview-depth V4_OVERVIEW_DEPTH\n                        Depth of directory tree in NFSv4 overview (default: 2)\n  --v4-show-exports-only\n                        Only show export root directories in the NFSv4 overview. Only works on Linux servers, does not show nested exports (default: False)\n  --check-v4            Run checks with v4 even if v3 is available (default: False)\n  --charset CHARSET     charset used by the server (default: utf-8)\n  --json-file JSON_FILE\n                        Output to a single json file (default: None)\n  --json-dir JSON_DIR   Output to one json file per host in given directory (default: None)\n  --findings-file FINDINGS_FILE\n                        Output a short summary of findings to a json file (default: None)\n  --verbose-errors      Verbose error logging (default: False)\n  --reload-pynfs        Reload pynfs after every host (default: False)\n```\n\n## Input and Output format\nA list of targets has to be provided. Each target can be an IP address, a hostname or a path to a file containing a host on each line.\n\nColored human-readable output is printed to the terminal, the colors can be disabled using the `--no-color` option.\nThere are three parameters to generate machine-readable output.\nThe most interesting one is `--findings-file` which provides a JSON containing an overview of all mountable exports and detected misconfigurations.\nThe `--json-file` parameter outputs verbose information on all performed checks to one file.\nThe `--json-dir` option is the same but it creates a file for each host in the given directory.\nAny combination of the three output options can be used.\n\n## Checks\nThe script performs the following checks:\n\n### Supported protocols\nThis check shows all supported protocols reported by portmap.\nIf this doesn't show anything, the server might be configured to only support NFSv4 which doesn't need portmap.\n\n### NFSv3 exports\nThis is an overview of all available NFSv3 exports, allowed clients, authentication methods and export file handles.\nOnly the authentication methods available to the current host are listed. Exports can be configured to allow different authentication methods for different hosts.\nIf nothing is shown, it could mean, that the server only supports NFSv4.\n\n### Clients connected to the NFS server\nThis is an overview of all clients connected to the server.\nThis list may be inaccurate for the following reasons:\n- NFSv4 clients are not shown\n- If clients do not unmount the export properly, they will remain in the list even if they are not connected anymore\n- If clients skip the mount protocol and communicate with NFS directly, they will not be listed\n- The Windows NFS server implementation does not list any clients\n\n### NFS versions supported by the server\nThis check shows if NFS version 3, 4.0, 4.1 and 4.2 are supported. Earlier NFS versions are not supported by this script.\n\nIf no version is reported, there could be multiple reasons:\n- The server only supports old NFS versions\n- The server only supports NFSv4 but on a port that is not 2049\n- The server is not an NFS server\n\nThis check takes a long time because the script has to wait some time between each connection attempt.\nOtherwise the server might return an error that the session is still open.\nThe delay between connection attempts can be set using the `--delay` option. The default value of 1000ms appears to be effective for Linux and Windows.\nDisable this check when scanning many hosts and version information is not needed using the `--skip-version-check` option in order to speed up the process.\n\n### Windows file handle signing\nIf an NFSv3 file handle looks like one from a Windows server, it checks if the last 10 bytes are 0 or not in order to determine if file handle signing is enabled.\nIf it is disabled, all files on the file system are accessible.\n\n### Escape\nIf the file handle looks like one from a Linux server, it tries to list the root directory of the file system of each export.\n\nThis only works if all of the following conditions are met:\n- The server uses Linux\n- The export does not have the option `subtree_check` set in `/etc/exports`\n- The export is stored on an `ext`, `xfs` or `btrfs` file system\n\nThe file handle of the file system root directory will be displayed. This file handle can be used by fuse_nfs to interact with the file system.\n\nIf the escape was sucessful, the check tries to read `/etc/shadow` using two methods:\n1. use uid and gid 0 -\u003e works if `no_root_squash` is set\n2. if gid of `/etc/shadow` is not 0, use that gid -\u003e works on SuSE and Debian based systems\n3. only on NFSv4 with idmapping: use the hardcoded gids 42 (Debian) and 15 (SuSE)\n\nThe `/etc/shadow` can only be read if the export is on the same partition where the operating system is installed.\n\nOn btrfs file systems there might be different versions of `/etc/shadow` in different snapshots.\n\n### no_root_squash\n**WARNING:** *This creates a directory in each export and deletes it immediately afterwards. For this reason it has to be manually enabled using `--check-no-root-squash`*\n\nThis check only works if the export allows `AUTH_SYS` and if it is writable.\nIt creates a directory owned by root and checks if the creation is successful.\nIf `no_root_squash` is enabled, file operations can be performed as root, which can lead to privilege escalation using setuid binaries and device files.\nEven if `no_root_squash` is disabled, it is still possible to perform privilege escalation on misconfigured clients in some cases.\nSee [section 5.2 in the wiki](https://github.com/hvs-consulting/nfs-security-tooling/wiki/5_2_0-Privilege_Escalation) for more details about privilege escalation.\n\n### Overview of directories available via NFSv4\nThis check is useful if the server doesn't support NFSv3. The overview depth can be configured using the `--v4-overview-depth` parameter.\n\n### Guessed NFSv4 exports\nIn the NFSv4 protocol, the client cannot get a list of exports from the server. There is only one directory tree that contains all exports as subdirectories.\nThis check analyses NFSv4 file handles from the directory overview check in order to guess which of the directories are export roots.\nThis only works on Linux servers and the result can be inaccurate because the directory overveiw has a limited depth and the script cannot tell if a file system mounted in an export is an independent export or not.\nIf the script was unable to get a list of exports using the mount protocol or if the option `--check-v4` was specified, it can run the other checks using this guessed export list over NFSv4.\n\n### Server OS guess\nThis check tries to guess the server OS by analyzing file handles, protocol versions and other unique properties of different operating systems.\n\n![nfs_analyze](img/nfs_analyze.png)\n\n# fuse_nfs\nThis is a fuse driver that can mount an NFSv3 export. The advantage of this script compared to the normal mount command is that it autamatically sends the right uid and gid to the server to get access to as many files as possible. It is also able to mount an arbitrary file handle including file system root file handles found by nfs_analyze.\nThis tool is based on [anfs](https://github.com/skelsec/anfs).\n\n## Required setup\nEdit `/etc/fuse.conf` and uncomment the line `user_allow_other`\n\n## Usage\n```\nusage: fuse_nfs [-h] (--export EXPORT | --manual-fh MANUAL_FH) [--uid UID | --fake-uid] [--fake-uid-allow-root] [--allow-write] [--remote-symlinks] [--unprivileged-port] [--fix-nested-exports] [--debug] [--debug-fuse] mountpoint host\n\npositional arguments:\n  mountpoint            Where to mount the file system\n  host                  IP address of the host\n\noptions:\n  -h, --help            show this help message and exit\n  --export EXPORT       Path of export directory\n  --manual-fh MANUAL_FH\n                        Set a root file handle manually as a hex string\n  --uid UID             Manualy set UID and GID number, format UID:GID\n  --fake-uid            Automatically fake UID and GID to access more files\n  --fake-uid-allow-root\n                        Enable if no_root_squash is enabled on the export\n  --allow-write         Allow writing\n  --remote-symlinks     Follow symlinks on the server, not the client\n  --unprivileged-port   Connect from a port \u003e1024\n  --fix-nested-exports  Make nested exports on NetApp servers work\n  --debug               Enable debugging output\n  --debug-fuse          Enable FUSE debugging output\n```\n\nWhen running this program, always provide exactly one of the options `--manual-fh` or `--export` to specify the export root.\nThe `--export`option allows you to mount an export just like the mount command. The `--manual-fh` option can be used to mount a file sytem root directory that nfs_analyze has found.\n\nTo stop the program, run ```umount mountpoint```. Also run this command when the program crashes and after interrupting it, otherwise there will be an error when starting it again on the same mountpoint.\n\nBy default only read operations are allowed. If you need to make changes to the server, use `--allow-write`.\n\nUse one of the options `--uid` or `--fake-uid`. If you want to browse a share, `--fake-uid` is the right option. If no_root_squash is enabled, also enable the `--fake-uid-allow-root` option to get access to files owned by root. If you want to upload a file with a specific UID and GID for privilege escalation, you can manually specify them using the `--uid` option.\nOn the client side, the operating system's permission checks are bypassed by setting the permission bits for others to the permission bits of the owner and the group of the file while still showing the correct uid and gid of the file.\nIt does not matter which user account you use to access files on your machine.\n\nThe inode numbers in the file system are not related to the actual inode numbers on the server. They are assigned by the anfs library based on when the file handle has been seen for the first time.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhvs-consulting%2Fnfs-security-tooling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhvs-consulting%2Fnfs-security-tooling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhvs-consulting%2Fnfs-security-tooling/lists"}