2012-08-05

The Wall of Sheep by Irongeek

I was searching a data dumb from this year's DC20 Wall of Sheep and came across Irongeek's script.  The date stamp on his post was 2006, kinda old but I just have the to find the time to test it out.  I've a also included the actual code at the bottom of this post.  There are links for an Slax iso at the bottom, but I'm not sure if it works, plus you might need a password by emailing Irongeek. 
 

Irongeek's Wall of Social Science Majors
(inspired by the Wall of Shame/Wall of Sheep)
        You all have seen the Wall of Shame/Wall of Sheep that they run at various hacker cons right? I know DefCON had one every year, and I saw something similar at PhreakNIC. Well, this is my version, the Wall of Social Science Majors. What the wall does is display the passwords of users at the con that are using insecure protocols. They set up a box on the gateway that sniffs for plaintext passwords (Telnet, HTTP Basic Authentication, FTP, POP3 etc. ) and displays them. Well, I could not find any code to do this on the web, so I made my own. You feed this PHP script with the output from Ettercap ("ettercap -Tq -d -m ettertest.log") and it seems to work pretty well, read the comments in the code for details on how to set it up. If you have any suggestions/changes/code fixes please email me. Feel free to use it on your co if you like.
Read the code and change the commenting to enable some of these features:
  • Display X characters of the password instead of the whole thing.
  • Change the automatic refresh rate.
  • Choose where the script finds the Ettercap log created with the -m option.

Download from:
Ver 1.2 (rename the txt file to shame.php)
Ver 1.0
Or you can get this 200MB+
Slax based live CD with Ver 1.2 of the Wall
(Having this up killed my bandwidth/connections limit with Dreamhost, email me for the password)
The CD has all of the basic tools needed to get the password wall up and running: Apache, Ettercap, PHP, Etc. However, you will have to edit the run scripts to fit your needs, your card may not be supported, and I'm not doing tech support if you have a problem with this Live CD. :)
Norad also set up a Rapidshare for the ISO:
http://rapidshare.com/files/25510785/igwall.0.1.part1.rar.html
http://rapidshare.com/files/25521883/igwall.0.1.part2.rar.html
http://rapidshare.com/files/25523205/igwall.0.1.part3.rar.html 
Here's the PHP script. (Rename it to shame.php)

<?
/*
 Irongeek's Wall Of Shame Code ver. 1.2
Irongeek -at- irongeek.com
http://www.irongeek.com
Contributors: 
 Julien Goodwin <jgoodwin#studio442.com.au>

Just a fugly script I wrote to take a logfile from Etthercap and display 
passwords to a webpage.

Ettercap supports:
TELNET, FTP,  POP,  RLOGIN,  SSH1,  ICQ,  SMB,
       MySQL,  HTTP,  NNTP, X11, NAPSTER, IRC, RIP, BGP, SOCKS 5, IMAP 4, VNC,
       LDAP, NFS, SNMP, HALF LIFE, QUAKE 3, MSN, YMSG (other protocols  coming
       soon...)
 Some help from:
 http://www.php.net/
 http://www.theukwebdesigncompany.com/articles/article.php?article=165

Consider this code GPLed, but it would be sweet of you to link back to 
Irongeek.com if you use it.
 */

//// Configuration settings
// Refresh time (in seconds), set to 0 to disable
$refresh = 30;

/*Point the line below to the log file you are creating with:
         "ettercap -Tq -D  -m ettertest.log".
 if you get an error like:
 BUG at [ec_ui.c:ui_register:339]
 ops->input == NULL
 then try just "ettercap -Tq  -m ettertest.log" without the daemon option..
 Also, you could ARP poison the gateway if you like with a command like:
 ettercap -Tq  -m /tmp/ettercap.log -M arp /gateway-IP/ //.
*/
// Logfile generated by ettercap
$logfile = '/tmp/ettercap.log';

// Show duplicate entries?
$showdupes = false;

