How-Tos Archives -

Lookbehind / Lookahead Regex in Vim

Here’s a nifty little vim tip for you.

I recently had to switch a few variables in PHP from $varname to $somearray[‘varname’]. Since there were quite a few of these replacements to be done, I found it convenient to use vim’s search/replace regex feature. In this case, I have to use lookbehind, since the matching string is simply varname, and I’m not interested in catching the $ at the beginning. I just want the regex to match anything starting with the $, without having the $ as part of the matching string itself.

So, let’s try to replace the following line:

authenticate($key, $secret, $uri);

with this one:

authenticate($somearray['key'], $somearray['secret'], $somearray['uri']);

We’ll want to construct a lookbehind for the $, with some string in front. Then, we’ll replace it with $somearray[‘matching_string‘]. In vim, lookbehind uses the special @ symbol, rather than the perl (?<=somestring) syntax. [shell] :'<,'>s/\$\@<=[a-z]\+/$somearray['&']/g [/shell] This will do the trick. As you can see, the $, @, and + must all be escaped. The lookbehind positive search chars, @<= can be replaced with @<! if a negative search is desired. Lookahead is similar to lookbehind’s syntax, but uses @= and @! instead. The special & character in the replace string designates a matching token, which you can use to place the matching string in your replacement.

So for reference:

  • :%s/\(some\)\@<=thing/one/g

    searches for all strings starting with some, then matching thing
    changes thing into one

    end result: something becomes someone

  • :%s/\(some\)\@<!thing/one/g

    searches for all strings not starting with some, then matching thing
    changes thing into one

    end result: something is not changed, but everything changes to everyone

  • :%s/some\(thing\)\@=/every/g

    searches for all strings ending with thing, then matching some
    changes some into every

    end result: something becomes everything

  • :%s/some\(thing\)\@!/every/g

    searches for all strings not ending with thing, then matching some
    changes some into every

    end result: something is not changed, but someone becomes everyone

Hardening your VPN Setup with iptables

I’ll be heading out to Defcon 19 next month, so I want my VPN connection to be stable and secure.

You probably know the situation. You’re at your local coffee shop, using their (hopefully not) wide-open unsecured wifi hotspot. But you’re smart enough not to send all your data out over the clear, since there might be malicious script kiddies ready to take your sensitive data and sell it to kids on the street. So you use a VPN. You fire up OpenVPN and connect to your VPN service. Then you start browsing, comforted by the fact that your traffic is encapsulated in a secure SSL tunnel. Better yet, the user experience is transparent: you don’t have to configure your applications to manually use a SOCKS5 proxy. OpenVPN handles your routing tables and creates a virtual interface using the tun module. It’s so simple, you don’t need to think about it. But there’s a problem with this setup.

No one can reach into your stream and extract or insert data, but there’s a caveat. Anyone can destroy your TCP stream by sending you a spoofed RST packet from the remote server, or otherwise making the service unavailable to you. Destroying the TCP stream destroys the virtual (tun) interface, which, in turn, destroys the routes associated with that interface. Now you’re using your physical interface unprotected from those pesky hackers. Worse still, you don’t realize it. Not a thing has changed from the perspective of user experience. Since everything is transparent, you don’t notice any change at all. Now you’re screwed.

Little did you know that this all could have been avoided by our friend iptables. Sure, you could modify your routes further to ensure that only traffic going to the remote server goes over your physical interface, but that’s too easy. Plus, routing tables aren’t intended for security, they’re inteded to move packets along. iptables seems like the tool for the task, so I modified a script I found here to make sure that we disallow any traffic that we don’t want:

if [[ $EUID -ne 0 ]]; then
	echo "This script must be run as root" 1>&2
	exit 1

# name of primary network interface (before tunnel)

# address of tunnel server
# address of vpn server

# gateway ip address (before tunnel - adsl router ip address)
# automatically determine the ip from the default route
GATEWAY=`route -n | grep $PRIMARY | egrep "^0\.0\.0\.0" | tr -s " " | cut -d" " -f2`

# provided by pppd: interface name

openvpn --config /my/path/to/riseup.ovpn --auth-user-pass /my/path/to/authentication.conf &

# iptables rules - important!


# Flush all previous filter rules, you might not want to include this line if you already have other rules setup
iptables -t filter --flush

