#!/usr/bin/php <?php error_reporting(0); /*** * Configuration Settings - CHANGE THESE */ $url = ""; // URL of GoPhish listner e.g. http://www.site.com:8080/ $key = ""; // GoPhish API key $pwd = "/opt/pwdlyser/"; // /directory/containing/pwdlyser $geoip = false; // use freegeoip.net on IP addresses? set to false to disable this. $formUsername = "username"; // username name of landing page form input box $formPassword = "password"; // password name of landing page form input box /*** * Main program - Don't edit below */ echo "╔═╗┌─┐╔═╗┌┬┐┌─┐┌┬┐┌─┐\n║ ╦│ │╚═╗ │ ├─┤ │ └─┐ v1.0\n╚═╝└─┘╚═╝ ┴ ┴ ┴ ┴ └─┘\n"; foreach (glob("Classes/*.php") as $filename) include $filename; $definitions = new \Clapp\CommandLineArgumentDefinition( array( "help|h" => "Shows help message", "list|l" => "List campaigns and their ID's", "campaign|c=i" => "Get campaign by id", "dump|d=s" => "Dump user:pass list to </path/to/file.txt>", "training|t=s" => "Dump list of users requiring training </path/to/file.txt>", "all|a" => "All of the below options", "ips|i" => "Top 10 IP's", "useragent|u" => "Top 10 user agents", "attempts|m" => "Top 10 attempts to log in", "active|o" => "Active times", "rolling|r" => "Activities per half hour", "speed|e" => "Clickthrough speed", "stats|s" => "Victim statistics", "pass|p" => "Password analysis with pwdlyser", ) ); $filter = new \Clapp\CommandArgumentFilter($definitions, $argv); if ($filter->getParam('h') === true || $argc < 2) { fwrite(STDERR, $definitions->getUsage()); exit(0); } /* Get list of campaigns */ if ($filter->getParam("list") !== false) { echo "[+] Getting data from server\n"; $curl = new curl(); $curl->url = "$url/api/campaigns/?api_key=$key"; $list = $curl->curlQuery(); if(isset($list->message) && $list->message == "Invalid API Key"){ echo "[!] Invalid API key\n"; exit(0); }else{ echo "[id] -campaign name-\n"; foreach($list as $id) echo "[".$id['id']."] ".$id['name']."\n"; } exit(0); } /* Get campaign data */ $campid = $filter->getParam('c'); if ($campid == null || !is_numeric($campid)) { echo "[!] Campaign ID not set\nn"; exit(0); }else{ echo "[+] Getting data from server\n"; $curl = new curl(); $curl->url = "$url/api/campaigns/$campid?api_key=$key"; $list = $curl->curlQuery(); if(isset($list->message) && $list->message == "Invalid API Key"){ echo "[!] Invalid API key\n"; exit(0); }else{ /* all data got correctly time to do stuff! */ echo "[$campid] ".$list['name']."\n"; echo "\n--- Notable times ---\n"; if(isset($list['launch_date']) && $list['launch_date'] <> ""){ $time = date('d-m-Y H:i', $datetime = strtotime(substr($list['launch_date'], 0, 10) . ' ' . substr($list['launch_date'], 11, 8 ))); echo "Campaign launched: $time\n"; } foreach($list['timeline'] as $record){ if($record['message'] == "Email Sent"){ $time = date('d-m-Y H:i', $datetime = strtotime(substr($record['time'], 0, 10) . ' ' . substr($record['time'], 11, 8 ))); echo "First email sent: $time\n"; break; } } foreach($list['timeline'] as $record){ if($record['message'] == "Email Sent"){ $time = date('d-m-Y H:i', $datetime = strtotime(substr($record['time'], 0, 10) . ' ' . substr($record['time'], 11, 8 ))); } } echo "Last email sent: $time\n"; foreach($list['timeline'] as $record){ if($record['message'] == "Clicked Link"){ $time = date('d-m-Y H:i', $datetime = strtotime(substr($record['time'], 0, 10) . ' ' . substr($record['time'], 11, 8 ))); echo "First email opened: $time\n"; break; } } foreach($list['timeline'] as $record){ if($record['message'] == "Clicked Link"){ $time = date('d-m-Y H:i', $datetime = strtotime(substr($record['time'], 0, 10) . ' ' . substr($record['time'], 11, 8 ))); echo "First page view: $time\n"; break; } } foreach($list['timeline'] as $record){ if($record['message'] == "Submitted Data"){ $time = date('d-m-Y H:i', $datetime = strtotime(substr($record['time'], 0, 10) . ' ' . substr($record['time'], 11, 8 ))); echo "First credentials submitted: $time\n"; break; } } if(isset($list['completed_date']) && $list['completed_date'] <> ""){ $time = date('d-m-Y H:i', $datetime = strtotime(substr($list['completed_date'], 0, 10) . ' ' . substr($list['completed_date'], 11, 8 ))); echo "Campaign finished: $time\n"; } } } /* Top 10 IP's */ if ($filter->getParam("ips") !== false || $filter->getParam("all") !== false) { $ips = array(); foreach($list['timeline'] as $item){ if($item['details'] <> ""){ $details = json_decode($item['details'], true); if($details['browser']['address'] !== "unknown") $ips[] = (string)$details['browser']['address']; } } $ips = array_count_values($ips); arsort($ips); $ips = array_slice($ips,0,10,true); echo "\n--- Top 10 IP's ---\n"; foreach($ips as $ip=>$no){ $geoip_details = ""; if($geoip == true){ $geojson = file_get_contents("http://freegeoip.net/json/$ip"); $geodetails = json_decode($geojson, true); $geoip_details = "- ".$geodetails['country_name'].", ".$geodetails['city']; } echo "[$no] $ip $geoip_details\n"; } } /* Top 10 user agent's */ if ($filter->getParam("useragent") !== false || $filter->getParam("all") !== false) { $agents = array(); foreach($list['timeline'] as $item){ if($item['details'] <> "" && $item['message'] == "Clicked Link"){ // only people who visited site, not email user agent $details = json_decode($item['details'], true); if($details['browser']['user-agent'] !== "unknown" && $details['browser']['user-agent'] !== "") $agents[] = (string)$details['browser']['user-agent']; } } $agents = array_count_values($agents); arsort($agents); $agents = array_slice($agents,0,10,true); echo "\n--- Top 10 User Agents ---\n"; foreach($agents as $ua=>$no){ echo "[$no] $ua\n"; } } /* Top 10 attempts to log in */ if($filter->getParam("attempts") !== false || $filter->getParam("all") !== false) { $userids = array(); foreach($list['results'] as $item){ $userids[$item['id']] = $item['email']; } $attemptrids = array(); foreach($list['timeline'] as $item){ if($item['details'] <> ""){ $details = json_decode($item['details'], true); if(isset($details['payload'][$formPassword][0]) && $details['payload'][$formPassword][0] <> ""){ $attemptrids[$details['payload']['rid'][0]] += 1; } } } arsort($attemptrids); $attemptrids = array_slice($attemptrids,0,10,true); echo "\n--- Top 10 Login Attempts ---\n"; foreach($attemptrids as $id=>$amount){ //$newemail= preg_replace('/(?:^|.@).\K|.\.[^@]*$(*SKIP)(*F)|.(?=.*?\.)/', '*', $userids[$id]); //echo "[$amount] $newemail\n"; echo "[$amount] $userids[$id]\n"; } } /* Active times */ if($filter->getParam("active") !== false || $filter->getParam("all") !== false) { $active_count = array(); $active_percent = array(); $total = 0; echo "\n--- Active times (hour, actions & percent) ---\n"; foreach($list['timeline'] as $item){ if($item['message'] != "Campaign Created" && $item['message'] != "Email Sent" ){ $hour = (int)substr($item['time'], 11, 2); $active_count[$hour]++; $total++; } } foreach($active_count as $id => $count) // populate percentages $active_percent[$id] = ($count / $total) * 100; for($i = 0; $i <= 12; $i++){ $iDsp = str_pad($i, 2, " ", STR_PAD_LEFT); $j = $i+12; $user1 = str_pad($active_count[$i], 4, " ", STR_PAD_LEFT); $user2 = str_pad($active_count[$j], 4, " ", STR_PAD_LEFT); $percent1 = number_format($active_percent[$i], 2, '.', ''); $percent1 = str_pad($percent1, 5, " ", STR_PAD_LEFT); $percent2 = number_format($active_percent[$j], 2, '.', ''); $percent2 = str_pad($percent2, 5, " ", STR_PAD_LEFT); echo "$iDsp - $user1 = $percent1% | $j - $user2 = $percent2% \n"; } } /* Rolling times */ if($filter->getParam("rolling") !== false || $filter->getParam("all") !== false) { $active_count = array(); $active_percent = array(); $total = 0; echo "\n--- Rolling times (clicked link or submitted data) ---\n"; foreach($list['timeline'] as $item){ if($item['message'] == "Clicked Link" || $item['message'] == "Submitted Data" ){ $month = (int)substr($item['time'], 5, 2); $day = (int)substr($item['time'], 8, 2); $hour = (int)substr($item['time'], 11, 2); $min = (int)substr($item['time'], 14, 2); $min = ($min < 30 ? "00" : 30); $hour2 = $hour; $min2 = $min; if($min == 30){$hour2++; $min2 = "00";}else{$min2 = 30;} $active_count[$month."/".$day." ".$hour.":".$min." - ".$hour2.":".$min2]++; $total++; } } foreach($active_count as $id => $count) echo "$id = $count\n"; } /* Clickthrough speed */ if ($filter->getParam("speed") !== false || $filter->getParam("all") !== false) { $speed_opened = array(); $speed_visited = array(); $speed_offset = array(); echo "\n--- Clickthrough Speed ---\n"; foreach($list['timeline'] as $item){ if($item['message'] == "Email Opened"){ $details = json_decode($item['details'], true); $check_rid = $details['payload']['rid'][0]; $current_time = strtotime(substr($item['time'], 0, 10) . ' ' . substr($item['time'], 11, 8 )); $existing_time = strtotime(substr($speed_opened[$check_rid], 0, 10) . ' ' . substr($speed_opened[$check_rid], 11, 8 )); if(!isset($speed_opened[$check_rid]) || $existing_time > $current_time) $speed_opened[$check_rid] = $item['time']; } if($item['message'] == "Clicked Link"){ $details = json_decode($item['details'], true); $check_rid = $details['payload']['rid'][0]; if(!isset($speed_visited[$check_rid])) $speed_visited[$check_rid] = $item['time']; } } foreach($speed_opened as $id=>$val){ // remove all the ones that didn't visit site if(!isset($speed_visited[$id])) unset($speed_opened[$id]); } foreach($speed_visited as $id=>$val){ // remove all the ones that didn't load email tracking image if(!isset($speed_opened[$id])) unset($speed_visited[$id]); } foreach($speed_opened as $id=>$val){ //calculate speed between reading email and clicking link $date_opened = substr($val, 0, 10); $time_opened = substr($val, 11, 8 ); $time_opened_stamp = strtotime($date_opened." ".$time_opened); $date_visited = substr($speed_visited[$id], 0, 10); $time_visited = substr($speed_visited[$id], 11, 8 ); $time_visited_stamp = strtotime($date_visited." ".$time_visited); $diff = $time_visited_stamp - $time_opened_stamp; if($diff > 0) $speed_offset[$id] = $diff; } unset($speed_opened); // check me out doing memory management and cleaning up! :D unset($speed_visited); $quickest = min($speed_offset); echo "Quickest click: $quickest sec\n"; $longest = max($speed_offset); $longest = floor(($longest / 60) % 60); echo "Longest click: $longest min\n"; $sec_5 = array_reduce($speed_offset, function ($a, $b){ return ($b <= 5) ? ++$a : $a; }); echo "Users clicked < 5 sec: $sec_5 \n"; $sec_30 = array_reduce($speed_offset, function ($a, $b){ return ($b <= 30) ? ++$a : $a; }); echo "Users clicked < 30 sec: $sec_30 \n"; $sec_60 = array_reduce($speed_offset, function ($a, $b){ return ($b <= 60) ? ++$a : $a; }); echo "Users clicked < 1 min: $sec_60 \n"; } /* Victim statistics */ if ($filter->getParam("stats") !== false || $filter->getParam("all") !== false) { $status = array(); foreach($list['results'] as $item){ if($item['status'] <> ""){ $status[] = $item['status']; } } echo "\n--- Victim Statistics ---\n"; $statusall = count($status); $counts = array_count_values($status); echo "Targets: ".$statusall."\n"; $openedpercent = ($counts['Email Opened'] / $statusall) * 100; echo "Email opened: ".$counts['Email Opened']." (".round($openedpercent, 2)."%)\n"; $linkpercent = ($counts['Clicked Link'] / $statusall) * 100; echo "Visited link: ".$counts['Clicked Link']." (".round($linkpercent, 2)."%)\n"; $subpercent = ($counts['Submitted Data'] / $statusall) * 100; echo "Submitted data: ".$counts['Submitted Data']." (".round($subpercent, 2)."%)\n"; foreach($list['timeline'] as $item){ if($item['details'] <> ""){ $details = json_decode($item['details'], true); if($details['payload'][$formPassword][0] <> "") $totalLoginAttempts++; } } echo "Total login attempts: $totalLoginAttempts\n"; } /* Pwdlyzer */ if ($filter->getParam("pass") !== false || $filter->getParam("all") !== false) { $username = array(); $password = array(); echo "\n--- Password Statistics ---\n"; foreach($list['timeline'] as $item){ if($item['details'] <> ""){ $details = json_decode($item['details'], true); if($details['payload'][$formPassword][0] <> ""){ $username[] = $details['payload'][$formUsername][0]; $password[] = $details['payload'][$formPassword][0]; } } } $tmpfname = tempnam("/tmp", "GoStats-"); $pwdfname = tempnam("/tmp", "GoStats-"); $handle = fopen($tmpfname, "w"); foreach($username as $id=>$user){ fwrite($handle, "$user:".$password[$id]."\n"); } fclose($handle); echo "[+] Launching pwdlyzer\n"; exec("cd $pwd && ./pwdlyser.py -p $tmpfname --all > $pwdfname"); unlink($tmpfname); echo "[+] pwdlyzer results at: $pwdfname\n"; } /* dump username:password list to file */ $dumpfile = $filter->getParam('dump'); if(file_exists($dumpfile)){ echo "[!] File already exists ($dumpfile)\n"; exit(0); } if(!file_exists($dumpfile) && isset($dumpfile)){ $username = array(); $password = array(); echo "\n--- Dumping username:password to file ---\n"; foreach($list['timeline'] as $item){ if($item['details'] <> ""){ $details = json_decode($item['details'], true); if($details['payload'][$formPassword][0] <> ""){ $username[] = $details['payload'][$formUsername][0]; $password[] = $details['payload'][$formPassword][0]; } } } $handle = fopen($dumpfile, "w"); foreach($username as $id=>$user){ fwrite($handle, "$user:".$password[$id]."\n"); } fclose($handle); echo "[+] File created: $dumpfile\n"; } /* dump list of users requiring training */ $dumpfile2 = $filter->getParam('training'); if(file_exists($dumpfile2)){ echo "[!] File already exists ($dumpfile)\n"; exit(0); } if(!file_exists($dumpfile2) && isset($dumpfile2)){ $tusername = array(); $temail = array(); $tstatus = array(); echo "\n--- Dumping list of users requiring training ---\n"; foreach($list['results'] as $item){ if($item['status'] == "Submitted Data" || $item['status'] == "Clicked Link"){ $tusername[] = $item['first_name']." ".$item['last_name']; $temail[] = $item['email']; $tstatus[] = $item['status']; } } $handle = fopen($dumpfile2, "w"); foreach($tusername as $id=>$user){ fwrite($handle, "$user, ".$temail[$id].", ".$tstatus[$id]."\n"); } fclose($handle); echo "[+] File created: $dumpfile2\n"; } ?>