/*Set the below to just show the first X characters of the password, "all" to
show all, or none to show all *'s */
//$showxchar = 3;
$showxchar = 'all';
//$showxchar = 'none';

// Show service names (instead of port numbers)
$showservnames = true;

// Do a reverse DNS query of target (WARNING! use only with a good local DNS cache)
$resolvetarget = false;

?>
<HTML>
<HEAD>
<?php if ($refresh > 0) { ?>
 <META HTTP-EQUIV="Refresh" Content = "<?= $refresh ?>; URL=shame.php">
<?php } ?>
 <TITLE>Irongeek's Wall Of Shame</TITLE>
<style type="text/css">
<!-- 
 BODY {
  background-color: #FFFFFF;
 }

 .SNMP {
  color: #009900;
 }

 .HTTP {
  color: #330099;
 }

 .TELNET {
  color: #CC33CC;
 }

 .POP {
  color: #8888FF;
 }

 .FTP {
  color: #004400;
 }

 .VNC {
  color: #007080;
 }

 .SMB {
  color: #F07080;
 }

 .IRC {
  color: #FF3333;
 }

 .YMSG {
  color: #BBBB00;
 }

-->
</style>
</HEAD>
<BODY>
<?

function between($somestring, $ss1, $ss2){
 if ($ss2 === false) { // That's what it does equate to in theory, just enforce it
  $ss2 = '';
 }

 preg_match('/' . $ss1 . '\s*(.*)\s*' . $ss2 . '/', $somestring, $matches);
 return $matches[1];
}

function showfirst($somestring, $chrnum) {
 global $showxchar;

 if ($showxchar == 'all') {
  return $somestring;
 } else if ($showxchar == 'none') {
  return str_pad(substr($somestring, 0, $showxchar), strlen($somestring), "*");
 } else {
  return str_pad(substr($somestring, 0, $showxchar), 10, '*');
 }
}

function padpw($string) {
 return showfirst($string, $showxchar);
}

function PrintCapItem($proto, $target, $user, $password, $info = false) {
 global $showservnames;
 global $resolvetarget;

// Generate full target data - NOTE, we assume TCP here
$server = explode(':', $target);
$host = $server[0];
$service = getservbyport($server[1],'tcp'); // Note this is a quick (and cached) operation so we do it anyway
if ((strlen($service) < 1) || ($showservnames === false)) {
 $service = $port;
} else {
 $service .= ' <small>(' . $server[1] . ')</small>';
}

if ($resolvetarget) {
 $host = gethostbyaddr($server[0]);
 if (strlen($host) < 1) {
  $host = $server[0];
 } else {
  $host .= ' <small>(' . $ip . ')</small>';
 }
}

?> <TR CLASS="<?= $proto ?>">
  <TD><B><?= $proto ?></TD>
  <TD><?= $host ?></TD>
  <TD><?= $service ?></TD>
  <TD><?= $user ?></TD>
  <TD><?= $password ?></TD>
 </TR>
<?php if ($info !== false) { ?>
 <TR CLASS="<?= $proto ?>">
  <TD></TD>
  <TD COLSPAN="4"><small><I>More Info:</I> <?= $info ?></small></TD>
 </TR>
<?php }
}

function linkify($text) {
 return preg_replace('/(https?:\/\/[a-zA-Z0-9\-\?\&\.\/\=\;]*)/','<a href="\1">\1</a>',$text);
}

$contents = file($logfile);
if ($contents === false) {
 echo 'Ettercap logfile could not be opened.';
 die();
}

$contents = array_reverse($contents);
// Note we want the latest entries first, by reversing first old values do show up, move the above line below the if to change this behaviour
if (!$showdupes) {
 $contents = array_unique($contents);
}

?>
<h1 align="center">Irongeek's<BR>
Wall Of Shame</h1>

