RSSAuthor Archive for admin

I am the I.T. Director and Information Security Officer for an ecommerce / production company. I'm also a graphic designer; musician; martial arts instructor; pilot and all around creative genius.

10 Amazing Life Lessons You Can Learn From Albert Einstein

Albert Einstein has long been considered a genius by the masses. He was a theoretical physicist, philosopher, author, and is perhaps the most influential scientists to ever live.

Einstein has made great contributions to the scientific world, including the theory of relativity, the founding of relativistic cosmology, the prediction of the deflection of light by gravity, the quantum theory of atomic motion in solids, the zero-point energy concept, and the quantum theory of a monatomic gas which predicted Bose–Einstein condensation, to name a few of his scientific contributions.

Einstein received the 1921 Nobel Prize in Physics “for his services to Theoretical Physics, and especially for his discovery of the law of the photoelectric effect.”

He’s published more than 300 scientific works and over 150 non-scientific works. Einstein is considered the father of modern physics and is probably the most successful scientist there ever was.

10 Amazing Lessons from Albert Einstein:

1. Follow Your Curiosity

“I have no special talent. I am only passionately curious.”

What piques your curiosity? I am curious as to what causes one person to succeed while another person fails; this is why I’ve spent years studying success. What are you most curious about? The pursuit of your curiosity is the secret to your success.

2. Perseverance is Priceless

“It's not that I'm so smart; it's just that I stay with problems longer.”

Through perseverance the turtle reached the ark. Are you willing to persevere until you get to your intended destination? They say the entire value of the postage stamp consist in its ability to stick to something until it gets there. Be like the postage stamp; finish the race that you’ve started!

3. Focus on the Present

“Any man who can drive safely while kissing a pretty girl is simply not giving the kiss the attention it deserves.”

My father always says you cannot ride two horses at the same time. I like to say, you can do anything, but not everything. Learn to be present where you are; give your all to whatever you’re currently doing.

Focused energy is power, and it’s the difference between success and failure.

4. The Imagination is Powerful

“Imagination is everything. It is the preview of life's coming attractions. Imagination is more important than knowledge.”

Are you using your imagination daily? Einstein said the imagination is more important than knowledge! Your imagination pre-plays your future. Einstein went on to say, “The true sign of intelligence is not knowledge, but imagination.” Are you exercising your “imagination muscles” daily, don’t let something as powerful as your imagination lie dormant.

5. Make Mistakes

“A person who never made a mistake never tried anything new.”

Never be afraid of making a mistake. A mistake is not a failure. Mistakes can make you better, smarter and faster, if you utilize them properly. Discover the power of making mistakes. I’ve said this before, and I’ll say it again, if you want to succeed, triple the amount of mistakes that you make.

6. Live in the Moment

“I never think of the future - it comes soon enough.”

The only way to properly address your future is to be as present as possible “in the present.”

You cannot “presently” change yesterday or tomorrow, so it’s of supreme importance that you dedicate all of your efforts to “right now.” It’s the only time that matters, it’s the only time there is.

7. Create Value

“Strive not to be a success, but rather to be of value."

Don’t waste your time trying to be successful, spend your time creating value. If you’re valuable, then you will attract success.

Discover the talents and gifts that you possess, learn how to offer those talents and gifts in a way that most benefits others.

Labor to be valuable and success will chase you down.

8. Don’t Expect Different Results

“Insanity: doing the same thing over and over again and expecting different results.”

You can’t keep doing the same thing everyday and expect different results. In other words, you can’t keep doing the same workout routine and expect to look differently. In order for your life to change, you must change, to the degree that you change your actions and your thinking is to the degree that your life will change.

9. Knowledge Comes From Experience

“Information is not knowledge. The only source of knowledge is experience.”

Knowledge comes from experience. You can discuss a task, but discussion will only give you a philosophical understanding of it; you must experience the task first hand to “know it.” What’s the lesson? Get experience! Don’t spend your time hiding behind speculative information, go out there and do it, and you will have gained priceless knowledge.

10. Learn the Rules and Then Play Better

“You have to learn the rules of the game. And then you have to play better than anyone else.”

To put it all in simple terms, there are two things that you must do. The first thing you must do is to learn the rules of the game that you’re playing. It doesn’t sound exciting, but it’s vital. Secondly, you must commit to play the game better than anyone else. If you can do these two things, success will be yours!

Thank you for reading and be sure to pass this article along!

Coincidence & Randomness

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Ed Uses His Rod Serling Voice:

You unlock this door with the key of imagination. Beyond it is another dimension – a dimension of sound, a dimension of sight, a dimension of mind. You’re moving into a land of both shadow and substance, of things and ideas. You’ve just crossed over into… the Command Line Zone.

It’s funny how these little coincidences happen, almost as though they are stitched into the very fabric of the universe. Two completely unrelated people working on very different projects happen to identify a command line need at about exactly the same time. Each, unknowing of the other, sends in a question to the unassuming band of shell freaks at the CLKF blog.

The scene opens with an e-mail from Éireann, a kind reader who wanted to run a command at some random time within the next 24 hours. The command in question should send an e-mail blast to a group of recipients around the globe.

Less than 48 hours earlier, a friend of the blog had submitted an eerily similar question. In designing a Capture the Flag game, he needed to run a script every hour, but at a random time within that hour.

Was this a mere coincidence? Was it a sinister plot for world domination? Or, has someone’s imagination and nostalgia for 1960’s TV shows just gotten out of hand?

Our story gets even weirder. The CtF game master was surprised because his command to generate random timing fu was simply not behaving randomly enough. He had tried:

C:\> for /L %i in (1,0,2) do @cmd.exe /v:on /c for /F %f in ('set /a !random!%3600') do
@echo %f & ping -n 3 127.0.0.1 >nul
2905
2912
2918
2925
2932
2941

As a first step in creating the random delay timer, the CtF designer was trying to spit out a stream of pseudo-random numbers by invoking a FOR loop to run continuously, launching a cmd.exe to activate delayed environment variable expansion, kicking off a FOR /F loop that used a little shell math to create a random number between 0 and 3599 by applying modulo arithmetic (!random!%3600), and then introducing a 2-second delay by pinging localhost thrice. But those numbers on the output look decidely unrandom.

When I received his e-mail, I had a pretty good suspicion of what the culprit was. My friend had been stomping on his own entropy by launching the cmd.exe to turn on delayed variable expansion within his FOR /L loop for continuous execution. And, it gets even worse. To perform the “set /a” command inside of the single quotes (‘), a FOR /F loop will launch another cmd.exe. So, each iteration of the FOR /F loop launches a cmd.exe, which uses a FOR /F loop to launch yet another cmd.exe to process the ’set /a’ command. It’s a double entropy stomper. But, even launching one cmd.exe can cause problems for your randomness. Consider this simplified example:

C:\> for /L %i in (1,0,2) do @cmd.exe /v:on /c set /a !random!%10
66666699999999999999999999999999999999333333333333333333333333333333336666666666
66666666666666666666669999999999999999999999999999999933333333333333333333333333
33333366666666666666666666666666666666999999999999999999999999999999992222

Those digits between one and ten change only every second or so. I immediately set out to create a fix. We’ve got to swap our invocation of delayed variable expansion (cmd.exe /v:on /c) and our FOR /L loop to make it run continuously. Otherwise, the constant launching of a shell dips back into our same old weak entropy pool each time it is invoked, which doesn’t change fast enough on a Windows machine to give us satisfactory results. Let’s check out the swap:

C:\> cmd.exe /v:on /c for /L %i in (1,0,2) do @set /a !random!%10
53443765137306108347857462987392509842433990177450065079938404591379539993991668
15958655065543980786504403929102313264126903224822440676335255418412842151910989

This result is much nicer, and significantly faster as we don’t have to continuously launch a shell for each random number.

Now, let’s apply it to the task at hand… running a script once per hour, at a random interval sometime in that hour. First off, we’ll create a little dummy script, which will simply print out the date and time it was executed. Simply append to this script any other command(s) you’d want to run:

C:\> echo @echo ^%date^% ^%time^%> script.bat

Instead of running the script at a random time within each hour, I’m going to speed things up by running it at a random time each minute. The following command achieves our goal:

C:\> cmd.exe /v:on /c "for /L %i in (1,0,2) do @(set /a delay=!random!%60+1+1>nul
& set /a finish=60+1+1-!delay!>nul & echo script to run after !delay! pings
and then pause for !finish! pings & ping -n !delay! 127.0.0.1>nul &
script.bat & ping -n !finish! 127.0.0.1>nul)"
script to run after 21 pings and then pause for 41 pings
Fri 02/26/2010 13:42:21.89
script to run after 20 pings and then pause for 42 pings
Fri 02/26/2010 13:43:21.04
script to run after 28 pings and then pause for 34 pings
Fri 02/26/2010 13:44:29.20
script to run after 51 pings and then pause for 11 pings
Fri 02/26/2010 13:45:52.38

If you want to run the script randomly timed every hour, replace the two occurrences of 60 above with 3600 (60 seconds times 60 minutes). If you want to run at a random time once every 24 hour interval, replace 60 with 86400 (60 sec times 60 min times 24 hours).

So, what is this monstrosity of applied technology doing? First, we invoke cmd.exe to perform delayed variable expansion (cmd.exe /v:on /c) so we can let our variables change value as the command runs. Then, we start a FOR /L loop to run forever, counting between 1 and 2 in steps of zero. At each iteration of the loop, we turn off display of command (@). That’s routine. Here’s where things get more interesting.

We now use the set /a command to do some math, having it set the variable called “delay” to a random number modulo 60 (!random!%60). That’ll give us a nice number between 0 and 59. But, why do I add 1 to it twice? Well, I’m going to later introduce delays using pings. To introduce an N second delay, I have to ping myself N+1 times. And, I’ll introduce two delays: one before the script runs, and one after the script runs. See, we don’t want to just run the command multiple times with a random delay between each run. If we did that, we might have the command run 18 times in one minute, just because our randomness returned a bunch of small numbers. Instead, we want it to run 18 times in 18 minutes, but at a random time within each minute. Therefore, we’ll need to have a delay up front, followed by the script execution, followed by a delay for the rest of that minute. Each of those two delays will be implemented with pings, which each consuming 0 seconds for their first ping. I have to add one twice here to account for the two sets of pings gobbling up their first ping in almost no time.

After calculating my delay, I then calculate a finish number of pings by taking 60, adding 2, and subtracting !delay!. With all my math done, I simply display the number of pings before the script will run and after it runs. Finally, I then run the first pings, then the script, and the remaining pings. After all that, we loop.

You can put pretty much anything you want in script.bat. Unfortunately, sending e-mail at the command line is something that cmd.exe itself is not capable of doing using only built-in tools. You can run “start mailto:EmailAddress” at the command line, which invokes Outlook Express to send e-mail. But, it would require a user to hit the Send button. There are other tools for sending e-mail at the command line that rely on third party commands, described here.

Our random timing script invoker above is ugly, complex, but very effective. Such are the lessons in for cmd.exe in… the Command Line Zone.

Hal has all the time in the world

I can do a loop that’s essentially the bash version of Ed’s idea:

$ while :; do delay=$(($RANDOM % 60)); sleep $delay; date; sleep $((60 - $delay)); done
Tue Mar  2 11:07:55 PST 2010
Tue Mar  2 11:08:02 PST 2010
Tue Mar  2 11:09:43 PST 2010
...

Here I’m setting $delay to a random value between 0 and 59 then sleeping for that amount of time. I’m calling the date command in the middle of the loop so that you can more easily see the random time intervals, but you could substitute any commands here that you want. Finally, we sleep for the remainder of the time interval and then start the loop all over again.

This loop works fine for one-minute intervals and even one-hour intervals, but $RANDOM only ranges from 0 to 32767, so I’d have to do two calculations to cover an entire day– pick a random hour between 0 and 24 for example, then pick a random time within that hour. Alternatively, we could just use the trick from Episode 58 to generate a larger random number:

while :; do
delay=$((`head /dev/urandom | tr -dc 0-9 | sed s/^0*// | cut -c1-8` % 86400))
sleep $delay
/path/to/your/command
sleep $((86400 - $delay))
done

I’ve modified the solution from Episode 58 slightly, including a sed command to strip off any leading zeroes from the result. Otherwise the random value we calculate may be interpreted as an octal number, which causes problems if there are any 8’s or 9’s elsewhere in the number. Let me demonstrate what I mean with a quick example using a hard-coded value that has a leading zero:

$ delay=$((09999999 % 86400))
bash: 09999999: value too great for base (error token is "09999999")

Actually, aside from the type of random loops we’re doing here, this kind of random delay is also useful for scheduled tasks like cron jobs. For example, in larger enterprises you might have hundreds or thousands of machines that all need to do the same task at a regular interval. Often this task involves accessing some central server– grabbing a config file or downloading virus updates for example. If a thousand machines all hit the server at exactly the same moment, you’ve got a big problem. So staggering the start times of these jobs across your enterprise by introducing a random delay is helpful. You could create a little shell script that just sleeps for a random time and then introduce it at the front of all your cron jobs like so:

0 * * * * /usr/local/bin/randsleeper; /path/to/regular/cronjob

The cron job will fire every hour, the “randsleeper” script will sleep for part of that time, and then your regular cron job will execute. This is a well-known old sysadmin trick.

Well that’s my weekly effort to serve man. Let’s see what Tim’s got cooking.

Tim[e] is on my side

My loop is pretty much a clone of Hal’s, and the explanation is very similar:

PS C:\> while (1) { $delay = (New-Object Random).next(1,60); Start-Sleep $delay;
Get-Date; Start-Sleep (60 - $delay) }
Saturday, February 27, 2010 9:55:45 PM
Saturday, February 27, 2010 9:56:47 PM
Saturday, February 27, 2010 9:58:05 PM
...

The variable $delay is set to a random number between 1 and 59, and unlike Ed, we have good entropy. To get a random number we need to use the .Net System.Random class. However, there is a bit of goofyness, the lower bound is inclusive, while the upper bound is exclusive. So if we wanted to get a random number between 1 and 6, like on a die, we would use a lower bound of 1 and an upper bound of 7. Why did they do it that way? I don’t know, and I been asking that since the beginning of the Microsoft shells.

Once we have the delay, we sleep for that amount of time. After waking up from our nap, the date and time are displayed. Of course any command (or commands) can be used. Finally, we sleep for the balance of the minute. The infinite While loop ensures that the process starts over again.

To change our loop to execute a command every hour, all that needs to be done is change 60 to 3600. If we wanted it to execute daily we would change the upper bound to 86400, and we don’t have Hal’s problem with big numbers. We can use really big numbers, up to 2,147,483,647. If the command was to run after 2.1 billion seconds it would be the year 2078, long after all the computers we are using are dead.

Finally, Ed mentioned sending an email at the random interval. Sending email from the Windows shells is a pain. It isn’t possible with cmd, but we can do it with PowerShell by using the .Net framework. The long version of the commands looks like this.

PS C:\> $emailFrom = "tim@domain.com"
PS C:\> $emailTo = "ed@domain.com"
PS C:\> $subject = "Mail"
PS C:\> $body = "How's it going?"
PS C:\> $smtpServer = "smtp.domain.com"
PS C:\> $smtp = new-object Net.Mail.SmtpClient($smtpServer)
PS C:\> $smtp.Send($emailFrom, $emailTo, $subject, $body)

We can condense it to one line for use in our fu.

PS C:\> (New-object Net.Mail.SmtpClient("smtp.domain.com")).Send("tim@domain.com",
"ed@domain.com", "Mail", "How's it going?")

If we wanted to send an email once every hour at a random time the command here is how we would do it.

PS C:\> while (1) { $delay = (New-Object Random).next(1,60); Start-Sleep $delay;
(New-object Net.Mail.SmtpClient("smtp.domain.com")).Send("tim@domain.com",
"ed@domain.com", "Mail", "How's it going?"); Start-Sleep (60 - $delay) }

That wraps it up for now, see you next week. Start-Sleep 604800

Social Engineer Toolkit – Website Attack How To

I found this while wandering about the web. Be careful – it works!

Social Engineering Toolkit – Website Attack How To

As with all things “hack” – be careful how you proceed. The opportunity to hack is always there – the ability to show constraint and remain ethical is a necessity! ‘Nuff said.

Enjoy.

Fixing the Filenames

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Hal Helps Out

A friend of mine contacted me the other day with an interesting problem. She was trying to recover some files from the backup of an old BBS. In particular, she was trying to get at the attachments for various postings.

The attachment files were in a big directory, but the file names unhelpfully used an internal attachment ID number from the BBS. So we had file names like “attachment.43567″. Now my friend also had a text file she extracted from the BBS that mapped attachment IDs to the real file names:

43567 sekrit plans.doc
44211 pizza-costs.xls
...

So the task was to take the file of “attachment ID to file name mappings” and use that to rename the files in the attachments directory to their correct file names.

I thought about it for a minute, and realized the solution was actually pretty straightforward:

$ while read id file; do mv attachment.$id "$file"; done <id-to-filename.txt

The trickiest part of the exercise was dealing with the file names that had spaces in them, like “sekrit plans.doc”. Luckily the format of the input file was “ID filename”, which meant that I could treat everything after the first whitespace as the file name. And this is exactly what the builtin “read” command will do for you: in this case it puts the first whitespace delimited token into the $id variable and then jams whatever is left over into the last “$file” variable. Once I got the right information into $file, it was simply a matter of making sure to quote this variable appropriately in the “mv” command inside the loop.

So there you go– a quick one-liner for me, but a real time-saver for my friend. And possibly a real time-sink for Tim and Ed as they try and figure out how to do this in their shells. Let’s see, shall we?

Ed Frustrates Hal

Sorry, Hal, but this one just isn’t crushing for me. I know that disappoints you, but sometimes (on fairly rare occasions) we don’t have to work too hard to coax little cmd.exe to do what we want. It does take two little tricks, though, but nothing too freakish.

Here’s the fu:

C:\> for /f "tokens=1,*" %i in (id_to_filename.txt) do @copy attachment.%i "%j"

I’m using a FOR /F loop to read the contents of id_to_filename.txt, one line at a time. Default delimiters of FOR /F parsing are spaces and tabs, which will work just fine for us here, so there’s no need to mess with custom delims. I’ve specified custom parsing of “tokens=1,*”, which will make it assign the first column of the file (the integer in Hal’s example) to my first iterator variable (which is %i). Then, the ,* stuff means to assign all of the rest of the line to my second iterator variable, which will be auto-allocated as %j. The ,* stuff is the first trick, which really comes in handy.

Then, in the body of my loop, I turn off display of commands (@) and invoke the copy command to take the contents of attachment.%i and place it into “%j”. The second trick, those quotes around %j, are important in allowing us to handle any spaces in the file name. Note that I’m using copy instead of move here, because I don’t wanna play Ed-Zilla stomping over the city just in case something goes awry (who’s to say that our id_to_filename.txt file will always look like we expect it to?). I guess you could call it the Hipposhellic oath: First do no harm. After we verify that our copy worked like we wanted with a quick dir command, we can always run “del attachment.*”

Whatcha got, Tim?

Tim frustrates most people

Sorry Hal, this isn’t too bad in PowerShell either. There are a few ways we can accomplish this task, but I elected to pick the shortest version, which also happens to be the one that brings up something we haven’t covered before. Here are the long version and short version of the fu. (The short version is identical but uses built in aliases)

PS C:\> Get-Content id-to-filename.txt | ForEach-Object { $id,$file =
$_.Split(" ",2); Rename-Item -Path attachment.$id -NewName $file }

PS C:\> gc id-to-filename.txt | % { $id,$file = $_.Split(" ",2); ren
attachment.$id $file }

The Get-Content cmdlet is used to read the contents of the file, and it is piped into Foreach-Object. Inside the Foreach-Object script block is where the line is split. The first parameter used in the Split method defines the delimiter and the second defines how many items it should be split into.

The only problem, the Split method’s output is multi-line. Here is an illustration:

PS C:\> gc id-to-filename.txt -TotalCount 1 | % { $_.Split(" ",2); }
43567
sekrit plans.doc

We need both portions of the split to do the rename, so here is where we bring up a new little trick. We can assign the output of split into variables. Each line is assigned to a variable, the first variable ($id) is assigned the first line and the second variable ($file) receives the remainder. After we have the Id and the Filename we can easily rename the files.

