Skip to content

How Chainalysis Made Their Way into Popular Monero Wallets ​

Written by: Ä°rem Kuyucu, Laurynas ÄŒetyrkinas

A now-deleted and actively censored training video from Chainalysis — a blockchain analysis company — revealed Monero RPC logs, seemingly from a popular public Monero "node" called node.moneroworld.com. Many wallets like Cake Wallet and Monerujo include it in their list of default public nodes. In this post we will explain how Chainalysis's malicious nodes were given to users choosing the public node node.moneroworld.com and the dangers of dangling DNS records of decomissioned Monero nodes.

What is node.moneroworld.com? ​

node.moneroworld.com is not an actual Monero node. Instead, the domain has numerous A records pointing to other Monero node IPs. The domain is controlled by the trusted community member Gingeropolous who decides which nodes to add or remove from the Round-robin DNS.

node.moneroworld.com at port 18089 - I point this one to whatever I think is best at the time being. Currently, its a small cohort of trusted monero community members.

Source: https://web.archive.org/web/20240822030528/https://moneroworld.com/#nodes

The Monero RPC logs shown in the Chainalysis video ​

To avoid DMCA claims from Chainalysis, we will redraw the tables from the video but keep the same data. There are two transactions shown in the video which have Monero RPC logs associated with them.

Transaction 1 (video timestamp: 29:02) ​

RPC Request:

DateIP AddressSourceRequestHeadersBody
2020-10-20, 10:19:21.190185.220.100.252003POST /sendrawtransactionnode.moneroworld.com, application/json; charset=utf-8, CLclient, tx_as_hex

Transaction 2 (video timestamp: 35:40) ​

RPC Request:

DateIP AddressSourceRequestHeadersBody
2020-10-02, 12:15:55.66985.248.227.164140POST /sendrawtransactionnode.moneroworld.com, application/json; charset=utf-8, CLclient, tx_as_hex

Unfortunately the tables don't directly disclose the IP/host information of the malicious nodes run by Chainalysis. But by inspecting the Headers column, we can see that this request was made to node.moneroworld.com, which resolved to a malicious node. Chainalysis's application UI omits header names and only displays the values, but we can see that:

Host: node.moneroworld.com
Content-Type: application/json; charset=utf-8
...

Based on the Source column, we can assume that node.moneroworld.com had A records pointing to at least two Chainalysis nodes (#003, #140) around 2020.

Luckily, the old DNS records have been cached in services like Virustotal. There is a total of 200 A records dating all the way back to 2017-05-14 in Virustotal.

The curious case of dallas.xmrnode.com ​

On 2024-09-05, Reddit user u/__lt__ made a post about the strange behavior they observed from one of the affiliated hosts after investigating node.moneroworld.com. The host in question is dallas.xmrnode.com (104.223.103.222). A port scan of it reveals that it has Monero node ports open alongside other services:

Nginx on port 443/tcp serves a self-signed certificate for fn.likauction.com. Searching for this hostname on Shodan leads to 6 different servers that have the exact same ports open.

However as of writing, probing the Monero node ports on these servers reveals that these ports don't belong to nodes or Monero RPC servers. It could be that the malicious node operators have pulled the plug.

On 2024-09-08 the Reddit post by u/__lt__ was mass reported and removed. It was restored after notifying the moderators on Monero Matrix room. I consider this an example of the Streisand effect.

Chainalysis may be abusing dangling DNS records of decomissioned Monero nodes ​

I found this comment on Reddit while dorking for "xmrnode.com".

Since we know that there were at least two different malicious nodes and one of them may have been dallas.xmrmode.com, I decided resolve the subdomains in the Reddit comment and search the IPs in the DNS record history of node.moneroworld.com.

2017-08-29 - 169.239.128.104 (africa.xmrnode.com)
2017-09-08 - 96.43.143.242 (kc6.xmrnode.com)
2017-09-20 - 104.223.103.222 (dallas.xmrmode.com)
2017-09-22 - 204.27.62.98 (kc3.xmrnode.com)
2017-10-09 - 213.197.187.236 (europe.xmrnode.com)
2017-10-09 - 96.43.143.250 (kc7.xmrnode.com)
2018-04-28 - 103.208.86.41 (nz.xmrnode.com)
2018-05-03 - 96.43.139.226 (xmrnode.com)
2018-05-03 - 96.43.139.226 (kc.xmrnode.com)

Turns out node.moneroworld.com was pointing to many *.xmrnode.com nodes.

I contacted rupeee in the #Monero Matrix room to ask about the strange behavior of the nodes and to my surprise this was their answer:

Apparently the nodes haven't been running since 2018. You can find rest of the conversation here.

Assuming that rupee is not a bad actor, this means that someone other than rupee has been running the nodes (most likely by going to the same hosting provider and asking to get assigned the same IPs). And up to 2020 these nodes were pointed at by node.moneroworld.com, hence the Chainalysis table data from those dates.

Chainalysis may have abused the leftover DNS records of rupee's nodes and the A records of node.moneroworld.com which were not removed after rupee stopped hosting the nodes. There is nothing stopping Chainalysis from submitting new public nodes to listings such as monero.fail, but node.moneroworld.com is a more desirable target because of the reputation of the person running it and the fact that it is one of the defaults for popular mobile wallets.

Lessons learned ​

Apart from the obvious RUN YOUR OWN NODE, if you must use a public node use Tor/i2p and do not use node addresses that aggrate or point to random nodes via DNS records. Because there might be Chainalysis somewhere along the way.

Extra: Reverse proxy investigation ​

We speculated that it wouldn’t make much financial sense for malicious actors to operate their own dedicated nodes, given the high resource requirements.

Instead, we considered that these so-called "fake nodes" might not be real nodes at all but rather Nginx servers acting as reverse proxies, forwarding traffic to legitimate nodes while capturing a copy of the underlying data.

To investigate this, we quickly developed a tool to gather all public Monero nodes listed by monero.fail and xmr.ditatompel.com. The tool analyzes them by attempting to identify unique data they generate across various Monero RPC endpoints.

go
// Copyright 2024 Laurynas ÄŒetyrkinas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"time"
)