iptables -t filter -X MYVPN
iptables -t filter -N MYVPN

# Exceptions for local traffic & vpn server
iptables -t filter -A MYVPN -o lo -j RETURN
iptables -t filter -A MYVPN -o ${TUNNEL} -j RETURN
iptables -t filter -A MYVPN --dst -j RETURN
iptables -t filter -A MYVPN --dst $LOCAL_NET -j RETURN
iptables -t filter -A MYVPN --dst ${SERVER} -j RETURN
iptables -t filter -A MYVPN --dst ${VPN_SERVER} -j RETURN
# Add extra local nets here as necessary

iptables -t filter -A MYVPN -j DROP

# MYVPN traffic leaving this host:
iptables -t filter -A OUTPUT -p tcp --syn -j MYVPN
iptables -t filter -A OUTPUT -p icmp -j MYVPN
iptables -t filter -A OUTPUT -p udp -j MYVPN

echo "nameserver" > /etc/resolv.conf

You’ll want to modify the openvpn command, interfaces, and servers to meet your needs. And that’s it! If your stream is taken down, you have these rules to protect you. I have this script as a post-connect hook for any untrusted networks I connect to (wicd is a nice network manager for adding hooks). Later, if you want your traffic to go over the clear again, you can use this script:

if [[ $EUID -ne 0 ]]; then
	echo "This script must be run as root" 1>&2
	exit 1

iptables -t filter --flush
iptables -t filter -X MYVPN

Using the android browser with tor or any socks proxy & privoxy

Update: If all  you’re looking to do is use TOR with android, please use this tutorial.  The below information is out of date for such uses.


  1. A jailbroken android install.
  2. Debian Armel on android.
  3. SSHD running in the chrooted debian environment.

Want to browse the web anonymously with your android device, without t-mobile recording your every move? Look no further.

Few are aware that the default android browser actually allows you to use an http proxy to connect to the web. It is a rather obscure setting to trigger, and there are no provisions for you to connect through a socks proxy, such as an ssh tunnel or the tor network. Luckily, privoxy handles all this for us. Privoxy is an http proxy that is able to forward http requests through the encrypted socks tunnel, and out to its intended recipient. In this tutorial, I will show you how to set your android browser to use privoxy, and how to configure privoxy to forward to a socks proxy.

Lets jump right in.

Using connectbot (available from the android market), ssh into your chrooted debian on localhost. Run:

apt-get install tor

