Sysprep Windows 7 & Secunia PSI

I am cooking up an unattended Windows 7 installation image for our users. This is done by carefully preparing a Reference VM using the Audit Mode. This basically means it logs on as administrator, and after sysprepping with the new CopyProfile option, this becomes the profile for newly created users.

I ran into an issue that when the newly created user logs in after installation, Secunia PSI is not started any more.

The reason is that if you install it in Windows 7 (and probably in Vista as well), PSI is not a real service, but merely a task that runs with highest privileges at logon. The task is configured to run with the credentials of the user that installed it – in this case Administrator. However, that account is wiped during sysprep, hence the task cannot be run.

Since I consider Secunia PSI to be vital, I searched around but no solution. I guess because PSI is not meant to be sysprepped and all, and you need Secunia’s corporate version (CSI) for that.
Since CSI was not a suitable solution in our scenario, I worked around quite nicely.

In the sysprep unattended xml file, define a script to be run right after initial logon of the new user. This is done using the FirstLogonCommands option. Suppose it is C:\tmp\runonce.bat.

The new Task Schedular in Windows Vista and 7 is able to import and export its tasks as XML files. The trick is to remove the existing task, which is using the Administrator account, and create a new one using the same XML code, but with the credentials changed to the new user.

Since there is no sed/awk in Windows, I had to resort to a vbscript called SearchAndReplace.vbs, which you can download here:

The relevant part of my runonce.bat looks like this:

C:\tmp\SearchAndReplace.vbs C:\tmp\Secunia.txt Administrator %USERNAME%
schtasks /delete /TN "Secunia PSI Logon Task"
schtasks /create /TN "Secunia PSI Logon Task" /xml C:\tmp\Secunia.txt

The Secunia.txt is an XML export of the original Secunia PSI Task, and has the string Administrator. This is replaced by the new user, and then imported back. For some obscure reason, the search/replace does not work when the file has an xml extension – that is why I use txt – whatever. You can create it yourself using schtasks.exe.

After the next reboot or logoff-logon PSI will happily start up πŸ™‚


Bootcamp FAT32 vs. NTFS

When installing Windows XP on a Mac, BootCamp creates a FAT32 partition for Windows, with ID “BOOTCAMP”.
When you remove that partition during the Windows installation process, and replace it with an NTFS one, Windows will happily install, but fail upon reboot with:

Windows could not start because the following file is missing or corrupt:
Please re-install a copy of the above file

The trick to get this working, is to leave the partition schema intact, and only reformat the filesystem.
What you should do, is select the FAT32 BOOTCAMP partition to install Windows on, then pick this option:

Format the partition using the NTFS file system (Quick)

Then press F to format the drive

This should give you a working Windows XP installation.


‘Onze welvaart is geleend’

Op vrijdag 14 augustus verscheen in de HP/De Tijd een interview met Kees de Kort.

Kees de Kort (52), financieel analist bij AFS Capital Management en beurscommentator bij BNR Nieuwsradio, staat bekend als somberste econoom van Nederland. Een gesprek over onterechte koersstijgingen en falende toezichthouders. ‘De reΓ«le economie staat er nu nog slechter voor en dat kan nog lang duren.’
Lees hier het volledige artikel (PDF).

PHP Programming

RoundCube email hangs on “Sending message…”

While configuring one of my clients RoundCube installation in combination with Plesk, it would work almost OK, except that when sending mails RoundCube would hang at the spinner with “Sending message…”.
After some digging it turns out that the Plesk-bundled PEAR module directory was before the RoundCube bundled PEAR modules directory. Both contain Mail_Mime, but the Plesk version was older and did not contain the getMessage() function.
Something similar to this will pop up in apache errorlog:
PHP Fatal error: Call to undefined method rcube_mail_mime::getMessage() in /usr/share/psa-horde/program/steps/mail/ on line 492

This was fixed by changing the include_path so that the RoundCube modules come first for this specific vhost.

Don’t know what else will break further up the chain however πŸ˜‰


550 User on holiday

Usually vacation messages are sent from userland software, but that option has the disadvantage that you still receive lots of messages during your holiday. Also, because the mailserver accepted the message, you have the responsibility to handle it.

In order to get around this, configure your mail server with a custom permanant error for your address. This way your messages will bounce back to the sender, and you will not receive any messages.

People cannot claim that they sent it – and you can prove it. Presto – no more mailbox weeding after returning from holiday.

Postfix configuration: /etc/postfix/

smtpd_recipient_restrictions =


/(dick|visser) 550 User on holiday

Best regards πŸ™‚


Running Secunia PSI as non-admin

Your machine was compromised (again!) by malware you caught up somewhere on the web. Sick and tired of it you went looking for a solution and after reading my religious Non-Admin HOWTO you decided to bite the bullet and downgrade yourself to the Users group. To keep all your applications up-to-date you installed Secunia PSI, which seems to work fine, but unfortunately it only runs with admin privileges:

The Secunia PSI can only be run by an Administrator. Please log in with Administrative privileges and try running the application again.

You seem to have to choices, both of which suck:

  • Be admin and run the PSI. You system is ready to be screwed but you do know about vulnerable 3rd party apps
  • Be non-admin, and don’t run the PSI. You are saver but you don’t know about vulnerable 3rd party apps. PSI only starts with admin privs so you log in with your admin account once a week and do a scan.

Secunia says it is designed this way so though luck for you. Damn!

However, using RUNAS there is a middle-of-the-road way to have the best of both worlds:

Edit your Secunia startup shortcut C:\Documents and Settings\Joe Average\Start Menu\Programs\Startup\Secunia PSI and change the target to:

runas /user:administrator /env /savecred "C:\Program Files\Secunia\PSI\psi.exe --start-in-tray"

(While you’re at it, consider moving the shortcut to the All Users settings)

Now you can be non-admin and run PSI πŸ™‚


Een goed begin…

Nieuwjaarspic 2009

Is het halve werk. Donderdagochtend met Vincent naar Scheveningen gereden om de nieuwjaarsduik te doen πŸ™‚


Michiel Meurs & Dorknoper

Is het iemand al eens opgevallen welke fysieke gelijkenis er is tussen Michiel Meurs, de voormalig financieel directeur van Ahold, en ambtenaar eerste klasse Dorknoper?

Ambtenaar eerste klasse Dorknoper
Ambtenaar eerste klasse Dorknoper
Michiel Meurs
Michiel Meurs
PHP Programming

Fixing the Apache “unable to include…” localised errors

Apache includes a nice feature that displays localised errors. This makes use of Server Side Includes (SSI).
When you use PHP and have it also parse .html documents, your localised errors are broken. In fact, because the initial error will generate new errors, it becomes a mess. You typically see this in your error log:

unable to include "include/top.html" in parsed file /usr/share/apache2/error/HTTP_NOT_FOUND.html.var
unable to include "include/bottom.html" in parsed file /usr/share/apache2/error/HTTP_NOT_FOUND.html.var

I fixed this by using a new extension .err for the error documents.
Snippet from my apache2.conf:

    AllowOverride None
    Options FollowSymlinks Includes

    AddType text/html err
    AddOutputFilter Includes err

    AddHandler type-map var
    Order allow,deny
    Allow from all
    LanguagePriority en cs de es fr it nl sv pt-br ro
    ForceLanguagePriority Prefer Fallback

Then go into /usr/share/apache2/error and rename all files to have .err.var extension (instead of .html.var):

rename 's/\.html\.var/\.err\.var/g' *

Rename the tree files in includes dir:

rename 's/\.html/\.err/g' includes/*

Finally recursively replace the strings in the type-map files too:

perl -pi -e 's/\.html/\.err/g' *

You /usr/share/apache2/error tree now looks something like this:


Now your localised errors should be back again, and you logs will not be flooded anymore.


Brute-forcing pksc12 passphrases with OpenSSL

For some project I needed to recover the password that was used to encrypt a PKCS12 key.

I found a nice patch for openssl by Aion but that did not compile on any of my machines.

After some trial and error, I was able to compile it under Debian Woody. For your convenience, I have put the openssl binary online. It runs on i386 linux systems.


./openssl pkcs12 -in mycert.p12 -aion /usr/share/dict/words

Remember: it is ancient OpenSSL-0.9.7c so full of security bugs, hence only use it to recover lost passwords.