Wednesday, April 15, 2009

Episode #23: Job Control

Hal Says:

Paul's last post left me hankering to talk a little bit more about job control in the Unix shell. Besides, it'll make Ed feel really bad about the Windows command shell, so what's not to like?

The simplest form of job control is to hit "^Z" to suspend a currently running process. Once the process is suspended, you get your command prompt back and can issue other commands. You can also type "bg" to force the suspended process into the background, where it will continue to run:

# tail -f /var/log/httpd/error_log
[... output not shown ...]
^Z
[1]+ Stopped tail -f /var/log/httpd/error_log
# bg
[1]+ tail -f /var/log/httpd/error_log &

Now you can fiddle with your Apache config file, restart the web server, etc. The "tail -f" process is still running in the background and displaying errors as they appear in the log file. I find this very useful if I'm working remotely to resolve problems on my web server. Actually, I could have simply started that "tail" command in the background by putting a "&" at the end of the command line:

# tail -f /var/log/httpd/error_log &
[1] 14050

I often use job control to flip in and out of a superuser shell:

$ /bin/su
Password:
# [... do some stuff as root ...]
# suspend

[1]+ Stopped /bin/su
$ [... do some stuff as a normal user ...]
$ fg
/bin/su
#

Notice that you use "fg" to start a suspended process running again. This sure beats having to keep using "su" and re-enter the root password all the time. Of course, you probably should be using "sudo", but that's a topic for another day.

By the way, you can also use job control to blip in and out of remote SSH sessions too:

[hal@localhost ~]$ ssh remotehost
hal@remotehost's password:
Last login: Sun Apr 5 10:06:26 2009 from ...
[hal@remotehost ~]$
[hal@remotehost ~]$ ~^Z [suspend ssh]

[1]+ Stopped ssh remotehost
[hal@localhost ~]$ fg
ssh remotehost

[hal@remotehost ~]$

Note that the key sequence to suspend an SSH session is "\n~^Z"-- you have to enter the tilde character at the beginning of a line, not while you're in the middle of a command-line. By the way, if you're logged into multiple machines in series, you can use multiple tildes to pick which of the chained SSH sessions you actually want to suspend.

Sometimes you might have multiple jobs suspended at the same time. You can use the "jobs" command to display them, and use the job number displayed in the output to interact with the different jobs:

# jobs
[1] Stopped vi /etc/httpd/conf/httpd.conf
[2]- Stopped vi /etc/httpd/conf.d/ssl.conf
[3]+ Stopped tail -f /var/log/httpd/error_log
# bg %3
[3]+ tail -f /var/log/httpd/error_log &
# fg %1
vi /etc/httpd/conf/httpd.conf
^Z
[1]+ Stopped vi /etc/httpd/conf/httpd.conf
# %2
vi /etc/httpd/conf.d/ssl.conf
^Z
[2]+ Stopped vi /etc/httpd/conf.d/ssl.conf
# fg
vi /etc/httpd/conf.d/ssl.conf

In general you do "[fg|bg] %n" to foreground or background job number "n". However, you can leave off the "fg" if you want because foregrounding a job is the default. If you don't specify a job number after the "fg" or "bg", then the most recently manipulated job number is assumed-- you can see this job with a "+" next to it in the output of the "jobs" command.

Ed Wimpers:

Job control?!? What are you, Hal... just plain cruel? I long for true job control in my cmd.exe. If I want true job control, I just install Cygwin.

But, there are some job control-like things I can do in a pinch on a box without Cygwin.

For example, if I want to start a process in a separate cmd.exe window, I can use the start command. Here, I'll use it to start a separate shell window to search for wmic.exe on the C:\ partition, using the file search capabilities we described in Episode #21:

C:\> start dir /s /b c:\wmic.exe
That pops up a separate Window that will display my results. The window will linger displaying my results after it's done. If I want to start it up minimized, I can run:

C:\> start /MIN dir /s /b c:\wmic.exe

If I want it to start a process in a separate window and then have it disappear when it is done running, I use:

C:\> start cmd.exe /c dir /s /b c:\wmic.exe

Sadly, there's no easy way to get access to standard out of these separately invoked shells windows while they are running, other than to have them dump their output into a file, with "> filename" at the command line invocation.

But now for the tricky part... how can you mimic the & feature of most Linux shells to run something in the background of the current cmd.exe while still dumping their standard output into the current shell's display? We can use the /b option of start to put something in the background, as in:

