Research / Monero / Security
Monero Port Scans: What 447,000 Packets Showed
Our passive Monero-port study recorded 32,231 connections. Packet captures reveal unfinished handshakes, reused scanner probes and wallet RPC requests.

We put passive listeners on Monero-associated ports to see what connecting software would send before receiving a reply. From October 30 through November 13, the study recorded 32,231 connections from 4,686 source addresses across 26 listeners. Reading the packet captures adds something the connection logs cannot show on their own: unfinished handshakes, repeated probes for unrelated services, and traffic that never becomes an accepted listener connection.
We checked every nonempty capture in the archive through November 13, 2026 at 18:44 UTC, or 10:44 a.m. Pacific. The captures confirm Monero protocol probes and requests for daemon information, version information and wallet balances. They also show software testing the same ports for SSH, SMB, Redis and other services. The passive listeners sent no application response bytes in the observed research traffic.
What we put on the internet
The sensors listen on TCP ports 18080, 18081 and 18089. They accept connections and record up to 4 KiB of opening data over at most five seconds. They do not run a Monero daemon, hold a wallet, answer RPC requests or relay transactions. We did not probe the connecting systems.
Monero uses 18080 as its default mainnet peer-to-peer port and 18081 for daemon RPC. Its configuration examples use 18089 for a separate restricted RPC listener. A port number gives a scanner a place to look, but does not establish what service is there. Monero network ports and configuration examples document those defaults and settings.
The listener records begin on October 30 at 19:50 UTC. Packet collection began later that evening, at 22:35 UTC, and covers 25 of the 26 sensors. The Singapore shared-host listener has no packet capture in this study. Five sensors joined later, so raw totals are not a comparison of sites with equal observation time.
The figures below exclude traffic carrying our validation marker. Untagged operator checks may still be present. An address is not a count of people, devices or independent scanner operators.
The connection totals through November 13
| Destination port | Connections since collection began | November 13 through 18:44 UTC |
|---|---|---|
| 18080 | 22,381 | 1,332 |
| 18081 | 7,018 | 154 |
| 18089 | 2,832 | 53 |
| Total | 32,231 | 1,539 |
The original 20-sensor cohort accounts for 25,590 connections. Across all 26 listeners, 2,019 source addresses reached more than one sensor, and 14 reached at least 20. Today's partial UTC day contributed 1,539 connections from 771 addresses.
The listener's HTTP label needs care. Of 5,928 records with that label, 879 have RTSP request lines and 333 have SIP request lines. Those protocols share verbs such as OPTIONS with HTTP. At least 20.4% of the label describes something other than HTTP. We checked the request lines instead of treating the classifier as the result.
Packet evidence beyond the connection logs
The archive held 447,741 packets in 484,156 files when we took the snapshot. Most files were empty because capture rotates every minute. We copied all 19,946 nonempty files, checked their recorded sizes and SHA-256 hashes, and decoded them offline with Wireshark's TShark. Every file check passed. Capinfos and the archive metadata agreed with TShark's total packet count.
Seventeen packets fell after the cutoff. We then excluded 645 tagged validation packets and 1,351 packets involving other local services. That left 445,728 research packets, grouped into 71,238 TCP streams from 5,225 source addresses.
The extra service traffic was a useful trap to catch. A capture filter for port 18081 matches either end of a connection. If a scanner uses source port 18081 while connecting to SSH on port 22, the filter captures it. We matched each sensor's local address and local port before counting Monero-port traffic. Otherwise, replies from other honeypot services could have looked like replies from our passive listeners.
A TCP stream is Wireshark's grouping of related packets. It can include an incomplete connection, so 71,238 streams does not mean 71,238 accepted connections. The packet and listener totals also cover different sensor populations and start times.
Even with those limits, packet capture adds visibility. It contains 718 source addresses absent from the entire listener export. Those addresses would not appear in a report based only on accepted connections.
Many probes stop before an application exchange
TCP normally starts with a three-step exchange: a client sends SYN, the server replies with SYN/ACK, and the client acknowledges the reply. The TCP specification describes this connection setup.
We observed that complete sequence in 46,462 streams. Another 24,317 contained SYN and SYN/ACK but no matching complete handshake in the capture. Of those, 23,286 also contained an incoming reset. A further 319 had an incoming SYN without an observed SYN/ACK.
A scanner may deliberately stop after receiving a reply. A return path may fail. A capture gap can also hide part of the exchange. We cannot call every unfinished stream a failed attack or a SYN-only scan.
There were 4,429 streams with a complete handshake and no incoming payload, while 49,385 carried at least one incoming payload segment. Some used unusual sequence numbers or sent different bytes at overlapping sequence positions. We retained those original packets rather than assuming they formed one ordinary application message.
The listeners' own behavior matters too. They close connections after their short collection period. A brief exchange or server-side closure can reflect that timeout.
The same ports attract many kinds of scanner
The captures contain HTTP requests, TLS ClientHello candidates, SSH banners, RTSP and SIP requests, SMB negotiation candidates and Redis PING bytes. The RDP-associated Cookie: mstshash= marker appears in 2,372 streams from 456 addresses across all 25 packet sensors.
One particularly clear match is a 17-byte MQTT probe with the client identifier LZR. Its bytes exactly match the public LZR scanner's MQTT probe. We found it in 1,271 streams from 36 addresses across 23 sensors, spread across all three ports.
LZR's documentation describes a tool for finding unexpected services on unexpected ports. The matching payload supports reuse of that tool or its probe template. It does not identify the operator. Anyone can copy public scanner code or run it independently of its authors.
HTTP requests also targeted /api/config and /v1/models. The latter appeared in 46 streams. A model-discovery path on a Monero-associated port tells us what the client tried to find. It does not establish that an AI service was present.

