Saturday, December 31, 2016

Making Free Phone Calls Using Asterisk and Google Voice

After installing the latest asterisk from source and configuring your dialplan extensions, you can use google voice to make and receive calls for free. Follow this guide to add google voice to your dialplan: Asterisk With Google Voice.
Then add the following to extensions.conf:
[outgoing-motif]
exten => _1XXXXXXXXXX,1,Dial(Motif/google/${EXTEN}@voice.google.com,,r)
[local]
include => incoming-motif
include => outgoing-motif
Now just dial 1+area_code+phone_number to dial a number or change:
exten => _1XXXXXXXXXX,1,Dial(Motif/google/${EXTEN}@voice.google.com,,r)
to
exten => _XXXXXXXXXX,1,Dial(Motif/google/${EXTEN}@voice.google.com,,r)
in order to just dial area_code+phone_number

Start screen on Boot in Kali Rolling, Ubuntu, or Debian Linux

After booting straight to CLI in Kali Rolling, Ubuntu, or Debian, I also wanted to have a screen session started on boot to use for my window manager. In order to do this, I had to edit /etc/rc.local and add this command:
/usr/bin/screen -c /root/.screenrc -dmU -h 10000 -S kali_screen_session

Then add the next command to ~/.bashrc:
export HOME="/root"

Then add these lines to ~/.screenrc (the most important being the shell line):
#don't display the copyright page
startup_message off

activity "%C -> %n%f %t activity!"
bell "%C -> %n%f %t bell!~"
pow_detach_msg "BYE"

#visable bell
vbell_msg "*beep*"

# Change scrollback to 100000 lines
defscrollback 100000

# fix the scrollback problem in putty (for windows users)
termcapinfo xterm ti@:te@

shell bash
# Uncomment the following line in Kali Linux in order to start new windows in ~ instead of /
#chdir /root

# programs to auto start
screen -t htop 0 htop

# status line at the bottom
hardstatus on
hardstatus alwayslastline
hardstatus string '%{gk}[ %{G}%H %{g}][%= %{wk}%?%-Lw%?%{=b kR}(%{W}%n*%f %t%?(%u)%?%{=b kR})%{= kw}%?%+Lw%?%?%= %{g}][%{Y}%l%{g}]%{=b C}[ %d/%m/%y %c ]%{W}'

Now to create a new terminal window press control+a then c.
To switch between windows press control+a control+a

Boot Kali Linux Rolling to CLI instead of GUI via systemd

Most of the tools I use in Kali are command line tools, and rarely need a full GUI, so in order to boot straight to CLI and get the maximum performance available on my system, I used this systemd command:
systemctl set-default multi-user.target

If you want to start a GUI, then type this command:
startx

Friday, December 30, 2016

Porting Kali NetHunter to LG G3 US990 with Cyanogenmod 13 Oct-OS-M ROM Android 6.0.1 Marshmallow

My latest project is trying to port Kali NetHunter to the LG G3 Running the latest OCT-OS-M CM13-based ROM (Android 6.0.1 Marshmallow).
I have yet to get the custom kernel to boot without the secure boot error, and am almost out of ideas, so if you can help, please drop me a line.
On your Android device:
Step 1. Root your phone.
Step 2. Unlock your bootloader and install TWRP.
Step 3. Install latest OCT-OS-M ROM.
On your Linux machine:
Step 4. Install Android toolchain as per kali wiki: here. (Note: An x86-64 machine is needed)
Step 5. Clone the OCT-OS kernel source github project named: platform_kernel_lge_us990
Step 6. Make kernel modifications and apply patches as per kali wiki: here. (Note: I had to disable Bluetooth USB HCI in order for the kernel to compile).
Step 7. Clone Kali NetHunter Source: here.
Step 8. Clone cbump source and cross-compile: here.
Step 9. Add cbump binary to kali-nethunter/nethunter-installer/boot-patcher/arch/armhf/tools/cbump
Step 10. Add
"$bin/cbump" boot-new.img || abort "Bumping boot image failed"
to kali-nethunter/nethunter-installer/boot-patcher/boot-patcher.sh (last line of build_boot() function.
Step 11. Add your device and build your zip as per wiki: here, and the README.md file in kali-nethunter/nethunter-installer/devices
In kali-nethunter/nethunter-installer/devices/devices.cfg add:
# LG G3 us990 for Cyanogenmod 13
[us990cm]
author = "mcraze123"
version = "1.0"
devicenames = us990
Copy your compiled and patched kernel image zImage to kali-nethunter/nethunter-installer/devices/marshmallow/us990cm
mkdir -p kali-nethunter/nethunter-installer/devices/marshmallow/us990cm
cp platform_kernel_lge_us990/kImage kali-nethunter/nethunter-install/devices/marshmallow/us990cm/
To get the lates apk's run:
python build.py -f
Then to build the zip, run:
python build.py -d us990cm -m
On Android:
boot into twrp, mount as mtp, copy zip to device, install zip

UPDATE:
I have managed to get past the secure boot error by flashing this zip, and removing the cross compiled version of cbump and modifications to boot-patcher.sh. Now the device recognizes on my mac as a keyboard but goes into a boot loop. I'm going to start with a known working kernel, then add features one by one in order to find what is causing the issues. Nethunter should be coming to the LG G3 US990 soon!

Wednesday, December 21, 2016

How to Install Asterisk and FreePBX on Ubuntu Server 16.04 Xenial with a MySQL root Password

So FreePBX "recommends" to not set a password for your MySQL root user, and leave it blank. I'm not sure how anyone could justify that leaving a password blank is a good recommendation. I don't care if your server is only listening on localhost or (hopefully not) facing the internet, this is a horrible recommendation, and it really makes me concerned with the quality the FreePBX code. Well, I decided to try out FreePBX anyway and had a lot of trouble figuring out how to configure it to use a password for mysql. I started grepping through the source code and finally hit pay dirt after using this command:
grep -R "Database Root" .
This told me that the code checking for connectivity to the database is in the file:
./installlib/installcommand.class.php
After opening this file, I was presented with the code where it stores its database settings
I changed line 33 to use my root database password:
'dbpass' => array(
'default' => 'your_mysql_root_password_goes_here',
'description' => 'Database password',
After re-running:
sudo ./install -n
It failed. damnit! But this time, it gives shows me all the flags that the install script accepts:
--dbuser Database username (default: "root")
--dbpass Database password (default: "")
Aha! And to see a full list of command line options, you can run the install script like so:
./install -h
Now to try again:
./install -n --dbuser="root" --dbpass="your_db_password_goes_here"
Annnnd... it worked!
I didn't notice anything in the documentation talking about the install scripts help or config flags, so I thought I'd post them here:
PHP Warning: Declaration of FreePBX\Install\FreePBXHelpCommand::setCommand(FreePBX\Install\FreePBXInstallCommand $command) should be compatible with Symfony\Component\Console\Command\HelpCommand::setCommand(Symfony\Component\Console\Command\Command $command) in /opt/freepbx/installlib/installhelpcommand.class.php on line 15
______ _____ ______ __
| ____| | __ \| _ \ \ / /
| |__ _ __ ___ ___| |__) | |_) \ V /
| __| '__/ _ \/ _ \ ___/| _ < > <
| | | | | __/ __/ | | |_) / . \
|_| |_| \___|\___|_| |____/_/ \_\
Usage:
install [--dbengine="..."] [--dbname="..."] [--cdrdbname="..."] [--dbuser="..."] [--dbpass="..."] [--user="..."] [--group="..."] [--dev-links] [--webroot="..."] [--astetcdir="..."] [--astmoddir="..."] [--astvarlibdir="..."] [--astagidir="..."] [--astspooldir="..."] [--astrundir="..."] [--astlogdir="..."] [--ampbin="..."] [--ampsbin="..."] [--ampcgibin="..."] [--ampplayback="..."] [-r|--rootdb] [-f|--force]

