A Crypto Security Lesson Worth $3800

While away from my keyboard, enjoying a trip to Hawaii, I lost ~$3800 in Crypto assets from my multisig wallet (app.safe.global).

I was eventually notified by my gnosis safe mobile app of a transaction moving some ENS out of my safe to an unknown address. Upon investigation I found my entire safe emptied.

The “attacker” as I’ll call them for now, began withdrawing funds from my multisig wallet on Ethereum at 0xec819F77d464aeeF84A204F88CA85284D96A3acF. The withdraws started the same day I left for my trip on the 16th of June 2023. Each day following around the same time another unique token in that wallet was moved to an address I was unfamiliar with (0x3851bb469Eb2fF35D3C8415d321a425e1E967858).

I was genuinely confused at first, because I am a very security conscious person and had no clue how one of my private keys associated with the multisig became compromised. Upon inspection I knew I didn’t own the address the coin was heading to and noticed the transactions were signed by my “backup” address (0xe0b4Ff23f7268508Eb5923C3Cb415F531110C42f).

I began wracking my brain while cruising threw the mountains of Oahu trying to remember everything I knew about how I setup this multisig safe and my “backup” wallet.

Mistake #1

When I created the safe wallet initially, mpoletiek.eth was the only address listed as an owner on the wallet and when I added the backup wallet I never adjusted the required number of confirmations for any transaction from 1 to say… 2. Had I done this, the “attacker” wouldn’t have been able to move the funds without an additional confirmation from my primary wallet.

I also remembered that I stored the private key to the backup wallet on a fully encrypted hard drive that could only be unlocked with a key stored on another fully encrypted device. That is pretty secure. Each device required physical access to read and I only ever imported the private key to the backup wallet once to validate it’s usability with the multisig safe. I used Metamask, which is a non-custodial wallet and immediately removed the wallet from Metamask when I was finished so even if my browser was compromised (It wasn’t) my private keys were safe.


Even after realizing my first mistake I was still confused as to how the “attacker” got ahold of my backup wallet’s private key. To be honest $3800 is not enough of a bag to tie up a ton of compute power to brute force so they must’ve easily nabbed the private key from my browser?

I did a ton of research as fast as I could. Were there any known security issues with Metamask? With Gnosis multisig wallets?? None that I could find. I don’t sign transactions at sketchy websites. I do a ton of research before hand and typically wouldn’t use my “secret” “backup” wallet to test a sketchy website….

Wait…. How did I even create this “backup” wallet? Since I was able to delete it from Metamask, I must’ve imported it, which means I didn’t use Metamask to create it….. Oh crap…. I’m such an idiot.

Mistake #2

While I don’t entirely remember exactly how I created this “backup” wallet, I definitely didn’t use localized software like ‘geth’ or even my Metamask plugin.

I most likely created this wallet a long time ago and stored the private key as a “backup”, but did so using some website like ethereumaddressgenerator or paperwalletcrypto.

The likelihood that small, simple websites like these are run by bad actors is very high. Additionally, it’s also highly likely that they are easily hacked without the owners knowledge and are stealing the private keys of any address created for later inspection.

Why I trusted this at the time is beyond me now, but I can only guess that in the past my involvement in Crypto and the amount of risk I was taking was relatively low compared to the $3800 I just watched vanish from my multisig. Still, probably chump change compared to the scores this individual is getting if this has been going on for as long as I can imagine.


While there wasn’t much I could do in Hawaii to validate the rest of my security profile, I did a little research into some of the addresses associated with the transactions that drained my multisig wallet.

I reached out to Gnosis Safe to validate that they didn’t see anything additional or had any other perspective on how these transactions were initiated. From what both of us could tell, it was and could only have been initiated from someone with the private key to my “backup” wallet.

Once I knew that I dug into the address the crypto was shipped to. At the time of this writing (06-25-23) the address (0x3851bb469Eb2fF35D3C8415d321a425e1E967858) still has all my crypto.

The “attacker” hasn’t moved the crypto out yet it seems.

I did some more digging and noticed an ENS address that was interacting with the address (0xtrippy76.eth).

Now I don’t want to make any claims that 0xtrippy76 is the attacker, but I will say that compared to other transactions this one is suspicious.

First, when knowingly taking crypto that wasn’t theirs, they spent a week withdrawing all the coin and have since held onto it for about another week. I’m comparing this to the transaction of almost 4billion PEPE from 0xtrippy76 and immediately shipping it to Uniswap (a decentralized exchange).

I did a quick search and found a twitter user by that same handle. If this is the attacker, that PEPE transaction must’ve been a mistake.

I figured it wouldn’t hurt to ask…..

They seem to be fairly active on twitter and a huge fan of PEPE so I’m hopeful they will reply. 🙂