The frozen Monero handshake keeps returning
Monero's Levin signature is a fixed marker at the start of a network message. It helps identify the format, but does not authenticate the sender.
The listener export contains 821 Levin-signature connections from 547 source addresses. The command fields contain 291 handshake candidates and 530 ping candidates, using the command IDs in Monero's protocol source.
The packet archive independently contains 789 streams with Levin-signature payloads. We reconstructed those messages across packet boundaries and checked their 33-byte headers against the declared body lengths. All 789 matched, without gaps or conflicting bytes in their reconstruction. This verifies framing length, not every field's meaning or a completed Monero exchange. Monero's Levin specification describes the header and message format.
One 259-byte handshake template appeared 232 times from 108 addresses across all 26 listeners. Its extracted local_time value is still January 31, 2021 at 11:24:20 UTC. Packet reconstruction confirms 223 copies across the 25 capture sensors.
An unchanged timestamp inside byte-identical messages supports reuse of a canned probe. It does not mean the sending computers have clocks stuck in 2021. The payload alone does not identify its operator. Comparing the source addresses with published scanner ranges adds stronger evidence.
Connections to named scanning operators
The frozen handshake has a supported connection to Palo Alto Networks' Cortex Xpanse scanning infrastructure. All 108 listener source addresses, accounting for all 232 copies, fall within the scanner ranges Palo Alto Networks publishes. All 103 source addresses in the packet-confirmed subset also match those ranges, and all 223 captured copies completed TCP handshakes.
Our captures provide a second link. Thirty-six of those 103 addresses also sent HTTP requests with a user agent identifying Palo Alto Networks. We found 366 streams carrying that name from 288 addresses, all within the published ranges. The range match and observed return-path handshakes make this stronger than a scanner name in a header alone. They support an infrastructure attribution. The captures do not identify an employee, customer or purpose behind each probe.
The following counts use the operators' published IPv4 lists retrieved on November 13. We matched source addresses directly against those lists.
| Published scanner ranges | Listener connections | Packet streams | Packet source addresses |
|---|---|---|---|
| Palo Alto Networks / Cortex Xpanse | 1,708 | 2,197 | 440 |
| Driftnet | 8,893 | 8,768 | 853 |
| Censys | 1,781 | 1,910 | 264 |
| Modat | 2,959 | 2,942 | 54 |
Internet Measurement identifies its operator as Driftnet and publishes its ranges. All 176 addresses sending the InternetMeasurement user agent matched that list. Modat publishes its scanner addresses and user-agent format. All 37 addresses sending that format matched its current address list. Censys provides its scanning ranges separately. Current lists can change, so these comparisons describe the lists we saved on the review date.
Other names remain weaker leads. The captures include 291 streams naming Infrawatch, 230 naming Apcosys and 70 naming zern. Infrawatch describes its measurement activity, but we have not independently verified the source addresses behind those three names. A self-selected user agent is not authentication.
The LZR MQTT and lzrORA probes came from exactly the same 36-address set. Every address also sent a zgrab user agent. That links these probe families within this dataset, while leaving the operator unresolved. We also saw 63 streams using Nmap's distinctive FourOhFourRequest probe path. Public templates can appear in many operators' tools.
A separate source sent 58 streams naming cryptohunt/2.0, each containing a get_info request, across 20 sensors between November 8 and 10. That defines an observable scanning cluster. We found no primary evidence identifying its operator. The two wallet-balance sources did not overlap any of these named user-agent groups or the LZR group. Their hosting-network labels do not tell us who controlled them.
These findings connect traffic to four commercial measurement services and define additional probe clusters. They do not establish a link to a criminal group, a state operation or transaction surveillance.
Requests for daemon information and wallet balances
The readable JSON-RPC requests were more specific than an empty visit to a familiar port:
| Method | Listener records | Source addresses | Packet-confirmed streams |
|---|---|---|---|
get_info |
155 | 51 | 147 |
get_version |
19 | 1 | 19 |
get_balance |
11 | 2 | 11 |
web3_clientVersion |
2 | 2 | 2 |
Monero documents get_info and get_version in its daemon RPC reference. The version requests reached 14 sensors, with 16 requests to port 18089 and three to 18081. Those requests occurred earlier in the collection period, not today.
The 11 get_balance requests arrived on November 4 between 06:20 and 06:59 UTC. They reached five sensors on port 18081 and requested account_index: 0. The wallet RPC documentation defines this method as a balance query.
That is consistent with searching for an exposed wallet RPC service. It is not evidence that a wallet was found. Our listeners had no wallets and sent no application replies. The captures show no balance disclosure or transfer in those exchanges. The two web3_clientVersion requests provide another example of software probing these ports for other services.
Source IPs behind the RPC requests
Four source addresses account for the wallet-balance requests, every version query and the cryptohunt/2.0 cluster. The table separates requests for each listed method from all captured TCP streams belonging to that address.
| Source IP | Named request | Streams containing that request | Sensors receiving that request | All captured streams from the address |
|---|---|---|---|---|
169.150.196.5 |
get_balance |
3 | 3 | 6 |
193.32.249.162 |
get_balance |
8 | 3 | 15 |
173.249.217.3 |
get_version |
19 | 14 | 46 |
79.124.58.218 |
get_info, with cryptohunt/2.0 |
58 | 20 | 255 |
The two balance-query addresses reached five sensors between them, with one sensor receiving requests from both. Their plaintext requests used POST /json_rpc HTTP/1.1, the user agent curl/8.5.0 and the same JSON body:
{"jsonrpc":"2.0","id":"0","method":"get_balance","params":{"account_index":0}}
The tcpdumps show a complete TCP handshake for all 11 balance requests. The full HTTP messages occupy 220 to 223 reconstructed client bytes, with the destination-specific Host header accounting for different lengths. The same addresses also opened ten separate streams carrying TLS ClientHello candidates: three from 169.150.196.5 and seven from 193.32.249.162. Together, their 21 streams contain 169 captured packets. None carries an application response from a listener.
The saved network enrichment labels 169.150.196.5 as Datacamp Limited and 193.32.249.162 as 31173 Services AB. The scanner operators remain unidentified. The shared request body, curl version and collection date support comparing the two addresses as a probe pattern, but do not prove common control.
For 173.249.217.3, the packet breakdown is 19 HTTP version requests, four TLS ClientHello candidates and 23 streams without client payload. All 19 version requests completed TCP setup. The 46 streams contain 295 packets. The saved enrichment identifies the network as tzulo. The client requested get_version with JSON-RPC ID 0, without a wallet account parameter.
For 79.124.58.218, the 58 cryptohunt/2.0 requests form only part of the address's activity. Its full capture record contains 255 streams and 1,385 packets across 21 sensors, including 197 streams without client payload. The readable requests all ask for get_info. Their JSON key order varies, while the method, ID 0 and JSON-RPC version 2.0 stay the same. The saved network label is Tamatiya EOOD. That label and the user agent do not identify who ran the scanner.
A busy source visible only in the tcpdumps
The busiest source address by captured stream count was 45.33.12.122, with 1,791 streams and 8,597 packets across 21 sensors. It reached all three monitored ports: 622 streams on 18080, 352 on 18081 and 817 on 18089. It has no record in the accepted-connection export.
Its packets include the LZR MQTT template, the lzrORA marker and HTTP requests carrying a zgrab user agent. That places it in the same 36-address probe group described above. Other payloads include an RDP cookie marker, SMB negotiation bytes and RTSP requests.
Incoming resets appear in 1,789 of its streams. Our packet analysis also recognizes complete TCP setup in 721 streams. Those categories overlap: a stream can complete setup and later contain a reset. Application acceptance requires its own log record. This source is a concrete example of why an application log and a tcpdump tell different parts of the story.
Across the full dataset, 5,547 streams contain more than one distinct client payload segment. TShark marks 18,628 packets as suspected retransmissions. We do not count retransmitted packets as separate RPC requests. For the Monero-specific payloads, reassembly gives a more useful result: complete Levin frames and exact RPC bodies, alongside scanner templates shared by multiple source addresses.