Path traversal in aiohttp (CVE-2024-23334)
aiohttp is an asynchronous HTTP framework for Python. When used as a web server with static routes (add_static), you set the root directory to serve files from. The follow_symlinks=True option controls whether symlinks outside that directory are followed, but in the affected versions it doesn't validate that the file read stays inside the root. The result is a path traversal: prefixing enough ../ to the static path escapes the directory and reads any file on the system the process can reach, even with no symlinks present.
CVE-2024-23334 affects aiohttp < 3.9.2. The abuse is trivial with curl --path-as-is (so it doesn't normalize the ../ before sending them):
curl --path-as-is "http://127.0.0.1:8080/assets/../../../../etc/passwd"Two practical details. First, the right prefix is the server's actual static route (it may be /static/, /assets/, etc.): discover it by fuzzing directories. Second, if the service only listens on 127.0.0.1 (a typical internal service), you must reach it through an SSH port forward before attacking it.
From there you read sensitive files: /etc/passwd, /etc/shadow, a flag (/root/root.txt) or, better still, root's SSH private key (/root/.ssh/id_rsa), which lets you log straight in as root over SSH.
How to detect it. aiohttp's access log shows requests to the static route (/static/, /assets/...) followed by unnormalized ../../ and known absolute paths (/etc/passwd, /root/.ssh/id_rsa). Since a legitimate client never sends raw ../ toward a static route, its presence is the signature; one source trying different depths or several sensitive files gives away the sweep. A reverse proxy that canonicalizes paths would turn those requests into 404, so seeing them reach the backend indicates there is no such protection.
Defence. Update aiohttp to 3.9.2 or later; disable follow_symlinks; and put a reverse proxy in front that canonicalizes and filters paths.
Machines where it's used
- ChemistryHackTheBox