<p>Using protocols that pass your credentials insecurely at a hacker con? Shame on you! Keep away from protocols like authenticated FTP, POP3, TELNET and Basic HTTP non-anonymous without SSL/TLS when you can. Try encrypted tunnels like SSH or a VPN to get through possibly hostile networks when you have to use such insecure protocols. Have a nice day.</p>
<P align="right">Your buddy,<BR>
Irongeek</P>
<hr>

<TABLE BORDER="1" ALIGN="CENTER">
<thead>
<TR>
 <TH>Protocol</TH>
 <TH colspan="2">Target</TH>
 <TH>User</TH>
 <TH>Password</TD>
</TR>
</thead>
<?
foreach ($contents as $line ) {
 $line   = htmlentities($line);
 $proto  = trim(substr($line, 0, strpos($line, ':')));
 $target = between($line, ' : ', ' -&gt;');
 switch ($proto) {
  case 'SNMP':
   $user     = 'N/A';
   $password = padpw(between($line, '-&gt; COMMUNITY:', 'INFO:'));
   $info     = between($line, 'INFO:', false);
   PrintCapItem($proto, $target,$user,$password, $info);
   break;

  case 'HTTP':
   $user     = between($line, 'USER:', 'PASS:');
   $password = padpw(between($line, 'PASS: ', '  INFO:'));
   $info     = linkify(between($line, 'INFO:', false));
   PrintCapItem($proto, $target,$user,$password, $info );
   break;

  case 'TELNET':
   $user     = between($line, 'USER:', 'PASS:');
   $password = padpw(between($line, 'PASS:', false));
   PrintCapItem($proto, $target, $user, $password);
   break;

  case 'POP':
   $user     = between($line, 'USER:', 'PASS:');
   $password = padpw(between($line, 'PASS:', false));
   PrintCapItem($proto, $target, $user, $password);
   break;  

  case 'FTP':
   $user     = between($line, 'USER:', 'PASS:');
   $password = padpw(between($line, 'PASS:', false));
   PrintCapItem($proto, $target, $user, $password);
   break; 

  case 'VNC':
   $user     = 'Challenge: ' . between($line, '-&gt; Challenge:', ' Response:');
   $password = 'Response: ' . between($line, ' Response:', false);
   PrintCapItem($proto, $target, $user, $password);
   break;

  case 'SMB':
   $user     = between($line, 'USER:', 'HASH:');
   $password = between($line, 'HASH:', false);
   PrintCapItem($proto, $target, $user, $password);
   break;

  case 'IRC':
   $user     = between($line, 'USER:', 'PASS:');
   $password = padpw(between($line, 'PASS:', 'INFO:'));
   $info     = between($line, 'INFO:', false);
   PrintCapItem($proto, $target,$user,$password, $info );
   break;

  case 'YMSG':
   $user     = between($line,'USER:', 'HASH:');
   $password = padpw(between($line, 'HASH: ', '  - '));
   $info     = between($line, '  - ', false);
   PrintCapItem($proto, $target, $user, $password, $info );
   break;

  case 'DHCP':
   break; // Just add any other protocols to hide to this list

  default:
   if (strpos($line, ' : ') != 0 && strpos($line, 'PASS') != 0){
    $target    = between($line, ' : ', ' -&gt; USER:'); 
    $user      = between($line, 'USER: ', '  PASS:');
    $password  = padpw(between($line, 'PASS:', false));
    PrintCapItem($proto, $target, $user, $password);
    break; 
   }else{
    $trash .= '<TR><TD>' . $proto . '</td><td colspan="3">' . $line . '</TD></TR>';
   }
 }
}
//Call the PHP script with a ?debug on the end to see the trash lines.
if (isset($_GET[debug])) {
?>
<tfoot>
 <tr><th colspan=4>Debug messages</th></tr>
<?= $trash ?>
</tfoot>
<?php
}
?>
</TABLE>
<HR>
<CENTER>Source code for this &quot;Wall of Shame&quot; script can be found at 
<A HREF="http://www.irongeek.com/">http://www.irongeek.com/</A></CENTER>
</BODY>
</HTML>