type MoneroFailNodes struct {
	Monero struct {
		Clear         []string `json:"clear"`
		WebCompatible []string `json:"web_compatible"`
	} `json:"monero"`
}

type XmrDitatompelNodes struct {
	Data struct {
		Items []struct {
			Hostname    string `json:"hostname"`
			Port        int    `json:"port"`
			Protocol    string `json:"protocol"`
			IsTor       bool   `json:"is_tor"`
			IsAvailable bool   `json:"is_available"`
			NetType     string `json:"nettype"`
		} `json:"items"`
	} `json:"data"`
}

type MoneroNode struct {
	IP map[string]NodeIdentifyInfo `json:"ip"`
}

type NodeIdentifyInfo struct {
	NodeGetInfoResponse            NodeGetInfoResponse            `json:"get_info"`
	NodeGetLimitResponse           NodeGetLimitResponse           `json:"get_limit"`
	NodeGetAltBlocksHashesResponse NodeGetAltBlocksHashesResponse `json:"get_alt_blocks_hashes"`
}

type NodeGetInfoResponse struct {
	AdjustedTime              int64  `json:"adjusted_time"`
	AltBlocksCount            int64  `json:"alt_blocks_count"`
	BlockSizeLimit            int64  `json:"block_size_limit"`
	BlockSizeMedian           int64  `json:"block_size_median"`
	BlockWeightLimit          int64  `json:"block_weight_limit"`
	BlockWeightMedian         int64  `json:"block_weight_median"`
	BootstrapDaemonAddress    string `json:"bootstrap_daemon_address"`
	BusySyncing               bool   `json:"busy_syncing"`
	Credits                   int64  `json:"credits"`
	CumulativeDifficulty      int64  `json:"cumulative_difficulty"`
	CumulativeDifficultyTop64 int64  `json:"cumulative_difficulty_top64"`
	DatabaseSize              int64  `json:"database_size"`
	Difficulty                int64  `json:"difficulty"`
	DifficultyTop64           int64  `json:"difficulty_top64"`
	FreeSpace                 uint64 `json:"free_space"`
	GreyPeerlistSize          int64  `json:"grey_peerlist_size"`
	Height                    int64  `json:"height"`
	HeightWithoutBootstrap    int64  `json:"height_without_bootstrap"`
	IncomingConnectionsCount  int64  `json:"incoming_connections_count"`
	Mainnet                   bool   `json:"mainnet"`
	Nettype                   string `json:"nettype"`
	Offline                   bool   `json:"offline"`
	OutgoingConnectionsCount  int64  `json:"outgoing_connections_count"`
	Restricted                bool   `json:"restricted"`
	RPCConnectionsCount       int64  `json:"rpc_connections_count"`
	Stagenet                  bool   `json:"stagenet"`
	StartTime                 int64  `json:"start_time"`
	Status                    string `json:"status"`
	Synchronized              bool   `json:"synchronized"`
	Target                    int64  `json:"target"`
	TargetHeight              int64  `json:"target_height"`
	Testnet                   bool   `json:"testnet"`
	TopBlockHash              string `json:"top_block_hash"`
	TopHash                   string `json:"top_hash"`
	TxCount                   int64  `json:"tx_count"`
	TxPoolSize                int64  `json:"tx_pool_size"`
	Untrusted                 bool   `json:"untrusted"`
	UpdateAvailable           bool   `json:"update_available"`
	Version                   string `json:"version"`
	WasBootstrapEverUsed      bool   `json:"was_bootstrap_ever_used"`
	WhitePeerlistSize         int64  `json:"white_peerlist_size"`
	WideCumulativeDifficulty  string `json:"wide_cumulative_difficulty"`
	WideDifficulty            string `json:"wide_difficulty"`
}