C:\> start /b dir /s /b c:\wmic.exe

So, we've got &-like behavior! However, it's not really full job control, because I can't pull that job into the foreground, or select one job from a group of backgrounded tasks. But, I can kill my background task, by hitting CTRL-break in the cmd.exe window that spawned it. Also, each time you run "start /b", it will leave an extra cmd.exe process running until you either exit that process (by typing... you guessed it... "exit") or killing it.

To kill "jobs" (if I can call them that) more thoroughly, I usually rely on wmic or taskkill, as defined in Episode #22.

So, there you have it... not quite job control, but an ability to kick things into the background so you can keep your current shell active and get more work done. Oh, and install Cygwin. You'll be glad you did. :)

Paul Says:

I will never forget when I was first learning Linux/UNIX (I actually got my feet wet with Linux/UNIX by using Linux at home, and AIX at work). I was configuring a proxy server, carefully constructing each command line switch and running the command. I'd hit ^Z to put the command in the background and wonder why my proxy server wasn't listening. I had forgotten to put the & after the command, so it truly did "suspend" the command. I never made that mistake again :)

I would also like to quickly highlight the nohup command. I often use this when I run a command that will take a long time and want to go back and check its output:

$ nohup nmap -sS -T4 -iL edswindowsnetwork -oA myscanresults &


Sometimes processes you start while logged into a remote host will SIGHUP when you logoff, and nohup can prevent that.

Monday, April 13, 2009

Episode #22: Death To Processes

Paul Says:

Ever been in the mood to just kill things? This happens to me when I use Windows. There are more interesting ways to kill things in Linux than you think, for example:

# killall top

Sometimes you want to put processes in the background. You can do this by appending "&" after the command, or hitting CTRL-Z and typing "bg" once the command has been started. But what if you try to quit the process and you are ignored? Reboot? (No, that's just if you're running Windows and this happens). You can hit CTRL-Z and then use the kill command as follows:

$ while :; do cat /dev/null; done
^Z
[1]+ Stopped cat /dev/null

The process is stopped, but it's still running:

$ ps waux | grep null
root 77241 0.0 0.0 599780 440 s005 R+ 10:28PM 0:00.00 grep null
root 77238 0.0 0.0 599700 372 s005 S 10:28PM 0:00.00 cat /dev/null

To kill the previous command that was put in the background, do the following:

$ kill %1

[1]+ Stopped cat /dev/null

Now it's not running at all:

$ ps waux | grep null
root 77243 0.0 0.0 599780 388 s005 R+ 10:28PM 0:00.00 grep null
[1]+ Terminated cat /dev/null

Now I will just wait until Hal hands something to me, usually it's something that rhymes with glass.

Hal Says:

Of course, if Paul wanted to kill the process, I'm wondering why he didn't just hit ^C instead of ^Z. Seriously, though, there's all kinds of interesting ways to kill processes in Unix. In addition to the killall command Paul's using, there's also pkill. I actually prefer pkill to killall, because it lets me do things like:

# pkill -P 1 sshd

This command means "kill all sshd processes whose parent process ID is 1", which kills only the master sshd process leaving all of the users on the system still logged in. Or I could kick Paul off the system:

# pkill -u paul

Did you know that you can use lsof to help you kill processes? Check this out:

# umount /home
umount: /home: device is busy
# kill `lsof -t /home`
# umount /home

The "-t" option to lsof tells it just to output the PIDs of the matching processes-- in this case all processes that have files open under /home. Once all of those processes are dead, you can successfully unmount the volume. Note that you're going to have some very unhappy users after this action, but if you absolutely positively have to unmount a file system for some reason...

Another point to mention is that you can kill commands via the top command. Just hit "k" in the window where you're running top and enter the PID you want to kill. This technique is useful for killing a runaway process that's eating all your CPU time. You can also use it to kill processes that are eating tons of memory: hit "O" to pick a different sorting criteria and select "q" to sort by Resident Size. Now you'll see the processes sorted by the "RES" column and it will be easy to pick out and kill the ones eating lots of memory.

Ed Steps up to the Plate:
Killing processes in Windows? Man, we have a lot of options. One of my favorite ways is to use wmic, God's gift to Windows. While you can manipulate many (most?) aspects of Windows using WMIC, here, we'll use it to kill processes by running:

C:\> wmic process where [where_clause] delete
It's the where_clause where we have some real power in fine tuning what we want to kill. To kill a process based on its name (like Paul's killall above), we can run:

C:\> wmic process where name="calc.exe" delete

Here, I've just killed any process named calc.exe, the little Windows calculator.

Would you rather kill something based on its pid number? You could run:

C:\> wmic process where processid="536" delete

You can construct where clauses around all kinds of process attributes, including executablepath, parentprocessid, or even commandline options. To see the attributes exposed via wmic process, run:
C:\> wmic process get /?

You can even write where clauses to match multiple attributes using an "and", putting in some parentheses where appropriate. To mimic Hal's fu about killing a process named sshd with a parent processid of 1, we could run:

C:\> wmic process where (name="sshd" and parentprocessid="1") delete

Of course, on a real Windows box, you likely won't use that specific name and parentprocessid, but you get the idea and can easily adapt it.

In addition to "and", note that "or" is also supported. Plus, you can do substring matching with where clauses that include "like" and "%", as follows:

C:\> wmic process where (name like "%bot.exe") delete
That'll kill any process with a name that ends with bot.exe.

But, there's one important attribute missing from wmic process: the user name! Doh! Thanks for nothing, Microsoft.

But, sometimes you really want to kill all processes running as a given user... Paul sometimes can be a bother when he logs onto a machine, after all. For this, we can rely on the taskkill command. That command allows us to kill processes based on all kinds of things, including processid (specified with /PID [N]) or process name (specificed with /IM [name]). But, taskkill gets really useful with its filtering rules, specified with /FI "[filter]". Let's kill all processes running as user paul:

C:\> taskkill /F /FI "username eq paul"
The /F means to forcefully terminate a process. The taskkill filtering language is very flexible, supporting wildcard strings of *, and offering options for eq (equals), ne (not equals), gt, lt, ge, le for a variety of process attributes. Various attributes we can filter on include status (running or not running), memusage (if you're a memory hog, I'll kill ya!), username (you'd better behave, Paul), modules (if a process has loaded metsrv.dll, the Metasploit Meterpreter, I can kill it! Oh, and if it's a critical system process, I just hosed my machine), services (kill the process inside which a given service runs), and even windowtitle. That's a lot of precision, letting you target your process kills.

Specific filtering syntax is available by running:
C:\> taskkill /?

Friday, April 10, 2009

Episode #21: Finding & Locating Files

Paul Writes In:

I'm one of those messy desktop people. There I said it, I keep a messy desktop with tons of files all over the place (partly due to the fact that when you do <4> in OS X to take a screen grab it puts the file on the desktop). So, it should some as no suprise that I often need help finding files. I don't know how many of you have actually run the find command in OS X (or even Linux), but it can be slow:

# time find / -name msfconsole
real 14m3.648s
user 0m17.783s
sys 2m29.870s

I actually stopped it at around 15 minutes because I couldn't wait that long. There are many factors in the performance equation of the above command, such as the overall speed of the system, how busy the system is when you execute the command, and some even say that find is slower if its checking across different file system types ("/" would also include mounted USB drives). A quicker way to find files is to use the locate command:

$ locate msfconsole | grep -v .svn
/Users/fanboy/metasploit/framework-2.7/msfconsole
/Users/fanboy/metasploit/framework-3.1/msfconsole
/Users/fanboy/metasploit/framework-3.2-release/msfconsole

This command reads from a database (which is generated on a regular basis) that consists of a listing of files on the system. It's MUCH faster:

$ time locate msfconsole
real 0m1.205s
user 0m0.298s
sys 0m0.050s

I'm wondering what Ed's going to do on Windows, unless he's come up with a way to get an animated ASCII search companion dog. :)

Hal Says:

One thing I will note about the locate command is that it's going to do sub-expression matching, whereas "find ... -name ..." will do an exact match against the file name. To see the difference, check out the following two commands:

# find / -name vmware
/etc/vmware
/etc/init.d/vmware
/usr/lib/vmware
/usr/lib/vmware/bin/vmware
/usr/bin/vmware
/var/lib/vmware
/var/lock/subsys/vmware
/var/log/vmware
# locate vmware
/etc/vmware
/etc/init.d/vmware
/etc/pam.d/vmware-authd
/etc/rc2.d/K08vmware
/etc/rc2.d/S19vmware
[... 5000+ addtl lines of output not shown ...]

Also, as Paul notes above, the database used by the locate command is updated regularly via cron. The program that builds the database is updatedb, and you can run this by hand if you want to index and search your current file system image, not the image from last night.