Options:
--dbengine Database engine (default: "mysql")
--dbname Database name (default: "asterisk")
--cdrdbname CDR Database name (default: "asteriskcdrdb")
--dbuser Database username (default: "root")
--dbpass Database password (default: "")
--user File owner user (default: "asterisk")
--group File owner group (default: "asterisk")
--dev-links Make links to files in the source directory instead of copying (developer option)
--webroot Filesystem location from which FreePBX files will be served (default: "/var/www/html")
--astetcdir Filesystem location from which Asterisk configuration files will be served (default: "/etc/asterisk")
--astmoddir Filesystem location for Asterisk modules (default: "/usr/lib/asterisk/modules")
--astvarlibdir Filesystem location for Asterisk lib files (default: "/var/lib/asterisk")
--astagidir Filesystem location for Asterisk agi files (default: "/var/lib/asterisk/agi-bin")
--astspooldir Location of the Asterisk spool directory (default: "/var/spool/asterisk")
--astrundir Location of the Asterisk run directory (default: "/var/run/asterisk")
--astlogdir Location of the Asterisk log files (default: "/var/log/asterisk")
--ampbin Location of the FreePBX command line scripts (default: "/var/lib/asterisk/bin")
--ampsbin Location of the FreePBX (root) command line scripts (default: "/usr/sbin")
--ampcgibin Location of the Apache cgi-bin executables (default: "/var/www/cgi-bin")
--ampplayback Directory for FreePBX html5 playback files (default: "/var/lib/asterisk/playback")
--rootdb (-r) Database Root Based Install. Will create the database user and password automatically along with the databases
--force (-f) Force an install. Rewriting all databases with default information
--help (-h) Display this help message
--quiet (-q) Do not output any message
--verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
--version (-V) Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
--no-interaction (-n) Do not ask any interactive question

Monday, December 5, 2016

Configure OpenVAS Vulnerability Scanner on Ubuntu Server 16.04 to Listen on Local LAN

To configure OpenVAS to listen on your local LAN and not just localhost on Ubuntu Server 16.04, issue these commands:
/etc/init.d/openvas-scanner stop
gsad --listen=0.0.0.0 --port=8080
/etc/init.d/openvas-scanner start

Fixing mysqltuner ERROR 1054 on Ubuntu Server 16.04

After installing mysql-server and mysqltuner through the default repositories on my Ubuntu Server 16.04 machine, I got this error:
ERROR 1054 (42S22) at line 1: Unknown column 'password' in 'where clause'
This is a known bug that was introduced when mysql changed the name of the 'password' column. There has been a bug report on mysqltuner's github page and the appropriate fixes have been committed, however the debian package still has not been updated to reflect the current changes. To fix this I cloned the current git source and symlinked /usr/bin/mysqltuner to my source tree's mysqltuner.pl. This has the added benefit of when the package is updated, it will replace the symlink and not mess with any file installed by the package.
To do this, type the following commands:
cd /opt
git clone https://github.com/major/MySQLTuner-perl.git
cd MySQLTuner-perl
sudo mv /usr/bin/mysqltuner /usr/bin/mysqltuner.bak # back up the file just in case we mess up
sudo ln -s /opt/MySQLTuner-perl/mysqltuner.pl /usr/bin/mysqltuner

Sunday, December 4, 2016

How to Run Your Perl and Python Scripts From a Portable USB Thumb Drive On Multiple Computers You Are Repairing Without Having to Install the Full Interpreter on the Host

I have a lot of Perl and Python scripts I wrote to speed up the computer repair tasks I've had to perform in the past, such as: http://crazesweb.blogspot.com/2016/07/a-perl-script-to-search-hard-drive-for.html and http://crazesweb.blogspot.com/2016/07/a-perl-script-to-search-hard-drive-for_2.html

This guide will show you how to put these types of scripts on a flash drive and use a portable interpreter so that you don't have to install perl or python on every machine that you work on.

First you will need to download the portable versions of your interpreters, for Perl, download Strawberry Perl portable x86. For python, download the portable python x86. Now copy these executables to your flash drive along with your scripts for repairing. Next download Pstart, which is like a start menu for your portable thumb drive programs. Edit your pstart menu to execute your script using the appropriate interpreter for the script you choose. An alternative way is to create a batch script for each script that uses the portable interpreter to execute the given script.