Taking Action

So, I’m fairly certain I’ll never see that coin again, but am grateful for the lesson and have taken the following steps to ensure one of my multisigs doesn’t get compromised again.

  • Create a new multisig with wallets I created myself that requires 3 confirmations before any transaction is executed. To withdraw crypto I will confirm the transaction from 3 separate devices (this is probably overkill). Safe!
  • Isolate my wallets to the devices they reside on. No need to maintain 1 wallet on all of my devices. Crypto isn’t “spending” money yet in today’s economy, it’s more a store of value and an investment today (with more utility arriving daily), so we will “store” our crypto in our multisig and withdraw what we need, when or before we need it. Smart!
  • Setup notifications on etherscan.io. The Gnosis safe app was very slow to notify me of the transactions happening. With notifications from etherscan.io I would have caught the first transaction and saved myself ~$1500 in pain. Alert!

In the end 2 big mistakes lost me $3800 USD of crypto at the current valuation. The lessons learned lead to 3 big steps in improving my crypto security posture.

Sometimes we wish we didn’t have to make mistakes to learn our lessons, but I know better these days and while it hurts, it’s just money in the end and I didn’t get my lunch stolen. I have spent enough time in security to know that the paranoia can destroy ya so I quickly shift to hardening my posture and charging forward, better armed, and equipped to go farther and longer for my people.

May I share appreciations to my enemies for keeping me sharp and strong.

To be continued?…… We’ll see.

Mastodon RSS Bot

I wrote a Mastodon RSS bot in Python today.

The script reads a CSV file of RSS feeds and checks each feed’s entries for the latest entries compared to the last time the bot posted.

Once a collection of new toots is created, the bot attempts to toot separating each post by 20 seconds.

run.sh runs the bot repeatedly, once a minute.

Posts are easy to create. I started with the entry title and link with some hashtags at the end.

Run Your Own VPN using Google Cloud & OpenVPN

Securing your connection to the internet is no longer something that is reserved for hobbyists who fit the paranoid, tin-foil hatted stereotype. Today, with the majority of our interactions involving some form of digital support, the opportunities for simple, pick-pocket level hacks that take advantage of unsuspecting victims are immeasurable.

While most services that individuals use are natively encrypted, its no longer necessary to see that user’s traffic in order to know what they’re doing. Simply knowing the destination of the traffic is enough to profile a target and increase the attack vector. If you know the target is going to facebook or twitter or similar platforms, its easy to find even more information.

On top of that, the websites we all visit today are selling our information to whomever asks for it. There are entire organizations dedicated to modeling our behavior online and identifying us as targets for all sorts of reasons. Those models could also be available to the highest bidder.

The reality is such that a number of companies are making a lot of money selling VPN services, currently for ~$100 per year. The value goes beyond security. Users are capable of masking or changing their geolocation, essentially deciding to enter the Internet from any location where the VPN service has a server.

I’m here to argue that VPN services are simple enough to setup nowadays, especially with the advent of cloud computing, that almost any level of hobbyist can do it. Especially if the hobbyist already has a presence on the internet.

Setting Up the Server

I chose Google Cloud to host my VPN server and have other things setup that make this overall process easier (like DNS and SSH), and there are a ton of articles that explain how to do this. The most important callout on Google Cloud is that the VM must be created with Port Forwarding enabled on the network interface. This option can’t be changed after the VM has been built. This took me a while to figure out and I owe my knowledge to the following article: https://medium.com/teendevs/setting-up-an-openvpn-server-on-google-compute-engine-9ff760d775d9

I used Ubuntu on my VM and followed this guide to set up OpenVPN as a server. https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04

By the end of that article you should understand how OpenVPN authenticates its clients, how to generate a Certificate Authority and sign certificate requests to create new client keys.

My server.conf ended up looking like the following:

port 1194
proto udp
dev tun

ca skylaski/ca.crt
cert skylaski/skylaski.crt
key skylaski/skylaski.key  # This file should be kept secret
dh skylaski/dh.pem

topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt

client-config-dir ccd
route 192.168.1.0 255.255.255.0

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

client-to-client
keepalive 10 120

tls-auth skylaski/ta.key 0 # This file is secret
max-clients 10

user nobody
group nogroup

persist-key
persist-tun

status /var/log/openvpn/openvpn-status.log
log-append  /var/log/openvpn/openvpn.log
verb 4

explicit-exit-notify 1

Setting Up the Client

The client will be unique to the device connecting to the VPN. Most of the value-add for VPN providers is their client. However, basic networking knowledge is all thats needed to get an OpenVPN client working. One thing that helps is to create a single ‘.ovpn’ file with all the authentication information inside that file.

On Android I used the official OpenVPN client and created my ‘.ovpn’ to look like the following…