I was curious whether doing a find from the root was faster than running updatedb followed by locate. Note that before running the timing tests below, I did a "find / -name vmware" to force everything into the file cache on my machine. Then I ran:

# time find / -name vmware >/dev/null
real 0m1.223s
user 0m0.512s
sys 0m0.684s

# time updatedb
real 0m0.263s
user 0m0.128s
sys 0m0.132s

# time locate vmware >/dev/null
real 0m0.314s
user 0m0.292s
sys 0m0.016s

It's interesting to me that updatedb+locate is twice as fast as doing the find. I guess this shouldn't really be that surprising, since find is going to end up calling stat(2) on every file whereas updatedb just has to collect file names.

Ed Kicks in Some Windows Stuff:

In Windows, the dir command is often used to search for files with a given name. There are a variety of ways to do this. One of the most obvious but less efficient ways to do this involves running dir recursively (/s) scraping through its results with the find or findstr command to look for what we want. I'll use the findstr command here, because it gives us more extensibility if we want to match on regex:

C:\> dir /b /s c:\ | findstr /i vmware
There are a couple of things here that may not be intuitive. First off, what's with the /b? This indicates that we want the bare form of output, which will omit the extra stuff dir adds to a directory listing, including the volume name, number of files in a directory, free bytes, etc. But, when used with the /s option to recurse subdirectories, /b takes on an additional meaning. It tells dir to show full paths to files, which is what we really want to see to know the file's location. Try running the command without /b, and you'll see that it doesn't show what we want. The /b makes it show what we want: the full path to the file so we know its location. Oh, and the /i makes findstr case insensitive.

But, you know, dumping all of the directory and file names on standard out and then scraping through them with findstr is incredibly inefficient. There is a better way, more analogous to the "find / -name" feature Paul and Hal use above:

C:\> dir /b /s c:\*vmware*

This command seems to imply that it will simply look inside of the c:\ directory itself for vmware, doesn't it? But, it will actually recurse that directory looking for matching names because of the /s. And, when it finds one, it will then display its full path because of the /b. I put *vmware* here to make this look for any file that has the string vmware in its name so that its functionality matches what we had earlier. If you omit the *'s, you'll only see files and directories whose name exactly matches vmware. This approach is significantly faster than piping things through the findstr command. Also note that it is automatically case insensitive, because, well, that's the way that dir rolls.

How much faster? I'm going to use Cygwin so I can get the time command for comparison. The $ prompt you see below is from Cygwin running on my XP box:

$ time cmd.exe /c "dir /s /b C:\ | findstr /i vmware > nul"

real 0m10.672s
user 0m0.015s
sys 0m0.015s

Now, let's try the other approach:

$ time cmd.exe /c "dir /s /b C:\*vmware* > nul"
real 0m6.484s
user 0m0.015s
sys 0m0.031s

It takes about half the time doing it this more efficient way. Oh, and note how I'm using the Cygwin time command here. I use time to invoke a cmd.exe with the /c option, which will make cmd.exe run a command for me and then go away when the command is done. Cygwin's time command will then show me how long the command took. I use time to invoke a cmd.exe /c rather than directly invoking a dir so that I can rely on the dir command built-into cmd.exe instead of running the dir command included in Cygwin.

OK... so we have a more efficient way of finding files than simply scraping through standard output of dir. But, what about an analogous construct to the locate command that Hal and Paul talk about above? Well, Windows 2000 and later include the the Indexing Service, designed to make searching for files more efficient by creating an index. You can invoke this service at the command line by running:

C:\> sc start cisvc

Windows will then dutifully index your hard drive, making searches faster. What kind of searches? Well, let's see what it does for our searches using dir:

$ time cmd.exe /c "dir /s /b C:\*vmware* > nul"
real 0m6.312s
user 0m0.015s
sys 0m0.046s

Uh-oh... The Windows indexing service doesn't help the dir command, whether used this way or in combination with the find command. Sorry, but dir doesn't consult the index, and instead just looks through the complete file system directory every time. But, the indexing service does improve the performance of the Start-->Search GUI based search. You can control which directories are included in the index via a GUI tool that can be accessed by running:

C:\> ciadv.msc
Also, in that GUI, if you select System-->Query the Catalog, you get a nice GUI form for entering a query that relies on the indexing service. I haven't found a built-in cmd.exe feature for searching directories faster using the indexing service, but there is an API for writing your own tools in VBS or other languages for quering the index. Microsoft describes that API and the indexing service in more detail here.

Wednesday, April 8, 2009

Episode #20: Ping Beep of Death

Ed says:

Paul threw down a challenge to Hal and me in e-mail just a few minutes ago:

"I want a string of commands that will ping a host and for each time a packet is missing (i.e. timeout) send a beep to the console."


The solution to this one in Windows includes some useful constructs, so let's have at it with this fu:

C:\> for /L %i in (1,0,2) do @(ping -n 1 HostIPaddr || echo ^G)
& ping -n 2 127.0.0.1
This command starts out with a FOR /L loop, set with an iterator variable of %i that I won't use, counting from 1 to 2 in steps of 0. In other words, it'll run forever, or until someone kills it. At each iteration through the loop, I turn off command echo (@), and ping the target host one time (ping -n 1). Pretty pedestrian so far.

Now we get to some interesting stuff. If the ping command fails to get a response, I'll have it run the echo command to make a beep. As we've seen in earlier episodes, we can use cmd1 && cmd2 to make the shell run cmd2 only if cmd1 succeeded. Likewise, we can use cmd1 || cmd2 to make the system run cmd2 only if cmd1 fails. This is more efficient than checking the %errorlevel% environment variable with an IF statement, but I digress. Of course, as always cmd1 & cmd2 means run cmd2 regardless of the success or failure of cmd1.

If the ping fails, we have "echo ^G". Note that it looks like I typed Shift-6 G, but I didn't. That little ^G is created by holding down the CTRL key and hitting G. It's just displayed like ^G. It's how we can make the echo command ring the system beep. After this, I simply introduce a 1-second delay by pinging localhost twice (first ping instantly, second ping one second later). So, there you have it.

BTW, if you want prettier output from this, you can dump various Standard Output to nul as follows:

C:\> for /L %i in (1,0,2) do @(ping -n 1 HostIPaddr > nul || echo ^G)
& ping -n 2 127.0.0.1 > nul


Hal Chimes In:

We can easily do the Unix equivalent of what Ed's doing in the Windows command shell:

$ while :; do ping -c 1 -w 1 HostIPaddr >/dev/null || echo -e \\a; sleep 2; done

Note the "echo -e \\a" syntax for emitting an "alert" (^G or BEL).

However, in its default mode the standard Unix ping command will run continuously. So it seems like you should be able to get some joy just by piping the output of ping into another command, without having to resort to a loop. Mr. Bucket had the clever idea of filtering the output of ping through awk and then sending the resulting misses to the "say" command on his OS X machine (because talking is much cooler than beeping):

$ ping x.x.x.x 2>&1 | awk -F: '/sendto:/ {print $3}' | say

The above command seems like it should work, but it wasn't bringing the noise. A confused Mr. Bucket emailed me for clarification.

What's happening here is that Mr. Bucket's clever idea is getting kneecapped by the standard buffering behavior of shell pipes. If you run that first ping command by itself and have the output go to your terminal, then you see the results of each ICMP packet, one line at a time. However, the minute you pipe the output of the ping command into another command, the shell switches to page buffering the output between the two commands. In other words, the awk command gets the output of the ping command in 4096 byte chunks, and the output of awk has to fill up 4096 bytes before the "say" command gets anything. If Mr. Bucket had let the command run long enough, eventually he would have gotten a burst of talking from the "say" command, but only long after the actual failed ping events.

Unfortunately, there is no magic shell variable you can set to fix this problem globally. However, applications in the Unix environment can force their output to be unbuffered if the application developer chooses to add this functionality to their program. Sometimes the software does this automatically-- the tee program in most Unix environments unbuffers its output by default (using setvbuf(3)). Sometimes you need to add an extra command-line option, like with the awk command on my Ubuntu system (which is really mawk):

$ ping x.x.x.x 2>&1 | awk -W interactive -F: '/sendto:/ {print $3}' | ...

That'll get you line-buffered output that you can pipe into another program. The GNU grep utility has the "--line-buffered" option, which is similar.

Paul Chimes In:

I have to confess, I really thought this would be something pretty easy. The page buffering thing threw me through a loop too (pun intended). I also discovered a much better way to do this in OS X:

$ ping -A 192.168.1.1