If we wanted to be a little safer then we could use Copy-Item (alias cp or cpi) instead of Rename-Item (alias ren or rni). Once we confirmed the copy was successful we can delete all the attachment files by using “Remove-Item attachment.*” (alias del, erase, ri, or rm).

A db_autopwn script run from msfconsole

Here’s a handy script I found on the web, written by HD Moore himself. It works like a charm!

$ vim ownitall.rc
db_create /tmp/mynet.db
db_nmap -sS -F -n 192.168.0.0/24 -T5
setg AutoRunScript scraper
db_autopwn -t -e -p -r

$ msfconsole -r ownitall.rc

Have fun with it.

Faster. Higher. Stronger – speeding up tasks

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Tim goes for Gold:

The Olympics are in full swing. The world’s finest athletes are doing everything they can to shave fractions of a second; and not get caught doping. This episode we try to shave off precious seconds from our tasks, and not get caught with our (Irish) coffee at work (again).

We all have those commands that we use regularly, and accessing those commands more quickly would save some time. With PoweShell we can do just that by using Set-Alias.

PS C:\> Set-Alias -Name ss -Value Select-String

The Name and Value paramters are positional, so we don’t have to use the parameter names. This command does the same thing:

PS C:\> Set-Alias ss Select-String

We have created our alias, now how can we use it? If we wanted to search all the files in a directory for the word “test” we had to use this command:

PS C:\> gci | Select-String test

…but now we can use this shorter command:

PS C:\> gci | ss test

The second command is half the length of the first command command. That is a nice efficiency gain.

What if we regularly checked the event log to see the five latest items? Obviously a short command would save us some time, but see what happens when we try to create an alias.

PS C:\> Set-Alias g5 Get-WinEvent -MaxEvents 5
Set-Alias : A parameter cannot be found that matches parameter name 'MaxEvents'.

That didn’t work, but we can do it, we just need to use a function.

PS C:\> function Get-Last5Events { Get-WinEvent -MaxEvents 5 }
PS C:\> Get-Last5Events

TimeCreated ProviderName Id Message
----------- ------------ -- -------
2/23/2010 8:12:1... Service Control ... 7000 The Diagnostic S...
2/23/2010 8:12:1... Microsoft-Window... 135 The Diagnostic P...
2/23/2010 8:12:1... Service Control ... 7000 The Diagnostic S...
2/23/2010 8:12:1... Microsoft-Window... 135 The Diagnostic P...
2/23/2010 8:11:4... Service Control ... 7036 The Computer Bro...

The name we picked for our function is a bit long, so let’s use Set-Alias to create an alias for the function.

PS C:\> Set-Alias g5 Get-Last5Events

So we’ve shaved a few seconds off of our commands, now on to the doping.

In PowerShell we can use snap-ins and modules to extend the shell. There are modules and snap-ins for managing Active Directory, Group Policy, Diagnostics, Exchange 2007 and 2010, SharePoint 2010, IIS 7, VMware, and many more servers and services.

Snap-ins load sets of cmdlets and providers. Modules, which are only available in v2, can include cmdlets, providers, functions, variables, aliases, and much more. Modules are easier to create than snap-ins and they appear destined to replace snapins as the main way to extend PowerShell. You programmers can think of modules as a “class” while a snap-in is just a collection of functions.

Here is how a snap-in is loaded:

PS C:\> Add-PSSnapin VMware.VimAutomation.Core

Wildard characters can be used in the module name. I use it since I can’t ever remeber to type VMware.VimAutomation.Core, so I just type *vmware*. Let’s see what cmdlets have been added.

PS C:\> Get-Command -Module *vmware*