Thursday, November 24, 2016

Installing Latest Kali Linux Rolling with All Packages on Any Android Device From Scratch With Latest LinuxDeploy Source

Before going through all of these steps, it might interest you to know that most Android devices usually do not have wireless drivers patched for injection, that being said, Kali still has many other useful tools that don't require patched drivers, i.e. metasploit. So, if you were wanting Kali on Android for wifi penetration testing, then you should look into Offensive Security's NetHunter, which includes patched drivers, but is only supported on a very limited set of Android devices. I'm currently looking into porting NetHunter to my LG G3 US990, and from what I can tell, is possible and encouraged. -Installing Linux on your Android device requires root, but anyone that's reading this probably has root already, right? -Get a 32GB class 10 microsd card, put it in your phone and choose to use it for Android only (format in ext4)
-Install Android Studio for your OS
-Clone latest LinuxDeploy source (git clone https://github.com/meefik/linuxdeploy.git)
-Open and build LinuxDeploy
-Install APK (adb install linuxdeploy.apk)
-Open LinuxDeploy, Go to settings, select: lock screen, lock wifi, wake lock, network trigger, enable cli
-Hit bottom right download button, select:
distribution: kali linux
installation type: directory
username: root
password: your_password
init: enable
init system: run-parts
mounts: enable
mount points: /store/emulated and /data
ssh: enable
-Menu -> install
-Menu -> configure
-Start
-Install VNC app, and connect to localhost:5900
-Open Terminal
-apt-get update
-apt-get install kali-linux-all # This installs like 3GB of packages, so be prepaired to wait
leave mysql password blank (default in kali and by default only listens on localhost)
set macchanger prompt to no
setuid root for kismet? -> No
set sslh to standalone
set wireshark to no
-To install only certain categories of tools (like to remove wifi or install password tools only):
apt-cache search kali-linux
apt-get remove --purge kali-linux-wifi
apt-get install kali-linux-pwtools
-Then to install openvas and tor:
apt-get install tor privoxy openvas

Monday, November 21, 2016

Here is a Patch That Adds Multithreading Support for coWPAtty 4.6 genpmk.c and the cowpatty.c Hashfile Attack, I changed the version to 4.7

I have added a patch to enable multi-threading (via pthreads) to the genpmk.c program of the coWPAtty wireless tools suite. genpmk.c breaks down the WPA/WPA2 dictionary attack process into two functions. The first allows you to pre-compute hashes for a given ssid from a given wordlist. Second, you use the hash file created to perform the dictionary attack on a 4-way handshake capture file. I have added posix thread support to help speed up the time it takes to calculate the hashes. You can download the source files from my github page here:
coWPAtty 4.7 multithreaded
You might be thinking, that breaking the process down doesn't speed it up any, and you would be correct. The benefit of this program is to allow for precomputing of hashes for common essid's. The WPA/WPA2 hashing algorithm does 4096 iterations, and salts it with the essid, so getting those calculations out of the way once will speed up future runs significantly. To prevent against this type of attack you would need to change your essid to something somewhat unique, and definitely something other than the default (if the default is not unique). Some ISP's have been trying to thwart this type of attack by giving default essid's containing the serial number part of the device's MAC ID. You might have seen Comcast's "HOME-XXXX" networks around, this coupled with a long default password that is random alpha-numeric sequence where a wordlist would take petabytes of space, makes the wifi network pretty secure against any attacks. The genpmk/cowpatty software is best used to attack essid's that you find most frequently, e.g. a default essid of "linksys". This program could also be ran in a shell script to calculate hashes for multiple essid's.

Usage:
./genpmk -f wordlist -d output_hashfile -s linksys -n 4
The -n flag is optional, it tells genpmk how many threads to create. It will default to the number of cpu's on the system + 1

Lists of essid's can be created easily too, with tools like crunch and seq. Here is a command that will generate all variations of the "NETGEARXX" essid:
seq 00 99 | perl -pe "s/^(.*)$/NETGEAR\1/g;"
or to generate all "HOME-XXXX" networks, we could use crunch:
crunch 4 4 ABCDEF0123456789 | perl -pe "s/^(.*)$/HOME-\1/g;"

Tuesday, November 15, 2016

Socks5 Proxy Scraping Perl Module for proxychains and DNS Leak Prevention

This is a perl module I wrote for scraping Socks5 proxies off websites. It verifies that the proxy is working before adding it to the mysql database. I will be adding support for performing OCR on an image matched by the ip or port regex with the tesseract perl library. I have also written a php frontend, and scripts that run on cron jobs to update the Max Mind geoip database and check the proxies in the mysql database.


# Socks5 proxy scraping module that stores working proxies in mysql database
# © Michael Craze -- http://projectcraze.us.to
#
# Example usage:
# use Proxy_Scraper;
#
# my $db = "proxies";
# my $user = "proxy_db_user";
# my $password = "proxy_db_pass";
#
# my $geoipdb="/home/$USER/code/get_proxies/GeoLiteCity.dat";
#
# # URL to scrape
# my $url = "http://www.some_proxy_site.com/socks5-list/";
#
# # IE7 - some pages print without javascript for IE7
# my $user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)';
#
# # Time in seconds to wait for a response from the site we are accessing via the proxy when checking
# my $time_out = 5;
#
# # Need parens on port_re, not ip_re
# my $ip_re = qr/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;
# my $port_re = qr/$ip_re:(\d{1,5})/;
#
# my $ps = Proxy_Scraper->new($user,$password,$db,$geoipdb);
# $ps->scrape_url($url,$ip_re,$port_re,$user_agent,$timeout); 
# $ps->close();
#
# The scrape_url() method can be called as many times as wanted on different urls before calling close

#!/usr/bin/perl

package Proxy_Scraper;

use strict;
use warnings;
use Exporter;
use LWP::Simple;
use LWP::UserAgent;
use Data::Dumper;
use Geo::IP;
use Socket;
use DBI;
use DateTime;
use Net::Whois::Raw;
use Net::Ping;

use vars qw($VERSION @ISA @EXPORT);

require Exporter;

$VERSION = 1.000_001;
@ISA = qw(Exporter);
@EXPORT = (); # list functions/variables that modules exports here

my $DEBUG_LEVEL = 0;
my $GET_WHOIS = 0;

# Dump of Max Mind GeoIPCity.dat Record
#$VAR1 = \bless( {
#                   'city' => 'Mountain View',
#                   'country_code3' => 'USA',
#                   'region_name' => 'California',
#                   'country_code' => 'US',
#                   'postal_code' => '94040',
#                   'continent_code' => 'NA',
#                   'metro_code' => 807,
#                   'area_code' => 650,
#                   'country_name' => 'United States',
#                   'longitude' => '-122.0881',
#                   'region' => 'CA',
#                   'latitude' => '37.3845',
#                   'dma_code' => 807
#                 }, 'Geo::IP::Record' );

sub new{
 my $class = shift;
 my $self = {
  user => shift,
  password => shift,
  db => shift,
  geoipdb => shift,
 };

 $self->{dsn} = "DBI:mysql:$self->{db}";

 $self->{gi} = Geo::IP->open($self->{geoipdb}, GEOIP_STANDARD);

 $self->{dbh} = DBI->connect($self->{dsn}, $self->{user}, $self->{password}, {
  PrintError => 0,
  RaiseError => 1,
  AutoCommit => 1,
 });

 bless $self, $class;
 return $self;
}

sub close{
 my ($self) = @_;
 $self->{dbh}->disconnect;
}

sub  trim { $_[0] =~ s/^\s+|\s+$//g; return $_[0]; };

sub is_numeric { $_ =~ m/^\d+$/ ? return 1 : return 0; };

sub get_current_date_time{
 my $dt = DateTime->now;
 return join ' ', $dt->ymd, $dt->hms;  
}

# reverse dns lookup
sub get_dns{ return gethostbyaddr(inet_aton($_[0]), AF_INET); };

# Check that the proxy is up and working
sub check_proxy{
 my ($self, $ip, $port) = @_;
 my $ua = new LWP::UserAgent(agent => $self->{user_agent});
 $ua->timeout($self->{time_out});
 $ua->proxy([qw(http https)] => "socks://$ip:$port");
 my $res = $ua->get("http://google.com");
 if($DEBUG_LEVEL){
  print "\nWhile checking proxy got: " . $res->code . " " . $res->message . "\n";
 }
 $res->code eq "200" ? return 1 : return 0;
}

sub ping{
 my $hostname = shift;
 my $p = Net::Ping->new();
 my $n = 2;
 my $time = 0;
 my $success = 0;
 if($DEBUG_LEVEL){
  print "Pinging $hostname $n times.\n";
 }
 foreach my $c (1 .. $n) {
  my ($ret, $duration, $ip) = $p->ping($hostname);
  if ($ret) {
   $success++;
   $time += $duration;
  }
 }
 if (not $success) {
  if($DEBUG_LEVEL){
   print "All $n pings failed.\n";
  }
  return 0;
 } 
 else {
  if ($success < $n) {
   my $i = ($n - $success);
   print $i . " lost packets. Packet loss ratio: " . int(100 * ($i / $n)) . "\n";
   return int(100 * ($n - $success) / $n);
  }
  if($DEBUG_LEVEL){
   print "Average round trip: " . ($time / $success) . "\n";
  }
  return ($time / $success);
 }
}

sub traceroute{
 my $host = shift;
 my $tr = Net::Traceroute->new(host => $host);
 if($tr->found) {
  my $hops = $tr->hops;
  if($hops > 1) {
   return "Router was " .
    $tr->hop_query_host($tr->hops - 1, 0) . "\n";
  }
  else{
   return "1 or less hops\n";
  }
 }
 else{
  return "No route found.\n";
 }
}

sub get_whois_str{
 $Net::Whois::Raw::CHECK_FAIL = 1;
 return whois($_[0]);
}

# Builds a hash table of proxies we have already found so we don't add them twice
sub get_proxies_from_db{
 my $self = shift;
 my %seen = %{$_[0]};
 my $sql = 'SELECT ip, port FROM proxies';
 my $sth = $self->{dbh}->prepare($sql);
 my $rv = $sth->execute();
 if($rv < 0){
  print STDERR $DBI::errstr;
 }
 while(my @row = $sth->fetchrow_array) {
  my $ip = $row[0];
  my $port = $row[1];
  $seen{$ip} = $port;
 }
 if($DEBUG_LEVEL >= 2){
  print Dumper \%seen;
 }
}

# Checks if scraped proxy is already in our database
sub proxy_in_db{
 my $ip = shift;
 my $port = shift;
 my %seen = %{$_[0]};
 for my $key (keys %seen){
  if($ip eq $key && $port eq $seen{$key}){
   return 1;
  }
 }
 return 0;
}

sub store_proxy_and_whois{
 my $self = shift;
 my $sth = $self->{dbh}->prepare("INSERT INTO proxies (ip, port, dns, country_code, country_name, region_name, city, postal_code, area_code, latitude, longitude, whois, ping, added, last_checked) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 my $rv = $sth->execute($_[0], $_[1], $_[2], $_[3], $_[4], $_[5], $_[6], $_[7], $_[8], $_[9], $_[10], $_[11], $_[12], $_[13], $_[14]);
 if($rv < 0){
  print STDERR $DBI::errstr;
 }
}

sub store_proxy{
 my $self = shift;
 my $sth = $self->{dbh}->prepare("INSERT INTO proxies (ip, port, dns, country_code, country_name, region_name, city, postal_code, area_code, latitude, longitude, whois, ping, added, last_checked) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 my $rv = $sth->execute($_[0], $_[1], $_[2], $_[3], $_[4], $_[5], $_[6], $_[7], $_[8], $_[9], $_[10], $_[11], $_[12], $_[13]);
 if($rv < 0){
  print STDERR $DBI::errstr;
 }
}

sub print_proxy_csv{
 print join(',',@_) . "\n";
}

sub scrape_url{
 my $self = shift;
 $self->{url} = shift;
 $self->{ip_re} = shift;
 $self->{port_re} = shift;
 $self->{user_agent} = shift;
 $self->{time_out} = shift;
 my %seen = {};
 $self->get_proxies_from_db(\%seen);
 my $ua = new LWP::UserAgent(agent => $self->{user_agent});
 $ua->timeout($self->{time_out});
 my $res = $ua->get($self->{url});
 if($res->code eq "200"){
  if($DEBUG_LEVEL >= 3){
   print $res->decoded_content;
  }
  my @ips = $res->decoded_content =~ m/($self->{ip_re})/gi;
  my @ports = $res->decoded_content =~ m/$self->{port_re}/gi;
  my $i=0;
  foreach my $ip (@ips){
   my @csv_items = ();
   my $port = $ports[$i];
   if(proxy_in_db($ip,$port,\%seen)){
    print "$ip:$port Already Seen.\n";
    last;
   }
  
   # Max Mind GeoIP record
   my $r = $self->{gi}->record_by_addr($ip);
   
   if($self->check_proxy($ip,$port)){
    my $ping = ping($ip);
    my $dns = get_dns($ip);
    my $whois_data = "";
    if($GET_WHOIS){
     $whois_data = get_whois_str($dns);
    }
    push(@csv_items,$ip,$port,$dns,$r->country_code,$r->country_name,$r->region_name,$r->city,$r->postal_code,$r->area_code,$r->latitude,$r->longitude);
    print_proxy_csv(@csv_items);
    
    my $now = get_current_date_time();

    if(defined $whois_data){
     $self->store_proxy_and_whois($ip, $port, $dns, $r->country_code, $r->country_name, $r->region_name, $r->city, $r->postal_code, $r->area_code, $r->latitude, $r->longitude, $whois_data, $ping, $now, $now);
    }
    else{
     $self->store_proxy($ip, $port, $dns, $r->country_code, $r->country_name, $r->region_name, $r->city, $r->postal_code, $r->area_code, $r->latitude, $r->longitude, $ping, $now, $now);
    }
   }
   else{
    print "$ip:$port is down.\n";
   }
   if($i > 0 && $i % 100 == 0){
    print "\n";
   }
   $i++;
  }
  return 0;
 }
 else{
  print STDERR "Couldn't get url ($self->{url}): " . $res->code . " " . $res->message . "\n";
  return 1;
 }
}

1;

Fixing MythTV's mythexport Web Interface on Ubuntu Server 16.04

In the current versions of Ubuntu mythexport installs to /var/www, however the new home for the www-data user is /var/www/html. mythexport still creates a symlink /var/www/mythexport which points to /usr/share/mythtv/mythexport. The perl mythtv bindings look in the www-data home directory for the .mythtv folder, which according to /etc/passwd is /var/www. So make sure there is a .mythtv folder and .mythtv/config.xml file symlinked to /etc/mythtv/config.xml. Move the mythexport symlink from /var/www/mythexport to /var/www/html/mythexport:
mv /var/www/mythexport /var/www/html/mythexport
Next since mythexport uses some hardcoded paths in the source code, we need to find all instances of /var/www and replace them with /var/www/html. To do this use grep:
pushd /usr/share/mythtv/mythexport grep -E "\/var\/www" *.cgi
Looks like we need to change two files:
mythexportRSS.cgi: my $file_len = -s "/var/www/mythexport/video/$rss_file"; save_system_setup.cgi:sudo mkdir -p $location && sudo chmod 775 $location && sudo chown mythtv:mythtv $location && sudo ln -s -f $location /var/www/mythexport/video


vi mythexportRSS.cgi
Search and replace vim command: %s/\/var\/www/\/var\/www\/html/g
Then edit save_system_setup.cgi with the same vim command.
I also notice the mythexport apache configurations file was in sites-available and not in sites-enabled. So I ran the commands:
a2ensite mythexport service apache2 restart /etc/init.d/mythexport restart
You should now be able to browse to http://mythtv_ip/mythexport and setup your configuration.

Saturday, July 2, 2016

Perl and Bash Shell Scripts To Download The Latest Driver Packs


#!/bin/bash

/usr/bin/perl /home/mike/code/dpmirror/dpmirror.pl > /dev/null
#cp /home/mike/code/dpmirror/torrents/*.torrent /store/torrent/watch/

#!/usr/bin/perl
# Driver Packs Scrapper v0.1
# Michael Craze 2012
#
# Scrapes the driverpacks.net RSS feed for the latest torrents,
# The RSS feed only give links to the website, so those links are
# scrapped for the links to the torrent files. They are saved in
# the $dest directory with their correct filenames.
# This can be used in conjunction with your torrent client's "watch"
# directory for automatic downloading of latest driver packs.
use strict;
use warnings;
use URI;
use XML::RSS;
use LWP::Simple;
use Web::Scraper;

my $log_file='/home/mike/code/dpmirror/driver_packs.log';
#my $dest='/home/mike/code/dpmirror/torrents';
my $dest='/store/torrent/watch';
my $feed='http://driverpacks.net/driverpacks/latest/feed';

my @driver_packs=();
open my $ILFH, '<', $log_file or die "Can't open $log_file: $!\n";
chomp(@driver_packs=<$ILFH>);
close $ILFH;

my $rss=new XML::RSS;
my $content=get($feed);
die unless $content;
$rss->parse($content);
foreach my $item (@{$rss->{'items'}}){
    next unless defined($item->{'title'}) && defined($item->{'link'});
    my $already_downloaded_flag=0;
    my $title=$item->{'title'};
    my $link=$item->{'link'};
    #
    my $data = scraper {
        process "div.download-link > a", 'urls[]' => '@href';
    };
    my $res = $data->scrape(URI->new("$link"));
    for my $i (0 .. $#{$res->{urls}}){
        print "Checking $link\n";
        my @fields = split /\//, $res->{urls}[$i];
        my $kind=$fields[7];
        my $arch=$fields[6];
        my $ver=$fields[8];
        $ver =~ tr/.//d;
        my $nt="";
        if($fields[5] =~ m/^7$/){ $nt="6"; }
        if($fields[5] =~ m/^xp$/i){ $nt="5"; }
        my $fn=$dest."/DP_".$kind."_wnt".$nt."-".$arch."_".$ver.".torrent";
        next if(-e $fn);
        for my $driver_pack (@driver_packs){
            if($fn =~ m/$driver_pack/){ $already_downloaded_flag=1; }
        }
        next if $already_downloaded_flag;
        push(@driver_packs,$fn);
        my $status=getstore($res->{urls}[$i],$fn);
        if(is_success($status)){
            my $time=localtime();
            print "Updated: $fn [$time]\n";
        }
    }
}

# Write new log file
open my $OLFH, '>', $log_file or die "Can't open $log_file: $!\n";
for my $driver_pack (@driver_packs){
        print $OLFH "$driver_pack\n";
}
close $OLFH;

exit;

__END__

Perl and Bash Shell Scripts To Download All Driver Packs Torrent Files

This is nice to use to mirror the driverpacks. Use with your torrent client's watch directory.


#!/bin/bash
#
# dl_all_dps.sh
#
# Downloads all the torrents for the current lastest releases of driver packs
# for all Windows operating systemss and all their architectures.
# TLDR: Downloads all available driver packs
#
# © Michael Craze -- http://projectcraze.us.to

for x in `lynx -dump http://driverpacks.net/driverpacks/latest | grep "http:\/\/driverpacks\.net\/driverpacks\/windows\/" | awk '{print $2;}'`; do
        #/driverpacks/windows/7/x86/monitors/10.01/download/torrent
        echo "Getting: $x";

        # This should work, but it doesn't - couldn't figure out why so rewrote script in perl
        #lynx -dump "$x" | grep "\/download\/torrent" | awk '{print $2}' | wget -i -
        lynx -force_html -dump "$x" | grep "\/download\/torrent" | awk '{print $2}'
done

#!/usr/bin/perl
#
# Downloads all torrents for all driver packs for all windows operating systems
# and architectures
#
# © Michael Craze -- http://projectcraze.us.to

use strict;
use warnings;
use LWP::Simple;

my $debug=0;
my $domain="http://driverpacks.net";
my $url=$domain."/driverpacks/latest";
my $content=get($url);
die "Couldn't get url: $url" unless defined $content;

if ($debug){
        print "$content\n";
}

my @torrent_links=($content =~ /(\/driverpacks\/windows\/(7|xp)\/(x86|x64)\/[-a-zA-Z]+\/\d+\.\d+)/g);
foreach my $link (@torrent_links){
        if($link =~ /(\/driverpacks\/windows\/(7|xp)\/(x86|x64)\/[-a-zA-Z]+\/\d+\.\d+)/g){
                #print "Getting: $domain"."$link\n";
                my $link_content=get($domain.$link);
                die "Couldn't get url: $url" unless defined $link_content;
                if($debug){
                        print "$link_content\n";
                }
                if($link_content =~ /(\/driverpacks\/windows\/(7|xp)\/(x86|x64)\/[-a-zA-Z]+\/\d+\.\d+\/download\/torrent)/g){
                        my $uri=$domain.$1;
                        print "Downloading: $uri\n";
                        my @dirs=split("/",$1);
                        my $filename="DP_".$dirs[2]."_".$dirs[3]."_".$dirs[4]."_".$dirs[5]."_".$dirs[6].".torrent";
                        print " Filename: $filename\n";
                        my $status=getstore($uri,$filename);
                        die "$status error while getting $uri" unless is_success($status);
                }
        }
}

A Shell Script To Download MVPS Host File And Use It On Our OpenWRT Router


#!/bin/sh

hosts_file="/etc/hosts"
old_hosts_file="old_hosts.txt"
new_hosts_file="new_hosts.txt"

if [ -f $hosts_file ] ; then
    mv $hosts_file ./hosts
    rm -f $HOSTFILE
fi

if [ -f "hosts.txt" ] ; then
    rm -f ./hosts.txt
fi

if [ -f "new_hosts.txt" ] ; then
    rm -f ./new_hosts.txt
fi

cp /etc/hosts ./old_hosts.txt
cat ./hosts | sed -e 's/0\.0\.0\.0.*$/\r/g' -e '/^\s*$/d' > $HOSTFILE
wget http://www.mvps.org/winhelp2002/hosts.txt
cat ./hosts.txt | sed -e 's/^#.*$/\r/g' -e 's/\s*#.*$/\r/g' -e '/^\s*$/d' | sed -e '1,2s/^.*$//g' -e '/^\s*$/d' | sed -e 's/127\.0\.0\.1/0\.0\.0\.0/g' >> $HOSTFILE
#cat $HOSTFILE > /etc/hosts


#wget -O - http://www.mvps.org/winhelp2002/hosts.txt | grep 127.0.0.1 | sed -e '2,$s/127.0.0.1/0.0.0.0/g' -e 's/[[:space:]]*#.*$//' > /etc/hosts
#logger "$0: Hosts-file downloaded"stopservice dnsmasq
#startservice dnsmasq
#logger "$0: DNSMasq restarted"

A Perl Script To Search A Hard Drive For All Images >300x200 Pixels


#!/usr/bin/perl
use strict;
use warnings;
use File::Find::Rule;
use File::Find::Rule::MMagic;
use File::Find::Rule::ImageSize;

if($#ARGV < 0){
    print "usage: ./ppf.pl \n";
    exit 1;
}

my $rule=File::Find::Rule->new;
$rule->file;
$rule->name('*.jpg','*.jpeg','*.png','*.tif','*.tiff'); # check extension
$rule->magic('image/*'); # check the mime type
$rule->image_x('>300'); # pictures will be >=320x240
$rule->image_y('>200');
my @imgz=$rule->in(@ARGV);

foreach my $i (@imgz){
    print "$i\n";
}

A Perl Script To Search A Hard Drive For Filenames Resembling Common Digital Camera Filenames


#!/usr/bin/perl
use strict;
use warnings;
use File::Find;

if($#ARGV != 0){
    print "Usage: ./finddc.pl \n";
    print "E.g.\n";
    print " ./finddc.pl C:\n";
    exit 1;
}

print "Searching $ARGV[0] for camera files...\n";

find({
    preprocess => \&preprocess,
    wanted => \&wanted
}, $ARGV[0]);

sub preprocess {
    my @list;
    foreach (@_){
        if( -d && $_ =~ m/DCIM/){ push @list, $_; }

        # .wav files are ommitted in the search
        if(-f && $_ =~ m/(DSC_|IMG_)\d+(\.jpg|\.tif|\.thm|\.png)/i){
            print "$_\n";
            push @list, $_;
        }

        # file names list came from:
        # http://diddly.com/random/about.html
        # Kodak
        if(-f && $_ =~ m/dcp\d+\.jpg/i){ push @list, $_; }

        # Nikon
        if(-f && $_ =~ m/dsc[n]?\d+\.jpg/i){ push @list, $_; }

        # Sony
        if(-f && $_ =~ m/mvc[-]?\d+\.jpg/i){ push @list, $_; }

        # Olympus
        if(-f && $_ =~ m/P(101|MDD)\d+\.jpg/i){ push @list, $_; }

        # RCA and Samsung
        if(-f && $_ =~ m/IM[A]?G\d+\.jpg/i){ push @list, $_; }

        # Canon
        if(-f && $_ =~ m/1\d+-\d+(_IMG)?\.jpg/i){ push @list, $_; }
        if(-f && $_ =~ m/(I|_)MG_\d+\.jpg/i){ push @list, $_; }

        # Fuji Finepix
        if(-f && $_ =~ m/dscf\d+\.jpg/i){ push @list, $_; }

        # Toshiba PDR
        if(-f && $_ =~ m/pdrm\d+\.jpg/i){ push @list, $_; }

        # HP Photosmart
        if(-f && $_ =~ m/(IM|EX)\d+\.jpg/i){ push @list, $_; }

        # Kodak DC-40,50,120, S is (L)arge (M)edium (S)mall.
        if(-f && $_ =~ m/DC\d+(L|M|S)\.jpg/i){ push @list, $_; }

        # Minolta Dimage
        if(-f && $_ =~ m/pict\d+\.jpg/i){ push @list, $_; }

        # Kodak DC290
        if(-f && $_ =~ m/P\d+\.JPG/i){ push @list, $_; }

        # Casio
        if(-f && $_ =~ m/(YYMDD|MMDD)\d+\.JPG/i){ push @list, $_; }

        # Pentax
        if(-f && $_ =~ m/IMGP\d+\.JPG/i){ push @list, $_; }

        # Panasonic
        if(-f && $_ =~ m/PANA\d+\.JPG/i){ push @list, $_; }

        # HTC Desire Z/Tmobil G2
        if(-f && $_ =~ m/IMG_\d{8}_\d{6}.JPG/i){ push @list, $_; }

        # Facebook
        if(-f && $_ =~ m/\d+_\d+_\d+_n.jpg/i){ push @list, $_; }

    }
    return @list;
}

sub wanted {
    foreach (@_){
        print "$_\n";
    }
    print "done...\n";
}

Crime City Game Mafia Code Auto-Bumper Perl Script

Run the following script like this:


/usr/bin/perl /home/mike/code/ccbumper/ccbumper.pl 2>&1 >> /dev/null &



#!/usr/bin/perl
# http://www.crimecitymafia.com mafia code auto-bumper
# Michael Craze
# 20130304
use strict;
use warnings;
use WWW::Mechanize;

# To get the following value, you have to go through the source code of the site
# and find the hidden form input field named bk, the value will need to be
# copied and pasted below.
my $bk = "f22f8cea8023e53d82c1ea51ee38b746";

# Read mafia codes from codes.txt and store in @codes array
my $code_file = "codes.txt";
open(FH, "< $code_file") or die "Can't open $code_file for read: $!";
my @codes=();
while(){
    if($_ =~ m/\d\d\d-\d\d\d-\d\d\d/){
        push(@codes, $_);
    }
}
close FH or die "Cannot close $code_file: $!";

my $url = "http://www.crimecitymafia.com/";
my $m = WWW::Mechanize->new( agent => 'Apple-iPhone4C1/901.406'); # iphone 4s
while(1){
    for(my $i=0; $i < scalar(@codes); $i++){
        #my $wait_time = int(rand(60)); # random int [0,60]
        $m->get($url);
        $m->form_number(2);
        $m->field('package', '1');
        $m->field('bk', $bk);
        $m->field('code', $codes[$i]);
        $m->submit();
        #my $response = $m->submit();
        #print $response->content();
    }
    sleep(3600);
}

A Forkbomb Written In C


/* forkbomb.c
   Michael Craze
   http://projectcraze.ath.cx
*/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

void usage(char *s);

int main(int argc, char **argv){
    int i, fv, iter;
    if(argc != 2){
        usage(argv[0]);
    }
    iter=atoi(argv[1]);
    for(i=0;i<iter;i++){
        if((fv=fork())==-1){
            perror(argv[0]);
        }
        else if(fv==0){
            sleep(1000);
        }
        else{
            printf("Process: %8d -- i/iter = %d/%d\n",getpid(),i,iter);
            fflush(stdout);
        }
    }
    return 0;
}

void usage(char *s){
    fprintf(stderr,"Usage: %s \n",s);
    fprintf(stderr," *Note: fork calls scale logrithmically\n");
    exit(1);
}

Adding To The Simple Port Scanner Written in C


/*
    TCP port scanner
    Written and Maintained by Michael Craze

TODO:
    make it use threads..
    make it check UDP
    make it scan ip address ranges for public use

    ip address ranges for private use:
    Class   Networks
    A   10.0.0.0 through 10.255.255.255
    B   172.16.0.0 through 172.31.0.0
    C   192.168.0.0 through 192.168.255.0
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

typedef struct{
    char *ip;
    int sport;
    int eport;
} Host;

void usage(char *a){
    fprintf(stderr,"Invalid invocation of %s\n",a);
    printf("Usage: %s   \n",a);
    exit(1);
}

/* Main programs starts*/
int main(int argc, char **argv){
    int sd;
    int port;
    int rval;
    int checkip;
    int pcount = 0;

    /* going to use these ints to iterate
       through public IP classes to find all
       open servers to automate attacks.
    */
    /*
       int A,B,C,D;
    */

    /*
        char *message="shell";
    */
    /*
        char response[1024];
    */

    Host *h;
    struct hostent *hostaddr;
    struct sockaddr_in servaddr;

    if (argc < 4 ){
        usage(argv[0]);
    }

    h = (Host *)malloc(sizeof(Host));
    if(h == NULL){
        fprintf(stderr,"couldn't allocate memory for %s\n",argv[1]);
        exit(1);
    }
    if(sscanf(argv[1],"%d",&checkip) != 1){
        fprintf(stderr,"%s was not a valid ip address\n",argv[1]);
        usage(argv[0]);
    }
    if(sscanf(argv[2],"%d",&h->sport) != 1){
        fprintf(stderr,"%s was not a valid integer\n",argv[2]);
        usage(argv[0]);
    }
    if(sscanf(argv[3],"%d",&h->eport) != 1){
        fprintf(stderr,"%s was not a valid integer\n",argv[3]);
        usage(argv[0]);
    }

    h->ip = strdup(argv[1]);
    printf("Scanning host: %s on ports %d thru %d\n", h->ip,h->sport,h->eport);


    /* Start scanning ports */
    for (port = h->sport; port <= h->eport; port++){
        /* creating the tcp socket */
        sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sd == -1){
            perror("Socket()\n");
            return (errno);
        }
        memset( &servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(port);
        hostaddr = gethostbyname(h->ip);

        memcpy(&servaddr.sin_addr, hostaddr->h_addr, hostaddr->h_length);

        /* below connects to the specified ip in hostaddr */
        rval = connect(sd, (struct sockaddr *) &servaddr, sizeof(servaddr));

        if(rval != -1){
            printf("  %-7d %-10s\n",port,"is open");
            pcount++;
        }
        close(sd);
    }
    if(pcount == 0){
        printf("No ports in range %d-%d are open on host %s\n",h->sport,h->eport,h->ip);
    }
    else{
        printf("%d ports in range %d-%d are open on host %s\n",pcount,h->sport,h->eport,h->ip);
    }

    free(h);
    return 0;
}

A Simple Port Scanner Written In C


#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdlib.h>
#include<netdb.h>
int main(int argc,char **argv)
{
        int i,err,net;
        struct hostent *host;
        struct sockaddr_in sa;
        if(argc!=2){
                printf("Error...Usage :%s ip-address",argv[0]);
                exit(0);
        }
        for(i=1;i<20000;i++){
                sa.sin_family=AF_INET;
                sa.sin_port=htons(i);
                sa.sin_addr.s_addr=inet_addr(argv[1]);
                net=socket(AF_INET,SOCK_STREAM,0);
            err=connect(net,(struct sockaddr_in *)&sa,sizeof(sa));
        if(err>=0){
                        printf("\n%d is open",i);
                }
                close(net);
        }
        printf("\n");
}

Hack In The Box Magazine Perl Script To Download All Issues As PDF

I wrote this a long time ago to scrape the Hack in the Box site and download all their magazines in PDF format:


#!/usr/bin/perl
# Downloads Hack In The Box Magazines
use strict;
use warnings;
use LWP::Simple;

for (my $i=1;$i<1000;$i++){
    my $url=sprintf("http://magazine.hitb.org/issues/HITB-Ezine-Issue-%03d.pdf",$i);
    my $pdf=sprintf("HITB-Ezine-Issue-%03d.pdf",$i);
    next if (-e $pdf);
    my $status=getstore($url,$pdf);
    if(is_error($status)){
        print "[$status] Couldn't download: $url\n";
        last;
    }
    else{
        print "[$status] Downloaded: $url\n";
    }
}

Using Python and Bash Scripts and sSMTP to Notify You by E-mail When a New Issue of 2600: The Hacker Quarterly Is Released

I wrote this python script to get notified when a new issue of 2600: The Hacker Quarterly is released:


#!/usr/bin/python
import re
import feedparser
url = 'http://www.2600.com/rss.xml'
f = "log.txt"
d = feedparser.parse(url)
fh = open(f, 'r+')
line = fh.readline()
if line != d['entries'][0]['link']:
        if re.match(r'(WINTER|SPRING|SUMMER|AUTUMN).*', d['entries'][0]['title']):
                print d['entries'][0]['title'] + " " + d['entries'][0]['link'] + "\r\n"
fh.seek(0)
fh.write(d['entries'][0]['link'] + "\r\n")
fh.truncate()
fh.close()


And here is the Bash Shell script to take the output from stdout and use it as the subject for an e-mail:


#!/bin/bash
#
# Executes the script given as argument #2,
# then if there is anything printed to stdout,
# it will email the text as the body of the email
#
# © Michael Craze -- http://projectcraze.us.to

if [ "$#" -ne 2 ] ; then
        echo "Usage: $0  <2600_script>"
        exit
fi

EMAIL="your_email@domain.com"
SUBJECT=$1
CLSCRIPT=$2
PY=`which python`
MAIL=`which mail`
BODY=`$PY $CLSCRIPT`

# send email if something was posted today
if [ -n "$BODY" ] ; then
        echo $BODY | $MAIL -s $SUBJECT $EMAIL
fi


Here is the crontab (crontab -e) entry I use to run it once daily:


30 8 * * * /bin/bash /home/mike/code/2600_notifier/2600-mail.sh New_2600 /home/mike/code/2600_notifier/2600_notifier.py


This will only work if you have your MTA setup correctly. I use a package called ssmtp (sudo apt-get install ssmtp), and set it up to use my gmail account to send mail, here is my ssmtp.conf:


# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
#root=postmaster
root=your_email@gmail.com

# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
#mailhub=mail
mailhub=smtp.gmail.com:587

AuthUser=your_email@gmail.com
AuthPass=your_password
UseTLS=YES
UseSTARTTLS=YES

# Where will the mail seem to come from?
#rewriteDomain=
rewriteDomain=gmail.com

# The full hostname
#hostname=MyMediaServer.home
hostname=your_email@gmail.com

# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES