Hacking into a 30M USD ICO


Thrive is a Blockchain based Marketplace to BUY and SELL Advertising at very low fees. People get PAID for data sharing and for reviewing the quality of each website in the ecosystem.

As a part of my ICO hacking series, I decided to look into Thrive ICO. I read all the details about their token sale, saved all the important dates to see whether I can find anything crucial before the launching of their private sale.

Blind XSS on admin panel

The most lucrative part of an ICO is the KYC. User gets the opportunity to interact with the Admins and gets the privilege to upload KYC documents to the server. I used xsshunter's BXSS payloads as my KYC details and the XSS payload fired in my dashboard. It made me hopeful that the payload will trigger on the admin end too. After 6-7 days of waiting I got an hit on BXSS. Apparently, there was no protection against XSS and CSRF on the entire portal. I got the following screenshot and html source of the admin panel from the BXSS. I also got phpsession of the admin user, but that couldn't be used to login to the admin panel, because the session was tied to user's IP address.

Local file inclusion via imgHandlerBack.php file

I found the following information from the BXSS.

  1. Thrive admin panel: https://reg.thrivelabs.io/back/
  2. A reference to a commented out php file (imgHandlerBack.php) from the following snippet:
<img id="divImgFront20573" class="materialboxed responsive-img" style="height: 100px;margin-bottom: 20px;">  
<!-- src="imgHandlerBack.php?p=">-->  

The first thing that hit my mind was a chance of local file inclusion via this imgHandlerBack.php. I tried to read /etc/passwd file and it worked like a charm after a few attempt:

The PHP files were rendering in plaintext instead of executing. I took this opportunity to know more about the application. So, I started collecting references of other files and started reading their source to find SQLi or RCE vulnerabilities.

Taking over [email protected] webmail account

I found the SMTP configuration file and grabbed the following:

    $mail->Host = "mail.thrivelabs.io";
    $mail->Port = 587;
    $mail->SMTPAuth = true;
    $mail->Username = '[email protected]';
    $mail->Password = '[redacted]';

Thrivelabs were using cPanel webmail. I logged in to that email address using the SMTP credentials. I found all in and out email's regarding KYC and whitelist applications from that support email.

Subdomain scan and SQLi on analytics subdomain

I ran a subdomain scan via the knockpy and it gave the following result:

Surprisingly, all the websites were hosted on same web server! So, pwning one will give any one higher chance to pwn the others. I started digging into the analytics subdomain and found a few SQLi and got access on thrive_news database. I ignored the database just because of its name, which was a great mistake. Cause later I found out that this database also contains all the user, admin and transaction details!

Accessing ICO address generation server via SQL injection

Thrive issues each user an unique deposit address for BTC, ETH and LTC. I found the following snippet which makes a call to a different server to generate wallet address:

function getWalletJW($command,$id,$currency)  
    $data = array(
        'command' => $command,
        'id' => $id,

    $url ="";
    $ch = curl_init($url);
    $postString = http_build_query($data, '', '&');

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    return $response;


I started looking into and found an SQLi in the login panel.

Double RCE on address generation server

I bypassed the admin login panel with 'or''=' and logged in as an admin. There was a file uploader inside the admin panel:
I uploaded a php command exec file and it got uploaded without any problem. That's how I got my first shell on a Thrive property. I started digging into this address generation server and landed on the code which was responsible for users address generation.

switch ($command)  
    case 'retrieveAddress':
        if (isset($_POST['currency']))
            switch ($_POST['currency'])
                case 'ETH':
                    $curr= 'eth';
                case 'BTC':
                    $curr= 'btc';
                case 'LTC':
                    $curr= 'ltc';
            $result=trim( getWallet($_POST['id'])[$_POST['currency']]);
            //$query="UPDATE `registration` SET `$curr` = '$result' WHERE `id` = $id";
            //ysqli_query($link, $query);
        echo $result;

function getWallet($id)  
    //$coef=$id + 19696;
    $shell="node /home/justwith/ethereum.js $id 2>&1";
    $BTCshell="python /home/justwith/bitcoin.py $id 2>&1";
    $LTCshell="python /home/justwith/litecoin.py $id 2>&1";
    $eth = shell_exec($shell);
    $result['ETH'] = $eth;
    $result['BTC'] = $btc;
    $result['LTC'] = $ltc;
    return $result;

The aforementioned code was passing an unfiltered variable to getWallet() function. This function passes that variable to shell_exec(), which causes command execution.

RCE on *.thrivelabs.io

After further digging, we identified the same getWallet() function in the reg.thrivelabs.io domain too and was able to execute arbitrary command on the main server too.


  1. Complete takeover of Thrivelabs business domain and all its subdomains.
  2. Complete access to thousands of users KYC documents.
  3. Complete access to thousands of users ICO account, including plaintext passwords!
  4. Capability to manipulate unique deposit address of each users.

So, basically thats the game over for this ICO.