Archives for the Month of August, 2005

PDC — TLN303 Monad: Advanced Command Line Scripting

For those of you going to the PDC, make sure to check these two out:

TLN303 - Monad: Advanced Command Line Scripting
September 13, 2:45 PM - 4:00 PM
404 AB
Jeffrey Snover, Jim Truher
Learn about Monad, Microsoft's next generation command line scripting solution. Monad combines the interactivity of KSH or BASH, the programmability of Perl or Ruby, and the production-orientation of AS400 CL or VMS DCL.

PNL03 - Scripting and Dynamic Languages on the CLR
September 16, 8:30 AM - 10:00 AM
515 AB
Bruce Payette, Dave Thomas, Erik Meijer, Jim Hugunin, Jim Miller, Paul Vick
With the recent rise in popularity of dynamic languages as a first class tool for software development, there are new questions around how to effectively use these tools, and how well they play in the .NET ecosystem. Join members of the CLR team, Microsoft languages teams, and external language implementers in a panel to answer questions around when and where dynamic languages should be used, the futures of these languages, and open discussion on the challenges and opportunities of implementing dynamic languages on the CLR.

In the first, Jeffrey and Jim will be presenting a detailed introduction to Monad.  These sessions usually end up being standing-room only, generating both spontaneous applause and cheers. 

In the second, Bruce will be part of the panel discussing scripting and dynamic languages on the CLR.

If you do plan to attend either presentation, please consider adding it to your PDC Session Scheduler soon.  This helps us plan for the appropriate audience size, and to gauge interest.

Also, Jeff Jones, Jim Truher, and I will be staffing Monad's "Hands on Labs."  In the hands on labs, you get to play with the shell, implement a C# cmdlet, and implement a cmdlet provider.  We'll also spend time in the track lounge, should you just want to chat.

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Another Benefit of Monad's WinFX Membership — SDK Documentation

As Adam and I mentioned before, Monad is now available in very public beta via the WinFX installer.

As Adam mentions in his post, "It's not installed by default (due to a last-minute setup integration problem), so you have to go to the Start menu, choose `"All Programs`", then `"Microsoft Windows SDK`", then `"Install Windows Command Shell`". That runs our standard installer (the same one you get from betaplace)." [Those back-ticks are my first Monad inside joke!]

Anyhow, part of the fun of SDK membership is SDK Documentation.  Feel free to browse our Getting Started Guide, our Conceptual Overview, or even our (mostly incomplete) API Documentation.

Of course, you can also do site-specific searches from search engines to help you glean the content quicker: MSH format-table .

(The equivalent MSN Search returns no results, sorry... )

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Monad team blog now up!

One of the shames about our team is that not all of the brilliant members have blogs.  One could also argue that none of the brilliant members have blogs 🙂

In any case, we're looking to fix that -- as we now have a Monad Team blog, where other folks from Monad will have a chance to contribute.  You'll recognize many of the names from our BetaPlace newsgroups -- Jeff and Marcel have already posted a few articles.