client
dev tun
remote YOURVPNIPORDOMAIN
resolv-retry infinite
nobind
persist-key
persist-tun
key-direction 1
verb 1
keepalive 10 120
port 1194
proto udp
remote-cert-tls server

<ca>
----INSERT YOUR CA HERE----
</ca>

<key>
----INSERT YOUR CLIENT KEY HERE----
</key>

<cert>
----INSERT YOUR CLIENT CERT HERE----
</cert>

<tls-auth>
----INSERT YOUR TLS AUTH KEY HERE----
</tls-auth>

These are some of the simplest configuration files I’ve ever seen in my life. I’ve tested this client configuration on the OpenVPN Client for Android AND Windows 10.

This is just one example. There are a number of ways to do this today and hosting in general is relatively inexpensive. DigitalOcean has a 1-click deploy option for an OpenVPN access server for relatively cheap as well. https://marketplace.digitalocean.com/apps/openvpn-access-server

Gentoo Laptop

Razer 15 mid-2019 Advanced :: RZ09-03017EM8

We’ve made it far enough. I’ve lost the ability to count the number of times I’ve installed Gentoo in the last month.

For some reason when I first began my journey down the Open Source Rabbit Hole, I started with Gentoo. I was obsessed at the idea of efficiency. Something about being able to make a decision at every step in the process of setting up a Gentoo system meant power to me. The idea that I could “tune” the code, pre-compilation to harmonize as much as possible with the tools I was working with, was important to me at the time. Harmony was and always will be important.

However, this was my personal harmony. Not exactly harmony with the rest of the internet which was standardizing and promoting mass adoption. That wasn’t a problem for me at that time either. During highschool from 2000-2005 the internet was still a very democratic place.

I digress…

Recently I required a new personal laptop. I had not owned one for some time. My 2 in 1 Asus Transformer had served its purpose getting me through school and I am still using an Intel NUC connected to my TV for everything else (watching hockey mostly).

We’re back and getting it on with a Razer 15 Mid-2019 Advanced.

It was a trip just getting my hands on this hardware.

WINDOWS

In order to get the correct drivers for installing from scratch say;

https://support.razer.com/gaming-laptops/razer-blade-15-mid-2019-advanced

I’d say setting up pro and moving about Windows 10 is a walk in the park these days. Had to install without internet, but that wasn’t a big deal with the link above.

GENTOO

Never skip the handbook: https://wiki.gentoo.org/wiki/Handbook:AMD64

Major props to the initial author of: https://wiki.gentoo.org/wiki/Razer_Blade_Pro_(2019)

The kernel configuration alone is invaluable.

I had to perform the following to get a Gentoo Kernel I could load the proper Wireless drivers on.

Kernel (Gentoo-Sources)

I needed a Linux 5.x kernel to get the wireless to work

echo "sys-kernel/gentoo-sources ~amd64" >> /etc/portage/package.keywords/gentoo-sources

Once the kernel was setup with ‘iwlwifi’ I still had to force build the right driver from ‘sys-kernel/linux-firmware’.

CONFIG_EXTRA_FIRMWARE="iwlwifi-cc-a0-48.ucode"
CONFIG_IWLWIFI=y
CONFIG_IWLWIFI_LEDS=y
CONFIG_IWLWIFI_BCAST_FILTERING=y
CONFIG_IWLWIFI_DEVICE_TRACING=y

Webcam

CONFIG_USB_MDC800=y

Graphics

Nvidia card is working. Offloading is still a bit messy, so I’m making the GPU run the display manager (lightdm) and desktop environment (cinnamon/fluxbox).

Learned a lot from here: https://wiki.gentoo.org/wiki/NVIDIA/Optimus

# /etc/X11/xorg.conf
#

Section "ServerLayout"
	Identifier     "Layout"
	Option		"AllowNVIDIAGPUScreens"
	Screen      0  "nvidia"
	Inactive	"intel"
EndSection

Section "Device"
	Identifier	"intel"
	Driver		"modesetting"
	BusID		"PCI:0:2:0"
	Option		"DRI" "3"
EndSection

Section "DRI"
	Group		"video"
	Mode		0666
EndSection

Section "Extensions"
	Option "Composite" "Enable"
	Option "RENDER" "Enable"
EndSection

Section "Screen"
	Identifier	"intel"
	Device		"intel"
EndSection

Section "Device"
	Identifier	"nvidia"
	Driver		"nvidia"
	BusID		"PCI:1:0:0"
EndSection

Section "Screen"
	Identifier	"nvidia"
	Device		"nvidia"
	Option		"AllowEmptyInitialConfiguration" "Yes"
EndSection

Sound & Bluetooth

Followed the ALSA & Pulseaudio guides for sound.

Alsa: https://wiki.gentoo.org/wiki/ALSA

