Memory and Path Attacks

In a file path, .. stands for the folder one level up. Enough of them in a row can name a file anywhere above the starting point, and a web server that follows them without checking can be made to hand out files it was never meant to serve.

Files behind a web address

The soccer league's registration site keeps its files on its server in folders, like any computer. The team photos, the schedule as a PDF, and the pictures on the home page sit in one folder that the web server software hands out to anyone who asks. The site's program and its settings sit in folders beside it, and one settings file holds the password the program uses to sign in to the database server that keeps the players' records.
When a parent opens a team photo, the browser sends the server a GET request, the request HTTP uses to fetch something. The server joins the path in the request to the folder it hands files out of and opens the file at the end:
Request:  GET /photos/u10-green.jpg
Opens: /srv/league/public/photos/u10-green.jpg

Directory traversal

The settings file is at /srv/league/private/settings.ini. Here is a second request, sent by someone who guessed the folder names. Work out which file the server opens if it joins the path the same way and checks nothing.
Request:  GET /photos/../../private/settings.ini
It opens the settings file. Joined to the public folder, the path reads /srv/league/public/photos/../../private/settings.ini. The first .. undoes photos, the second undoes public, and what is left is /srv/league/private/settings.ini. The server sends back the database password as readily as a team photo, because nothing in its program asks whether the file it reached is still inside the public folder.
Served folder: /srv/league/public. Add photos: /srv/league/public/photos. Add ..: /srv/league/public. Add ..: /srv/league. Add private: /srv/league/private. Add settings.ini: /srv/league/private/settings.ini. The last path is outside the served folder.
The request's path joined to the served folder, one piece at a time.
The usual target in examples is a system file that lists the computer's user accounts. A file the program reads for itself, like the league's settings, can do more damage, since the database password in it opens every family's records to anyone who can reach the database.

Fortinet's VPN, 2019 to 2021

Fortinet sells FortiGate firewalls, and many of them also run a VPN, so that employees at home can sign in through a web page on the firewall and work as if they were in the office. A FortiGate is a box, often mounted in a rack, that sits where an organization's network meets the internet. Its sign-in page has to answer anyone on the internet, since employees sign in from wherever they are.
The white front panel of a rack-mounted Fortinet FortiGate 6501F, with large vented fan grilles across the top and rows of network ports along the bottom.
A FortiGate 6501F, one of Fortinet's large firewalls for data centers. Photo: Premeditated, CC BY-SA 4.0, via Wikimedia Commons.
In May 2019 Fortinet published a fix for a directory traversal flaw in that page, reported by two researchers at the security firm DEVCORE. A request built the right way let anyone, without signing in, download a system file from the device. The file worth taking held the VPN's current sessions, with usernames and passwords in plain text.
Many devices were never updated. In November 2020 someone posted a list of 49,577 that were still open to the flaw on a hacker forum, and the passwords taken from them soon followed. Before and after that, U.S. agencies warned that state-sponsored groups were using the flaw to get into networks. In September 2021 Fortinet reported that an attacker had published sign-in details for about 87,000 of its devices, some of which had since been updated. How could a device that had been fixed still leak?
The fix closed the hole and did nothing about what had already been taken through it. A device whose session file was copied before the update still accepted the same usernames and passwords afterward. Fortinet told customers to install the update, reset every VPN password, and turn on multifactor sign-in.

The jersey name

Back at the league, the registration form has a box for the name printed on the back of a jersey, at most 14 letters. The program that receives the form is an older one written in C, a language that leaves counting to the programmer, and it sets aside room in memory for those 14 characters before it copies them in. Memory is one long row of numbered places, and right after that room sits other data the program is using, such as the player's team or the address of the instruction the program should run next.
Memory, a row of numbered places, one byte each, places 1200 to 1218 (last two digits shown). Places 1200 to 1213: jersey name, room for 14, holding R O D R I G U E Z and five empty places. Place 1214: team. Places 1215 to 1218: where to run next.
The room set aside for a jersey name, holding RODRIGUEZ, and the places right after it.
Suppose a request arrives with 300 characters in the jersey name and the program copies all of them without counting. What happens to the data that sat after the 14-character room?
It gets overwritten by the extra characters. If what sat there was ordinary data, the program now works with garbage and may crash, which can take registration down for every family at once. If what sat there told the program where to go next, an adversary who chose those extra characters with care can send the program to instructions of the adversary's own.
The fix in the jersey program is a count. It checks the length first and refuses any name over 14 characters with a message asking for a shorter one, so nothing longer than the room is ever copied in. A check on the form in the browser isn't enough on its own, since nothing obliges a request to come from the league's form at all.
Sources: Fortinet PSIRT advisory FG-IR-18-384 (May 24, 2019); BleepingComputer, "Passwords exposed for almost 50,000 vulnerable Fortinet VPNs" (November 25, 2020); CISA and FBI advisory AA20-283A (October 9, 2020); Fortinet PSIRT blog, "Malicious Actor Discloses FortiGate SSL-VPN Credentials" (September 8, 2021).