type NodeGetLimitResponse struct {
	LimitDown int64  `json:"limit_down"`
	LimitUp   int64  `json:"limit_up"`
	Status    string `json:"status"`
	Untrusted bool   `json:"untrusted"`
}

type NodeGetAltBlocksHashesResponse struct {
	BlksHashes []string `json:"blks_hashes"`
	Credits    int      `json:"credits"`
	Status     string   `json:"status"`
	TopHash    string   `json:"top_hash"`
	Untrusted  bool     `json:"untrusted"`
}

func main() {
	var nodes []string
	err := fetchMoneroFailNodes(&nodes)
	if err != nil {
		log.Println("Error fetching nodes:", err)
		return
	}
	err = fetchXmrDitatompelNodes(&nodes)
	if err != nil {
		log.Println("Error fetching nodes:", err)
		return
	}
	moneroNodes := make(map[string]MoneroNode)
	var wg1, wg2 sync.WaitGroup
	var mu sync.Mutex
	for _, host := range nodes {
		wg1.Add(1)
		go func(host string) {
			defer wg1.Done()
			var node MoneroNode
			node.IP = make(map[string]NodeIdentifyInfo)
			pUrl, err := url.Parse(host)
			if err != nil {
				return
			}
			ipAddresses, err := net.LookupIP(pUrl.Hostname())
			if err != nil {
				return
			}
			for _, ip := range ipAddresses {
				ipStr := ip.String()
				wg2.Add(1)
				go func(ip, host string) {
					defer wg2.Done()
					nodeInfo, err := identifyMoneroNode(ip, host)
					if err != nil {
						log.Println("Failed to getMoneroNodeInfo for:", host, ip, err)
						return
					}
					mu.Lock()
					node.IP[ip] = nodeInfo
					moneroNodes[host] = node
					mu.Unlock()

				}(ipStr, host)
			}
			wg2.Wait()
		}(host)
	}
	wg1.Wait()

	uniqueNodes := make(map[string][]string)
	for host, node := range moneroNodes {
		for ip, info := range node.IP {
			rdns := "nil"
			rdnsa, err := net.LookupAddr(ip)
			if err == nil {
				rdns = rdnsa[0]
			}
			outJSON, err := json.Marshal(info)
			strJSON := string(outJSON)
			uniqueNodes[strJSON] = append(uniqueNodes[strJSON], ip+" "+rdns+" "+host)
		}
	}

	group := 1
	for _, ips := range uniqueNodes {
		fmt.Println("Host group", group)
		for _, ip := range ips {
			fmt.Println(ip)
		}
		group++
		fmt.Println()
	}

}

