# Locally Listening Services and Internal Ports on Linux

> Identify locally bound services and internal ports on Linux using ss, netstat, and /proc/net to uncover hidden attack surface during post-exploitation enumeration.

- **URL:** https://hackindex.io/platforms/linux/enumeration/locally-listening-services
- **Path:** Linux > Enumeration
- **Up:** [Enumeration](https://hackindex.io/platforms/linux/enumeration.md)
- **Published:** 2026-03-15
- **Updated:** 2026-08-11

Services bound to `127.0.0.1` or `::1` are invisible from outside the host. They only become accessible once you have a shell. These are often databases, admin interfaces, caching layers, message brokers, and internal APIs: and they frequently run without the same hardening applied to externally facing services.

## Listing All Listening Ports

```bash
ss -tunlp
# Netid  State   Recv-Q  Send-Q  Local Address:Port  Process
# tcp    LISTEN  0       128     0.0.0.0:22           users:(("sshd",pid=1001))
# tcp    LISTEN  0       128     127.0.0.1:3306       users:(("mysqld",pid=1342))
# tcp    LISTEN  0       128     127.0.0.1:6379       users:(("redis-server",pid=1489))
# tcp    LISTEN  0       128     127.0.0.1:8080       users:(("java",pid=2031))
# tcp    LISTEN  0       128     127.0.0.1:5432       users:(("postgres",pid=1521))
```

The `Local Address` column is the key field. `0.0.0.0:PORT` means externally reachable. `127.0.0.1:PORT` means `localhost` only: these are the ones you could not see from outside.

The `Process` column requires either root or ownership of the process to populate. As a low-privilege user it may show empty: the port is still there, the process name is just not visible.

```bash
netstat -tunlp 2>/dev/null
```

> [!NOTE]
> This tool is old, deprecated, or rarely used in modern engagements. Prefer `ss`.

## Reading Process Names Without Root

When the `Process` column is empty, match ports to processes manually:

```bash
cat /proc/net/tcp
cat /proc/net/tcp6
```

The `local_address` column is in hex: convert to decimal to match ports. Alternatively, iterate open sockets:

```bash
ls -la /proc/*/fd 2>/dev/null | grep socket | head -20
```

Or check which process owns a specific port using `/proc`:

```bash
for pid in /proc/[0-9]*/net/tcp; do grep -l ":0CEA" $pid 2>/dev/null; done
```

Replace `0CEA` with the hex representation of the port you are looking for.

## Common `Localhost`-Only Services

| Port | Service | Notes |
| --- | --- | --- |
| 3306 | MySQL | Often no auth or weak creds locally |
| 5432 | PostgreSQL | May trust local connections without password |
| 6379 | Redis | Frequently unauthenticated on `localhost` |
| 27017 | MongoDB | Often no auth on `localhost` |
| 11211 | Memcached | No auth by design |
| 8080/8443 | Admin panels, Tomcat, Jenkins | Commonly restricted to `localhost` |
| 9200 | Elasticsearch | Often unauthenticated |
| 4848 | GlassFish admin | Default admin interface |
| 2181 | ZooKeeper | Usually no auth |

## Accessing `Localhost` Services

Once a listening port is identified, interact with it directly from the shell:

```bash
curl -s http://127.0.0.1:8080/
curl -s http://127.0.0.1:9200/_cat/indices
redis-cli -h 127.0.0.1 ping
mysql -u root -h 127.0.0.1 -e "show databases;" 2>/dev/null
psql -h 127.0.0.1 -U postgres -c "\l" 2>/dev/null
```

To reach a `localhost` service from your attacker machine, forward the port over SSH:

```bash
ssh -L $LPORT:127.0.0.1:REMOTE_PORT $USER@$TARGET_IP
```

Then connect to `127.0.0.1:$LPORT` locally to interact with the remote service through your own tools.

## Unix Domain Sockets

Some services do not listen on TCP at all: they use Unix sockets.

```bash
ss -xlp
find /var/run /run /tmp -name "*.sock" -o -name "*.socket" 2>/dev/null
```

Notable sockets:

- `/var/run/docker.sock`: write access means Docker-based privilege escalation. See [Docker Container Escape and Host Privilege Escalation](https://hackindex.io/platforms/linux/privilege-escalation/docker-container-escape).
- `/run/mysqld/mysqld.sock`: local MySQL connection without TCP
- `/var/run/postgresql/`: local PostgreSQL socket
- `/run/php/php*.fpm.sock`: PHP-FPM socket, may allow code execution if writable

Check permissions on any socket you find:

```bash
ls -la /var/run/docker.sock
```

Writable sockets for privileged services are direct escalation paths.