[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Cracking Software to Run as Non-Admin

This is one of the lamer things I’ve done as a computer geek, and that’s saying a lot.  However, any self-respecting person does not compromise on their values.  One of my computer values happens to be “Run with Least Privilege.”

What’s a geek to do, then, when a cherished application fails to run under a non-admin account?  Often, the solution is more of a negotiation between your security goals, and the software reality.  A program scribbles all over its installation directory (in Program Files\<Program>,) so you grudgingly grant yourself full control over that specific directory.  Or, it performs a similar travesty by continually modifying data under HKLM\Software\<Vendor>\<Program>.  So, you grudgingly grant yourself full control over that specific registry key.

Now, the cherished software in question is very helpful: Macro Maker.  It’s a very useful macro program, but not very friendly when run as a non-Administrator.

After installing it (as Administrator,) you run into issues the first time you run it:

Temporarily(!) giving ourselves full access to this key makes the error go away, and the program loads fine.  However, that’s not something I’m willing to negotiate.  If I have full access to HKLM\Software, I can completely destroy my system, as can malware acting on my behalf.  I can add spyware to my startup folders, and much more.  So, hastily remove our elevated permissions from the Software key.

Next, we fire up RegMon from a MakeMeAdmin window to see what the problem is.  Set your filter to MacroMaker.exe, and try to run the program again.  The offending entry appears:

The requested access is 0xF003F (just off of the screen shot above.)  You can determine what this means by looking in MSDN, or by looking up the values for the registry access flags in the header files that ship with Visual Studio.

However, we intend to fix the program, so let’s try another approach.  Before we start, copy “MacroMaker.exe” to “MacroMaker.exe.bak.”

Now, open up OllyDbg from a MakeMeAdmin window, and then open the MacroMaker.exe program.  The main debugging window comes up, so right-click it.  Select “Search for | All referenced text strings.”

In the window that pops up, right-click and select “Search for text.”  Search for “Error opening Software key.”  OllyDbg shows a hit, so double-click on it.

Now, OllyDbg has some pretty awesome analysis capabilities.  It’s pinpointed the entrypoint to the assembler routine several lines above: “> 6A 00”.  Right-click that line, and select “Find references to | Selected command.”  OllyDbg opens a references window that shows two locations: “JNZ MacroMak.00410E71” (may be different on your system,) and “PUSH 0, (Initial CPU Selection).”  The first one is a jump into this routine, while the second is the routine itself.  Double click on the first address.

The culprit pops out almost immediately, 6 lines above the jump to the “Error Routine:”

MacroMaker opens the Software key (presumably to see if it exists,) but uses KEY_ALL_ACCESS as the access request.   Do you recognize the number in the assembly instruction for that line?  PUSH 0F0030F.

So how do we fix this?  Well, we’ll make it request only KEY_READ access.  After all, that’s all it should require.

MSDN documents the values for the registry access flags well in this article.  The value for KEY_READ is 0x20019.  Double-click the line with “Access = KEY_ALL_ACCESS,” and change “PUSH 0F003F” to “PUSH 020019”, then click “Assemble.”

Right-click anywhere in the disassembly window, and select “Analysis | Analyze Code.”  Voila, it now requests KEY_READ access.

Right-click the disassembly area again, select “Copy to executable | All modifications,”  then click “Copy All.”  In the window that opens, right-click the disassembly, select “Save file,” and name the program “MacroMakerFixed.exe”

Finally, select the “Debug” menu option, “Close,” and click “Yes.”  Close OllyDbg.

Now, run “MacroMakerFixed.exe” and enjoy your cherished least privilege account!  When you feel comfortable that you haven’t broken the program, copy it over MacroMaker.exe and delete MacroMakerFixed.exe.

Mission Accomplished.

A new perspective … from 13,000 feet.

On Saturday, I finally got the chance to do something I’ve long waited for – Sky Diving.

That’s right.  Climbing well past the height where airplanes allow you to remove your seatbelts.  Jumping from said perfectly good airplane.  Throwing myself to the ground at 120 mph.

As soon as we landed, all I could think about was doing it again.

We picked as our drop zone, as they offer the best rates, the highest jumps, and a great view.  They do tandem jumps from 13,000 ft (weather permitting,) unlike many other places that only take you to 8,000 with the base rate.

Tandem jumps have you strapped to the front of your instructor, and are by far the best value for your first time.  You don’t participate much in the mechanics of the jump, so you go much higher – and get much more time in the air.  The alternative is a “static line” jump, where your parachute is automatically deployed as you exit the aircraft.  You do the jump (and land) on your own, but only from about 4,000 ft. 

We arrived at Pierce County Airport for our reservations at 11:00, shortly after the morning haze burned off.  We couldn’t have asked for better weather, as they sky was cloudless and almost crystal blue.  Mt Rainier loomed impressively to the southwest – its summit just a few hundred feet higher than our ultimate altitude. 

After waiting about half an hour for a load to come back, one of the owners suited us up with jump harnesses, helmets, and goggles.  We strapped ourselves in – tightly, so that we didn’t continue to travel when the harness stopped as the parachute deployed.

An instructor gave us instructions on proper exit protocol, free-fall queues, and landing technique just before we paired with our jump masters to board the airplane.  All signals and queues are physical – in freefall, the roaring wind makes voice communication about as effective as telepathy.  My jump master was April Ashley: technically excellent, fun, and and all-around great person.

After getting organized, we boarded the idling Twin Otter – a powerful, large-capacity plane that easily took us to 13,000 ft.  As I mentioned earlier, many sky diving outfits only take you to 8,000 ft, and charge a lot extra to go to 10,000 ft.  This is because they fly a Cessna 182, with a much smaller engine.  It climbs quickly to 6,000 ft, but labours the rest of the way.  The Twin Otter climbs the entire 13,000 ft at the same rate that the Cessna makes its first 6,000.

[ ]

There were about 15 of us – facing each other as we sat on long benches that ran the length of the aircraft.  I looked up and down the two rows of my companions – surprisingly everybody looked eager to do this.  I was extremely excited and chatty – feeling the impatient expectation you get before a huge amusement park ride.

After taxiing onto the runway, we buckled up as our pilot applied full throttle.  The loud din of dual propellers overwhelmed our conversation as the plane quickly picked up speed.  Talk subsided, as we watched the ground begin to blur beside us.  After a few moments, we felt the familiar heaviness of the plane pulling skyward, lifting from the ground.  “Wow, we’re high,” I thought, not even 1,000 ft from the ground.

[|-122.290265&style=h&lvl=19&v=1 ]

We started chatting again – although chatting doesn’t really describe yelling over the noise of a propeller-driven airplane.  April pointed out the magnificent scenery rapidly becoming visible.  Mount St. Helens was now readily apparent, as was Mount Olympus.  Streams sparkled in the morning sunlight, shining as though laden with silver ore.

I glanced at the altimeter.  “Wow, we’re high,” I thought, just now approaching 8,000 ft.  “You know,” I joke-screamed.  “We’re the most prepared we could ever be for plane troubles.”  “If the plane had any issues and we had to jump – our only regret would be that it wasn’t higher!”

As we started to approach our ultimate altitude of 13,000 ft, the Twin Otter cut broad circles in the sky as it continued its aggressive climb.  Our jump masters tightly joined our harnesses with theirs – essentially strapping us to their laps.  Each of the four connection points could bear the entire load many times over. 

As we reach 13,000 ft, one of the operators slides the jump door of the aircraft up.  Cold air streams in, as I get my first glance of the patchwork quilt of green and gold that lays below us.  Thrill pours over me in anticipation.  The camera man exits first, followed shortly by a few individual advanced sky divers.  April and I nudge up along the bench toward the front of the airplane, and then approach the window.  I hold my chest harness, minimizing the amount I contribute to our aerodynamics.  After a few moments of preparation, we jump into the enormous blast of rushing wind.  I arch my back and curl my legs rearward as April stabilizes us.  My mind, overwhelmed by pleasure and stimulus, spins in excitement.

April gives a hearty cheer, as she turns us left, then right.  The enormous vista spins beneath me, as I absorb the immense, rushing view.

[|-122.296822&style=a&lvl=14&v=1 ]

The wind tries to force its way down my throat, but a firmly planted toothy smile prevents it.  My heart beats heavily – not in panic, but pure, unadaultered joy.

After about 60 seconds, April taps me, giving me the signal to extend my arms.  This slows our descent, as she prepares to deploy the parachute.  She pulls the rip cord, and the parachute deploys.  We quickly (but gently) decelerate from 120 MPH to about 20 MPH.  From this point on, it’s some leisurely fun-time in the air.

[|-122.297159&style=a&lvl=16&v=1 ]

We’re at about 6,000 ft now, as April shows me how to use the toggles that control the parachute – handles attached to the rigging of the canopy.  One goes in each hand.  With both arms up, you accelerate forward.  With both arms down, you slow down.  With one arm down (and the other up,) you turn in the direction of your down arm.

She spins us around for a bit, pulling us deeper into our harnesses with the G forces.  She offers me the handles, which I gladly accept – although slightly anxious about making a mistake.  I put us into a hard spiral, extracting another hearty cheer from us both.  I thoroughly enjoy myself at the controls – changing speed and direction at a whim.

After about 3 or 4 minutes of this, April takes the toggles again in preparation for our approach.  We’re about 2,000 ft from the ground, targeting the cleanly-mowed landing area to the right of the pond, at the bottom-left of the picture below:

[|-122.297159&style=a&lvl=18&v=1 ]

After more of my non-stop talking, April nicely asks me to be quiet so that she can concentrate on the task at hand.

A few moments later, we finally touch earth again – sliding on our heels, and then gently falling onto to our butts.  Running landings are out of vogue these days, as they tend to cause ankle injuries.

I spring to my feet, thanking April heartily.  I can barely contain my enthusiasm, already wondering how soon again I can go.

I found this video that gives a very realistic portrait of somebody else’s jump, just like mine:


Desperately seeking C#? Desperately seeking Prospects!

KBCafe recently posted an entry, "Desparately seeking C#."

I've gotta say, there's a desparate shortage of technical jobs in Toronto, let alone C# jobs.  Let's not forget about salaries -- the job market in Toronto pays a LOT less than jobs in the US.  Even taking into account crazy cost of living in some US cities.

In July of 2002, I graduated from the University of Toronto with a specialist (Hons. BSc.) in Computer Science.  I also took a major in Professional Writing, and was only 1.5 credits away from a minor in Math.  (1.5 credits is 30% of a semester's workload.)  I had a 16-month internship at General Electric under my belt, and felt well-prepared to compete with any other graduate for jobs.

I didn't have to worry about competing for any Canadian jobs, though.  There were none worth competing for.

I pursued job opportunities for companies that excited me -- both via outside sources, and the university's career centre.  The most telling statement about the Canadian technical industry was the scene I saw at the big career fair.

I went to the fair with a list of companies that I wanted to speak with.  I brought resumes tailored specifically to them, and prepared discussion points specifically for them.  As I approached most booths, they would drop their eyes and shuffle around when we started to talk.  After a short while, they would say something like, "I really enjoyed our conversation -- but to tell you the truth, we're not really accepting resumes.  We're mostly here to just keep a presence."  Or "Oh, you're looking for a full-time job?  Sorry, we're only accepting resumes for internships."

It was atrocious.

On the other hand, the Microsoft booth was staffed by 3 recruiters, with their hands full recruiting.  They were taking resumes on the spot, speaking briefly with students about them, annotating them, and putting serious thought into them.  The attendees of the career fair, finally sensing a glimmer of opportunity, literally swarmed the booth.  Respectfully, of course.  They packed a semi-circle 10 deep, all eager to speak with a company that provided them at least a distant prospect of a job.  This massive flow of interest stayed the same the entire time I was at the fair.  By the end of the day, the recruiter I spoke with had lost his voice from shouting over so many people.

Maybe there is a shortage of C# developers in Toronto.  Maybe that's because they're all being taken by the companies that are hiring.  Or, they're being taken by companies that realize smart developers can be rolling with "Shiny Technology X" before their first paycheck.  I was not taught a single programming language, technology, or operating system in school.  But I learned a hell of lot of them.  They were simply prerequisites that you had to teach yourself in order to complete your coursework.

Want some tips? 

  • Recruit at universities.
  • Make it clear that you are hiring.
  • Engage with those that provide you resumes.
  • Don't get stuck looking for Shiny Technology X.

Demonstration of Monad's Security Features

In an earlier post, I wrote a brief overview of Monad's three main security features:

  • Not allowing users to double-click on Monad scripts by default
  • Requiring that all scripts be signed by a trusted publisher
  • Requiring that users explicitly invoke scripts in the current directory

The discussion was helpful, but a little abstract.  How do the security features of Monad compare to those of other shells?    How exactly do Monad's security features prevent a scripting virus attack?  I'd like to spend a few minutes to demonstrate that.  We'll do this from the perspective of a determined attacker, and very willing victim.

The first line of defense comes from the email transport infrastructure, such as that of a managed Exchange deployment.  To start, the attacker sends their original attempt: a malicious Monad script directly attached to email.  With server-side virus scanning, the user sees only:

This is where most fully-automated email worms would be stopped.  If the user follows security best practices, their desktop-based anti-virus software will strip the virus if their mail server does not.  However, the user is very interested, and replies: "I'm sorry, Evil Hacker.  Exchange quarantined your virus!  Please send again!"

In response, the attacker changes the malicious script to evade the signature-based virus detection algorithms.  Some viruses, known as "polymorphic" viruses, do this automatically.

Now, any type of script is really an executable.  This is true for WSH ".vbs" attachments, Batch ".bat" attachments, Unix ".sh" attachments, and more.  MSH scripts are no different.  Exchange server blocks most of these on the server side.  In addition, both Outlook and Outlook Web Access block many forms of executable content on the client side.  MSH scripts will be no different:

Since the user is really interested, he or she replies, "I'm sorry, Outlook blocked your executable attachment.  Please send again!"

To get around this, the attacker sends the file in a password-protected ZIP file.  Some viruses do this automatically, as their relative lack of success can attest to. 

Alternately, the user might use an email client that does not support executable attachment blocking (and might use a server that does not, either.)  In that case, the attacker's script would get through.

Now, let's see how different shells would protect a user, once they've gone through the difficulty of shepherding the malicious script on to their system.  The user double-clicks the .cmd file, and up pops its window:

DOS didn't offer much resistance.

Unix does much better, as it's not generally configured to allow you to double-click on a script.  In addition, you have to explicitly tell it that the script is both in the current directory, AND executable.

Now, let's see the attack with an MSH script.

Like the Unix shell, the user was not able to double-click on the file to run it.  It would have opened notepad if he or she were to try.  Also like the Unix shells, they had to explicitly call the script from the current directory.

At this point, the attacker's best chances are to instead send the user a traditional Windows executable.  However, we're not talking about traditional executables, we're talking about Monad.

The user replies, "I'm sorry, attacker.  Could you please sign that script?  My system only accepts scripts signed by trusted publishers, with certificates granted by a reputable Certificate Authority"

Our attacker, being a willing participant, goes to an industry-recognized certificate authority (such as Verisign or Thawte) to get a code signing certificate.  He or she provides the required Government-approved documentation to the business, along with the $400 application fee.  The business then verifies:

  • They are issuing it to the correct Company.
  • The company owns the Internet Domain Name in the request.
  • The Company is registered in one or more countries.
  • The registered Company Name is the same as the name on the Certificate Request.


The attacker then signs the script, and re-sends it to the user in a password-protected zip file.  The user dutifully runs it, and sees:

At this point, the user has made almost half a dozen implicit trust decisions, and one very explicit trust decision.  If the user decides to run the script at the "Untrusted Publisher" prompt, then no amount of infrastructure can save them from themselves.  The user is responsible for his or her actions, not the implementation language of the attack in question.

It's at that point where security best practices (such as running with least privilege) can help limit the amount of damage that malicious code can do.

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Loving DasBlog 1.8

Well, Scott and Omar have been busy again, and have just released DasBlog 1.8. It's added a few helpful new features, and plenty of themes. The upgrade went painlessly as far as I can tell -- be sure to let me know if you see any issues!

I've set "BlogXP" as my theme -- it sure is beautiful. My pet peeve of the old "Discreet Blog Blue" was that the sidebar would float all around, and generally mess with layout. Especially on Administration pages. BlogXP is fully functional, and bug-free so far 🙂

The only down-side is that I try to port the general look and feel back to the stylesheet of my regular homepage when I change the look of the blog. I try to limit this to the colours and minor design elements, though, so my main homepage looks pretty darn plain again. Oh well, the last time I updated that page was over a year ago!

That reminds me. I've been meaning to drop a line to Scott and Omar, thanking them for a wonderful blogging system. I'll probably forget that again for a long time, so let me say it now -- Thank You! You guys have really got a great system going.

Monad Technet Webcast Pt. 2

Just as a reminder, the second Monad technet webcast is happening right now (9:30am PST to 11:00 am PST):

I posted more about the Technet Webcasts here.

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Monad? Astroturfing?

If you've read Adam's post ("Preparing for Slashdot",) you probably read how we worked to inform the Slashdot crowd via early entries in the discussion. Luckily, they were moderated up fairly quickly, and people were able to continue commenting with quite a bit more basis in fact than the original article provided.

Often, this is called "Astroturfing," alluding to "fake grass" in a grass-roots movement.

Scoble brought it up, as have some internal discussions over the past few days. Scoble wrote:

Here's one place I got uncomfortable. In the past Microsoft astroturfed its way into issues. I always told myself if I saw astroturfing going on I'd point it out and oppose its use. (...) I'm not saying Adam and Lee crossed the line here (they didn't), but I wanted to point out what they did so that we can have a public discussion about it. I think what they did was OK simply because it was in the spirit of getting the facts out.

I personally don't even think this even approached astroturfing. First of all, I do consider myself a member of the Slashdot community. In fact, I first heard about Monad from Slashdot before I worked at Microsoft. I've been at the karma cap for years, and don't generally post about Microsoft articles. Is the MSRC team astroturfing by going to BlackHat?

Second, I was very careful to mention my connection with Monad exactly to prevent the perception of astroturfing. My first comment, "Comments from a Monad developer," has about as obvious a title I could have given it. Of course, another option was "MOD SELF DOWN. COMMENTS FROM A BORG MICRO$$$LOTH DRONE."

Finally, the side-bar on the blog very clearly states: "Disclaimer: I work for Microsoft."

Let the public discussion continue, but it's pretty clear to me that recent events shouldn't be part of it.

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]