# FTP Writable Directory Check

> Identifies writable FTP directories by testing anonymous or authenticated access, enabling upload of malicious files or further exploitation of misconfigured servers.

- **URL:** https://hackindex.io/services/ftp/vulnerability-discovery/ftp-writable-directory-check
- **Path:** FTP > Vulnerability Discovery
- **Up:** [Vulnerability Discovery](https://hackindex.io/services/ftp/vulnerability-discovery.md)
- **Published:** 2026-03-29
- **Updated:** 2026-08-11

A writable FTP directory becomes a critical finding when it overlaps with a path served by a web server. Uploading a file to `/var/www/html/uploads` over FTP and then requesting it over HTTP gives remote code execution without any vulnerability in the web application itself. This page confirms whether write access exists and identifies whether the writable path is web-accessible.

## Check Write Permissions in the Listing

When connected to FTP, the directory listing shows permissions in Unix format:

```bash
curl -s --user $USER:$PASSWORD ftp://$TARGET_IP:$PORT/ -l
```

Connect interactively and check permissions:

```bash
ftp $TARGET_IP $PORT
```

Inside the session:

```bash
ls -la
# drwxrwxrwx    2 1000  1000  4096 Mar 10 09:00 uploads
# drwxr-xr-x    3 0     0     4096 Mar 10 09:00 pub
# -rw-r--r--    1 0     0      512 Mar 10 09:00 readme.txt
```

`drwxrwxrwx` means world-writable. `drwxrwxr-x` means group-writable. Both may permit upload depending on the FTP daemon configuration and which user it runs as.

## Test Upload Directly

Create a test file and attempt to upload it to each directory:

```bash
echo "writetest" > /tmp/writetest.txt
curl -s --user $USER:$PASSWORD -T /tmp/writetest.txt ftp://$TARGET_IP:$PORT/uploads/writetest.txt
```

Confirm it landed:

```bash
curl -s --user $USER:$PASSWORD ftp://$TARGET_IP:$PORT/uploads/
```

If `writetest.txt` appears in the listing, write access is confirmed. Clean it up after confirming:

```bash
curl -s --user $USER:$PASSWORD -Q "DELE /uploads/writetest.txt" ftp://$TARGET_IP:$PORT/
```

## Check for Web Root Overlap

The critical question after confirming write access is whether the writable path is also accessible over HTTP. Common paths to check:

```bash
curl -s -o /dev/null -w "%{http_code}" http://$TARGET_IP/uploads/writetest.txt
curl -s -o /dev/null -w "%{http_code}" http://$TARGET_IP/writetest.txt
curl -s -o /dev/null -w "%{http_code}" http://$TARGET_IP/ftp/writetest.txt
```

A `200` response confirms the file is served by the web server. If you know the FTP root path from the banner or configuration disclosure, map it against likely web roots:

Common FTP roots that overlap with web directories:

- `/var/www/html/`
- `/var/www/html/uploads/`
- `/srv/ftp/`
- `/home/USERNAME/public_html/`
- `C:\inetpub\wwwroot\`
- `C:\xampp\htdocs\`
- 

## What Writable FTP Access Enables

A writable directory not served by a web server still enables staging files for later retrieval, uploading tools during post-exploitation, or overwriting configuration files if the path is sensitive.

A writable directory served by a web server enables web shell upload and direct remote code execution. The full exploitation workflow is in [FTP Web Shell Upload](https://hackindex.io/services/ftp/exploitation/ftp-web-shell-upload).

## References

- [ftp-anon NSE Script](https://nmap.org/nsedoc/scripts/ftp-anon.html) - Lists directory contents and permissions during anonymous FTP enumeration