This will fetch both tor and privoxy for you. Now, you’ll need to configure privoxy to forward its http requests through tor, or whatever other tunnel you’ve created through ssh (see my previous post, Append the following line to your /etc/privoxy/config file:

forward-socks5 / localhost:9050 .

Change 9050 to whatever port your tor or ssh tunnel is listening on. Default is 9050 for tor. Now, start tor and privoxy with:

/etc/init.d/tor start
privoxy /etc/privoxy/config

I had to make /dev/null world-writable for tor to stop complaining. You’ll have to run that last part every time you restart your android device. Now on to the annoying part. In terminal emulator (also available from the android market):

sqlite3 /data/data/
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> INSERT INTO system VALUES (99, 'http_proxy', 'localhost:8118');
sqlite> .quit

Change 8118 to whatever port privoxy is listening on, but that port is the default. Now the browser is configured to use privoxy as its http proxy. Privoxy, in turn, is configured to forward connections through tor or the ssh tunnel. This means your done, congratulations!

If you want to stop the browser from using the proxy at any point, in terminal emulator:

sqlite3 /data/data/
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> DELETE FROM system WHERE name='http_proxy';
sqlite> .quit

It’s quite frustrating to go through this process every time you want to switch between proxified and raw browsing, so I suggest installing a second browser such as ‘steel’ for your raw connection, and only using the default browser for proxified connections.

VMWare Workstation in BackTrack {3, 4} Live

BackTrack 4


There’s been a number of situations in the past where, even though I’m perfectly happy running BackTrack as a host operating system, it would nonetheless be sweet to run any number of virtualized guest machines as well. For instance, if exploit code or a tool has been released in Windows (e.g. Ferret/Hamster) but is not yet, or will never be, released for Linux. Or if you want to do research in a virtualized network environment. And of course in general, it’s just a good idea to keep your options open, to sharpen your axe before you go out and chop some wood. My virtualization software of choice is VMWare Workstation, especially the newer versions >= 6.5. I’m not going to go into why I favor VMWare over other options, but suffice to say that they are just the best choice for non-commercial virtualized environments (and, uhm, unity mode is kickass.) So this will be a quick run-through for you to create a customized .lzm file for BackTrack Live with a full and functioning install of VMWare Workstation.


While on the road to creating a customized .lzm file, I was steering for the path of least resistance. Basically, I created a before- and after-install list of files across the entire file system. I then compared the two – the difference being the new files that were created from the install. Copy those files over to a subdirectory structure, and run dir2lzm. Place .lzm file into the appropriate directory, uncompressed at boot time. Done. (Here I have to add a disclaimer: this method probably can be improved upon, since it doesn’t take into account those files which the install did not create, but may have only modified. Perhaps checking modification timestamps would be better.)

Boot up to BackTrack Live, and lets get started:

mkdir ~/vmware-install-tracking/
cd ~/vmware-install-tracking/
find / | sort > before

Now that we have a list of files before the install takes place, it’s time for us to install VMWare. Once you’ve installed it, run it, customize your settings, enter your serial number, etc. Open a few virtual machines. Get your settings to a point where you’re comfortable with them – you won’t be able to modify them again after this point. Close VMWare.

find / | sort > after
diff before after > new_files
cat new_files | egrep -v "^---$" | egrep -v "^[0-9]" | egrep -v "[><] /dev" | egrep -v "[><] /mnt/live" | egrep -v "[><] /proc" | egrep -v "[><] /sys" | egrep -v "[><] /tmp" | egrep -v "[><] /var/run" | egrep -v "[><] /var/lock/subsys/vmware" | egrep -v "[><] /root/vmware-install-tracking/" | cut -d" " -f2 > required_files
echo "/lib/modules/" >> required_files # don't forget those modules!

The directory in the last line will vary based on current kernel version. At this point we have compiled a list of all the files and directories we need for the .lzm file. But we need a script that will parse through required_files and create a file/directory structure from it. I threw the following together in python,


import subprocess, os, sys
if len(sys.argv) is not 3:
        print "Usage: " + sys.argv[0] + " [file list to parse] [destination path]"

dest_path = sys.argv[2]
if dest_path[len(dest_path) - 1] is '/':
        dest_path = dest_path[0:len(dest_path) - 1]

        fp = open(sys.argv[1],"r")
        print "Error: Could not open file for reading!"

x = fp.readline().strip()
file_list = []
dir_list = []
while x:
        if os.path.isdir(x):
        if os.path.isfile(x):
        x = fp.readline().strip()

for dir in dir_list:
        if not os.path.isdir(dest_path + dir):
      'mkdir -p ' + dest_path + dir,shell=True)

for file in file_list:
        file_components = file.split('/')
        containing_dir = '/'.join(file_components[0:len(file_components) - 1])
        if not os.path.isdir(dest_path + containing_dir):
      'mkdir -p ' + dest_path + containing_dir,shell=True)'cp ' + file + ' ' + dest_path + file,shell=True)

Now all thats left to do is call the script, create the .lzm, and put it in the loadtime modules directory. Make sure the destination path in the script has enough storage space.

./ required_files vmware-tmp/
dir2lzm vmware-tmp/ vmware.lzm
mv vmware.lzm /mnt/sdb1/bt4/modules/

Reboot to your live distribution. You now have a working install of VMWare Workstation on your BackTrack Live. Enjoy!

A quick tutorial on getting USB EVDO working on BackTrack {3, 4}

I recently attended Shmoocon 2009, and was surprised to find a few attendees asking me how I got my EVDO Sprint Novatel u727 modem working in BackTrack 3. The process should be the same for BT4, which was just released on Friday at Shmoocon. So for convenience sake, I provide the script I use to connect, and the configuration file for kppp.

if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
eject /dev/sr0 2>/dev/null
sleep 1
modprobe -r usbserial
modprobe usbserial vendor=0x1410 product=0x4100
sleep 1
nohup kppp -c "Sprint Wireless" > /dev/null 2> /dev/null &

A note that the vendor and product codes will probably need to be changed if you’re using a different provider or card. Contact your provider for this information.



Name=Sprint Wireless

DefaultAccount=Sprint Wireless
DefaultModem=EVDO Modem


FlowControl=Hardware [CRTSCTS]
Name=EVDO Modem