func fetchMoneroFailNodes(nodes *[]string) error {
	resp, err := http.Get("https://monero.fail/nodes.json")
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	var resNodes MoneroFailNodes
	err = json.NewDecoder(resp.Body).Decode(&resNodes)
	if err != nil {
		return err
	}
	for _, host := range resNodes.Monero.Clear {
		url, err := normalizeURL(host)
		if err != nil {
			continue
		}
		// Get rid of i2p
		if strings.Contains(url, ".i2p") {
			continue
		}
		addUnique(nodes, url)
	}
	return err
}

func fetchXmrDitatompelNodes(nodes *[]string) error {
	resp, err := http.Get("https://xmr.ditatompel.com/api/v1/nodes?page=1&limit=1000")
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	var resNodes XmrDitatompelNodes
	err = json.NewDecoder(resp.Body).Decode(&resNodes)
	if err != nil {
		return err
	}
	for _, item := range resNodes.Data.Items {
		if !item.IsAvailable || item.IsTor || item.NetType != "mainnet" {
			continue
		}
		u1 := url.URL{
			Scheme: item.Protocol,
			Host:   fmt.Sprintf("%s:%s", item.Hostname, item.Port),
		}
		u, err := normalizeURL(u1.String())
		if err != nil {
			continue
		}
		addUnique(nodes, u)
	}
	return err
}

func normalizeURL(rawURL string) (string, error) {
	parsedURL, err := url.Parse(rawURL)
	if err != nil {
		return "", err
	}
	if parsedURL.Scheme == "http" && parsedURL.Port() == "80" {
		parsedURL.Host = strings.TrimSuffix(parsedURL.Host, ":80")
	}
	if parsedURL.Scheme == "https" && parsedURL.Port() == "443" {
		parsedURL.Host = strings.TrimSuffix(parsedURL.Host, ":443")
	}
	return parsedURL.String(), nil
}

func addUnique(slice *[]string, item string) {
	uniqueMap := make(map[string]struct{})
	for _, v := range *slice {
		uniqueMap[v] = struct{}{}
	}
	if _, exists := uniqueMap[item]; !exists {
		*slice = append(*slice, item)
	}
}