This command will beep (ASCII 0x07) "when no packet is received before the next packet is transmitted." so says the man pages. This is exactly what I was looking for to monitor hosts while I scan them with various security tools (like Nessus) and alert me if they crash or become unresponsive.

Monday, April 6, 2009

Episode #19 - Clearing The Contents Of A File

Paul Writes In:

Ever want to delete just the contents of a file, but not the file itself? There are many ways to do this on UNIX/Linux systems, here's one:

$ cat /dev/null > my_file

Probably the most common usage for this is to clean out a log file. I'm certain Hal will have several suggestions, and Ed will have to (again!) be creative without /dev/null in Windows :)

Hal Says:

I generally "set -o noclobber" in my .bashrc because I don't want to accidentally overwrite files with output redirection (and you should too, Paul!). Thus, Paul's command line above is not as useful for me. My idiom is usually just:

$ cp /dev/null my_file

It's also two characters (not counting extraneous spaces) shorter than Paul's version. Go me!

Ed Responds:

While we don't have /dev/null in Windows, we do have the very handy nul, the rough equivalent of /dev/null. I use it rather often to make things go away, usually directing unwanted Standard Out to it. But, to delete the contents of a file, you could use nul like this:

C:\> type nul > my_file

This will keep the file's creation time (viewable with "dir /tc my_file", as we discussed in Episode 11), while making the contents of the file empty.

Alternatively, we can remove the contents of a file in Windows using Hal's approach of copying with:

C:\> copy nul my_file

Oh, and my copy command is four less characters less to type than Hal's fu above, a whopping six characters less than Paul's. Efficiency, thy name is Windows. Go Windows! Now there's something that you don't hear often in a battle of the command shells!

BTW, thanks for the "set -o noclobber" tip, Hal. Very useful! Almost always in my SANS 560 class, attendees accidentally hose their systems by flipping a <> and destroying /etc/passwd or /etc/shadow on their Linux boxen, even though I warn them about it. I'll set noclobber by default for their shells, which should prevent that from happening, but will introduce frustrations when their bad command doesn't work. I guess the frustration is better than hosing the system.

And, the hits just keep on coming...

Friday, April 3, 2009

Episode #18 - Clearing The System DNS Lookup Cache

Paul Says:

In an effort to provide some quick command like tips (we lovingly call them "quickies") I wanted to share the OS X command to clear the local client's lookup cache:

# dscacheutil -flushcache

This is especially useful if you are doing some DNS changes and don't want the local client's cache to obscure your results.

Hal Says:

Repeat after me: "Client side caches are a lousy idea that can only lead to confusion and suffering. If your naming services are so unreliable that you can't live without a client cache, then it's time to get a new naming service."

The Name Services Caching Daemon ("nscd") is the client-side cache for Solaris and Linux systems. Generally I just turn it off on all of my machines, but if you leave it running you can flush the cache with a command like:

# nscd -i hosts

"passwd" and "group" are also valid arguments instead of "hosts", but it's the local DNS cache that generally gets you into the most trouble.

Ed Cleans Up:


Per Hal's request to repeat after him: "Client side caches are a lousy idea that can only lead to confusion and suffering. If your naming services are so unreliable that you can't live without a client cache, then it's time to get a new naming service."

So, if it's got confusion and suffering, you better believe its an integral component of the architecture of Windows. :)

In all seriousness, while Hal might not like it, I find the DNS cache in Windows hugely useful when conducting investigations, so I can see what has been recently resolved on the box. You can dump the DNS cache of a Windows machine with:

C:\> ipconfig /displaydns

The output will include all cached records, showing their remaining TTL in seconds. Run it every one second, and you can see the times decrement. If you happen to know the original TTL, you can get a feel for how long the record has been in the cache (realize, however, that the original TTL may not have been the value set by the authoritative server, because the machine may have gotten it from some intermediate server where it was cached for a while). Anyway, that's some useful information in an investigation, so you can piece together a timeline of when certain actions were taken.

But, the challenge at hand deals with clearing the DNS cache, which we can do with:

C:\> ipconfig /flushdns

My buddy Lara Corcoran refers to some things as "easy peasy". When I first heard her use this phrase, I found it annoying. But, it's addictive, and saying it reminds me of Lara, which always makes me smile.

Hal Puts in the Last Word:


Actually, Ed, instead of using the local DNS cache as a proxy to figure out what hosts the local machine has been communicating with recently, in Linux we can actually dump out the kernel's internal routing cache:

$ netstat -rCn
Kernel IP routing cache
Source Destination Gateway Flags MSS Window irtt Iface
68.238.96.36 67.18.149.10 67.18.149.10 l 0 0 0 lo
212.118.133.101 67.18.149.10 67.18.149.10 l 0 0 0 lo
72.95.246.206 67.18.149.10 67.18.149.10 l 0 0 0 lo
69.158.249.37 67.18.149.10 67.18.149.10 l 0 0 0 lo
67.18.149.10 68.105.28.76 67.18.149.9 1500 0 0 eth0
67.18.149.10 200.149.55.136 67.18.149.9 1500 0 0 eth0
67.18.149.10 93.190.136.10 67.18.149.9 1500 0 0 eth0
67.18.149.10 62.253.181.25 67.18.149.9 1500 0 0 eth0
[...]

What you see are a bunch of host routes corresponding to the machines that this host has been communicating with recently. This is incredibly useful information in a forensic investigation.

Paul Chiming In One More Time:

To view the DNS cache table in OS X, you can use the following command:

# dscacheutil -cachedump -entries Host


Which will output something like:

DirectoryService Cache Overview:
AAAA Queries - Enabled
Buckets Used - 40
Cache Size - 10

Entry count by category:
Host - 8
User - 2

Cache entries (ordered as stored in the cache):

Category Best Before Last Access Hits Refs TTL Neg DS Node
---------- ------------------ ------------------ -------- ------ -------- ----- ---------
Host 03/30/09 16:39:19 03/30/09 16:39:12 3 4 9
Key: h_name:twitter.com ipv4:1 ipv6:1
Key: h_name:twitter.com ipv6:1
Key: h_name:twitter.com ipv4:1


This allows you to see which hosts are in the cache when the command was run. I could not find a way to do the equivalent of a "netstat -C" in OS X.

Wednesday, April 1, 2009

We Interrupt This Blog...


Hal Comments:

Somehow this seems like an appropriate forum to make an announcement that I've been in "stealth mode" about for some time now. But apparently details have leaked to the press and we're expecting some wild stories to be posted later today, and so I thought I'd blog about this personally, just to reduce the amount of misinformation that's going to be put out there.

For almost a year now, I've been working for Microsoft, helping to architect the next generation Windows operating system (the one that's coming after Windows 7). No one was more surprised than I that I accepted this position, but when I heard about the plans for the new operating system, I knew it was an offer I just couldn't refuse.

You see, Microsoft is only too keenly aware of the environmental impact caused by users having to buy newer, faster, more power-hungry machines just to handle the increasing computing requirements of each new release of Windows (to say nothing of the impact of all of the old, discarded equipment being introduced into landfills around the planet). So as part of a company-wide initiative to be more "green", the decision was made to remove the Windows GUI and instead go with a command-line only interface in the next release of Windows (codenamed WinDOS, btw). Here's a snapshot of Internet Explorer 8 in command-line mode:


This is a very exciting time for us here at Microsoft! Bill Gates was telling the team just the other day how happy he was that Microsoft was "returning to his original vision of MS-DOS".

Of course, I haven't completely abandoned my Unix roots. In fact, my primary area of responsibility in the WinDOS project is re-implementing some of the more useful features of the Unix command shell, pursuant to Microsoft's well-documented "embrace and extend" policy. Most recently, I've been working on an upgraded version of the popular "rear" command. Never heard of "rear"? Just type "man rear" into any Unix/Linux command shell you happen to have handy.

Working with the brilliant minds at Microsoft, helping to create a convergence between Windows and Unix, and saving the planet at the same time? Who wouldn't love this job? Wish me luck, folks!

Ed Responds:
Wow! Hal... this is huge. I remember your stint at Google a couple years back. You seem to have a thing for the siren song of large companies bent on world domination. It must somehow fulfill an obscure longing you have. Just out of curiosity, were you bottle fed as an infant?

Anyway, given that Microsoft hired both Crispin Cowan and Bill Arbaugh last year, I guess this makes it a trifecta for them. Go Microsoft!

So, my friend, here's to you and Microsoft. I wish you the best in your new digs, and I am very much looking forward to seeing your influence permeate the future evolution of Windows!

Paul Responds:

Congrats to Hal and Microsoft! Finally they have seen the light and hired the best when it comes to 1980's style user interfaces (which are, btw, the interfaces of the future). This is a huge win for the community, I can't wait to install the new version of WinDOS on my old 486 laptop!