PulseAudio: https://wiki.gentoo.org/wiki/PulseAudio

Installed ‘pavucontrol’ for managing sound levels.

Using Bluez & Blueberry for Bluetooth.

Bluez: https://wiki.gentoo.org/wiki/Bluetooth

Bluetooth Headset: https://wiki.gentoo.org/wiki/Bluetooth_headset

Gentoo Specifics:

/etc/portage/make.conf

# make.conf
#

USE="lm-sensors theora native-headset abi_x86_32 client networkmanager xkb dhcpcd bluetooth bluetooth-audio png jpeg ffmpeg gtk3 gtk introspection gnome-keyring pulseaudio elogind mount cairo python cups dbus opengl text ssl icu minizip inspector sqlite secure-delete postproc apng xorg udev X alsa"
MAKEOPTS="-j13"
CHOST="x86_64-pc-linux-gnu"

COMMON_FLAGS="-march=core2 -O2 -pipe"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"

# NOTE: This stage was built with the bindist Use flag enabled
PORTDIR="/var/db/repos/gentoo"
DISTDIR="/var/cache/distfiles"
PKGDIR="/var/cache/binpkgs"

# This sets the language of build output to English.
# Please keep this setting intact when reporting bugs.
LC_MESSAGES=C

GRUB_PLATFORMS="efi-64"
INPUT_DEVICES="libinput synaptics"
VIDEO_CARDS="nvidia"

NOTES:

I am running elogind, which has forced me to mask a lot of packages with USE=”-consolekit”. So far this hasn’t been a problem, even though I also run consolekit for PulseAudio.

Additional Props:

Discord – Linux Blade: https://discord.gg/T8pJbz

The Hacker’s Manifesto

Found here: http://phrack.org/issues/7/3.html

                               ==Phrack Inc.==

                    Volume One, Issue 7, Phile 3 of 10

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The following was written shortly after my arrest...

                       \/\The Conscience of a Hacker/\/

                                      by

                               +++The Mentor+++

                          Written on January 8, 1986
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

        Another one got caught today, it's all over the papers.  "Teenager
Arrested in Computer Crime Scandal", "Hacker Arrested after Bank Tampering"...
        Damn kids.  They're all alike.

        But did you, in your three-piece psychology and 1950's technobrain,
ever take a look behind the eyes of the hacker?  Did you ever wonder what
made him tick, what forces shaped him, what may have molded him?
        I am a hacker, enter my world...
        Mine is a world that begins with school... I'm smarter than most of
the other kids, this crap they teach us bores me...
        Damn underachiever.  They're all alike.

        I'm in junior high or high school.  I've listened to teachers explain
for the fifteenth time how to reduce a fraction.  I understand it.  "No, Ms.
Smith, I didn't show my work.  I did it in my head..."
        Damn kid.  Probably copied it.  They're all alike.

        I made a discovery today.  I found a computer.  Wait a second, this is
cool.  It does what I want it to.  If it makes a mistake, it's because I
screwed it up.  Not because it doesn't like me...
                Or feels threatened by me...
                Or thinks I'm a smart ass...
                Or doesn't like teaching and shouldn't be here...
        Damn kid.  All he does is play games.  They're all alike.

        And then it happened... a door opened to a world... rushing through
the phone line like heroin through an addict's veins, an electronic pulse is
sent out, a refuge from the day-to-day incompetencies is sought... a board is
found.
        "This is it... this is where I belong..."
        I know everyone here... even if I've never met them, never talked to
them, may never hear from them again... I know you all...
        Damn kid.  Tying up the phone line again.  They're all alike...

        You bet your ass we're all alike... we've been spoon-fed baby food at
school when we hungered for steak... the bits of meat that you did let slip
through were pre-chewed and tasteless.  We've been dominated by sadists, or
ignored by the apathetic.  The few that had something to teach found us will-
ing pupils, but those few are like drops of water in the desert.

        This is our world now... the world of the electron and the switch, the
beauty of the baud.  We make use of a service already existing without paying
for what could be dirt-cheap if it wasn't run by profiteering gluttons, and
you call us criminals.  We explore... and you call us criminals.  We seek
after knowledge... and you call us criminals.  We exist without skin color,
without nationality, without religious bias... and you call us criminals.
You build atomic bombs, you wage wars, you murder, cheat, and lie to us
and try to make us believe it's for our own good, yet we're the criminals.

        Yes, I am a criminal.  My crime is that of curiosity.  My crime is
that of judging people by what they say and think, not what they look like.
My crime is that of outsmarting you, something that you will never forgive me
for.

        I am a hacker, and this is my manifesto.  You may stop this individual,
but you can't stop us all... after all, we're all alike.

                               +++The Mentor+++
_______________________________________________________________________________