- #!/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";
- }
-
- ?>