Again, this is simply my personal configuration. These should work quite the same for other distributions as well, provided that your card is connected via USB.

BackTrack 3, the EEE 701, and Disk Encryption

Explanation and Advantages

I recently decided to make BackTrack 3 the primary OS on my pearly EEE 701.  Given my EEE’s whopping 4GB of solid-state storage, I decided that rather than installing BackTrack directly onto the SSD, I would instead install the live distro to an 8GB SDHC card I had lying around, and use the remaining internal 4GB SSD as an encrypted /root partition using cryptsetup.  There are a few distinct advantages of such a setup.  Firstly, since the OS is installed as a live distro on a removable device, portability is not sacrificed – I am still able to boot into BackTrack from the same SDHC card plugged into another machine (assuming, of course, that machines BIOS supports booting from SD.)  Secondly, by overriding the default /root partition which is created by root.lzm, any changes I make to /root are persistent, and do not require a recompression of root.lzm.  This allows me to store application settings and files in a much more convenient manner.  Thirdly, since /root is encrypted, saving settings or files containing passwords or other sensitive information is less of a security risk.


To install BackTrack onto the SDHC card, we use the same method as a USB install.  Format the SDHC to contain a vfat filesystem.  Extract the BackTrack 3 USB .iso file into the filesystem mount point, and run boot/  I tried this in Ubuntu 8.10, and had some trouble: the device was recognized as /dev/mmcblk0 and the partition as /dev/mmcblk0p1, a designation that shell script got mixed up on.  Running the script on the EEE’s previous OS, Xubuntu 8.04, the device and partition were recognized as /dev/sda and /dev/sda1, and I encountered no further problems.

Once we boot into BackTrack, we configure and install cryptsetup:

cd ~
tar -xvf cryptsetup-1.0.5.tar.bz2
cd cryptsetup-1.0.5
make install

Next, we create a .lzm file for cryptsetup to ensure that it will be available each time we boot:

mkdir -p usr/include usr/lib usr/man/man8 usr/sbin usr/share/locale/de/LC_MESSAGES
cp /usr/include/libcryptsetup.h usr/include/
cp /usr/lib/cryptsetup usr/lib/
cp /usr/lib/libcryptsetup.* usr/lib/
cp /usr/man/man8/cryptsetup.8 usr/man/man8/
cp /usr/sbin/cryptsetup usr/sbin/
cp /usr/share/locale/de/LC_MESSAGES/ usr/share/locale/de/LC_MESSAGES/
tar -zcvf cryptsetup.tgz usr/
tgz2lzm cryptsetup.tgz cryptsetup.lzm
cp cryptsetup.lzm /mnt/sda1/BT3/modules/ # my mountpoint was /mnt/sda1, yours probably is too

Now we have cryptsetup available in the live environment.  Next step is to format the EEE’s internal SSD.  I set up one primary filesystem, recognized as hdc1.  We’ll be formatting this with cryptsetup using a secure passphrase.

cfdisk # to set up the partition
umount /dev/hdc1
cryptsetup luksFormat /dev/hdc1
cryptsetup luksOpen /dev/hdc1 root_dir
mkfs.ext2 /dev/mapper/root_dir

And now we have an encrypted partition on the SSD.  Next mount it and copy the existing BackTrack /root files.

mkdir /mnt/root_dir
mount /dev/mapper/root_dir /mnt/root_dir
cp -a /root /mnt/root_dir
mv /mnt/root_dir/root/* /mnt/root_dir/root/.* /mnt/root_dir/
rmdir /mnt/root_dir/root

And we’re almost done.  We’ll create a script to make it easy to mount our /root every time we boot.  Create a file in /root/root/ with the following contents:

cryptsetup luksOpen /dev/hdc1 root_dir
mount /dev/mapper/root_dir /root

Finally, create an .lzm file for the script.

cd ~
tar -zcvf decrypt_root.tgz root/
tgz2lzm decrpyt_root.tgz decrypt_root.lzm
cp decrypt_root.lzm /mnt/sda1/BT3/modules/

And we’re finished.  If all goes well, when you restart your machine you will have this script in your /root directory, and once run it will mount your encrypted SSD partition to /root.  From this point, you can issue a ctrl-alt-backspace and re-login, and startx if you’d like.  Welcome to a world of BackTrack possibilities!