func identifyMoneroNode(ip, host string) (NodeIdentifyInfo, error) {
	client := &http.Client{
		Transport: &http.Transport{
			DialContext: func(c context.Context, n, a string) (net.Conn, error) {
				_, port, err := net.SplitHostPort(a)
				if err != nil {
					return nil, err
				}
				return net.Dial(n, net.JoinHostPort(ip, port))
			},
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
		Timeout: 5 * time.Second,
	}
	req, err := http.NewRequest("GET", host+"/get_info", nil)
	if err != nil {
		return NodeIdentifyInfo{}, err
	}
	req.Host = host
	resp, err := client.Do(req)
	if err != nil {
		return NodeIdentifyInfo{}, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return NodeIdentifyInfo{}, fmt.Errorf("Non-OK HTTP status:", resp.Status)
	}
	var getInfo NodeGetInfoResponse
	err = json.NewDecoder(resp.Body).Decode(&getInfo)

	req, err = http.NewRequest("GET", host+"/get_limit", nil)
	if err != nil {
		return NodeIdentifyInfo{}, err
	}
	req.Host = host
	resp, err = client.Do(req)
	if err != nil {
		return NodeIdentifyInfo{}, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return NodeIdentifyInfo{}, fmt.Errorf("Non-OK HTTP status:", resp.Status)
	}
	var getLimit NodeGetLimitResponse
	err = json.NewDecoder(resp.Body).Decode(&getLimit)

	req, err = http.NewRequest("GET", host+"/get_alt_blocks_hashes", nil)
	if err != nil {
		return NodeIdentifyInfo{}, err
	}
	req.Host = host
	resp, err = client.Do(req)
	if err != nil {
		return NodeIdentifyInfo{}, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return NodeIdentifyInfo{}, fmt.Errorf("Non-OK HTTP status:", resp.Status)
	}
	var getAltBlocksHashes NodeGetAltBlocksHashesResponse
	err = json.NewDecoder(resp.Body).Decode(&getAltBlocksHashes)

	identifyInfo := NodeIdentifyInfo{
		NodeGetInfoResponse:            getInfo,
		NodeGetLimitResponse:           getLimit,
		NodeGetAltBlocksHashesResponse: getAltBlocksHashes,
	}
	return identifyInfo, err
}

And we got such output out of it {ip} {reverse_dns} {node_url}:

Host group 1
81.163.200.3 pppoe-dynamic-a-3.interblock.pl. http://81.163.200.3:18089

Host group 2
172.232.19.26 172-232-19-26.ip.linodeusercontent.com. http://xmr-node.agates.io:18089
2600:3c06:1::ace8:131a nil http://xmr-node.agates.io:18089

Host group 3
84.23.142.12 012.ftthmackmyra1.gavlenet.com. http://opennode.xmr-tw.org:18089
84.23.142.12 012.ftthmackmyra1.gavlenet.com. https://opennode.xmr-tw.org:18089
84.23.142.12 012.ftthmackmyra1.gavlenet.com. http://xmr.monopolymoney.eu:18089

Host group 4
147.45.79.135 nil http://monerodice.pro:18089

Host group 5
65.109.30.253 iv.datura.network. https://datura.network:18081
65.109.30.253 iv.datura.network. http://datura.network:18081

Host group 6
82.153.138.209 nil http://82.153.138.209:18089

Host group 7
37.27.70.253 crypto.cruncher.com. https://crypto.cruncher.com:18081

Host group 8
88.99.195.15 static.15.195.99.88.clients.your-server.de. http://node3.monerodevs.org:18089

Host group 9
2a01:4f8:231:76a::2 cheems.de.box.skhron.com.ua. https://monero-rpc.cheems.de.box.skhron.com.ua:18089
195.201.247.11 cheems.de.box.skhron.com.ua. https://monero-rpc.cheems.de.box.skhron.com.ua:18089

Host group 10
172.105.13.82 xmr.grub.net. http://xmr.grub.net:18089
172.105.13.82 xmr.grub.net. https://xmr.grub.net:18089

Host group 11
167.114.172.211 xmr.robmanfred.fail. http://xmr.robmanfred.fail:18081

Host group 12
65.21.185.116 static.116.185.21.65.clients.your-server.de. http://node.yeetin.me:18089

Host group 13
87.197.115.178 static-dsl-178.87-197-115.telecom.sk. https://xmr.why.tf:18081

Host group 14
2a0b:f4c2:2::63 tor-exit-63.for-privacy.net. http://xmr-de.boldsuck.org:18081

Host group 15
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18889

Host group 16
175.38.15.166 n175-38-15-166.meb2.vic.optusnet.com.au. http://175.38.15.166:18081

Host group 17
51.68.212.53 vps-4a3dd5a8.vps.ovh.net. http://xmr-full.p2pool.uk:18089

Host group 18
185.240.242.36 nodes.hashvault.pro. https://nodes.hashvault.pro:18081
185.240.242.36 nodes.hashvault.pro. http://nodes.hashvault.pro:18081

Host group 19
92.131.11.157 alille-657-1-66-157.w92-131.abo.wanadoo.fr. https://xmr.mailia.be:18088
2a01:cb10:249:7300::6 nil https://xmr.mailia.be:18088

Host group 20
135.125.206.110 vps-6fef879a.vps.ovh.net. http://monero.earth:18081
135.125.206.110 vps-6fef879a.vps.ovh.net. http://vps-6fef879a.vps.ovh.net:18081

Host group 21
176.114.248.225 176-114-248-225.rychlydrat.cz. http://server.cnet.cz:18081

Host group 22
213.165.76.129 ip213-165-76-129.pbiaas.com. http://node.xmr.rocks:18089

Host group 23
79.205.108.252 p4fcd6cfc.dip0.t-ipconnect.de. http://nexper-xmr-node.tplinkdns.com:18081

Host group 24
65.21.100.162 eu.node.monero.net. https://node.monero.net:18081

Host group 25
95.216.15.156 moneronode1.relaycrun.ch. http://moneronode1.relaycrun.ch:18081

Host group 26
167.235.112.134 static.134.112.235.167.clients.your-server.de. http://167.235.112.134:18081

Host group 27
92.131.11.157 alille-657-1-66-157.w92-131.abo.wanadoo.fr. https://node.mailia.be:18085
2a01:cb10:249:7300:b:c:b:c nil https://node.mailia.be:18085

Host group 28
103.176.58.34 druckt.mavibettv74.com. http://thereisnospoon.pm:18089

Host group 29
144.91.121.7 vmd62396.contaboserver.net. http://144.91.121.7:18089
144.91.121.7 vmd62396.contaboserver.net. http://econanon.com:18089

Host group 30
37.120.165.105 v22019017574680478.happysrv.de. http://node.cryptocano.de:18089

Host group 31
162.210.173.15 monero.forked.net. http://monero.forked.net:18089

Host group 32
23.128.248.240 nil http://xmr.stormycloud.org:18089
2602:fc05::240 nil http://xmr.stormycloud.org:18089

Host group 33
71.229.155.41 c-71-229-155-41.hsd1.co.comcast.net. http://xmrbandwagon.hopto.org:18081

Host group 34
202.61.250.91 next.fackler.cloud. http://monero-g2.hexhex.online:18081

Host group 35
2a0b:f4c2:2:1::223 nil http://xmr-de-2.boldsuck.org:18081
185.220.101.223 tor-exit-223.for-privacy.net. http://xmr-de-2.boldsuck.org:18081
185.220.101.223 tor-exit-223.for-privacy.net. http://tor-exit-223.for-privacy.net:18081
2a0b:f4c2:2:1::223 nil http://tor-exit-223.for-privacy.net:18081

Host group 36
207.66.71.46 nil http://monero.sphinxlogic.com:18089

Host group 37
185.112.144.198 vps-185-112-144-198.1984.is. http://185.112.144.198:18089

Host group 38
151.48.191.155 adsl-ull-155-191.48-151.wind.it. http://edge7.servebeer.com:18089

Host group 39
15.204.197.8 monero.stackwallet.com. https://monero.stackwallet.com:18081

Host group 40
190.115.19.98 mail.miningcompany.ltd. http://node.majesticbank.at:18089
190.115.19.98 mail.miningcompany.ltd. http://node.majesticbank.is:18089

Host group 41
14.224.137.18 static.vnpt.vn. http://monero.hexalink.xyz:18081

Host group 42
85.160.78.94 85-160-78-94.reb.o2.cz. http://85.160.78.94:18089

Host group 43
194.163.176.218 hantaan.fullm00n.de. http://194.163.176.218:18089
194.163.176.218 hantaan.fullm00n.de. http://hantaan.fullm00n.de:18089

Host group 44
193.200.227.16 dc1-nat.filmweb.pl. http://monero.filmweb.pl:18081
193.200.227.16 dc1-nat.filmweb.pl. http://193.200.227.16:18081

Host group 45
37.187.74.171 ns3365046.ip-37-187-74.eu. http://node.moneroworld.com:18089
37.187.74.171 ns3365046.ip-37-187-74.eu. https://node.moneroworld.com:18089
37.187.74.171 ns3365046.ip-37-187-74.eu. http://node2.monerodevs.org:18089

Host group 46
23.154.81.12 mail.yuuta.moe. https://xmr.winslow.cloud:18081
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18989

Host group 47
65.100.46.162 65-100-46-162.dia.static.qwest.net. http://moneronode.xyz:18089
2602:41:642e:a610::251 nil http://moneronode.xyz:18089

Host group 48
188.245.34.63 static.63.34.245.188.clients.your-server.de. http://static.63.34.245.188.clients.your-server.de:18089

Host group 49
23.137.57.100 nil http://node.sethforprivacy.com:18089
68.118.241.70 syn-068-118-241-070.res.spectrum.com. http://68.118.241.70:18089
23.137.57.100 nil https://node.sethforprivacy.com:18089

Host group 50
192.99.8.110 ns508306.ip-192-99-8.net. http://node.moneroworld.com:18089
192.99.8.110 ns508306.ip-192-99-8.net. https://node.moneroworld.com:18089
192.99.8.110 ns508306.ip-192-99-8.net. https://uwillrunanodesoon.moneroworld.com:18089
192.99.8.110 ns508306.ip-192-99-8.net. http://opennode.xmr-tw.org:18089
192.99.8.110 ns508306.ip-192-99-8.net. http://uwillrunanodesoon.moneroworld.com:18089
192.99.8.110 ns508306.ip-192-99-8.net. https://opennode.xmr-tw.org:18089
192.99.8.110 ns508306.ip-192-99-8.net. http://node.monerodevs.org:18089

Host group 51
38.105.209.54 vmi732985.contaboserver.net. http://38.105.209.54:18089

Host group 52
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18189

Host group 53
70.77.245.214 S010694a67ee915ac.cg.shawcable.net. http://compking.ddns.net:18089

Host group 54
194.163.172.26 btc.heelsn.eu. https://xmr.heelsn.eu:18089

Host group 55
23.137.254.9 nil http://23.137.254.9:18081

Host group 56
135.181.202.85 static.85.202.181.135.clients.your-server.de. http://static.85.202.181.135.clients.your-server.de:18089

Host group 57
83.135.90.98 i53875A62.versanet.de. http://monero.firewall-gateway.de:18081

Host group 58
77.237.238.26 vmi1839646.contaboserver.net. http://77.237.238.26:18081
77.237.238.26 vmi1839646.contaboserver.net. http://xmr.perkele.digital:18081

Host group 59
64.74.162.85 nil http://xmr.vectorlink.io:18089

Host group 60
184.107.109.143 nil http://xmr.vectorlink.io:18089

Host group 61
68.251.60.69 68-251-60-69.lightspeed.sntcca.sbcglobal.net. http://68.251.60.69:18089

Host group 62
179.43.158.213 hostedby.privatelayer.com. https://xmr.yemekyedim.com:18089
179.43.158.213 hostedby.privatelayer.com. http://xmr.yemekyedim.com:18081
179.43.158.213 hostedby.privatelayer.com. http://179.43.158.213:18089
179.43.158.213 hostedby.privatelayer.com. https://xmr.yemekyedim.com:18081

Host group 63
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18689

Host group 64
69.85.89.42 nil http://xmr.tcpcat.net:18089

Host group 65
188.40.85.196 static.196.85.40.188.clients.your-server.de. http://monero.homelinux.org:18081

Host group 66
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18489
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18789
179.36.224.11 179-36-224-11.speedy.com.ar. http://monero.10z.com.ar:18089

Host group 67
51.195.219.36 anstee.dev. https://anstee.dev:18081
2001:41d0:801:2000::5811 anstee.dev. https://anstee.dev:18081

Host group 68
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18389

Host group 69
93.95.228.74 vps-93-95-228-74.1984.is. http://93.95.228.74:18089

Host group 70
146.185.21.170 nil http://p2pool.uk:18089
146.185.21.170 nil http://xmr-pruned.p2pool.uk:18089

Host group 71
185.66.143.190 nil http://xmr.litepay.ch:18081

Host group 72
65.109.50.106 static.106.50.109.65.clients.your-server.de. http://65.109.50.106:18081

Host group 73
190.211.255.227 public.deepdns.net. https://xmr.cryptostorm.is:18081

Host group 74
154.201.90.46 nil http://node.c3pool.org:18081

Host group 75
45.88.200.82 nil http://xm.rip:18081

Host group 76
46.32.46.171 2E202EAB.rev.sefiber.dk. http://46.32.46.171:18081
46.32.46.171 2E202EAB.rev.sefiber.dk. https://storj.myqnapcloud.com:18081

Host group 77
87.202.12.6 athedsl-03054.home.otenet.gr. http://monero.homeqloud.com:18089

Host group 78
194.5.183.35 nil http://xmr.nodes.masberthet.fr:18081

Host group 79
152.89.105.105 moneronode.org. http://moneronode.org:18081
152.89.105.105 moneronode.org. https://moneronode.org:18081

Host group 80
104.168.82.96 104-168-82-96-host.colocrossing.com. http://xmr.support:18081

Host group 81
125.168.80.60 60.80.168.125.sta.wbroadband.net.au. http://moneropay.techthis.online:18089

Host group 82
104.153.209.162 nil http://104.153.209.162:18081

Host group 83
185.162.249.141 owl.lc. http://owl.lc:18089

Host group 84
95.217.143.178 static.178.143.217.95.clients.your-server.de. http://rucknium.me:18081

Host group 85
2a01:4f8:a0:3800::7 nil https://xmr2.julias.zone:18089
88.198.38.83 dedi2.julias.zone. https://xmr2.julias.zone:18089

Host group 86
159.69.153.93 xmrvsbeast.com. http://p2pmd.xmrvsbeast.com:18081

Host group 87
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18089

Host group 88
193.168.143.9 nil http://monero.anycolo.net:18081

Host group 89
190.115.29.70 ddos-guard.net. http://node.majesticbank.at:18089
190.115.29.70 ddos-guard.net. http://node.majesticbank.is:18089

Host group 90
89.147.109.91 vps-89.147.109.91.1984.is. http://89.147.109.91:18089

Host group 91
88.212.32.151 ip-88-212-32-151.antik.sk. http://xmr.ppke.sk:18081

Host group 92
2a01:cb10:249:7300:b:c:b:c nil https://node.mailia.be:18089
92.131.11.157 alille-657-1-66-157.w92-131.abo.wanadoo.fr. https://node.mailia.be:18089

Host group 93
204.8.45.35 r2.ckwp.dyni.net. http://monero.dyni.net:18081

Host group 94
147.45.79.135 nil https://monerodice.pro:18089

Host group 95
51.195.200.94 vps-a6d1909f.vps.ovh.net. http://node.community.rino.io:18081

Host group 96
135.148.45.230 richfowler.net. http://opennode.xmr-tw.org:18089
135.148.45.230 richfowler.net. https://opennode.xmr-tw.org:18089
135.148.45.230 richfowler.net. http://node.richfowler.net:18089

Host group 97
125.229.105.12 125-229-105-12.hinet-ip.hinet.net. http://node1.xmr-tw.org:18081

Host group 98
186.190.208.100 nil http://node3-us.monero.love:18081

Host group 99
141.98.153.205 vmi1917710.contaboserver.net. http://141.98.153.205:18089

Host group 100
50.86.7.28 nil http://xmr.cruxexperts.com:18089

Host group 101
37.187.74.171 ns3365046.ip-37-187-74.eu. https://uwillrunanodesoon.moneroworld.com:18089
37.187.74.171 ns3365046.ip-37-187-74.eu. http://uwillrunanodesoon.moneroworld.com:18089

Host group 102
184.75.221.107 mojeooffers.net. http://monero.us.to:18193

Host group 103
185.25.108.186 185025108186.net-el.pl. http://185.25.108.186:18081

Host group 104
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18289

Host group 105
95.217.178.183 static.183.178.217.95.clients.your-server.de. http://95.217.178.183:18089
37.27.89.118 static.118.89.27.37.clients.your-server.de. http://37.27.89.118:18089

Host group 106
167.172.30.17 nil http://xmr.bikini.cafe:18081

Host group 107
172.104.202.210 172-104-202-210.ip.linodeusercontent.com. http://xmr-node.cakewallet.com:18081
172.104.202.210 172-104-202-210.ip.linodeusercontent.com. http://xmr-node-uk.cakewallet.com:18081
172.104.202.210 172-104-202-210.ip.linodeusercontent.com. http://xmr-node-eu.cakewallet.com:18081

Host group 108
77.51.51.199 nil http://l4nk0r.dev:18089

Host group 109
89.147.109.123 vps-89.147.109.123.1984.is. http://89.147.109.123:18089

Host group 110
185.218.124.120 vmi2088507.contaboserver.net. http://185.218.124.120:18589

Each host group in this output (regardless of protocol or IP) represents the same underlying Monero node.

Based on these results we concluded that there is less of such attack happening than we initially thought. However we found a few such hosts:

  • Host group 49: http://68.118.241.70:18089 is a proxy for http://node.sethforprivacy.com:18089.
  • Host group 66: http://185.218.124.120:18489 is a proxy for http://monero.10z.com.ar:18089 or the other way around.
  • Host group 105: http://95.217.178.183:18089 is a proxy for http://37.27.89.118:18089 or the other way around.

Another bad thing we noticed is that Host group 50 has 4 different domain names pointing to the same underlying Monero node server:

  1. node.moneroworld.com
  2. uwillrunanodesoon.moneroworld.com
  3. opennode.xmr-tw.org
  4. node.monerodevs.org (actual domain name of this node)

This increases the chances that this node will be selected over others even while picking randomly.

What can Digilol do for you? ​

Digilol offers full-stack development, managed hosting, consulting and penetration testing services. We accept Monero and help others do too.