undocumented drush command


Drush is a great tool for managing Drupal.  The other day I wanted to write a script to check a lot of Drupal sites for pending security updates (just list them, not apply) and I stumbled across this undocumented command that does just that:  drush pm-updatestatus (you can use it in combination with the --pipe argument for scripting)

shell_exec timeout


I was looking for an easy way to provide a timeout for a shell_exec command and came across this useful suggestion using the (you guessed it...) timeout command:

shell_exec("timeout ".$timeout_in_sec."s ".$your_cmd);

exFAT for external hard drives


Pro Tip: if your external hard drive or thumb drive is larger than 4 GB and you want to easily move files between Windows, Mac, and Linux computers, format it using the exFAT format.

bruteforce subdomain finder


The first step in a cyber attacker's kill chain or penetration testing is reconnaissance.  Preferably, this step includes as much passive analysis as possible to avoid detection.  If you know nothing about a target, you typically start with web-based reconnaissance, including mapping out their web-accessible network and infrastructure.  Obtaining a list of active subdomains is really handy (think vpn, ftp, smtp, etc.) but not always easy.  There are a few dictionary-based and search-engine-based tools that can help spot the most commonly used subdomains (pentest-tools, dnsmap, gxfr, subdomain-bruteforcer, fierce2), but what if you have lots of time on your hands and want to run a true bruteforce rainbow table-style analysis?  I couldn't find anything so I put together a quick script called brutesub based on Matteo Redaelli's wg.pl script.  This takes a ridiculously long time to run for anything beyond 4 or 5 character subdomains but fortunately netops and end users are lazy and like short domains (and short aliases to longer domains) to remember.  The script is also handy for large organizations (such as higher education or government) that haven't documented how many subdomains they have.

USAGE: perl brutesub.pl options

options are:
-c number: max consecutive letters (how many consecutive 'a' do you want?)
-d string: root domain
-f : optimized fast scan, but less results than medium or full scan
-h : help
-i : optimized medium scan, but less results than full scan
-l number: min length of the subdomain
-o number: max number of occurrencies of a letter
-m string: custom nameserver
-n number: max number of n-ple  (AA, BBB, CCC, DDDD)
-r number: max number of repeatitions (ABCABABBCDBCD has 5 repeatitions: 3 reps of AB and 2 of BCD)
-s string: filename to save results
-t : trace on
-u number: max length of the subdomain


# usage
perl brutesub.pl -h

# optimized fast scan, but less results than medium or full scan  -->  ~1.2 minutes, 157 domains found
perl brutesub.pl -f -d facebook.com -s /tmp/brute_facebook_f.txt -u 3

# optimized medium scan, but less results than full scan  -->  ~34 minutes, 681 domains found
perl brutesub.pl -i -d facebook.com -s /tmp/brute_facebook_i.txt -u 3

# full scan (slowest, but rainbow-table precise)  -->  ~34 minutes, 805 domains found
perl brutesub.pl -d facebook.com -s /tmp/brute_facebook_full.txt -u 3

note: scan time difference between medium and full becomes more apparent at u > 4

Download script

Laughter is the best medicine


Classic case of missing the forest for the trees...


An insightful lesson from the Pixar Cars animators

cool tribute


It's neat when an obscure band pays tribute to an equally obscure movie:



running sudo commands with phpseclib PHP library


phpseclib makes running SSH commands easy.  Unfortunately, running sudo commands is not easy because ALL the documentation is WRONG (official site, blogs, stackoverflow, etc.).  This is what finally worked for me:

$ssh->read('/.*@.*[$|#]/', NET_SSH2_READ_REGEX);
$ssh->write("sudo YOUR COMMAND HERE\n");
$output = $ssh->read('/.*@.*[$|#]|.*[pP]assword.*/', NET_SSH2_READ_REGEX);
if (preg_match('/.*[pP]assword.*/', $output)) {
    $ssh->read('/.*@.*[$|#]/', NET_SSH2_READ_REGEX);

Thanks to this post for pointing me in the right direction.

PHP include gotcha


This took an embarrassing amount of time to figure out so I thought I'd pass it along...

If you want to include or include_once a PHP library but don't want to include that library locally with your PHP application, you can use set_include_path to tell PHP where to look for includes.

For example, if you have the phpseclib library in a central location on your server, you can use:


in-place editing the right way (hint: don't use sed or perl)


So you have a text file you want to edit via a bash command-line script and you do some quick Google searching and find practically everyone agreeing that you should use sed or perl.  Great!  So you plop their example code into your script and cross your fingers.  Well, 99% of the time it works and you move on with your life a little happier.  Unfortunately, 1% of the time you get something that looks like:

sed: couldn't open temporary file /your/text/file/location/sedxV3rms: Permission denied
Hmmm, that's odd.  After digging a little more you discover you have write permission to edit the file but not write permission on the file's directory and sed and perl both create a temporary file to make the edits and then try to replace the original file with the temporary file upon save (which your folder permissions won't allow).  The easy fix is to update the folder permissions to give the user (or user's group) write permissions.

What if (for security, policy, etc.) reasons, you can't (or don't want to) change the folder permissions?  Is there another way?  It turns out there is.  Unfortunately, it requires using a rather arcane tool called ed.

Ed is a command-line text editor that, unlike nano or vi, accepts edit commands, rather than the file contents, as input.  A good overview can be found here.  Great, but how do I fix my problem?  Basically, you pass a number of text commands in sequential order to modify the file truly in-place (via memory buffer).

For example, to replace all the instances of "foo" with "bar" you would run:
printf "%s\n" ',s/foo/bar/g' wq | ed -s myfile.txt
Yeah, I know - ugh!  Don't worry, it's a little easier to understand if you break down the command piece by piece:

  1. ed will open the file (myfile.txt) and suppress output (-s) so it doesn't interfere with the rest of your script logic
  2. printf will loop through each argument (highlighted in green and purple) and pass (pipe) them to ed as individual line commands (i.e. commands separated by a newline return)
  3. the first command it sends ed (highlighted in green) is a regular expression that says to look through the entire document (indicated by the comma right before the s — you can also use the longhand equivalent 1,$)  and find every string instance of "foo" and replace it with the string "bar" (if you only wanted to change the first occurrence, you would omit the g)
  4. the final command it sends ed (highlighted in purple) tells ed to save the changes (w) and quit the program (q)

....and that's just the tip of the iceberg!  Here's a more complicated example:
printf "%s\n" '/foo/--a' 'bar' . wq | ed -s myfile.txt
  1. the first command it sends ed (highlighted in green) tells it select the first line it finds that has the word "foo" (/foo/), go up two lines (--), and switch into input mode (similar to vi switching into insert mode)
  2. the next command (highlighted in red) tells ed to enter the text "bar" as a new line
  3. the next command (a single period highlighted in blue) tells ed to exit input mode
  4. the final command it sends ed (highlighted in purple) tells ed to save the changes (w) and quit the program (q)
With a little practice (and an ed cheat sheet handy), you'll be scripting file edits in no time (with the added bonus of being lightning fast and avoiding permission issues).