CommandType Name Definition
----------- ---- ----------
Cmdlet Add-VMHost Add-VMHost [-Name] <String> ...
Cmdlet Add-VMHostNtpServer Add-VMHostNtpServer [-NtpSer...
Cmdlet Apply-VMHostProfile Apply-VMHostProfile [-Entity...
Cmdlet Connect-VIServer Connect-VIServer [-Server] <...
...

Now, let’s load a module and then see what new cmdlets are available:

PS C:\> Import-Module GroupPolicy
PS C:\> Get-Command -Module GroupPolicy

CommandType Name Definition
----------- ---- ----------
Cmdlet Backup-GPO Backup-GPO -Guid <Guid> -Pat...
Cmdlet Copy-GPO Copy-GPO -SourceGuid <Guid> ...
Cmdlet Get-GPInheritance Get-GPInheritance [-Target] ...
Cmdlet Get-GPO Get-GPO [-Guid] <Guid> [[-Do...
...

We have these new aliases, functions and cmdlets, but we don’t want to go through the same setup everytime. We can automatically load these by editing our profile, but where is it?

There are four profiles, but we typically only work with the one stored in $profile. This file may not exist, so you may need to create it.

PS C:\> $profile
C:\Users\tim\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

We can edit the file with good ol’ notepad.

PS C:\> notepad $profile

Once we have it open we can add all of our aliases, functions, snap-ins and modules.

Set-Alias -Name ss -Value Select-String
function Get-Last5Events { Get-WinEvent -MaxEvents 5 }
Add-PSSnapin VMware.VimAutomation.Core
Get-Command -Module GroupPolicy
Clear-Host
Write-Host "Welcome to Tim's shell..."

This is a good spot to add those commands and functions that aren’t built into PowerShell such as Test-Hash and Get-Netstat.

Let’s see how the other shells compete.

Hal’s Been There, Done That

“See how other shells compete”? Kid, Unix shells were medalling in the Olympic Aliasing event before Powershell was even a gleam in some demented Microsoft developer’s eye.

Setting up aliases in bash is straightforward. Here’s how I make it easy to access the history command in my shell:

$ alias h=history
$ h
...
501 alias h=history
502 h
$ type h
h is aliased to `history'

Notice that the type command will tell you when a given command is an alias (or a shell built-in, or a regular command, or…), and thus is preferrable to commands like which.

Aside from using aliases to shorten commands that I use frequently, I’ll often use aliases as a way of making sure I get the program I want, even when I type the wrong thing:

alias more=less
alias mail=mutt

And, yes, I still regularly use mutt to read my email. You got a problem with that?

Aliases can always have multiple arguments, you just need to be careful with your quoting:

alias clean='rm -f *~ .*~'
alias l='ls -AF'
alias tless='less +G'

Aliases can do pretty much any shell code you can imagine, but they do have one shortcoming: any variables you put into an alias are expanded when the alias is read during the start-up of your shell. You can’t generally have variables that get interpolated when the alias is executed. For example, I wanted to create an alias that did a “cd” to whatever directory the last file I accessed lives in. But that requires run-time interpolation in order to know the last file accessed, so I can’t do it in an alias.

However, you can use shell functions for this:

$ function f { cd `dirname $_`; }
$ cp ~/.bashrc ~/stuff/testing/src/clkf/aliases/bashrc.example
$ f
$ pwd
/home/hal/stuff/testing/src/clkf/aliases

I called the function “f” for “follow”– as in, “copy that file to a directory and then follow it over there”. It’s hugely useful.

You’ll notice that the function uses the magical bash builtin variable “$_”, which is always set to the last argument of the previous command. So my function only works if the last argument of the last command is a file name, but that’s good enough for my purposes. If I had specified a directory instead of a file name in the cp command, then I could have just used “cd !$” instead of “f”:

$ cp ~/.bashrc ~/stuff/testing/src/clkf/aliases
$ cd !$
cd ~/stuff/testing/src/clkf/aliases

If you’re wondering what the heck that “!$” is all about, you need to go back and check out Episode #14.

The best place to put your aliases and shell functions is in your ~/.bashrc file. That way, they’ll get read every time you fire off a shell.

Hmmm, I hope this isn’t another one of those “easy for Unix (and Powershell), hard for CMD.EXE” kinds of things. Ed always gets so cranky about those…

Ed’s Not Overly Cranky Today

Cranky? Moi? Nevah. Well, mostly never. Ok… sometimes.

Despite my non-cranky demeanor, support for aliases in the cmd.exe shell isn’t particularly strong. In this corner of the shell-o-sphere, we typically apply two common approaches to mimicking aliases: doskey macros and small batch files. Let’s look at each.

Didja shudder just a little bit when I mentioned doskey? Yeah, it’s very old skool, but it can help us get some work done. To define a macro, you could simply run:

C:\> doskey <MacroName>=<Macro>

For example, if you want to display your running processes by simply running “ps”, you could run:

C:\> doskey ps=wmic process list brief
C:\> ps

HandleCount Name Priority ProcessId ThreadCount WorkingSetSize
0 System Idle Process 0 0 1 24576
426 System 8 4 97 581632
---SNIP---

That simple macro is nice, but it’s got a big limitation we’ve got to overcome by expanding our macro knowledge. To see this limitation, let’s try running our new macro and searching its output for cmd.exe:

C:\> ps | find "cmd.exe"
HandleCount Name Priority ProcessId ThreadCount WorkingSetSize
0 System Idle Process 0 0 1 24576
426 System 8 4 97 581632
---SNIP---

Doh! We only got the full output of our ps macro, without our search taking effect. What happened? Well, the macro substitution by default just ignores anything that follows it on the command line, unless we define the macro to end with $*, which holds the remainder of the command line typed in after the macro. By putting it at the end of our macro, everything typed after the macro will be executed after macro expansion. So, a better ps would be:

C:\> doskey ps=wmic process list brief $*
C:\> ps | find "cmd.exe"
23 cmd.exe 8 676 1 1462272
28 cmd.exe 8 4008 1 2785280

That’s what Momma likes.

Next, to more closely mimic what Hal does above with shell history by simply running the “history” command or the “h” command, you could use:

C:\> doskey history=doskey /history $*
C:\> doskey h=doskey /history $*

C:\> h

Note that I did use $* here, in case someone wants to pipe our output to another command or to redirect it into a file. If you just run the macro with nothing after it, $* contains nothing, so it executes as you’d expect… no harm, no foul. You can even split up the command line options following your macro, referring to each component as $1 up to $9, using each independently. And, if you want to have multiple commands in a macro, enter them as command1$Tcommand2, rather than using & between them. But, if you really want to use &, modern versions of Windows allow you to define the macro as command1 ^& command2. Likewise, if you want to do any piping in doskey macros, make sure you use a ^|.

If you ever want to list all of the macros you’ve created, run:

C:\> doskey /macros

It should be noted that these macros take precedent over any normal commands you type at cmd.exe, so you could really make your shell useless with them. For example, if you run:

c:\> doskey dir=echo No Way Dude!

c:\> dir
No Way Dude!

You’ve lost access to the dir command. To undefine a macro, simply use doskey to redefine a macro name with nothing after the equals sign:

C:\> doskey dir=
C:\> dir
Volume in drive C has no label.
Volume Serial Number is 442A-03DE
---SNIP---

Now, these little toy macros we’ve defined above are cute, but let’s get into some macros that really save us some serious time. Faithful readers of this blog (Hi Mom!) know that many of my episodes include certain constructs, like making a command run forever or invoking delayed variable expansion. Let’s look at some macros for those:

C:\> doskey forever=for /L %z in (1,0,2) do @$*

C:\> forever ipconfig /displaydns & ping -n 2 127.0.0.1 > nul

Here, I’ve created a macro called “forever” that invokes a FOR /L loop, set to count from 1 to 2 in steps of zero. That way, it’ll run forever. In the DO clause of my loop, I turn off the display of commands (@) and run whatever follows the invocation of forever. Note that I have to define a variable for my FOR loop, and I’ve chosen %z. That’s because I want to minimize the chance I’ll have a collision with any variables I might choose for my command to forever-ize. If I had used a %i in my macro, I’d really be thrown for a loop (no pun intended) if I used %i in my follow-up command. With FOR /F loops that have multiple tokens, variables are dynamically allocated alphabetically, so I hang out at the end of the alphabet here to lower the chance of collision.

You could put your ping delay inside the forever macro, but I find it best to keep it out, giving me more flexibility as I define my commands. Note that the command I’m running after forever here will run ipconfig to dump the DNS cache, followed by a one-second delay introduced by pinging myself twice (first ping happens immediately, followed by another ping one second later).

And, to perform delayed variable expansion (described in Episode #12), I could define a macro of:

C:\> doskey dve=cmd.exe /v:on /c "$*"

Note that you can put stuff in a macro _after_ the $* remainder of your command-line invocation, as I’m putting in a close quotation mark here to make sure that my full command gets executed in the context of delayed variable expansion. Now, I can do crazy stuff like this from Episode 58, filling the screen with random numbers to look a little like the Matrix:

C:\> dve for /L %i in (1,0,2) do @set /a !random!

It’s important to note that any environment variables whose value changes in your command must be referred to using !variable_name!, instead of the more traditional %variable_name%.

Ahhh… “But wait,” you say. After running dve in this example, I manually typed out a FOR /L loop that was simply my “forever” macro from before. Couldn’t I just do a dve followed by a forever? Let’s try it:

C:\> dve forever set /a !random!
'forever' is not recognized as an internal or external command, operable program
or batch file.

No sir. You can’t nest these suckers. Also, they have a problem if they aren’t the first command included on your command line. Consider:

C:\> echo hello & ps
hello
'ps' is not recognized as an internal or external command,
operable program or batch file.

So, we’ve got some pretty serious limitations here*, but, as Tim points out, they can shave off a precious few seconds, especially for things we often start our command-lines with, such as the forever FOR loop or delayed variable expansion.

Wanna see a really whacked out macro? This one was provided by Brian Dyson, a cmd.exe warrior like no other (and a long-lost twin of my friend Mike Poor, but that is a story for another day). Brian showed me a macro in which he emulates the !command feature of bash, which Hal alludes to above. Check out this amazing action, which I quote from Brian:

For the hard-core DOSKEY macro lover, a ‘!’ DOSKEY macro that acts (somewhat like) Bash, running the last command:

c:\> doskey !=doskey /history ^| findstr /r /c:"^$*" ^| findstr /rv /c:"^!" ^>
"%TEMP%\history.txt" ^&^& ((for /f "tokens=*" %a in (%TEMP%\history.txt) do
@set _=%a) ^&^& call echo.%_^% ^& call call ^%_^%) ^& if exist "%TEMP%\history.txt"
del "%TEMP%\history.txt"

Here we get the history and pipe it into a `findstr` command searching
for commands that begin with the arguments to `!`. We remove any
previous `!` command and redirect everything into a temporary file. (I
couldn’t find a work-around for the temporary file). If the final
findstr was successful, parse through the temporary file and set ‘_’ to
the last command (like Bash). If this was successful, then echo out the
command and call it via double `call`. Finally, clean up the temporary
history file.

Dude! Nice. Now, to invoke Brian’s macro, you have to run ! followed by a space, followed by a command or letters and it will invoke the last instance of whatever previous command started with the letters you type. Check it out:

C:\> ! di
dir
Volume in drive C has no label.
Volume Serial Number is 442A-03DE

Directory of c:\
---SNIP---

That space between the ! macro and the first part of the command we want to run is very important. Without it, cmd.exe tries to find a command called !di and bombs. With it, Brian’s macro kicks in and expands it to the most recent command that starts with those letters.

Note that a given set of macros only applies to the shell in which it is created. Your macros aren’t carried to other currently running shells, nor do they even apply to child shells that you spawn. If you exit your shell, they are gone. If you want to make your macros permanent, you should first define them, as we show above and put all those definitions in a file. Then, you can export them into a file, by running:

C:\> doskey /macros > macros.txt

You can call the file anything you want, but I like calling it macros.txt because it’s easy to remember. Then, at any time, you can import these macros by running:

C:\> doskey /macrofile=macros.txt

If you want to apply your macros to every cmd.exe you launch going forward, you can place your macros.txt in a convenient place on your system (such as your common user home directory or even in system32). Then, put a command like the following into any of your autostart locations:

%systemroot%\system32\doskey.exe /macrofile=%systemroot%\system32\macros.txt

For macros, I typically put them in the autostart entry associated with the command shell itself, namely the Autorun Registry key at HKCU\Software\Microsoft\Command Processor. You can define this key by running:

C:\> reg add "hkcu\software\microsoft\command processor" /v Autorun /t reg_sz /d
"%systemroot%\system32\doskey.exe /macrofile=%systemroot%\system32\macros.txt"

Be careful! If you already have a command set to autorun via this key, you may want to append the command to your already-existing one by simply inserting an & between the two commands. The reg command will prompt you to confirm or reject the overwrite if you already have something there.

*To get around some (but not all) of the limitations of doskey macros, you could alternatively use small bat files placed in %systemroot%\system32 to kick off familiar commands. For example, you could run:

C:\> echo @wmic process list brief > %systemroot%\system32\ps.bat
C:\> ps
HandleCount Name Priority ProcessId ThreadCount WorkingSetSize
0 System Idle Process 0 0 1 24576
404 System 8 4 97 774144
---SNIP---

The advantages of doing your command-line shrinkage with bat files is that you can now run them as little commands themselves, anywhere in your command invocation:

C:\> echo hello & ps
hello
HandleCount Name Priority ProcessId ThreadCount WorkingSetSize
0 System Idle Process 0 0 1 24576
404 System 8 4 97 745472
---SNIP---

The downside of this approach is that your bat file must contain whole commands, not just the start of a command, like we can do with macros. That’s why my forever and dve examples above work so well as macros and not as bat files. They are the starter of something else, but not whole commands to themselves, as is the ps and history examples we’ve touched on here.

So, back to Tim’s juicing metaphor. You get to pick your poison with cmd.exe and alias-like behavior. While both methods have some limitations, shell jocks can use macros or bat files to shave off a few precious seconds and boost your performance.

Using SED, and such

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Ed’s Got Sed (well, a little bit of it at least):

In a celebratory mood, I belt out:

C:\> cmd.exe /v:on /c "for /f "delims=" %i in ('echo Hippy barfday spew do you!')
do @set stuff=%i& echo !stuff! & set stuff=!stuff:i=a! & echo !stuff! & set
stuff=!stuff:arf=irth! & echo !stuff! & set stuff=!stuff:spew=to! & echo !stuff!
& set stuff=!stuff: do=! & echo !stuff! & set stuff=!stuff:yo=f! & echo. & echo
!stuff!"
Hippy barfday spew do you!
Happy barfday spew do you!
Happy birthday spew do you!
Happy birthday to do you!
Happy birthday to you!

Happy birthday to fu!

If you couldn’t tell, we’re celebrating the FIRST BIRTHDAY of this blog! Yes, we’ve already made it through one orbit of that big ball of gas at the center of our Solar System, and we’re looking forward to even more. It was one year ago today that three merry command line bandits decided to take a fun little brawl of command-line one-upmanship from Twitter to blog format, so we could get into deeper fu. As a birthday present, my command above shows how we can perform string substitutions at the Windows cmd.exe command line.

I’ve never hid the fact that I’ve often longed for the sed command, which allows for nifty stream editing. Although it’s got a ton of flexible features, one of sed’s most common uses is replacing a string with another string in a stream of data, such as Standard Output. What’s not to like? Well, the fact that we don’t have a built-in equivalent in cmd.exe is one thing that’s a bummer.

So, I got to thinking about this problem the other day, when I realized that I could do the substitution and replacement thing using string altering options in cmd.exe. I could take the data I want to alter, put it in a variable, and then change all occurrences of given strings to other strings using the notation:

set string=%string:original=replacement%

Or, if we use delayed environment variable expansion, we rely on:

set string=!string:original=replacement!

I’ve done just that above, starting by turning on delayed environment variable expansion (cmd.exe /v:on) to execute the command (/c) of FOR /F. My FOR /F command is designed to take the output of my echo command and put it in the variable %i. Alternatively, if I wanted to change text inside of a file, I could have used the “type filename” command instead of echo, iterating through each line of the file making substitutions. I turn off default parsing on spaces and tabs using “delims=”, so that my whole line of data gets shoved into %i. This is all very routine stuff for life inside of cmd.exe, even on your barf^h^h^h^hbirthday.

Then, I move my iterator value into a variable that I can take action on (set stuff=%i). I now can use my string replacement technique to start altering that variable, in a shallow and pale (but useful) mimicking of but one of the features of sed.

I can change individual characters into other characters, such as “i” to “a”:

set stuff=!stuff:i=a!

I can change multi-character substrings like barf into birth:

set !stuff:arf=irth!

I can replace whole words, changing “spew” into “to”:

set stuff=!stuff:spew=to!

I can delete whole words, like ” do”:

set stuff=!stuff: do=!

This one might be worth a note. Here, I’m replacing something with nothing by placing nothing after the equals sign. The item I’m replacing is ” do”, with a space in it. Otherwise, I’d have a double space left behind. And, yes, I could have alternatively replaced “do ” (with a space after it) with nothing. Or, I could have replaced ” do ” with ” ” using !stuff: do = !. There are many options.

And I can even take bigger strings and replace them with smaller strings:

stuff=!stuff:yo=f!

This is really cool and useful, but it does have some limitations. Note that every instance of the substring I specify is replaced, and there really is no means for just changing, for example, the first occurrence of the substring. Also, this doesn’t work for non-printable ASCII characters. You have to be able to type it to get it into that syntax. I’ve also gotta shove everything into a string to make this work, but that’s not so bad.

So, there you have it… a highly obfuscated command for wishing ourselves Happy Birthday.

Whatcha got Hal & Tim?

Tim blows out the candles:

Tim let’s it rip:

PS C:\> "Hippy barfday spew do you!" | Tee-Object -Variable stuff;
$stuff -replace "i","a" | Tee-Object -Variable stuff;
$stuff -replace "arf","irth" | tee -var stuff;
$stuff -replace "spew","to" | tee -va stuff;
$stuff -replace " do","" | tee -va stuff;
Write-Object; $stuff -replace "yo","f"

Hippy barfday spew do you!
Happy barfday spew do you!
Happy birthday spew do you!
Happy birthday to do you!
Happy birthday to you!

Happy birthday to fu!

One orbit around that big ball of gas huh? I’m sure there is joke related to Ed and his love of beans, but we are here to celebrate not disgust.

For those of you who followed the blog since the beginning, the original third bandit was Paul Asadoorian, not me. For those The Three Stooges fans out there, I guess you call me Curly, and Paul would be Shemp. Although, I can’t decide if that would make Hal Moe or Larry. Let’s get back to business and this week’s PowerShell nyuk, nyuk, nyuk.

It is rather fitting that PowerShell is second this week. Cmd’s string replacement is pretty weak and the syntax is terrible, while Linux is the opposite. PowerShell is somewhere in between, but much closer to the linux side of things.

Before we dig into the entire command above, we’ll first do the string substituion without all the extra output.

PS C:\> "Hippy barfday spew do you!" -replace "i","a"
-replace "arf","irth" -replace "spew","to" -replace " do",""
-replace "yo","f"

Happy birthday to fu!

The Replace operator is used to replace strings, duh! By default, the Replace operator is case insensitive, but to be explicitly case insensitive use the IReplace operator. For a case senstitive replace use the CReplace operator.

Now, let’s do all of Ed’s tricks:

Change individual characters into other characters, such as “i” to “a”:

... -replace "i","a"

Change multi-character substrings like barf into birth:

... -replace "arf","irth"

Replace whole words, changing “spew” into “to”:

... -replace "spew","to"

Delete whole words, like ” do”:

... -replace " do",""

We can even to tricks that Ed can’t, by using regular expressions:
Replace “y” with “f” but only if it is the first character in a word:

PS C:\> "Happy birthday to do yu!" -replace "\sy"," f"
Happy birthday to do fu!

Swap the first two words in a line:

PS C:\> "birthday Happy to fu!" -replace "^(\w+)\s(\w+)","`$2 `$1"
Happy birthday to fu!

The last command uses regular expression groups. We won’t go into the depths of regex, but in short, “\w+” will grab a word and “\s” will grab a space. The caret (^) is used to anchor the search to the beginning of the string, and the parentheses are used to define the groups. In the replacment portion we use `$1 and `$2 to represent (respectively) the first and second groups (words) found. Since we want to output them in reverse order we use “`$2 `$1″ to put the second word before the first word.

Back to the original command:

PS C:\> "Hippy barfday spew do you!" | Tee-Object -Variable stuff;
$stuff -replace "i","a" | Tee-Object -Variable stuff;
$stuff -replace "arf","irth" | tee -var stuff;
$stuff -replace "spew","to" | tee -va stuff;
$stuff -replace " do","" | tee -va stuff;
Write-Object; $stuff -replace "yo","f"

We want to display each change as it happens. To pull this off we will have to use the Tee-Object cmdlet. Similar to the linux’s tee command, Tee-Object takes the command output and saves in in a file or variable, as well as sending it down the pipeline or to the console.

If we break it down, this command has three parts that are repeated.

<input object> | Tee-Object -Variable stuff | $stuff
-replace <original> <replacment>

We start with the input object “Hippy barfday spew do you!” and pipe it into Tee-Object (alias tee). The only reason we use Tee-Object is so we can display the output and work with it further down the pipeline. After tee, we do the replace. The output of the previous portion becomes the input for the next. Rinse and repeat.

Towards the end of command we throw in the Write-Object cmdlet (alias write, echo) to add the extra line break.

One quick thing to note, when using the Tee-Object cmdlet’s Variable parameter, do not use a $. The parameter accepts a string, which is the name of the variable.

So that a more lucid version of Ed’s highly obfuscated command, and now it is time for Hal to hand out the Birthday spankings.

MoeHal sedsSays

Huh, I was sure Ed was Curly. At Ed’s current rate of hair loss, he’s going to resemble Curly before too much longer.

Hmmm, my Windows colleagues are desperately trying to achieve some of the functionality of sed in their silly little command shells. Here’s a hint guys: Cygwin is your friend. Then you could do things like this:

$ echo 'Hippy Barfday Spew Do You!' |
sed 's/\(H\)i\(ppy B\)arf\(day \)Spew D\(o \)Yo\(u!\)/\1a\2irth\3T\4F\5/'
Happy Birthday To Fu!

The whole trick here is leveraging sub-expressions– the text enclosed in “\(…\)”– in the first part of the sed substitution expression. Essentially I’m using the sub-expressions to “save” the bits of the line that I want to keep. You’ll notice the bits of our input string that I don’t want are carefully kept outside the “\(…\)” boundaries.

You can refer to the contents of the sub-expressions on the righthand side of the substitution using the \1, \2, … variables. Sub-expressions are numbered left to right by opening parenthesis– this is an important distinction when you start doing crazy stuff like nested sub-expressions. In this case, however, all I have to do is output the contents of my sub-expressions in order with appropriate text in between them to form our final message.

So really I’m just using sed sub-expressions like a cookie cutter here to chop out the bits of the line I want. This functionality makes sed very useful as a surgical tool for reformatting text into a regular format. Another example of this comes from one of our earliest Episodes where I showed ShempPaul how to bring the sed madness to parse the output of the host command.

Now the problem is that these sed expressions always end up looking awkward because of all of the backwhacks floating around. If you have GNU sed handy, you can use the “-r” (extended regex) option. This allows you do create sub-expressions with “(…)”, saving yourself a lot of backwhack abuse:

$ echo 'Hippy Barfday Spew Do You!' |
sed -r 's/(H)i(ppy B)arf(day )Spew D(o )Yo(u!)/\1a\2irth\3T\4F\5/'
Happy Birthday To Fu!

Still ugly, but definitely more readable.

Thanks everybody for taking time out of your busy lives to keep up with our humble little blog in the past year. We’ll save you a bit of the birthday cake!

How to Reliably Crash the iPhone’s E-mail Client

From https://secure.grepular.com/ by by Mike Cardwell

I have tested the following on two separate iPhones and it caused crashes on them both. I don’t have an iPhone of my own to test with, so I’m not able to investigate this much further.

1.) Create a blank file named anything.txt and then upload it to some webspace. It needs to be completely blank… 0 bytes. It must be served as text/plain. At least, “text/plain” is the only content type I know for sure it works with as I didn’t try any others.

2.) Send an HTML email to an email account that the iPhone can access. The HTML email must contain a meta refresh tag to the file which you have just created. Example:

<head>
<meta http-equiv="Refresh" content="1; URL=http://EXAMPLE/anything.txt"/>
</head>

3.) Open the email on an iPhone.

The iPhone email client actually honours the meta refresh and attempts to load the URL. It then proceeds to crash. Next time you open the email client it will have to re-sync all of the email.

This information comes with no warranty. Use it only for good, and only on your own phone.

Searching Text Strings

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Hal checks out the mail

We love getting email from readers of the blog. And we love getting cool shell hacks from readers even more. Recently, loyal reader Rahul Sen sent along this tasty little bit of shell fu:

How to search for certain text string in a directory and all its subdirectories, but only in files of type text, ascii, script etc:

$ grep 9898 `find /usr/local/tripwire -type f -print | xargs file |
egrep -i 'script|ascii|text' | awk -F":" '{print $1}'`
/usr/local/tripwire/te/agent/data/config/agent.properties:tw.local.port=9898
/usr/local/tripwire/te/agent/data/config/agent.properties:tw.server.port=9898

That’s totally cool, Rahul!

Honestly, when I first looked at this I thought, “There’s got to be a shorter way to do this.” But the tricky part is the “only in files of type text, ascii, script, etc” requirement. This basically forces you to do a pass through the entire directory first in order to locate the relevant file types. Thus the complicated pipeline to pass everything through the file command and egrep.

A few minor improvements I might suggest:

1. I’m worried that for a large directory you’ll end up returning enough file names that you exceed the built-in argument list limits in the shell. So it might be better to use xargs again rather than backticks.

2. I probably would have chosen to use sed at the end of the pipeline rather than awk, just to be more terse.

3. You don’t actually need “-print” on modern versions of find– it’s now the default. Only old-timers like me and Rahul end up doing “-print” all the time because we were trained to do so by old versions of find.

So my revised version would look like:

$ find /usr/local/tripwire -type f | xargs file |
egrep -i 'script|ascii|text' | sed 's/:.*//' | xargs grep 9898

Mmmm-hmmm! That’s some tasty fu! Let’s see what my Windows brethren have cooking…

Ed Unfurls:

This is a helpful little technique. Now, unfortunately at the Windows command line (man, if I only had a dime ever time I said that phrase), we do not have the “file” command to discern the type of file. But, fear not! We do have a couple of alternative methods.

For a first option, we could use a nifty feature of the findstr command to ignore files that have non-printable characters. When run with the /p option, findstr will ignore any files that contain high-end ASCII sequences, letting us skip over EXEs, DLLs, and other stuff. It’s not as fine a grained scalpel as scraping the output of the the Linux file command for script, ascii, and text, but it’ll serve us well as follows:

C:\> findstr /s /p 9898 *

Here, I’m using findstr to recurse the file system (/s) from wherever my current working directory is, skipping files with non-printable characters (/p), looking for the string 9898 in any file (*). If you want to get even closer to the original, we can specify a directory where we want to start the search using the /d: option as follows:

C:\> findstr /d:C:\windows /s /p 9898 *

Now, for our second option, there is another way to refine our search besides the /p option of findstr, getting us a little closer to the file types Rahul specified in Linux using the find command. It turns out that Microsoft actually put an indication of each file’s type in the name of the file itself. You see, by convention, Windows file names have a dot followed by three letters that indicate the file type. Who knew?!?! :)

To map the desired functionality to Windows, we’ll rely on file name suffixes to look inside of .bat, .cmd, .vbs, and .ps1 files (various scripts), .ini files (which often contain config info), and .txt files (which, uh… you know). What’s more, many commands associated with searching files allow us to specify multiple file names, with wild cards, such as the dir command in this example:

C:\> dir *.bat *.cmd *.vbs *.ps1 *.ini *.txt

And, happy to say, dir isn’t the only one that lets us look for multiple file names with wildcards. For my second solution to this challenge, I’m going to use a FOR /R loop. These loops recurse through a directory structure (/R, doncha know) setting an iterator variable to the name of each file that is encountered. Thus, we can use the following command as a rough equivalent to Rahul’s Linux fu:

C:\> FOR /R C:\ %i in (*.bat *.cmd *.vbs *.ps1 *.ini *.txt) do @findstr 9898 "%i" && echo %i

Here, I’m running through all files found under C:\ and its subdirectories, looking inside of any file that has a suffix of .bat, .cmd, etc, running findstr on each file (whose name is stored in %i, which has to be surrounded in quotes for those cases when the value has one or more spaces in the file name) looking for 9898. And, if I successfully find a match, I echo out the file’s name. Now, this output looks a little weird, because the file’s name comes after each line that contains the string. But, that is a more efficient way to do the search. Otherwise, I’d have to introduce unnecessary complexity by using a variable and parsing to store the line of the file and print its name first, then print the contents. I’d certainly do that for prettiness in a script. But, at the command line by itself, I’d eschew the complexity and just go with what I’ve shown above to get the job done.

Now, there’s a gazillion other ways to do this as well. For a third possibility, we could take the first option above (findstr) and use the multiple file suffix specification of option 2 (*.bat *.cmd *.vbs *.ps1 *.ini *.txt) to come up with:

C:\> findstr /d:C:\windows /s 9898 *.bat *.cmd *.vbs *.ps1 *.ini *.txt

I actually like this third approach best, because it’s relatively easy to type, makes a bunch of sense, has nicer-looking output than the FOR /R option, and has better performance.

Fun, fun, fun! Thanks for the great suggestion, Rahul.

Whatcha got for us, Tim?

Tim delivers:

Sadly, PowerShell is missing the same “file” command as the standard Windows command line. Also, there isn’t a PowerShell cmdlet similar to “findstr /p” either, but of course we could use FindStr since all the Windows commands are available in PowerShell. Ed already covered FindStr so we will just use just PowerShell cmdlets.

If we know that the files in question are in a specific directory, not subdirectories, there is a pretty simple command to find the files using the Select-String cmdlet.

PS C:\> Select-String 9898 -Path *.bat,*.cmd,*.vbs,*.ps1,*.ini,*.txt
-List | Select Path

Path
----
C:\temp\a.txt

According to the documentation “the Select-String cmdlet searches for text and text patterns in input strings and files. You can use it like Grep in UNIX and Findstr in Windows.” Whoah, big difference there! Grep has much more robust regular expression support when compared to FindStr, and yes, PowerShell does give us rich regular expressions.

Back to the task at hand. We only care if the file contains the text in question, not how many times the text is found in the file. The List parameter is used as a time saver, since it will stop searching after it finds the first match in a file.

For each match, the default console output displays the file name, line number, and all text in the line containing the match. Of course the output is an object and we just want the file’s path, so the results are piped into Select-Object (alias select) in order to get the full file path.

But we want to search though subdirectories too. To do that we have to use Get-ChildItem (alias dir, gci, ls).

PS C:\> Get-ChildItem -Include *.bat,*.cmd,*.vbs,*.ps1,*.ini,*.txt
-Recurse | Select-String 9898 -List | Select-Object path

Path
----
C:\temp\subfolder\b.txt
C:\temp\a.txt

The Recurse parameter specifies that the search should recursively search through subdirectories. The Include parameter retrieves only the files that match our filter. We could use the Exclude parameter if we wanted to search all files that aren’t exe’s or dll’s.

PS C:\> Get-ChildItem -Exclude *.exe,*.dll -Recurse |
Select-String 9898 -List | Select-Object path

The command can be shortened even further since the full parameter name doesn’t have to be used. As long the shortened parameter name isn’t ambiguous a short version of the parameter name can be used. Since there is no other parameters that start with R we or I this command will work as well:

PS C:\> ls -i *.bat,*.cmd,*.vbs,*.ps1,*.ini,*.txt -r |
select 9898 -L | select path

There is a catch if you are using version 1 of PowerShell, the Select-String cmdlet natively doesn’t take the input from Get-ChildItem and use it to specify the path. We have to use a For-EachObject loop (alias %) in order to accomplish the same task.

PS C:\> Get-ChildItem -Include *.bat,*.cmd,*.vbs,*.ps1,*.ini,*.txt
-Recurse | % { Select-String 9898 -List -Path $_.FullName } |
Select-Object path

A side note:
As you probably already know, Windows XP, Vista, and 2003 don’t come with Powershell and require a separate install, but for the love of Pete, install it. Version 2 has been available for quite a while and there are many enhancements over v1 (and even more when compared to cmd). Windows 2008 R2 and Windows 7 come with v2 by default.

PowerShell v1 in Windows 2008 (R1) is an optional feature that needs to be enabled. It can be installed using the Windows command line by running this command:

C:\> ServerManagerCmd.exe -install PowerShell

This is probably the most useful Windows command available (sorry Ed).

Time Bandits – Stomping, Stomping, Stomping …

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

I have always wanted to time travel. Since it isn’t possible to go back and kill Hitler I thought, maybe we can go back in time and change some files. Obviously, we don’t have the technology to actually go back in time and make changes. However, what if we could make it appear that we went back in time by altering timestamps.

First, let’s create a few files for our time warp. By the way, this next set of commands are all functionally equivalent.

PS C:\> Write-Output aaaa | Out-File a.txt
PS C:\> Write bbbb | Out-File b.txt
PS C:\> echo cccc | Out-File c.txt
PS C:\> echo dddd > d.txt

Now to see the time related properties available to us for the file object.

PS C:\> Get-ChildItem | Get-Member -MemberType Property | Where-Object { $_.Name -like "*time*" }

TypeName: System.IO.FileInfo

Name MemberType Definition
---- ---------- ----------
CreationTime Property System.DateTime CreationTime {get;set;}
CreationTimeUtc Property System.DateTime CreationTimeUtc {get;set;}
LastAccessTime Property System.DateTime LastAccessTime {get;set;}
LastAccessTimeUtc Property System.DateTime LastAccessTimeUtc {get;set;}
LastWriteTime Property System.DateTime LastWriteTime {get;set;}
LastWriteTimeUtc Property System.DateTime LastWriteTimeUtc {get;set;}

The Get-Member cmdlet (alias gm) is used to get the properties and methods available for an object that has been sent down the pipeline. In our case, the object sent down the pipeline is the file object. We just want to look at the properties (not methods, scriptproperties, etc) of the object, so we use the MemberType parameter for filtering. Then the Where-Object cmdlet (alias ?) is used to filter for properties with “time” in the name. The properties above are read/write, as shown by {get;set;}. Well, lookey there, we can set the timestamps!

An important side note: The Get-Member cmdlet is an extremely useful command. I can’t begin to say how often I’ve used this command to find properties and methods available for an object. There are other MemberTypes, but we will have to cover those at a later time. For a full description check out the MemberType parameter on this Microsoft help page.

The xxxxxTime and xxxxxTimeUtc properties are actually the same property, the only difference is how they display the date in regards to the UTC (coordinated universal time) offset. In my case, the difference is 6 hours. For the sake of brevity the UTC times will be ignored since they are essentially redundant.

Let’s take a look at our files.

PS C:\> gci | select Name, LastWriteTime, CreationTime, LastAccessTime

Name LastWriteTime CreationTime LastAccessTime
---- ------------- ------------ --------------
a.txt 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM
b.txt 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM
c.txt 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM
d.txt 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM 1/23/2010 11:16:24 AM

Now let’s go back in time.

(gci a.txt).LastAccessTime = Get-Date ("1/1/2010")
(gci b.txt).CreationTime = Get-Date ("1/1/2010")
(gci c.txt).LastWriteTime = Get-Date ("1/1/2010")

Since there isn’t a cmdlet for setting the time properties, we need to access properties in a different manner. To do this, we get the object and use the dot notation to access the property. The Get-Date cmdlet creates a valid date/time object for our new timestamp. Let’s see how that worked.

PS C:\> gci | select Name, LastWriteTime, CreationTime, LastAccessTime

Name LastWriteTime CreationTime LastAccessTime
---- ------------- ------------ --------------
a.txt 1/23/2010 11:16:24 AM 1/23/2010 12:07:05 PM 1/1/2010 12:00:00 AM
b.txt 1/23/2010 11:16:24 AM 1/1/2010 12:00:00 AM 1/23/2010 12:07:05 PM
c.txt 1/1/2010 12:00:00 AM 1/23/2010 12:07:05 PM 1/23/2010 12:07:05 PM
d.txt 1/23/2010 11:16:24 AM 1/23/2010 12:07:05 PM 1/23/2010 12:07:05 PM

Interesting, the times have been changed, but can we forensically find a difference? After taking an image of the drive and using the istat tool from the SluethKit.org guys it is very obvious that something weird has happened. Let’s take a look at an istat output snippet to see where the problem lies.

$STANDARD_INFORMATION Attribute Values:
Flags: Archive
Owner ID: 0
Security ID: 408 ()
Created: Fri Jan 01 00:00:00 2010
File Modified: Fri Jan 23 11:16:24 2010
MFT Modified: Fri Jan 23 11:20:43 2010
Accessed: Fri Jan 23 11:16:24 2010

$FILE_NAME Attribute Values:
Flags: Archive
Name: a.txt
Parent MFT Entry: 9946 Sequence: 10
Allocated Size: 0 Actual Size: 0
Created: Fri Jan 23 11:16:24 2010
File Modified: Fri Jan 23 11:16:24 2010
MFT Modified: Fri Jan 23 11:16:24 2010
Accessed: Fri Jan 23 11:16:24 2010

The PowerShell commands modify the STANDARD_INFO’s created, file modified and accessed times. As you can see, there is a discrepancy in the Creation times between the FILE_NAME and STANDARD_INFO attribute values. Also, if you look at the STANDARD_INFO’s MFT Modified date you can take a good guess as to when this change was made. The MFT Modified stamp is updated to the current system time whenever any of our PowerShell commands make a change to the file. The MFT Modified timestamp only marks the last change, so we could change all the dates to make it more confusing as to what change happened at that time.

While making the changes to the timestamps in PowerShell is effective when looking at the file system via the GUI or command line, not everything is hidden when looking at it with forensic tools.

While we can’t go back in time and bump off Hitler, we did go back in time and take this functionality out of the standard Windows command line. OK, that’s not really true. But what is true is that there is no way in cmd.exe to manipulate time stamps. So Ed won’t be joining us with any cmd fu this week.

Hal’s palms are getting hairy…:

Changing atimes and mtimes on Unix files is easy because we have the touch command. If you simply “touch somefile”, then the atime and the mtime on that file will be updated to the current date and time (assuming you’re the file owner or root).

But if you’re root, you can also specify an arbitrary time stamp using the “-t” flag:

# touch -t 200901010000 /tmp/test
# alltimes /tmp/test
/tmp/test
atime: Thu Jan 1 00:00:00 2009
mtime: Thu Jan 1 00:00:00 2009
ctime: Sun Jan 24 05:33:56 2010

The ctime value is always set to the current date and time, because the touch command is updating the atime and mtime meta-data in the inode and ctime tracks the last meta-data update. By the way, don’t bother looking for the alltimes command in your Unix OS. It’s a little Perl script I wrote just for this Episode (download the script here).

The touch command also has “-a” and “-m” flags that allow you to selectively update only the atime or the mtime:

# touch -a -t 200909090909 /tmp/test
# touch -m -t 201010101010 /tmp/test
# alltimes /tmp/test
/tmp/test
atime: Wed Sep 9 09:09:00 2009
mtime: Sun Oct 10 10:10:00 2010
ctime: Sun Jan 24 05:49:29 2010

As you can see from the above example, touch is perfectly willing to set timestamps into the future as well as the past.

OK, so what about tweaking the ctime value? In general, setting the ctime on a file to an arbitrary value requires specialized, file system dependent tools. The good news(?) is that for Linux EXT file systems, the debugfs command will let us muck with inode meta-data. If you’re dealing with other file system types or other operating systems, however, all I can say is good luck with your Google searching.

debugfs has a huge number of options that we don’t have time to get into here. I’m just going to show you how to use set_inode_field to update the ctime value:

# debugfs -w -R 'set_inode_field /tmp/test ctime 200901010101' /dev/mapper/elk-root
debugfs 1.41.9 (22-Aug-2009)

The “-w” option specifies that the file system should be opened read-write so that we can actually make changes– by default debugfs will open the file system in read-only mode for safety. We also need to specify the file system we want to open as the last argument. Sometimes this will be a disk partition device name like “/dev/sda1″, but in my case I’m using LVM, so my disk devices have the “/dev/mapper/” prefix. If you’re not sure what device name to use you can always run a command like “df -h /tmp/test” and look for the device name in the first column.

The “-R” option can be used to specify a single debugfs command to run in non-interactive mode. Note that there’s also a “-f” option that allows you to specify a file of commands you want to run. If you leave off both “-R” and “-f” you’ll end up in an interactive mode where you can run different commands at will.

In this case, however, we’re going to use “-R” and run set_inode_field to set the ctime on /tmp/test. As you can see, you use a time stamp specification that’s very similar to the one used by the touch command. And speaking of touch, we could use debugfs to “set_inode_field … atime …” or “set_inode_field … mtime …” instead of touch if we wanted to. This would allow us to update the atime/mtime values for a file without updating the ctime like touch does.

Anyway, now our ctime value should be updated, right? Let’s check:

# alltimes /tmp/test
/tmp/test
atime: Wed Sep 9 09:09:00 2009
mtime: Sun Oct 10 10:10:00 2010
ctime: Sun Jan 24 05:49:29 2010

That doesn’t look right! What’s going on?

What’s happening is that we’ve run afoul of the Linux disk cache. We actually have updated the information in the inode, but we’ve done it in such a way as to do an end-run around the normal Linux disk access routines, so our changes are not reflected in the in-memory file system cache. The good news is that (at least as of Linux kernel 2.6.16) there’s a simple way to flush the inode cache:

# echo 2 > /proc/sys/vm/drop_caches
# alltimes /tmp/test
/tmp/test
atime: Wed Sep 9 09:09:00 2009
mtime: Sun Oct 10 10:10:00 2010
ctime: Thu Jan 1 01:01:00 2009

That looks better!

By the way, if you “echo 1 > /proc/sys/vm/drop_caches”, that flushes the page cache. If you “echo 3 > /proc/sys/vm/drop_caches” it flushes both the page cache and the inode/dentry cache.

A Sort of List

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Hal starts off:

Way back in Episode #11 I showed you a little trick for sorting directory listings by inode number. But it struck me recently that we hadn’t talked about all of the other interesting ways you can sort directory listings.

For example, you can use “ls -S” to sort by file size:

$ ls -lS
total 6752
-rw-r----- 1 syslog adm 1271672 2010-01-18 05:36 kern.log.1
-rw-r----- 1 syslog adm 1016716 2010-01-18 05:39 messages.1
-rw-r----- 1 syslog adm 499580 2010-01-18 05:38 daemon.log.1
[...]

Add “-h” if you prefer to see those file sizes with human-readable units:

$ ls -lSh
total 6.6M
-rw-r----- 1 syslog adm 1.3M 2010-01-18 05:36 kern.log.1
-rw-r----- 1 syslog adm 993K 2010-01-18 05:39 messages.1
-rw-r----- 1 syslog adm 488K 2010-01-18 05:38 daemon.log.1
[...]

Also, adding “-r” (reverse sort) can be useful so that the largest files end up at the bottom of the directory listing, closer to your next command prompt:

$ ls -lShr
total 6.6M
[...]
-rw-r----- 1 syslog adm 488K 2010-01-18 05:38 daemon.log.1
-rw-r----- 1 syslog adm 993K 2010-01-18 05:39 messages.1
-rw-r----- 1 syslog adm 1.3M 2010-01-18 05:36 kern.log.1
$

You have to do much less scrolling around this way.

In addition to sorting by size, you can also sort by the so-called “MAC time” values: last modified (mtime), last access (atime), and last inode or meta-data update (ctime). By default, “ls -t” will sort by last modified time. This is another good one to use “-r” on so you can quickly find the most recently modified files in a directory:

$ ls -lrt
total 6752
[...]
-rw-r----- 1 syslog adm 86080 2010-01-18 08:10 kern.log
-rw-r----- 1 syslog adm 120492 2010-01-18 08:17 syslog
-rw-r----- 1 syslog adm 3310 2010-01-18 08:17 auth.log
$

If you want to sort by ctime you use “-c” in addition to “-t”. However, to sort by atime you need to use “-u” (“-a” was reserved for something else, obviously):

$ ls -lrtu
total 6752
[...]
-rw-r--r-- 1 root root 219990 2010-01-18 08:00 udev
-rw-r--r-- 1 root root 120910 2010-01-18 08:00 Xorg.0.log
-rw-r----- 1 root adm 56275 2010-01-18 08:00 dmesg
$

Now let’s see what my Windows brethren have up their sleeves, shall we?

Ed Responds:

Although not as full featured as the Linux ls command, the humble dir command offers us a bunch of options, allowing us to mimic pretty much everything Hal has done above. The main options we’ll use here are:

* /o followed by a one-character option that lets us specify a sort order (we’ll use /os to sort by size and /od by date… with a – sign in front of the one character to reverse order)
* /t, also followed by one character which lets us specify a time field we’re interested in (the field options we have and their definitions, according to the dir command’s help, are /tc for Creation time, /ta for Last Access time, and /tw for Last Written time).

So, to get a directory listing sorted by size (smallest to largest), we’d run:

C:\> dir /os

Want them reversed? We would use:

C:\> dir /o-s

Want those sizes in human readable form? Install Cygwin and use the ls command, for goodness sakes. This is the dir command we’re talking about here. We don’t need no stinkin’ human readable format. Actually, the default output for dir does show commas in its size numbers, making things a little more readable than the stock Linux output.

To see directory contents listed by Last Written (which is what dir calls them… roughly the same as last modified times in Linux parlance), in reverse order (with the most recently modified near the top), you could execute:

C:\> dir /o-d /tw

But, like we see with the ls command, Last Written is the default, so you can leave off the /tw to get the same results.

Wanna sort by creation time, again in reverse? Use:

C:\> dir /o-d /tc

And, how about last access? You could go with:

C:\> dir /o-d /ta

It’s a good thing that the /od and /o-d sort options pick up the proper timestamp specified by the /t option, or else we’d be forced to do some waaaaay ugly sort command nonsense. Whew!

Tim responds too:

To get a directory listing we use Get-ChildItem. The name is a bit odd, but it is a generic command and can be used to get the child items from any container such as the registry, file system, or the certificate store. Today we are just looking at the file system.

First, let’s take a look at the aliases for this useful cmdlet.

PS C:\> Get-Alias -Definition Get-ChildItem

CommandType Name Definition
----------- ---- ----------
Alias dir Get-ChildItem
Alias gci Get-ChildItem
Alias ls Get-ChildItem

I typically use ls since it is 33% more efficient to type than dir. But I digress…

Let’s sort by file size:

PS C:\> gci | sort length

Directory: C:\

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 6/10/2009 4:42 PM 10 file1.txt
-a--- 6/10/2009 4:42 PM 24 file2.txt
-a--- 11/24/2009 3:56 PM 1442522 file3.zip

The Get-ChildItem cmdlet does not have sorting capability built in, none of the cmdlets do. But that is what the pipeline and the Sort-Object cmdlet are for.

Want to sort by file size in reverse order? Use the Descending parameter.

PS C:\> gci | sort length -descending

Directory: C:\

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 11/24/2009 3:56 PM 1442522 file3.zip
-a--- 6/10/2009 4:42 PM 24 file2.txt
-a--- 6/10/2009 4:42 PM 10 file1.txt

We can sort by any property, including LastAccessTime, LastWriteTime, or CreationTime.

PS C:\> gci | sort LastWriteTime

We can even sort on two properties.

PS C:\> gci | sort LastWriteTime, Length

Directory: C:\

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 6/10/2009 4:42 PM 24 file2.txt
-a--- 6/10/2009 4:42 PM 10 file1.txt
-a--- 11/24/2009 3:56 PM 1442522 file3.zip

The files will first be sorted by write time. If two files have the same write time, they will then be sorted by length.

Finally, we come to displaying the size in a human readable format, and it isn’t pretty. We have to write a custom expression to display the size in KB or MB.

PS C:\> gci | format-table -auto Mode, LastWriteTime, Length,
@{Name="KB"; Expression={"{0:N2}" -f ($_.Length/1KB) + "KB" }},
@{Name="MB"; Expression={"{0:N2}" -f ($_.Length/1MB) + "MB" }},
Name

Mode LastWriteTime Length KB MB Name
---- ------------- ------ -- -- ----
-a--- 6/10/2009 4:42 PM 10 0.01KB 0.00MB file1.txt
-a--- 6/10/2009 4:42 PM 24 0.02KB 0.00MB file2.txt
-a--- 11/24/2009 3:56 PM 1442522 1,408.71KB 1.38MB file3.zip

We can specify custom properties to display. This format works with any of the format cmdlets (Get-Command -Verb Format) or select-object. The custom columns are created by using a hashtable. A hashtable is specified by using @{ key1=value1, key2=value2 }. In our case we specify a name and an expression. Here is a simple example.

..., @{Name="Foo"; Expression={ $_.Length + 1 }}, ...

In this case we would add a column with the heading Foo and with a value of the Length plus 1. The expression can include all sorts of math or other crazy PowerShell fu.

Ironically, getting a human readable output comes from a non-human readable command.

CISOs Keep Breach Costs Lower

The latest “Cost of a Data Breach” survey from the Ponemon Institute finds companies with a CISO are better able to handle loss of sensitive information

By Joan Goodchild, Senior Editor

Companies continue to pay a high price to clean up the mess created by a data breach, but having a Chief Information Security Officer (CISO) may offer some protection. That is the conclusion of a study released Monday by the Ponemon Institute, a Michigan-based consultancy that conducts independent research on privacy, data protection and information security policy.

This is the fifth year Ponemon has conducted its “Cost of a Data Breach” survey, which examined actual data breach experiences of 45 U.S. companies from 15 different industry sectors. This year, the cost of a data breach has increased to $204 from last year’s $202 per customer record. However, companies that had a CISO (or equivalent title) who managed the data breach incident experienced an average per capita cost of $157 versus $236 for companies without such CISO leadership.

Approximately 40 percent of participating companies had a CISO in charge of managing the data breach incident, according to the survey.

“While other functional areas are typically involved in crisis management activities surrounding the data breach, our results suggest CISO leadership substantially reduces the overall cost of data breach,” the report states.

“The one big take away on positive takeaway is that in (companies) that have CISO involvement, breaches tend to cost less because they have a more strategic view of protecting data than the old idea of whack-a mole, fix-it a hundred different times, ” explained Phillip Dunkelberger, president and CEO of PGP Corp., which co-sponsored the study. “CISO involvement at a higher level means less cost of a data breach and less chance of repeating it because of the strategic view of protecting it that these professional take.”

While the cost of a breach only rose two dollars per record this year, Dr. Larry Ponemon, founder and chair of the Ponemon Institute, pointed out the massive increase in cost over the five years since the study’s inception, when breaches cost $138 per compromised customer record. In figuring out the costs, the study takes into account a wide range of business costs, including expense outlays for detection, escalation, notification, and after the fact (ex-post) response. The economic impact of lost or diminished customer trust and confidence, measured by customer churn or turnover rates, is also analyzed.

Other highlights from this year’s research include:
- Forty two percent of all cases in this year’s study involved third-party mistakes or flubs. Data breaches involving outsourced data to third parties, especially when the third party is offshore, are most costly. The per capita cost for data breaches involving third parties is $217 versus $194, more than a $21 difference, according to Ponemon.

-Twenty four percent of all cases in this year’s study involved a malicious or criminal attack that resulted in the loss or theft of personal information. Research shows data breaches involving malicious or criminal acts are much more expensive than incidents resulting from negligence. The per capita cost of a data breach involving a malicious or criminal act averages $215. The per capita cost of a data breach involving a negligent insider or a systems glitch averages $154 and $166, respectively.

-Thirty six percent of all cases in this year’s study involved lost or stolen laptop computers or other mobile data-bearing devices. Data breaches concerning lost, missing or stolen laptop computers are more expensive than other incidents. Specifically, in this year’s study the per victim cost for a data breach involving a lost or stolen laptop is $225.

“Its not just about bad guys, but also good guys who make mistakes,” noted Ponemon.

Companies on IT Security Spending: Where’s the ROI?

Companies have spent millions to bolster their IT security in recent years. But some are starting to wonder if it’s been worth it, according to the 2010 Cyber Security Watch survey CSO conducted with the U.S. Secret Service, Carnegie Mellon University CERT and Deloitte & Touche.

By Bill Brenner, Senior Editor, CSO Online

Companies have spent many millions of dollars to build defenses around their IT assets this past decade, motivated by malware attacks, data security breaches and the resulting regulatory compliance cattle prod.

But the bad guys are still a few steps ahead in terms of sophistication and speed and some wonder if their investments were all for nothing, according to the newly-released 2010 Cyber Security Watch Survey.

More than 500 respondents, including business and government executives, professionals and consultants, participated in the survey, conducted by CSO Magazine with help from the U.S. Secret Service, Carnegie Mellon Software Engineering Institute (CERT) and Deloitte’s Center for Security and Privacy Solutions. Though respondents point to sizable efforts to keep their companies secure, many admit it’s getting almost impossible to outpace the bad guys.
Also see Network Security: The Basics

“Security confidence seems to be waning. Respondents are spending more money and implementing new capabilities, but overall they seem to be unsure about how truly effective their efforts really are toward ensuring security,” said Ted DeZabala, principal at Deloitte & Touche LLP and U.S. leader of Deloitte’s Security & Privacy services.

The survey showed a drop in cybercrime victims — 60 percent this year compared to 66 percent in 2007. But the affected organizations have experienced significantly more attacks than in previous years, fueling doubts over a lack of return-on-investments (ROI).

Between August 2008 and July 2009 more than a third (37 percent) of respondents experienced an increase in cybercrimes compared to the previous year. While outsiders (non-employees or contractors) are the main culprits of cybercrime in general, the most costly or damaging attacks are more often caused by insiders (employees or contractors). One quarter of all cybercrime attacks were committed by an unknown source.

Although the number of incidents rose, the ramifications have not been as severe. Since 2007, when the last cybercrime survey was conducted, the average monetary value of losses resulting from cybercrimes declined by 10 percent. This can likely be attributed to an increase in both IT security spending (42 percent) and corporate/physical security spending (86 percent) over the past two years.

And yet, as technology advances, so do the attack methods, and many respondents worry that the bad guys are still winning. Outsiders invade organizations with viruses, worms or other malicious code; phishing; and spyware, while insiders most commonly expose private or sensitive information unintentionally, gain unauthorized access to/use of information systems or networks, and steal intellectual property.

The survey finds that insiders most often use their laptops or copy information to mobile devices as a means to commit electronic crimes against their organization. Respondents suggested data is often downloaded to home computers or sent outside the business via e-mail. This may lead to damaged reputations and may put organizations in violation of state or federal data protection laws.

More than half of the respondents — 58 percent — do believe they are more prepared to prevent, detect, respond to or recover from a cybercrime incident compared to the previous year. But only 56 percent have a plan for reporting and responding to an incident.

The research also indicated that businesses are trying to take steps to identify insider threats. Nearly one-third (32 percent) now monitor the online activities of employees who may be disgruntled or who have turned in their resignations.

Dawn Cappelli, technical manager for the Threat and Incident Management division of the Software Engineering Institute CERT Program, said insider attacks continue to be seen as a bigger problem than anything that might come from the outside.

“Attacks are more costly than outside attacks, and seven of the top eight practices that were indicated as being most effective at prevention, detection and deterrence apply to employees,” she said.

Though many respondents may be doubting the ROI of their security investments, the activity to deal with the insider threat at least indicates that no one is thinking about tightening up on their spending. Perhaps that’s because many feel like they have no choice but to keep spending, lest they fall even further behind the bad guys.

“This looks like good news — they have found effective practices for handling the most costly threats,” Cappelli said. “However, the technical solutions for insider threat mitigation were ranked alarmingly low: DLP, Ranked 9th least effective and change control/configuration management systems, ranked 5th least effective. In addition, account audits are only being performed by 43 percent of respondents, probably because of the technology gap.

To that end, her parting advice is not to the respondents, but to the vendor community: Come up with something better to help customers achieve the DLP and change control/configuration management they need.

Your 5-Step Malware-Analysis Toolkit

From http://www.campustechnology.com By Lenny Zeltser

A LARGE NUMBER of computer intrusions involve some form of malicious software (malware), which finds its way to the victim’s workstation or to a server. When investigating the incident, the IT responder typically seeks to answer questions such as: What actions can the malware specimen perform on the system? How does it spread? How, if at all, does it maintain contact with the attacker? These questions can all be answered by analyzing the offending malware in a controlled environment.

A simple analysis toolkit, built from free and readily available software, can help you and your IT team develop the skills critical to responding to today’s security incidents. The steps below will help get you started. We’ll focus on malware analysis in a Windows environment, since that platform is particularly popular among malware authors.

Step 1: Allocate physical or virtual systems for the analysis lab

A common approach to examining malicious software involves infecting a system with the malware specimen and then using the appropriate monitoring tools to observe how it behaves. This requires a laboratory system you can infect without affecting your production environment.

The most popular and flexible way to set up such a lab system involves virtualization software, which allows you to use a single physical computer for hosting multiple virtual systems, each running a potentially different operating system. Free virtualization software options include:

Running multiple virtual systems simultaneously on a single physical computer is useful for analyzing malware that seeks to interact with other systems, perhaps for leaking data, obtaining instructions from the attacker, or upgrading itself. Virtualization makes it easy to set up and use such systems without procuring numerous physical boxes.

Another useful feature of many virtualization tools is the ability to take instantaneous snapshots of the laboratory system. This way, you can record the state of the system before you infect it, and revert to the pristine environment with a click of a button at the end of your analysis.

If using virtualization software, install as much RAM into the physical system as you can, as the availability of memory is arguably the most important performance factor for virtualization tools. In addition, having a large hard drive will allow you to host many virtual machines, whose virtual file systems typically are stored as files on the physical system’s hard drive.

Take precautions to isolate the malware-analysis lab from the production network, to mitigate the risk that a malicious program will escape.

Because malware may detect that it’s running in a virtualized environment, some analysts prefer to rely on physical, rather than virtual, machines for implementing laboratory systems. Your old and unused PCs or servers can make excellent systems for your malware-analysis lab, which usually doesn’t need high-performing CPUs or highly redundant hardware components.

To allow malware to reach its full potential in the lab, laboratory systems typically are networked with each other. This helps you observe the malicious program’s network interactions. If using physical systems, you can connect them with each other using an inexpensive hub or a switch.

Step 2: Isolate laboratory systems from the production environment

You must take precautions to isolate the malware-analysis lab from the production network, to mitigate the risk that a malicious program will escape. You can separate the laboratory network from production using a firewall. Better yet, don’t connect laboratory and production networks at all, to avoid firewall configuration issues that might allow malware to bypass filtering restrictions.

If your laboratory network is strongly isolated, you can use removable media to bring tools and malware into the lab. It’s best to use write-once media, such as CDs, to prevent malicious software from escaping the lab’s confines by writing itself to a USB key. If using a USB key, which is more convenient than a CD, get a model that includes a physical write-protect switch.

Some malware-analysis scenarios benefit from the lab being connected to the internet. Avoid using the production network for such connectivity. If possible, provision a separate, and usually inexpensive, internet connection, perhaps by dedicating a DSL line to this purpose. Avoid keeping the lab connected to the internet all the time to minimize the chance of malware in your lab attacking someone else’s system on the internet.

If virtualizing your lab, be sure to keep up with security patches released by the virtualization-software vendor. Such software may have vulnerabilities that could allow malware to escape from the virtual system you infected and onto the physical host. Furthermore, don’t use the physical machine that’s hosting your virtualized lab for any other purpose.

Step 3: Install behavioral analysis tools

Before you’re ready to infect your laboratory system with the malware specimen, you need to install and activate the appropriate monitoring tools. Free utilities that will let you observe how Windows malware interacts with its environment include:

  • File system and registry monitoring: Process Monitor and Capture BAT offer a powerful way to observe in
    real time how local processes read, write, or delete
    registry entries and files. These tools can help you
    understand how malware attempts to embed into the
    system upon infection.
  • Process monitoring: Process Explorer and Process Hacker replace the built-in Windows Task Manager, helping
    you observe malicious processes, including local network
    ports they may attempt to open.
  • Network monitoring:Wireshark and SmartSniff are
    network sniffers, which can observe laboratory network
    traffic for malicious communication attempts, such as
    DNS resolution requests, bot traffic, or downloads.
  • Change detection: Regshot is a lightweight tool for comparing the system’s
    state before and after the infection, to highlight
    the key changes malware made to the file system and
    the registry.

Behavioral monitoring tools can give you a sense for the key capabilities of malicious software. For further details about its characteristics, you may need to roll up your sleeves and perform some code analysis.

Step 4: Install code-analysis tools

Examining the code that comprises the specimen helps uncover characteristics that may be difficult to obtain through behavioral analysis. In the case of a malicious executable, you rarely will have the luxury of access to the source code from which it was created. Fortunately, the following free tools can help you reverse compiled Windows executables:

  • Disassembler and debugger: OllyDbg and IDA Pro Freeware can parse compiled Windows
    executables and, acting as disassemblers, display their
    code as Intel x86 assembly instructions. These tools
    also have debugging capabilities, which allow you to
    execute the most interesting parts of the malicious program
    slowly and under highly controlled conditions, so
    you can better understand the purpose of the code.
  • Memory dumper: LordPE and OllyDump help obtain protected code located in the
    lab system’s memory and dump it to a file. This technique
    is particularly useful when analyzing packed executables,
    which are difficult to disassemble because
    they encode or encrypt their instructions, extracting
    them into RAM only during run-time.

Step 5: Utilize online analysis tools

To round off your malware-analysis toolkit, add to it some freely available online tools that may assist with the reverse engineering process. One category of such tools performs automated behavioral analysis of the executables you supply. These applications look similar at first glance, but use different technologies on the back end. Consider submitting your malware specimen to several of these sites; depending on the specimen, some sites will be more effective than others. Such tools include:

Another set of potentially useful online tools provides details about websites that are suspected of hosting malicious code. Some of these tools examine the sites you specify in real time; others provide historical information. Consider submitting a suspicious URL to several of these sites, because each may offer a slightly different perspective on the website in question:

Next Steps

With your initial toolkit assembled, start experimenting in the lab with malware you come across on the web, in your e-mail box, on your systems, and so on. You may find this one-page cheat sheet convenient.

Begin analysis with the tools and approaches most familiar to you. Then, as you become more familiar with the inner workings of the malware specimen, venture out of your comfort zone to try other tools and techniques. The tools I’ve listed within each step operate virtually identically. Since they’re all free, you should feel free to try them all. You’ll find that one tool will work better than another, depending on the situation. And with time, patience, and practice, you will learn to turn malware inside out.

Advanced Process Whack-a-Mole

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Ed Prepares to Open Up a Can of Process Whoop-Ass:

I’ve never considered myself a particularly violent man. But, I have to admit it: Sometimes it just feels good to kill processes. I’ve even been heard to mutter a deadpan “Dodge This” in my lab late at night as I obliterate errant or evil processes just begging to meet their maker. Then, to make sure such a process doesn’t pop back up to start bothering me again, I sow the ground with command-line kung fu salt to strangle any other similar process that might pop up in its place.

This technique, which we’ve taken to calling “Process Whack-a-Mole”, can be helpful to people in all walks of life. I’m sure it’s happened to pretty much everyone at some point. You find yourself playing defense in a Capture the Flag tournament against an elite team of ninjas from a three-letter government agency who want to completely control your boxen. They repeatedly gain access, and you have to shew them out before they score and you lose points. To deal with such situations, we can run a command to continuously look for processes with certain characteristics of our adversaries, and then kill them when they appear. We touched upon the idea of killing a process that starts to listen on a given TCP port in Episode #76. But, let’s go further this time, discussing how you can make much more flexible whack-a-mole commands to deal with various process characteristics.

These techniques are useful even outside of Capture the Flag games. I often use them in malware analysis and even system administration when I want to suppress some activity temporarily while I’m analyzing or configuring something else.

The basic structure I use for process whack-a-mole consists of the following three parts:

<Continuous Loopinator> <Process Selector> <Process Terminator>

Quite often the Process Selector and Process Terminator are combined together in a single command, because we can select or filter for the process we want in the same command we use to whack it. However, to filter for certain specific process characteristics, we’ll have to split out these two entities. I’ll show you what I mean in a bit.

We start out with our Continuous Loopinator:

C:\> for /L %i in (1,0,2) do @ping -n 2 127.0.0.1 >nul

This is a simple FOR /L loop that starts counting at 1, goes up to 2, in steps of 0. In other words, it’s the cmd.exe equivalent of while (true), used to keep something running continuously. At the start of the loop, we introduce a 1-second delay by pinging ourselves twice (-n 2) and throwing the standard output away so as not to clutter our output (>nul). That way, we’ll run our Process Selector and Process Terminator approximately every 1 second, helping to minimize our impact on performance. If you want a faster Process Selector, simply omit that ping, and your system will run our whack-a-mole command as fast as it can, but performance may drag.

We then follow with our Process Selector. If you keep in the ping delay, put in an & followed by the Process Selector, which lets us make one command run after another. Otherwise, just put the Process Selector after the @ (which turns off command echo, by the way… no sense having our output clogged up with commands).

The two most common Process Selectors I use are wmic and taskkill, which have the nice property of also including the ability to act as Process Terminators in the same command. Let’s look at wmic first.

The wmic command can be used to select given processes based on our constructing a where clause, using the following syntax:

C:\> wmic process <where clause> <verb clause>

In the where clause, we can specify any attribute or group of attributes of processes that can be listed via wmic process. To get a list of these attributes, you could run:

C:\> wmic process get /?

So, for example, if you want to select a processID of 4242, you could write your wmic command as:

C:\> wmic process where processid=4242

Or, we could look for processes that have a given Parent Process ID:

C:\> wmic process where parentprocessid=3788

Or, we could look for processes with a given name:

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

These where clauses also support AND and OR, but you’ve got to make sure you put the guts of your where clause inside of parentheses. The where clauses also support not equals (!=). Check this out:

C:\> wmic process where (name="cmd.exe" and processid != 676)

Now, we haven’t supplied a verb clause here, so all our wmic commands are simply displaying raw, unformatted process information on Standard Output.

Let’s start doing our whack-a-mole by specifying a Process Terminator by using the verb clause of wmic with the simple verb “delete”. That’ll kill a process.

Putting these pieces together, suppose you want to kill all cmd.exe processes other than the current cmd.exe you, the administrator, are running. Let’s assume that your own cmd.exe has a process ID of 676. You could run:

C:\> for /L %i in (1,0,2) do @ping -n 2 127.0.0.1 >nul & wmic process where (name=
"cmd.exe" and processid!=676) delete

Now, let’s see ‘em try to run a cmd.exe. Every time someone tries to launch one, your loop will kill it.

Next, suppose you want to prevent a given process with processid 4008 from spawning child processes. Maybe process ID 4008 is a cmd.exe shell, and you want to prevent the person who is using it from being able to run any commands that aren’t built-into the shell itself. Or, better yet, maybe process ID 4008 is Tim Medin’s PowerShell process, and you wanted to pee in his Corn Flakes, depriving him of the ability to run any separate EXE commands, forcing him to rely solely on built-in capabilities of Powershell itself. We can do this one without our ping-induced delay to really confound him:

C:\> for /L %i in (1,0,2) do @wmic process where parentprocessid=4008 delete

These wmic where clauses also support substring matches, with the use of “like” and %. For example, suppose you want to continuously kill every process that is running from an EXE with a path in a given user’s directory. You could run:

c:\> for /L %i in (1,0,2) do @ping -n 2 127.0.0.1 >nul & wmic process where
(executablepath like "c:\\users\\tim\\%") delete

Note that in a “where” clause with the “like” syntax, you have to surround the elements with parens. Also, note that if you have a \ in your where clause, you have to specify it as \\, the first \ indicating an escape, and the second indicating your backslash.

You can combine these where clause elements (=, !=, AND, OR, LIKE, and %) in all kinds of ways to mix and match against various process attributes for whack-a-mole. I’m sure our readers can dream up all kinds of interesting and useful combinations.

But, there is a missing attribute from “wmic process get /?” — it’s the user name that process is running under. To play whack-a-mole based on user names, we can turn to another Process Selector and Terminator: taskkill. I wrote about taskkill filters back in Episode 22, showing how we can use it to kill a process based on its owner username. Here, we’ll wrap that in our whack-a-mole construct:

C:\> for /L %i in (1,0,2) do @ping -n 2 127.0.0.1 >nul & taskkill /F /FI
"username eq tim"

Sorry, Tim. That’s what you get for using a shell on the same system I’m on. Hal’s over on some lonely Linux that no one ever uses, so I leave him alone. :)

Anyway, where was I? Ah, yes, we were discussing attributes of processes that wmic doesn’t include, but which may be handy in whack-a-mole games. How about DLLs? Suppose a bad guy is hacking your system and keeps trying to inject a DLL into some process, and you want to kill that process. Maybe Evil Badguy (yes, that’s his full name) has injected metsrv.dll, the Metasploit Meterpreter, into a running process, and uses process migration to jump from process to process. Sorry, but getting the system to unload that DLL using only built-in tools at the command line is very difficult, but killing that process is totally doable:

C:\> for /L %i in (1,0,2) do @ping -n 2 127.0.0.1 >nul & taskkill /F /FI
"modules eq metsrv.dll"

Now, I mentioned above that the Process Selector and Process Terminator components are typically combined in a single command, as we’ve seen so far with wmic and tasklist. When would you have two different commands for these pieces? Well, one example is with netstat, which can show TCP and UDP port usage and the processes associated with each port. That’s exactly what we used in Episode #76, where our Process Selector was netstat (whose output I parsed with a FOR /F loop to pull out the ProcessID number), and the Process Terminator was taskkill:

C:\> for /L %i in (1,0,2) do @(ping -n 2 127.0.0.1>nul & for /f "tokens=5"
%j in ('netstat -nao ^| find ^":47145^"') do @taskkill /f /PID %j)

So, keeping in mind those three components of process whack-a-mole, you can use almost any command that lists processes in pretty much any arbitrary way to build a whack-a-mole command for fun and profit.

And now, for a routine disclaimer: Be careful with any of these commands. If you kill a vital system process, such as lsass.exe, you could bring your whole box down. You have been warned. So, now that you are armed and dangerous, go have fun!

Tim prepares for war:

It seems that Ed has a bit of shell envy. So let’s kick that inferior shell off “our” machine and keep it (and him) off our machine.

As Ed described, the structure for whack-an-Ed whack-a-mole has three parts, and that basic structure will be very similar in PowerShell.

<Continuous Loopinator> { <Process Selector> | <Process Terminator> }

The Continuous Loopinator repeatedly calls the Process Selector whose results are piped into the Process Terminator. Let’s see how each piece works.

Continuous Loopinator:

There are many ways to do a continuous loop, but the easiest and quickest method is to use the While loop.

PS C:\> while (1) { <code to run ad infinitum>; Start-Sleep 1 }

This loop is pretty self explanatory. It is a simple While loop that runs while 1 is true, which it always will be. The Start-Sleep cmdlet (alias sleep) will suspend activity for the specified amount of time. If we wanted a shorter nap we could use the -milliseconds parameter. Since Ed’s command runs every second, we should run ours a bit faster just because we can. How about 5 times a second?

PS C:\> while (1) { <code to run ad infinitum>; Start-Sleep -milliseconds 200 }

Process Terminator:

I’m covering this a bit out of order because the Terminator is so simple, so indulge me for a bit. The cmdlet used for killing is Stop-Process (alias spps or kill). It can even be used for some rudimentary process selection before the assassination. We can kill based on the Process Id:

PS C:\> Stop-Process 1337

…or the process name.

PS C:\> Stop-Process -Name cmd

In the second example every process with the name “cmd” would be stopped, but what if we wanted to be a little more high tech in making Ed’s processes “sleep with the fishes?”

As described earlier, the results of the Process Selector can be piped into our Process Terminator. We can pick any method to retrieve the process(es) to be killed, but more on that later. Here is what it would look like:

<Get Processes> | Stop-Process

By default, Stop-Process will ask for confirmation prior to terminating any process not owned by the current user. To get around that safety mechanism we can use the Force parameter.

<Get Processes> | Stop-Process -Force

Short version:

<Get Processes> | kill -f

We could just kill the processes with Stop-Process by giving it a Process Id or process name, but we want more options. Now let’s see how we can find more processes to kill.

Process Selector:

To get a process or a number of processes we use Get-Process (aliases ps and gps). This is our Process Selector. We have covered this before, but we have a number of ways to get a process or a list of processes. To get help on the command you can run:

PS C:\> Get-Help Get-Process

…or for those who have seen the light and come from the linux side but have a bad memory, this works too:

PS C:\> man ps

To see the examples use the Examples parameter, or use the Full parameter to see everything. From the help we can see how to get a process with a given Process ID. We will be looking for PID 4242:

PS C:\> Get-Process -Id 4242
PS C:\> ps -Id 4242

To get all the cmd.exe processes:

PS C:\> Get-Process cmd
PS C:\> ps cmd

Note that the process name does NOT include .exe.

We can also use filters in order to get more granular. We already had our loop to kill all cmd processes, but what if Ed wants to use PowerShell? We need to make sure that we are King of the PowerShell Hill, and any other PowerShell usurper is destroyed. This will find any PowerShell processes that aren’t ours.

PS C:\> Get-Process powershell | ? { $_.ID -ne 21876 }

The weaponized version of the command could look like this:

PS C:\> While (1) { ps powershell | ? { $_.ID -ne 21876 } | kill -f; sleep 1 }

The next thing Ed did, after tee-tee’ing in my Kelloggs, was to prevent me from kicking off any processes from a cmd or PowerShell process. So let’s do the same to him. Unfortunately, the objects returned by Get-Process do not have a Parent Process Id property, so we will have to use WMI to find processes with a given parent.

PS C:\> Get-WmiObject win32_process -Filter "ParentProcessId=5552" |
% { Get-Process -Id $_.ProcessID }

Get-WmiObject (alias gwmi) is used to access WMI in order to get all processes with a Parent Process Id of 5552. The results are piped into a ForEach-Object (alias %) loop. In the loop we use Get-Process and the Process Id retrieved from WMI in order to get the process object. We can then pipe that into our kill(er). Similar to what Ed did, we want to run this continuously so he doesn’t have a chance. Here is what our command looks like:

PS C:\> While (1) { gwmi win32_process -Filter "ParentProcessId=5552" |
% { ps -Id $_.ProcessID } | kill -f }

We also want to make sure that Ed isn’t able to run anything from his user directory (which includes his desktop).

PS C:\> While (1) { ps | ? { $_.Path -like "c:\users\ed\*" } | kill -f }

We use the Where-Object (alias ?) to filter our list of processes based on the path. The Like operator is used with our wildcard search string in order to find any of Ed’s processes. Again, we pipe the results into Stop-Process in order to kill it.

Just to make sure that Ed doesn’t run anything, we will kill any process where he is the owner. Again, we will have to use WMI in order to find the owner of a process.

PS C:\> While (1) { Get-WmiObject Win32_Process |
? { $_.GetOwner().User -eq "ed" } | % { Get-Process -Id $_.ProcessId } |
Stop-Process -Force }

This command is a little complicated, so let’s break it down piece by piece. The While loop portion should be obvious so we’ll skip that bit of explanation. The first chunk…

Get-WmiObject Win32_Process | ? { $_.GetOwner().User -eq "ed" }

We start off by querying WMI and retrieving WMI objects representing each process running on the current machine. The results are then piped into our filter, Where-Object (alias ?). The “current pipeline object”, represented by the variable $_, allows us to access the properties of each object passed down the pipeline. For all intents and purposes, the $_ variable is used to iterate through each object passed down the pipeline. It takes the first object, in our case the first process, and accesses the GetOwner method’s User property. We then check to see if the value is equal (-eq) to “ed”. If it is equal, then our WMI object passes our filter and is sent further down the pipeline. Remember, the objects are WMI Process Objects, not PowerShell Process Objects, and they will need to be converted to the PowerShell version so we can natively deal with them in PowerShell. On to the conversion.

... | % { Get-Process -Id $_.ProcessId } ...

The objects that passed through the filter are now sent into our ForEach-Object (alias %) loop. This loop is used to iterate through each object and execute some fu on each of the WMI objects. Again, $_ represents the current object. To retrieve the PowerShell version of the process object we use Get-Process. We need to use Id parameter with the Process Id property of the current object ($_.ProcessId). Now we have PowerShell Process Objects. YAY!

... | Stop-Process -Force

Finally, the processes are piped into Stop-Process to be destroyed. The Force option is used since we don’t want a confirmation to kill each process.

Next, let’s look for the processes with the injected Meterpreter dll. How do we find this dll? We need to look at the modules a process has loaded. Here is what the Modules property looks like for the PowerShell process.

PS C:\> Get-Process powershell | select modules

Modules : {System.Diagnostics.ProcessModule (powershell.exe), System.Diagnostic
s.ProcessModule (ntdll.dll), System.Diagnostics.ProcessModule (kernel
32.dll), System.Diagnostics.ProcessModule (KERNELBASE.dll)...}

As you can see the dll name is wrapped in parenthesis. So here is how we kill it.

PS C:\> Get-Process | ? { $_.Modules -like "*(metsrv.dll)*" } | Stop-Process

Actually, the modules property is a collection of module objects. So we can use a nested Where-Object to filter.

PS C:\> ps | ? { $_.Modules | ? {$_.ModuleName -eq "metsrv.dll" }} | kill

In this command we retrieve all the processes. We then filter the Modules, where the ModuleName is metsrv.dll. The results are piped into Stop-Process.

We can also parse netstat in order to kill a process similar to Episode #76. Let’s take that command and wrap it in our infinite loop.

PS C:\> While (1) { netstat -ano | ? {$_ -like "*:47145 *"} |
% { $_ -match "\d+$"; stop-process $matches[0] } }

And as Ed said, be careful not to kill the wrong process or the whole box could go down. Of course, when it is down it is pretty dang hard to attack. Of course, it is also pretty dang hard to use too.

Now that Ed and I have spent all of our energy going after each other, Hal is going to show up and mop the floor with our tired carcases.

Disclaimer: No Eds where harmed in the making of this episode.

Hal’s Analysis:

Why are Ed and Tim so angry all the time? It couldn’t have anything to do with the platform they’ve chosen to work on, could it? Hey guys, don’t worry, be happy! You can always install Linux for free, or even just use Cygwin.

When Ed first proposed this topic, I was pretty stoked because I thought it was going to be a cake-walk for me with my little friend lsof. But not all of Ed’s challenges that could be answered purely with lsof. Some required a bit more shell fu.

Let’s start with the simple stuff first. The “infinite loop with 1 second delay” idiom for bash is something we’ve seen before in previous Episodes:

# while :; do [...your commands here...]; sleep 1; done

In this case, the commands we put into the while loop are going to be a kill command and usually some variant of “`lsof -t …`” we’ll be using to select the PIDs we want to kill. Remember from previous Episodes that “lsof -t” causes lsof to print out just the PIDs of the matching processes, specifically so we can use the output as arguments to the kill command.

For example, let’s suppose we want to kill all of Ed’s processes. We can use lsof’s “-u” option to select processes for a particular user:

# while :; do kill -9 `lsof -t -u skodo`; sleep 1; done

Or we could nuke all the bash shells on the machine, using “-c” to select commands by name:

# while :; do kill -9 `lsof -t -c bash`; sleep 1; done

Of course, this would hammer our own shell, so it pays to be more selective:

# while :; do kill -9 `lsof -t -a -c bash -u^root -u^hal`; sleep 1; done

Here I’ve added the “-a” flag which means do a logical “and” on my selection criteria. Those criteria are “all commands named bash” (“-c bash”) and “not user root” (“-u^root”) and “not user hal” (“-u^hal”). Note that lsof’s negation operator (“^”) only works when selecting user names, PIDs (with “-p”), process group IDs (with “-g”), command names (with “-c”), and protocol state info (“-s”, as in “-s^TCP:LISTEN”).

Another one of Ed’s challenges was killing processes where the binary is in a particular directory. Again we can do this with lsof:

# while :; do kill -9 `lsof -t -a -d txt +d /home/skodo`; sleep 1; done

Here we’re looking for process binaries using “-d txt”. In the lingo, the binary is what’s used to create the “text segment” of a process (where the executable code lives), hence “-d txt” for lsof. The “+d” tells lsof to look for open files under a particular directory. Yes, lsof has so many command line options that the author had to start doubling up on letters using “+” instead of “-” (there’s a reason the lsof manual page is nearly 50 pages long when printed out).

Note that “+d” only searches “one level deep”. So if Ed were running “/home/skodo/evil”, then our loop above would whack that process. But if Ed were running “/home/skodo/bin/evil”, then we wouldn’t catch it. If you want to do full directory recursion, use “+D” instead of “+d”. lsof distinguishes these with separate options because full directory searches are so time-consuming.

However, as I mentioned earlier, Ed had challenges that I wasn’t able to come up with a “pure lsof” solution for. For example, while lsof has the “-R” option for displaying parent process ID (PPID) values, there aren’t any switches in lsof to select particular processes by PPID. So we’ll need to resort to some awk:

# while :; do kill -9 `lsof -R -d cwd | awk '($3 == 8552) { print $2 }'`; sleep 1; done

Here the lsof command is outputting PPID values (“-R”) in addition to the normal lsof output, and we’re only outputting the lines showing the current working directory of each process (“-d cwd”). The “-d cwd” hack is a good way of ensuring that you only get one line of lsof output per process– so we don’t end up outputting the same PID multiple times and generating spurious error messages from kill. The awk code simply matches against a particular PPID value in column #3 and outputs the PID value in column #2.

Even though I had to resort to a bit of awk in the last example, you have to admit that having lsof makes this challenge unfairly easy for us Unix/Linux folks. Ahhh, lsof! How I love thee! Let me count the ways…

USB History

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Ed Embarks:

Believe it or not, one of the things that we strive for in this blog is to be, not to put too fine a point on it, actually useful. We keep our musings here away from the theoretical and focused on the practical, in the hopes of helping people do their jobs better with a little bit of command-line fun. Almost* nothing gives Hal that special warm glow like e-mail from readers telling us that a recent article saved them tons of work, or allowed them to accomplish something they thought impossible. And, once Tim taught his mom to spoof e-mail addresses, the amount of such e-mail we receive has gone up a full 33% since we brought Tim on board.

Regular readers know that most of the techniques we cover here are focused on system administration and security work (such as audit, penetration testing, or, occasionally, forensics). For this episode, I’d like to address a technique that I find quite useful in my forensics work. As is our way, I’ll talk about it in good ol’ cmd.exe. But, I’m especially interested in seeing what magickal incantations Tim can add with PowerShell, and then I really want to see how Hal can tease this kind of information from Linux.

Sometimes, when working on a forensics case, we need to determine whether a given USB device was plugged into a given computer. Perhaps we are wondering if a user brought in an unauthorized USB token and attached it, infecting their system with malware which then spread. Or, maybe we want to get an idea if an intruder with physical access to a machine plugged in a USB hard drive so he or she could have copied large numbers of files. Sometimes, for a huge number of reasons, we need historical information about USB activities on the box for some extra proof of a perpetrators actions.

Windows stores information in the registry about every USB device plugged into the box. We can view this information with the following command:

c:\> reg query hklm\system\currentcontrolset\enum\usbstor /s

HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52

HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0
DeviceDesc REG_SZ @disk.inf,%disk_devdesc%;Disk drive
Capabilities REG_DWORD 0x10
HardwareID REG_MULTI_SZ USBSTOR\DiskSanDisk_Enterprise______6.52\0USBS
TOR\DiskSanDisk_Enterprise______\0USBSTOR\DiskSanDisk_\0USBSTOR\SanDisk_Enterprise______6\0SanDisk_Enterprise______6\0USBSTOR\GenDisk\0GenDisk
CompatibleIDs REG_MULTI_SZ USBSTOR\Disk\0USBSTOR\RAW
ClassGUID REG_SZ {4d36e967-e325-11ce-bfc1-08002be10318}
Driver REG_SZ {4d36e967-e325-11ce-bfc1-08002be10318}\0001
Class REG_SZ DiskDrive
Mfg REG_SZ @disk.inf,%genmanufacturer%;(Standard disk drives)
Service REG_SZ disk
ConfigFlags REG_DWORD 0x0
FriendlyName REG_SZ SanDisk Enterprise USB Device

HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Device Parameters

HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Device Parameters\MediaChangeNotification

HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Device Parameters\Partmgr
Attributes REG_DWORD 0x0

HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\LogConf

HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Properties
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Control

The /s indicates that I want the reg command to recurse the Registry, showing all settings under this area. In my output, I first see an indication of the vendor and product information, which is prefaced with “Disk&Ven”. I can just pull that information by piping the output through the find command in a case-insensitive (/i) fashion:

c:\> reg query hklm\system\currentcontrolset\enum\usbstor /s | find /i "Disk&Ven"

Here, you’ll see stuff like SanDisk (for a lot of thumb drive memory tokens), Lexar, WD, SAMSUNG, and much more. You’ll also typically see a “Prod” indication on this same line, showing the product name or number the vendor associates with the device. A quick Google search on the vendor and product data will often show you more details about the product.

After that, we get a registry entry with a unique id number associated with the device (0B919380B2629895&0 in the example above). This value is derived from a serial number from the device. With this number, I can track the usage of a single USB device across multiple machines.

Also, keep in mind that the reg key can be used remotely, so I can pull this data from target systems where I have admin credentials and SMB access, by simply prefixing the hklm above with \\MachineName\. Oh, and one more nifty bonus: The reg key is case insensitive, so I don’t have to memorize the annoying CamelCase nonsense of registry keys when using reg. No, unfortunately, the cmd.exe reg command doesn’t have tab autocomplete with registry paths, something that I’m sure Tim is going to extol in his PowerShell write-up.

*Don’t ask. You really don’t wanna know.

Tim finds his way in:

So we are digging to the registry huh? Well, that’s easy. Especially with tab completion! (Insert angel AAAAAAAAHHHHH sound here) Tab completion in the registry is such a hand feature, expecially when you can’t remember if the CurrentVersion key has a space in the middle (it doesn’t).

PS C:\> gci -r HKLM:\SYSTEM\curr<Press tab>

PS C:\> gci -r HKLM:\SYSTEM\CurrentControSet

See how easy that was? That saved a dozen key strokes, keystrokes that can be shipped to the keystroke challenged and help them with their crops and…uh…let’s get back to what we are supposed to be working on.

So we are using Get-ChildItem, the same command we use to browse the file system. However, when we use Get-ChildItem with the registry it doesn’t display the values. Why? Well, you don’t see the contents of files with you do a directory listing do you? Ok, that is a bit weak, but it does make sense if you think about it just right.

Another thing that might take you by surprise is that you can “change directory” into the registry. Technically “cd” is an alias for Set-Location, but it still works the same as the “cd” you know and love from the other shells.

PS C:\> cd HKLM:
PS HKLM:\> cd software
PS HKLM:\SOFTWARE> ls

Hive: HKEY_LOCAL_MACHINE\SOFTWARE

SKC VC Name Property
--- -- ---- --------
1 0 ActiveTouch {}
4 0 Adobe {}
1 0 AGNS {}
2 0 Alps {}
...

Now that you have seen some of the mind-bending features of PowerShell let try to recreate what Ed did.

PS C:\> gci -r HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR | select name
Name
----
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Device Parameters
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Device Parameters\MediaChangeNotification
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Device Parameters\Partmgr
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\LogConf
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Properties
HKEY_LOCAL_MACHINE\system\currentcontrolset\enum\usbstor\Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52\0B919380B2629895&0\Control
...

We use -r, which is short for Recurse, in order to show all the keys below our current location. Now let’s find all of the devices that have been plugged in.

PS C:\> gci -recurse HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR |
? { $_.PSPath -match ".*Disk&Ven[^\\]*$" } | select PSChildName
Disk&Ven_SanDisk&Prod_Enterprise&Rev_6.52
Disk&Ven_&Prod_USB_Flash_Memory&Rev_PMAP
Disk&Ven_Generic&Prod_&Rev_6000
Disk&Ven_IronKey&Prod_Secure_Drive&Rev_1.00
...

First, we get the results of Get-ChildItem. Next, we filter the results based on a regular expression. The regular expression looks for Disk&Ven followed by any characters that are NOT a backslash. Finally, we select the name of the node using the PSChildName property. The PSChildName is the name of the node in question. The property name leaves a little to be desired, but it works.

We got the Vender &: Product info, and we can use a similar command to get all the unique ids.

PS C:\> gci -recurse HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR |
? { $_.PSParentPath -match ".*Disk&Ven[^\\]*$" } | select PSChildName
0B919380B2629895
...

The difference between the commands is subtle. In the second command we use our regular expression on the parent item, not the current item. This takes us one step deeper and gets us the unique id.

PowerShell allows us to use the .NET framework, which gives us access to a lot of cool tools. While I wasn’t able to finish it for this episode, we can use the Windows API in order to get the last write time of the registry keys. It isn’t pretty, but it works. Much like some friends of mine.

Hal is happy to come along

I was really happy when Ed proposed this idea because the Linux side was something I’d been meaning to research for quite some time now. But now Ed just let me in on where all of those fan emails are coming from and I’m all depressed. Ah well, nothing to do but get really geeky in order to take my mind of things.

So your first question might be, how exactly does one research something like this? I went for the “brute force and massive ignorance” approach, using a technique similar to the find trick I discussed back in Episode #29. I simply used touch to update the timestamp on an empty file, plugged in the USB device, and then did a “find … -newer …” to locate any files that had changed as a result of the device being inserted. So the command line looked like:

# touch /root/timestamp
[... plug in USB device ...]
# find / -newer /root/timestamp

The results were actually quite interesting and fairly consistent across the two Linux distros I tested against: CentOS 5.4 (a Red Hat derivative running kernel v2.6.18) and Ubuntu 9.10 aka “Karmic Koala” (a Debian derivative running kernel v2.6.31). Here’s what I found:

1. When the device is plugged in, it inherits the next available “sd” device name. So on my laptop, for example, the internal drive is “sda”, so the first USB device gets “sdb”, the second “sdc”, and so on. Also a number of symlinks are created under /dev pointing to the sd device for the USB drive that was just inserted. Here’s some of the pathnames to show you what I’m taking about:

/dev/disk/by-uuid
/dev/disk/by-uuid/80a5317f-8e4c-4c83-88ea-b5192b442f97
/dev/disk/by-path
/dev/disk/by-path/pci-0000:02:02.0-usb-0:1:1.0-scsi-0:0:0:0-part1
/dev/disk/by-path/pci-0000:02:02.0-usb-0:1:1.0-scsi-0:0:0:0
/dev/disk/by-id
/dev/disk/by-id/usb-Kingston_DataTraveler_2.0_8990000000000000000000B0-part1
/dev/disk/by-id/usb-Kingston_DataTraveler_2.0_8990000000000000000000B0
/dev/.udev/links
/dev/.udev/links/disk\x2fby-uuid\x2f80a5317f-8e4c-4c83-88ea-b5192b442f97
/dev/.udev/links/disk\x2fby-uuid\x2f80a5317f-8e4c-4c83-88ea-b5192b442f97/b8:17
/dev/.udev/links/disk\x2fby-path\x2fpci-0000:02:03.0-usb-0:1:1.0-scsi-0:0:0:0-part1
/dev/.udev/links/disk\x2fby-path\x2fpci-0000:02:03.0-usb-0:1:1.0-scsi-0:0:0:0-part1/b8:17
/dev/.udev/links/disk\x2fby-id\x2fusb-Kingston_DataTraveler_2.0_8990000000000000000000B0-0:0-part1
/dev/.udev/links/disk\x2fby-id\x2fusb-Kingston_DataTraveler_2.0_8990000000000000000000B0-0:0-part1/b8:17
/dev/.udev/links/disk\x2fby-path\x2fpci-0000:02:03.0-usb-0:1:1.0-scsi-0:0:0:0
/dev/.udev/links/disk\x2fby-path\x2fpci-0000:02:03.0-usb-0:1:1.0-scsi-0:0:0:0/b8:16
/dev/.udev/links/disk\x2fby-id\x2fusb-Kingston_DataTraveler_2.0_8990000000000000000000B0-0:0
/dev/.udev/links/disk\x2fby-id\x2fusb-Kingston_DataTraveler_2.0_8990000000000000000000B0-0:0/b8:16

You can see the manufacturer name for the device (“Kingston DataTraveler 2.0″), the serial number of the device (“8990000000000000000000B0″), and the UUID associated with the file system on the device (“80a5317f-8e4c-4c83-88ea-b5192b442f97″) in the path names above. And if you look closely, you’ll see that there’s a single partition on the device (in addition to the links that point to the device as a whole). If you wanted to, you could also run the mount command (see Episode #59) to get more information about this file system.

The only problem with all of this information is that it’s completely ephemeral. As soon as the drive is removed, all of this information goes away. So from an “after the fact” sort of forensic perspective, it’s not really all that useful.

2. In addition to the device files and links under /dev, the OS also creates some information files under /dev/.udev/db. CentOS calls these files names like “/dev/.udev/db/block@sdb” and “/dev/.udev/db/block@sdb@sdb1″, while the newer kernel on my Ubuntu box uses names like “/dev/.udev/db/block:sdb” and “/dev/.udev/db/block:sdb1″, but the basic information in the files is pretty much the same. Here’s the data in the “/dev/.udev/db/block:sdb1″ file from my Ubuntu system:

N:sdb1
S:block/8:17
S:disk/by-id/usb-Kingston_DataTraveler_2.0_8990000000000000000000B0-0:0-part1
S:disk/by-path/pci-0000:02:03.0-usb-0:1:1.0-scsi-0:0:0:0-part1
S:disk/by-uuid/80a5317f-8e4c-4c83-88ea-b5192b442f97
W:51
E:ID_VENDOR=Kingston
E:ID_VENDOR_ENC=Kingston
E:ID_VENDOR_ID=0951
E:ID_MODEL=DataTraveler_2.0
E:ID_MODEL_ENC=DataTraveler\x202.0
E:ID_MODEL_ID=1603
E:ID_REVISION=1.00
E:ID_SERIAL=Kingston_DataTraveler_2.0_8990000000000000000000B0-0:0
E:ID_SERIAL_SHORT=8990000000000000000000B0
E:ID_TYPE=disk
E:ID_INSTANCE=0:0
E:ID_BUS=usb
E:ID_USB_INTERFACES=:080650:
E:ID_USB_INTERFACE_NUM=00
E:ID_USB_DRIVER=usb-storage
E:ID_PATH=pci-0000:02:03.0-usb-0:1:1.0-scsi-0:0:0:0
E:ID_FS_UUID=80a5317f-8e4c-4c83-88ea-b5192b442f97
E:ID_FS_UUID_ENC=80a5317f-8e4c-4c83-88ea-b5192b442f97
E:ID_FS_SEC_TYPE=ext2
E:ID_FS_VERSION=1.0
E:ID_FS_TYPE=ext3
E:ID_FS_USAGE=filesystem
E:DKD_PARTITION=1
E:DKD_PARTITION_SCHEME=mbr
E:DKD_PARTITION_NUMBER=1
E:DKD_PARTITION_TYPE=0x83
E:DKD_PARTITION_SIZE=4018885632
E:DKD_PRESENTATION_NOPOLICY=0

There isn’t a whole lot here we couldn’t have pulled out of the link names shown above, but this format is definitely a lot more readable. Unfortunately, this file is also ephemeral and gets cleaned up as soon as the drive is disconnected from the system.

At this point you’re probably asking yourself if there’s any forensic technique we could use to recover the deleted. The bad news is that both the links and the db files created by the device insertion are created in a memory-based file system:

$ df /dev/.udev
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1992768 276 1992492 1% /dev
$ df /dev/disk
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1992768 276 1992492 1% /dev

Assuming the system hasn’t been rebooted since the device was inserted, I suppose it’s possible that you might find some strings still floating around in the memory image of the system (or possibly in the disk-based swap area). But frankly, I don’t hold out much hope for you. At least the db file has a nice regular structure to assist in searching.

3. There are, however, some more permanent records of the device having been connected to the system. Any of you who’ve been using Linux for a while know that when you hook up a removable device to the system, the Nautilus agent in the standard Gnome desktop will position an icon on the desktop that represents the device. You may have noticed that if you disconnect and later reconnect the same device, the icon will always re-appear in the same spot on the desktop. Nautilus keeps track of this in a file in your home directory.

On CentOS, the file is called “~/.nautilus/metafiles/x-nautilus-desktop\:%2F%2F%2F.xml” and looks like this:

<?xml version="1.0"?>
<directory><file name="trash" timestamp="1200596020" icon_position="64,182"/>
<file name="home" timestamp="1200596020" icon_position="64,102"/>
<file name="computer" timestamp="1200596020" icon_position="64,22"/>
<file name="CD-ROM%20Drive.volume" timestamp="1206558600" icon_position="64,282"/>
<file name="CD-RW%2FDVD%C2%B1RW%20Drive.volume" timestamp="1212709603" icon_position="64,282"/>
<file name="465.8%20GB%20Volume.volume" timestamp="1263069239" icon_position="64,282"/>
<file name="USB%20DISK%202.0.volume" timestamp="1263070714" icon_position="64,282"/>
<file name="Kingston%20DataTraveler%202.0.volume" timestamp="1263073745" icon_position="64,582"/></directory>

What’s interesting to me about this file is the time stamp value. The time stamp is in the Unix “seconds since Jan 1, 1970″ format, but this can easily be converted to something human readable, if my co-authors will permit me to use a little bit of Perl:

$ perl -e 'print scalar(localtime(1263073745)), "\n";'
Sat Jan 9 13:49:05 2010

The only problem is that this time stamp value gets updated if the user moves the icon for the device around on their desktop. But since users don’t tend to do this very often, it usually reflects the time the device was first connected to the system.

On my Ubuntu box running a newer version of Gnome, the Nautilus agent actually creates a separate file for each new device. For example, the information for the “4.0 GB Filesystem” on my Kingston device ends up in a file called “~/.gconf/apps/nautilus/desktop-metadata/4@46@0@32@GB@32@Filesystem@46@volume/%gconf.xml”, which looks like this:

<?xml version="1.0"?>
<gconf>
<entry name="nautilus-icon-position-timestamp" mtime="1263074552" type="string">
<stringvalue>1263074552</stringvalue>
</entry>
<entry name="icon-scale" mtime="1263074552" type="string">
<stringvalue>1</stringvalue>
</entry>
<entry name="nautilus-icon-position" mtime="1263074552" type="string">
<stringvalue>64,10</stringvalue>
</entry>
</gconf>

What’s nice about the newer file format is that there are multiple time stamps in the file. The “icon-scale” time stamp does not get updated if the user repositions the icon on their desktop, and therefore may give you a truer reading on when the device was first connected to the system.

The only problem with data in a user’s home directory, is that an astute user may clean up after themselves if they’re doing something nefarious. And they may use a secure deletion tool (see Episode #32) to prevent recovery of the data.

4. The last place to find information about the device is in the system logs. Both the kernel and the file system drivers log information about the device being inserted.

Here’s the log from my CentOS system when the device is inserted:

Jan 9 13:51:22 localhost kernel: usb 1-1: new high speed USB device using ehci_hcd and address 8
Jan 9 13:51:22 localhost kernel: usb 1-1: configuration #1 chosen from 1 choice
Jan 9 13:51:22 localhost kernel: scsi7 : SCSI emulation for USB Mass Storage devices
Jan 9 13:51:28 localhost kernel: Vendor: Kingston Model: DataTraveler 2.0 Rev: 1.00
Jan 9 13:51:28 localhost kernel: Type: Direct-Access ANSI SCSI revision: 02
Jan 9 13:51:28 localhost kernel: SCSI device sdb: 7856128 512-byte hdwr sectors (4022 MB)
Jan 9 13:51:28 localhost kernel: sdb: Write Protect is off
Jan 9 13:51:28 localhost kernel: sdb: assuming drive cache: write through
Jan 9 13:51:28 localhost kernel: SCSI device sdb: 7856128 512-byte hdwr sectors (4022 MB)
Jan 9 13:51:28 localhost kernel: sdb: Write Protect is off
Jan 9 13:51:28 localhost kernel: sdb: assuming drive cache: write through
Jan 9 13:51:28 localhost kernel: sdb: sdb1
Jan 9 13:51:28 localhost kernel: sd 7:0:0:0: Attached scsi removable disk sdb
Jan 9 13:51:28 localhost kernel: sd 7:0:0:0: Attached scsi generic sg1 type 0
Jan 9 13:51:29 localhost kernel: kjournald starting. Commit interval 5 seconds
Jan 9 13:51:29 localhost kernel: EXT3 FS on sdb1, internal journal mode.
Jan 9 13:51:29 localhost hald: mounted /dev/sdb1 on behalf of uid 500

And here’s what happens when the device is removed:

Jan 9 14:00:43 localhost hald: unmounted /dev/sdb1 from '/media/disk' on behalf of uid 500
Jan 9 14:00:47 localhost kernel: usb 1-1: USB disconnect, address 8

You’ll notice that the system logs the UID of the user on the console of the system, as well as giving you information about the device name (no serial number though), and the size and type of file system found on the device.

The information logged on my Ubuntu box with a newer kernel version is slightly different:

Jan 9 14:02:26 ubuntu kernel: [ 2350.984617] usb 1-1: new high speed USB device using ehci_hcd and address 5
Jan 9 14:02:26 ubuntu kernel: [ 2351.365130] usb 1-1: configuration #1 chosen from 1 choice
Jan 9 14:02:26 ubuntu kernel: [ 2351.377732] scsi6 : SCSI emulation for USB Mass Storage devices
Jan 9 14:02:26 ubuntu kernel: [ 2351.378321] usb-storage: device found at 5
Jan 9 14:02:26 ubuntu kernel: [ 2351.378330] usb-storage: waiting for device to settle before scanning
Jan 9 14:02:31 ubuntu kernel: [ 2356.399268] usb-storage: device scan complete
Jan 9 14:02:31 ubuntu kernel: [ 2356.404119] scsi 6:0:0:0: Direct-Access Kingston DataTraveler 2.0 1.00 PQ: 0 ANSI: 2
Jan 9 14:02:31 ubuntu kernel: [ 2356.406027] sd 6:0:0:0: Attached scsi generic sg2 type 0
Jan 9 14:02:31 ubuntu kernel: [ 2356.438414] sd 6:0:0:0: [sdb] 7856128 512-byte logical blocks: (4.02 GB/3.74 GiB)
Jan 9 14:02:31 ubuntu kernel: [ 2356.441587] sd 6:0:0:0: [sdb] Write Protect is off
Jan 9 14:02:31 ubuntu kernel: [ 2356.441594] sd 6:0:0:0: [sdb] Mode Sense: 23 00 00 00
Jan 9 14:02:31 ubuntu kernel: [ 2356.441599] sd 6:0:0:0: [sdb] Assuming drive cache: write through
Jan 9 14:02:31 ubuntu kernel: [ 2356.463161] sd 6:0:0:0: [sdb] Assuming drive cache: write through
Jan 9 14:02:31 ubuntu kernel: [ 2356.463231] sdb: sdb1
Jan 9 14:02:31 ubuntu kernel: [ 2356.495857] sd 6:0:0:0: [sdb] Assuming drive cache: write through
Jan 9 14:02:31 ubuntu kernel: [ 2356.495900] sd 6:0:0:0: [sdb] Attached SCSI removable disk
Jan 9 14:02:32 ubuntu kernel: [ 2356.945441] kjournald starting. Commit interval 5 seconds
Jan 9 14:02:32 ubuntu kernel: [ 2356.957462] EXT3 FS on sdb1, internal journal
Jan 9 14:02:32 ubuntu kernel: [ 2356.957535] EXT3-fs: mounted filesystem with writeback data mode.
[... device is removed ...]
Jan 9 14:12:17 ubuntu kernel: [ 2942.693376] usb 1-1: USB disconnect, address 5

You’ll notice that the Ubuntu system isn’t logging the UID of the user on the console at the time the drive is connected. But you could always get this information by running “last” to get the last login history of the system. The other problem, however, is that the newer kernel logs use a slightly different format for reporting the device manufacturer info, so there isn’t a simple grep expression that will work when parsing logs from multiple different kernel versions.

Phew! That’s a whole lot of information! The short summary, though, is that the only data that may exist long after the drive has been removed is the limited data in the system logs plus possibly some data in user home directories. I have to say that Windows leaves a much more detailed forensic trail. Whether you consider this a “feature” or not is up to you. I suppose it depends on whether you’re representing the prosecution or the defense.

How to convert email addresses into name, age, ethnicity, sexual orientation

From: http://maxklein.posterous.com/

So you have somehow begged, borrowed or stolen an email list of 1000 users who you believe are interested in your new service. Would it not be great if you could somehow convert that list into real people, with real photos, and perhaps even more concrete information like “My service has a higher than average gay consumer group” or “My dating service seems to be very popular among 9 year old girls”? Such information can help you correct course before you are too invested in a particular idea you have.

Well, a few weeks back, we were handed down this lovely present by our masters from above: Facebook. Save your email list as a CSV file (just comma separate those email addresses). Upload this file to your facebook account as if you wanted to add them as friends. Voila, facebook will give you all the profiles of all those users (in my test, about 80% of my email lists have facebook profiles). Now, click through each profile, and because of the new default facebook settings, which makes all information public, about 95% of the user info is available for you to harvest.

If your email list is too large, then use the very same CSV file and upload it to mechanical turk (a list of 10.000 would cost you about $10), and ask the mechanical turk guys to gather this information for you.

After you have all the demographic information you want, try to do good with it. My personal advice to facebook users: Switch on your privacy settings, make your friendslist private. Business want this information, and facebook has given it to them.

Update (from a reddit comment): Use this URL http://www.facebook.com/search/?ref=ffs&q=name@domain.com&o=2048&init=ffs and screenscrape for even more spammy goodness.

Say Hello to My Little Friend Netstat

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Ed greets 2010:

Many times on our little blog here, I’ve spoken appreciatively of some of my favorite Windows command-line friends, including wmic, netsh, and sc. Yes, I’ve fought the desire to personify them, but I can’t help but think of them as buddies… Buddies with annoying quirks, a bad attitude, and flaws that sometimes let you down, but compadres nonetheless.

While spending some time over the holidays hanging out with these trustworthy sidekicks, something occurred to me: We haven’t spent nearly enough time on this blog with the good ol’ netstat command. Sure, we touched upon him a little bit in analyzing protocol statistics, checking out whether we’ve got a SYN flood, and even as an example of ways to get help from Windows commands. But, so far, I’ve truly let one of my most faithful and useful commands down by not giving him the spotlight he deserves. So, without further adieu, let’s look at some really useful invocations of netstat:

Detecting when a scan reaches a given target box: So, Mike Poor and I were at a client’s facilities conducting a large-scale vulnerability scan of thousands of hosts. Mike was running the scanning tool from the corporate headquarters, while I was located at another building sitting with the client in front of one of their Windows servers that was included in Mike’s scan. The client and I wanted to know when Mike’s scan would reach us. I asked the client if I could install a sniffer on their server, or connect my laptop to a span port on the switch so I could use my own sniffer to see when Mike’s scan reached us. “No dice,” said the client, who wasn’t authorized to let us install any software or get access to the switch. I asked the client if we could logon to the Windows server and run a simple single netstat command that would show us when Mike’s scan reached us, with approximately 1 second accuracy. He said, “Sure thing,” so I ran:

C:\> netstat -na | find /i "Listening"

Here, I’m just checking to make sure there is at least one listening TCP port, piping netstat’s output through the find command in a case-insensitive fashion (/i) because I didn’t want to hold down the shift-lock key to type LISTENING. Sure enough, on this Windows server, I saw several listening ports, including TCP 445. When Mike’s scanner reached us, it would open a connection to that port.

Then, I ran:

C:\> netstat -na 1 | find "[MikePoorIPaddr]"

That little space followed by a 1 means that Netstat will re-run approximately every 1 second. I scrape through its output looking for the string of Mike’s address. If I see no output, there is no connection from Mike. When I start seeing output, I’ll know that Mike’s scan has reached me. Sure, this isn’t perfect. It’s quite possible that the scanning tool will make and drop connections so quickly that they will fall in between the 1-second interval we’re working with here. However, that’s quite unlikely. And, sure enough, we were able to determine when Mike’s scan reached us, and finished with us. We then headed for lunch.

Detecting when a piece of malware starts interacting with the network: I was in my lab, fully clothed, analyzing some malware. After it finished some initialization actions, this little gem would start listening on TCP port 47145. Again, I wanted to know when it would start to listen, with 1-second accuracy… I ran:

C:\> netstat -na 1 | find ":47145"

I then wanted to go a little further, and find when the bad guy actually made a connection to this listener. For that, I executed:

C:\> netstat -na 1 | find ":47145" | find /i "Established"

Finding the mysterious cause of an ICMP Host Unreachable Message: A student who was taking my SANS 504 class told me that he was getting a mysterious ICMP Host Unreachable message coming from their border firewall back into their network a couple times per day, and he wanted to know what was triggering it. I asked him what the destination address of the packet was. It was one of their Windows 2003 servers. So, the Windows 2003 server was trying to send a message out through the firewall, but the firewall was responding that it didn’t know how to reach the destination machine. The student wanted to know which program on the Win2K3 box was sending the original message. I had him run:

C:\> netstat -nao 1 | find "[DestIPaddr]"

As long as that program was trying to make a TCP connection, we’d see output from netstat for the half open connection, and could see the process ID number (the -o in netstat gives me the PID of the process using the port). We were then able to run the wmic command to get all kinds of info about that process:

C:\> wmic process where processid="[pid]" list full

Playing process whack-a-mole: I was playing a king-of-the-hill style capture the flag game, and my adversaries were trying to listen on a given TCP port on the target box, which I had already compromised. I wanted to simply kill any process that started on that port as quickly as possible. The netstat invocations listed above are quite nice, but they don’t really help much for this need. You see, putting the integer after the netstat invocation makes netstat run continuously, showing us its output every 1 second. We can scrape through that output with the find command, but we cannot then run any other command after that, such as a taskkill. That’s because netstat never stops running, so we cannot kickoff another command. For this, we’ll have to wrap things in a FOR /L loop to get our continuity of operation, and in a FOR /F loop, to parse out the PID from our netstat output, as follows:

C:\> for /L %i in (1,0,2) do @for /f "tokens=5" %j in ('netstat -nao ^| find ^":47145^"')
do @taskkill /f /PID %j
SUCCESS: The process with PID 3152 has been terminated.
SUCCESS: The process with PID 2432 has been terminated.
SUCCESS: The process with PID 4068 has been terminated.

Here, I’ve simply set up a FOR /L loop to count from 1 to 2 in steps of zero to implement a continuous loop. Then, at each iteration through the loop, I run a FOR /F loop set to parse the fifth column (the PID) from the output of a netstat -nao command, whose output itself is filtered by the find command looking for our port. Once I’ve got my PID, I then use taskkill to forcefully (/f) kill that PID. The evil listening process cannot listen for very long now.

Note that I’ve eliminated the 1 second delay — this thing will run as fast as it can, useful in a CtF game as long as you aren’t worried about being a performance hog. If you want a delay, we can simply add “& ping -n 2 127.0.0.1>nul” inside our FOR /F loop to ping ourselves twice (which takes about 1 second), as follows:

C:\> for /L %i in (1,0,2) do @(ping -n 2 127.0.0.1>nul & for /f "tokens=5"
%j in ('netstat -nao ^| find ^":47145^"') do @taskkill /f /PID %j)

Create a real-time network sentinel by adding a date and timestamp and dumping process info: Now, let’s really get jiggy with it. Instead of killing processes or using the above commands in an interactive mode, wouldn’t it be nice if we could run a command that would just watch a given TCP port, and when it finds something using that port, it displays the date/time and various vital aspects of that process? Of course it would!

But, we’d only want it to print information when a new processID starts to listen on the given port. That way, if one process starts and listens for a while, and then stops, and another starts up, we would capture on our output the time and details of each process that interacted with the port, a diligent sentinel gathering data for us. That would allow us to run a command that can watch for given network activity over night, and then come back to see what happened and when it happened later. I use this concept and the resulting command a lot during investigations. Check this out:

C:\> cmd.exe /v:on /c "set status=0 & for /l %i in (1,0,2) do @for /f "tokens=5"
%j in ('"netstat -nao ^| find ":47145""') do @if NOT !status!==%j echo !date!
!time! & wmic process where processid="%j" list full & set status=%j"

Sun 01/03/2010 5:36:47.79

CommandLine=nc -l -p 47145
CSName=FRED2
Description=nc.exe
ExecutablePath=C:\tools\netcat\nc.exe
ExecutionState=
Handle=3116
HandleCount=33
InstallDate=
KernelModeTime=0
MaximumWorkingSetSize=1413120
MinimumWorkingSetSize=204800
Name=nc.exe
OSName=Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1
OtherOperationCount=208
OtherTransferCount=124718
PageFaults=475
PageFileUsage=540672
ParentProcessId=3584
PeakPageFileUsage=540672
PeakVirtualSize=14987264
PeakWorkingSetSize=1953792
Priority=8
PrivatePageCount=540672
ProcessId=3116
QuotaNonPagedPoolUsage=2376
QuotaPagedPoolUsage=29780
QuotaPeakNonPagedPoolUsage=2376
QuotaPeakPagedPoolUsage=29924
ReadOperationCount=5
ReadTransferCount=15977
SessionId=0
Status=
TerminationDate=
ThreadCount=1
UserModeTime=300432
VirtualSize=14987264
WindowsVersion=5.1.2600
WorkingSetSize=1953792
WriteOperationCount=1
WriteTransferCount=72

In this command, I start by running a cmd.exe with /v:on to enable delayed variable expansion. I’ll need that, because I need to store status to track if the PID using the port changes. I then set my initial status to zero, since no process should have that PID. I then start a FOR /L loop to run everything continuously. Then, I run a FOR /F loop to invoke my netstat command, piping its output through the find command to look for that port (47145, although you could also look for an IP address, as shown earlier in the article). I take the fifth column of output, the PID, and store it in iterator variable %j. Then, in the do clause of my FOR /F loop, I use an IF command to see if my status has changed (if the status variable is NOT the same as my PID, it has changed since the last iteration). When I detect such a change, I print out the date and time (note that !status!, !date!, and !time! have the exclamation points because I want their values to float over time with delayed variable expansion). I also run wmic to get full details of the given process. Finally, I set my status to the current PID. That way, I can check to see if it changes in the next go-round. This may look complicated, but it is darn useful. I’m simply dumping output to the screen here, but you could append it to a results file if you’d like by using >>results.txt at the end.

As you can see, there are a lot of fun things my little friend netstat can do using these building blocks.

Hal jumps in:

It’s always been interesting to me how much Windows completely ripped off the Windows netstat command is like the Unix version. With some minor changes, most of Ed’s examples work perfectly well on most Unix systems. Obviously, you end up using “grep” instead of “find” to filter the output, but the netstat options are almost 100% compatible. Here’s the Unix equivalent of Ed’s first netstat command as an example of what I’m talking about:

$ netstat -na | grep -i listen

Note that the output that Ed wants to match in this example is “LISTEN” in the Unix universe, not “LISTENING”.

One important difference between Unix and Windows netstat is the way you get netstat to run continuously rather than producing one set of output and then exiting. With the Unix version, you need to use “-c” to specify continuous mode:

$ netstat -nac | grep <Mike's IP addr>

The interval for “-c” is fixed at one second– you can’t specify your own interval like you can with Windows. If you want to use a less frequent interval, you’ll have to write your own loop and use “sleep”, like so:

$ while :; do netstat -na | grep <Mike's IP addr>; sleep 5; done

Frankly, though, I think I’d just use our old friend the “watch” command instead of either “netstat -c” or the loop option:

$ watch -n 1 'netstat -na | grep <Mike's IP addr>'

The watch command is not only quicker to type than the loop, it allows us to easily choose our preferred monitoring interval, which we can’t do with “netstat -c”.

But really I wouldn’t use netstat for this at all as long as I was on a machine that had the lsof command installed. With lsof, not only can I do this in less keystrokes, but I’ll also get more information than I would from the netstat. lsof is *my* little friend and the friend of Unix admins everywhere.

The downside is that you usually have to be root to get complete output from lsof:

# watch -n 1 lsof -nPi @<Mike's IP addr>

“lsof -i @<ipaddr>” show you all connections related to the specified IP address. As with netstat, “-n” suppresses IP address to hostname mappings. However, while “netstat -n” also suppresses port number to port name mappings, lsof wants you to use the “-P” option to show numeric port numbers.

We can also use lsof to do something similar to Ed’s port monitoring examples:

# watch -n 1 lsof -nPi :47145

Notice that you prefix port numbers with a colon when using lsof, while IP addresses are prefixed with “@” as we saw above. This allows us to stack IP address and port combinations to be even more specific. For example, suppose I was interested in SSH connections to a particular box, I could write:

# watch -n 1 lsof -nPi tcp@<ipaddr>:22

The above example also shows how to specify a particular protocol type (usually “tcp” or “udp”) along with the IP address and port information. If I just wanted SSH connections to all IP addresses, I could do:

# watch -n 1 lsof -nPi tcp:22

Another advantage to using lsof instead of netstat is that lsof’s “-t” option makes “process whack-a-mole” dead easy:

# while :; do kill -9 `lsof -t -i :47145`; done

As we discussed back in Episode #69, “lsof -t” just outputs the PIDs of the matching processes. This means it’s easy to kill those processes by using backticks and the kill command as we’re doing here.

Ed’s final monitoring loop is interesting. Here’s how I’d do something similar on a Linux machine:

# while :; do
pid=`lsof -ti :47145`
[[ "X$pid" == "X" || "X$pid" == "X$lastpid" ]] && continue
lastpid=$pid
echo -n '*** '
date
ps e --cols 1600 -fl -p $pid
lsof -p $pid
done

I’m first getting the PID of the process we’re interested in using “lsof -t…”. If there’s currently no PID associated with this port, or if the current PID is the same as the previous time we ran the loop then we just start the loop all over again.

Otherwise I update the value of $lastpid and output some info about the new process. You could choose to use whatever commands you want, but here I start by throwing out some asterisks with “echo -n” so that it’s easier to find the start of each section of output. Then I follow that up with the date command to get a timestamp. Since I used “echo -n”, the date output will appear on the same line as the asterisks.

Then I use the ps command to dump some information about the process. “ps e” will dump any environment variables that are set in the process context. Since this output tends to be long, I also add the “–cols 1600″ option to specify the screen width as a larger value so that the output doesn’t get truncated (on narrower displays, the lines will simply wrap). I also use “-fl” to get the most detailed output possible. The “-p” option is used to specify the PID we’re interested in. While the ps command will give us plenty of output, I’m also using lsof to dump information about all of the open files associated with the process.

It’s worth noting that both Ed’s loop and mine assume that only one process at a time is ever going to be associated with the port we’re monitoring. But if the port is a back-door login port, you might actually have multiple connections to the port at the same time. I’d finesse this in bash by using an array to track multiple PIDs at the same time, but I think it would be next to impossible for Ed to deal with this in cmd.exe.

Tim leaps in:

Of course we can use netstat in PowerShell, but it would be mostly redundant (with the exception of the all of Ed’s For Loops). Also, Hal seems upset about Windows “stealing” netstat so let’s try the same thing in PowerShell without using netstat. Without netstat we will have to use the .NET framework available to us through PowerShell.

Here is the PowerShell and .Net equivalent of the first netstat command.

PS C:\> ([Net.NetworkInformation.IPGlobalProperties]::
GetIPGlobalProperties()).GetActiveTcpListeners()
AddressFamily Address Port
------------- ------- ----
InterNetwork 0.0.0.0 80
InterNetwork 0.0.0.0 135
InterNetwork 0.0.0.0 445
InterNetwork 192.168.1.5 139
...

Most of the information we are going to need is accessed via the IPGlobalProperties object’s methods and properties. Since we are going to be using it a lot let’s dump it into a variable so we can save keystrokes in future commands.

PS C:\> $a = [Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()

Now we can run the first command again like this:

PS C:\> $a.GetActiveTcpListeners()

The name of this method is pretty self explanatory, it returns the active TCP listeners. Not much to talk about, so we’ll move on.

The next task is to find out when Mike connects.

PS C:\> while (1) {$a.GetActiveTcpConnections() | ?
{$_.RemoteEndPoint.Address -eq "[MikePoorIPaddr]"} }

We use a while loop that will run forever since “1″ is always true (except for very small values of 1). Then we get the active TCP connections and look for Mike’s IP address.

This will really hit the processor, so we probably should put in a delay of a at least a half a second.

PS C:\> while (1) {$a.GetActiveTcpConnections() | ?
{$_.RemoteEndPoint -like "[MikePoorIPaddr]:*";
sleep -milliseconds 500}}

…or maybe two seconds

PS C:\> while (1) {$a.GetActiveTcpConnections() | ?
{$_.RemoteEndPoint -like "[MikePoorIPaddr]:*";
sleep 2}}

So no we move on to the malware that Ed was analyzing. In the example, the port to be monitored is TCP 47145.

PS C:\> $a.GetActiveTcpListeners | ? {$_.Port -eq 47145}

We get the active tcp listeners and then filter the results for connections where the local port is 47145.

Now we have the problem of killing the process. Without using netstat we don’t have a way to determine the PID. It looks like we will have to cave in an use our old friend netstat (even though Hal is trying to poison this friendship).

PS C:\> netstat -ano | ? {$_ -like "*:47145 *"} |
% { $_ -match "\d+$"; stop-process $matches[0] }

The output of netstat is filtered for connections on port 47145. Using a regular expression inside the ForEach-Object loop we look for a number at the end of the line. In regular-expression-land \d+ means at least one numeric digit and $ means it has to be at the end of the line. The number that we found is represented by the $matches object so we use the first and only match, $matches[0], with stop-process to kill it.

Ed’s grand finale, the monitoring loop done in PowerShell.

PS C:\> while(1) {netstat -ano | ? {$_ -like "*:47145 *"} |
% {
$_ -match "\d+$";
Get-Process -id $matches[0] | Format-List *;
(Get-Process -id $matches[0]).WaitForExit()
}
}

While it ain’t pretty, I think we can safely say that the PowerShell version is the easiest to read of the bunch (finally), but I did add a few extra line breaks and spaces to make it even easier to read. How does it work?

First, we have our friendly infinite while loop. Nested inside the loop is our netstat command and our filter to search for port 47145. As before, we use the match operator to find the PID. Then we get all of the properties for the process. Piping the Get-Process command into Format-List * will display all the properties, not just the most commonly used properties. Finally we wait for the process to end and then our loop continues from the beginning. By using the WaitForExit method we know when that process dies and we can look for a new process. We don’t have to worry about finding, keeping track of, and comparing the PID. It makes it much easier and cleaner. It also has the added benefit of being very light on system resources while it is waiting.

Yule Be Wanting an Explanation Then

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket
Hal returns to the scene of the crime

I opened last week’s post saying there would be no “explanations or excuses”, but apparently that wasn’t good enough for some of you. So at the request of our loyal readers, we’d like to revisit last week’s episode and explain some of the code. Especially that crazy cmd.exe stuff that Ed was throwing around.

Of course the bash code is completely straightforward:

$ ct=12; while read line; do
[ $ct == 1 ] && echo -n Plus || echo -n $ct;
echo ” $line”;
((ct–));
done < keyboards drumming
... lines removed ...
command line hist-or-y!
EoLines

First we're initializing the "ct" variable we'll be using to count down the 12 Days of Fu. Then we start a while loop to read lines from the standard input.

Within the body of the loop, we use the quick and dirty "[...] && ... || ..." idiom that I've used in previous Episodes as a shortcut instead of a full-blown "if ... then ... else ..." clause. Basically, if we've counted down to one then we want to output the word "Plus"; otherwise we just output the value of $ct. Notice we use "echo -n ..." so that we don't output a newline. This allows us to output the text we've read from the standard input as the remainder of the line. Finally, we decrement $ct and continue reading lines from stdin.

The interesting stuff happens after the loop is over. Yeah, I could have put the text into a file and read the file. But I was looking for a cool command-line way of entering the text. The "EoLines" syntax at the end of the loop starts what's called a "here document". Basically, I'm saying that the text I type in on the following lines should be associated with the standard input (of the while loop in this case). The input ends when the string "EoLines" appears by itself on a line. So all I have to do is type in the 12 lines of text for our 12 Days of Fu and then finish it off with "EoLines". After that we get our output. Neat!

Everybody clear? Cool. I now throw it over to Tim to get the lowdown on his PowerShell madness.
Tim goes back in time

Let's unwrap what we did last week.

PS C:\> $ct=12; “keyboards drumming
admins smiling
… lines removed …
command line hist-or-y!”.split(“`n”) |
% { if ($ct -eq 1) {“Plus $_”} else {“$ct $_”}; $ct– }

Here is the break down:

First, we initialize the $ct variable to begin our count down.

ct=12;

That was easy. Next, we take a multi-line string and split it in to an array using the new line character (`n) as the delimiter.

“keyboards drumming
… lines removed …
command line hist-or-y!”.split(“`n”)

We could have just as easily read in content from a file using Get-Content, but I wanted to demonstrate some new Fu that was similar to Hal’s Fu. The nice thing is that reading from a file would be an easy drop-in replacement.

Once we have an array of Fu Text, we pipe it into ForEach-Object so we can work with each line individually.

if ($ct -eq 1) {“Plus $_”} else {“$ct $_”}

Inside the ForEach-Object loop we use an IF statement to format the output. If the count is one, then we output “Plus” and the Fu Text, otherwise we output the value of $ct and the Fu Text.

Finally, we decrement the value of $ct.

$ct–

Simple right? That was pretty straightforward. But sit back, and grab some spiked Egg Nog before you proceed further.
Ed Surveys the Madcap Mayhem:

I really liked this episode because it required the use of a few techniques that we haven’t yet highlighted in this blog before. Let’s check them out, first reiterating that command:

c:\> copy con TempLines.txt > nul & cmd.exe /v:on /c “set ct=12& for /f
“delims=” %i in (TempLines.txt) do @(if not !ct!==1 (set prefix=!ct!) else (set prefix=
Plus)) & echo !prefix! %i & set /a ct=ct-1>nul” & del TempLines.txt
keyboards drumming
—-snip—-
command line hist-or-y!
^Z (i.e., hit CTRL-Z and then hit Enter)

OK… we start out with the copy command, which of course copies stuff from one file to another. But, we use a reserved name here for our source file: con. That’ll pull information in from the console, line by line, dumping the results into a temporary file, very cleverly named TempLines.txt. Of course, there is the little matter of telling “copy con” when we’re done entering input. While there are several ways to do that, the most efficient way to do so that has minimal impact on the contents of the file is to hit CTRL-Z and then Enter. Voila… we’ve got a file with our input. By the way, I throw away the output of “copy con” with a “> nul” because I didn’t want the ugly “1 file(s) copied.” message to spoil my output. By the way, it kinda stinks that that message is put on Standard Output, doesn’t it? Where I come from, that is much more of a Standard Error thing. But, I’m sure we could get into a big philosophical debate about what should go on Std Out and what should go on Std Err. But, let’s just cut the argument short and say that many Windows command line tools are all screwed up on this front, regardless of your philosophy. That’s because there are no reasonable and consistent rules for directing stuff to Std Out versus Std Err in Windows command line output.

Anyway, back to the point. I then run “cmd.exe /v:on” so I can do delayed variable expansion. That’ll let me use variables with values that can change as my command runs. Otherwise, cmd.exe will expand all variables to their values instantly when I hit Enter. I need to let these puppies float. I use the cmd.exe to execute a command, with the /c option, enclosing the command in double quotes.

So far, so good. But, now is where things get interesting.

To map to Hal and Tim’s fu, I then set a variable called ct to a value of 12, just a simple little integer. But, what’s with that & right after the 12? Well, if you leave it out, you’ll see that the output will contain an extra space in “12 keyboards drumming”… it’ll look like “12[space][space]keyboards drumming”. Where does the extra space come from? Well, check this out:

c:\> cmd.exe /v:on /c “set var=foo & echo !var!bar”
foo bar

c:\> cmd.exe /v:on /c “set var=foo& echo !var!bar”
foobar

Do you see what’s happening here? In the first command, the set command puts everything in the variable called var, starting right after the = and going up to the & (which separates the next command), and that includes the space! We have to omit that space by having [value] with the & right after it. For a more extreme example, consider this:

c:\> cmd.exe /v:on /c “set var=stuff & echo !var!blah”
stuff blah

I typically like to include a space before and after my & command separators when wielding my fu, for ease of readability. However, sometimes that extra space has meaning, so it has to be taken out, especially when used with the set command to assign a string to a variable, like the ct variable in that big command above.

Wait a second… earlier I referred to ct as an integer, and now I’m calling it a string? What gives? Just hold on a second… I’ll come back to that in just a bit.

We have to deal with our FOR loop next. I’m using a routine FOR /F loop to iterate through the contents of the TempLines.txt file. I’m specifying custom delimiters, though, to override the default space and tab delimiters that FOR /F loops like to use. With “delims=”, I’m specifying a delimiter of… what exactly? The equals sign? No… that’s actually part of the syntax of specifying a delimiter. To make an equals a delimiter, I’d have to use “delims==”. So, what is the delimiter I’m setting here? Well, friends, it’s nothing. Yeah. I’m turning off parsing, because I want the full line of my input to be set to my iterator variable. In the past, when I was but a young cmd.exe grasshopper, I would turn off such parsing by setting a delim of a crazy character I would never expect in my input file, such as a ^, with the syntax “delims=^”. But, I now realize that the most effective way to use FOR /F loops is to simply let them use you. I turn off parsing by making a custom delimiter of the empty set. Do not try and bend the spoon… That’s impossible. Instead try to realize the truth…. that there is no spoon.

Anyway, so where was I? Oh yea, with my delimiterless lines now being assigned one by one to my iterator variable of %i, I’m off and running. In the DO clause of my FOR loop, I turn off the display of commands (@) and jump right into an IF statement, to check the value of my ct variable. I expand ct into its value with a !ct!, because I’m using delayed variable expansion. Without delayed expansion, variables are referred to a %var%. My IF statement checks to see if !ct! is NOT equal (==) to 1. If it’s not, I set another variable called prefix to the value of ct.

Then, I get to my ELSE clause. Although I use ELSE a lot in my work, I have to say that this is the first time I’ve had to use it in one of our challenges on this blog. The important thing to remember with ELSE clauses in single commands (not in batch scripts) is that you have to put everything in parentheses. So, if !ct! is equal to 1, my ELSE clause kicks in and sets the prefix variable to the string “Plus”. That way, later on, I can simply print out prefix, which will contain the ct number for most of the days, but the word “Plus” for the last day.

And, here we back to that string/integer thing I alluded to above. The cmd.exe shell uses loosely typed variables. No, this is not a reference to how hard you hit the keys on your keyboard when typing. Instead, like many interpreted languages, variable types (such as strings and integers) are not hard and fast. In cmd.exe, they are evaluated in real time based on context, and they can even change in a single command. My ct variable behaves like an integer, for the most part. I can add to it, subtract from it, and store its value in another variable. But, when I defined it originally with the set command, if I had used “set ct=12 &…”, it would have been a string with the trailing space until I used it in some math, and then that space would disappear. Also, the prefix variable is given the value of ct most of the time, which is just an integer. But, when ct is one, I give the prefix variable a string of “Plus”. I’m an old C-language programmer, so this loose type enforcement kinda weirds me out. Still, it’s quite flexible.

Then, I echo the prefix (!prefix!) and the line of text (%i). I then subtract one from my ct with the “set /a ct=ct-1″, throwing the output of the set command away (>nul). Note that I want to show the prefix and the text on the same line, so I use a single echo command to display both variables on the same line. Most cmd.exe command-line tools actually put their output on standard out with a Carriage Return Line Feed (CRLF) right afterward. Thus, two echo commands, one for each variable, would have broken the prefix and the file content on separate lines, a no-no when trying to reproduce exactly the output of Hal and Tim. When formulating commands that need to display a lot of different items on a single line, I often chunk them into variables and then echo them exactly as I need them on a single line with a single echo statement.

Now, there is one interesting counter-example to the general rule that cmd.exe command-line tools insert a CRLF at the end of their output: the “set /a” command. It does its math, and then displays the output without any extraneous return, as in:

c:\> set /a 8-500 & echo hey
-492hey

I used that little fact in this fun command to spew Matrix-like gibberish on the screen from Episode #58:

C:\> cmd.exe /v:on /c “for /L %i in (1,0,2) do @set /a !random!”

When I first was working on this 12-days challenge, I was thinking about using set /a to display !ct! and then the line from the file. It would all be on the same line because of that special “no-CRLF” property of “set /a”. But, I ran into the little problem of the “Plus” for the last line of input, so I instead introduced the prefix variable and played on the loose typing. There are dozens of other ways to do this, but I tried to focus on one that, believe it or not, I thought made the most sense and was simplest.

Oh, and to close things out, I delete the TempLines.txt file. Can’t litter our file system with crap, now can we?

So, as you can see, there were a bunch of ideas we haven’t used in this blog so far that popped out of cmd.exe in this innocuous-seeming challenge, including empty-set delims, an ELSE clause, weak type enforcement, and variable building for a single line of output. That’s a lot of holiday cheer, and it makes me happy.

With that said, all of us at the Command Line Kung Fu blog would like to wish our readers a Happy and Prosperous New Year!

Yule Love It!

From: COMMAND LINE KUNG FU: PaulDotCom, Ed Skoudis, Hal Pomeranz, byte_bucket

Hal has indulged in a bit too much holiday cheer:

Presented for your enjoyment with no explanation or excuses:

$ ct=12; while read line; do
[ $ct == 1 ] && echo -n Plus || echo -n $ct;
echo " $line";
((ct--));
done <<EoLines
keyboards drumming
admins smiling
systems thrashing
networks crashing
hosts a-pinging
Windows versions
(billion) Linux distros
Windows loops!
authors coding
shells hacked
types of hosts
command line hist-or-y!
EoLines
12 keyboards drumming
11 admins smiling
10 systems thrashing
9 networks crashing
8 hosts a-pinging
7 Windows versions
6 (billion) Linux distros
5 Windows loops!
4 authors coding
3 shells hacked
2 types of hosts
Plus command line hist-or-y!

Tim got run over by a reindeer:

PS C:\> $ct=12; "keyboards drumming
admins smiling
systems thrashing
networks crashing
hosts a-pinging
Windows versions
(billion) Linux distros
Windows loops!
authors coding
shells hacked
types of hosts
command line hist-or-y!".split("`n") |
% { if ($ct -eq 1) {"Plus $_"} else {"$ct $_"}; $ct-- }
12 keyboards drumming
11 admins smiling
10 systems thrashing
9 networks crashing
8 hosts a-pinging
7 Windows versions
6 (billion) Linux distros
5 Windows loops!
4 authors coding
3 shells hacked
2 types of hosts
Plus command line hist-or-y!

Ed’s Nuts Roasting on an Open Fire:

c:\> copy con TempLines.txt > nul & cmd.exe /v:on /c "set ct=12& for /f
"delims=" %i in (TempLines.txt) do @(if not !ct!==1 (set prefix=!ct!) else (set prefix=
Plus)) & echo !prefix! %i & set /a ct=ct-1>nul" & del TempLines.txt
keyboards drumming
admins smiling
systems thrashing
networks crashing
hosts a-pinging
Windows versions
(billion) Linux distros
Windows loops!
authors coding
shells hacked
types of hosts
command line hist-or-y!
^Z (i.e., hit CTRL-Z and then hit Enter)

12 keyboards drumming
11 admins smiling
10 systems thrashing
9 networks crashing
8 hosts a-pinging
7 Windows versions
6 (billion) Linux distros
5 Windows loops!
4 authors coding
3 shells hacked
2 types of hosts
Plus command line hist-or-y!

Best wishes for a happy holiday season and a joyous and prosperous new year!