Federico Di Marco - The genesis of StarterService component of the SIMATIC IT industrial automation suite (fededim.github.io)

Federico Di Marco

I’m a senior software engineer, born in Genova, Italy, with a master degree in computer science, in the second half of his forties.

Started using a computer at six years, gone through logo, basic, assembly, C/C++, java and finally to .NET and .NET core. Proficient also in databases, especially Sql Server and reporting. Let’s say I have also some experience on security but mainly in the past, now things have become much more difficult and I do not have too much time to keep me updated, but sometimes I am still kicking in.

Fan of videogames, technologies, motorbikes, travelling and comedy (click my name above for my main page).

Famous quotes:

The genesis of StarterService component of the SIMATIC IT industrial automation suite.

Many years ago at the beginning of my career I was working as a consultant at Siemens Automation and Drives in my home town Genova, Italy in the R&D unit in "Services" group as a C/C++ software engineer and on March-April 2005 I was tasked of developing a windows service which could execute “lawfully” programs on remote computers under the user currently logged in (so the user HAD to be logged) without requiring its password which was deemed impossible for security reasons. I was unable to speak in detail about this component I developed anywhere due to a NDA (non-disclosure agreement) which Siemens AD required to sign at the beginning of employment to every employee and collaborator.

Essentially an NDA is a legal contract which forces the person signing it not to reveal for an indefinite time any information about what he learns or discovers during his work activity in the company. So why am I saying this? First of all, I want to restore the dignity and the honesty of my person and my family. Moreover the windows operating system changed a lot its Api starting from Vista version, removing the following way of RPE (remote program execution), which however I want to explain (there although other ways which I detail below).

After some research I found out that in Windows C/C++ header files there were some structures providing a handle to the user token inside (you can simply search for the hToken inside c headers folder in order to retrieve all possible entry points :-), in particular inside the WLX_NOTIFICATION_INFO structure passed when some events were raised from the Winlogon notification package subsystem, in particular the WLEventLogon, which was raised whenever a user logged in.

Win32 Api supports the CreateProcessAsUser (two versions ANSI and Unicode) which allows you to create a new process under the security context of another user provided that you have its user token. The idea at the beginning (shared even with a Siemens correspondent from Microsoft in USA which replied back as feedback that it wouldn't probably work) was therefore to create a windows service (I named this "fatherhood" StarterService.exe) which:

Unluckily the idea was not successful at the beginning because every time you called the CreateProcessAsUser it always raised error 5 access denied, no matter how you passed the token (I tried even with Win32 Api Duplicate Token).

After several failed attempts I had an epiphany, why not starting the RPE server directly inside the WLEventLogon event (by creating a new listening thread, IMHO thread creation inside callbacks is a major security flaw even on current version of Windows) which was the user token owner? In fact, the WLEventLogon callback was called inside the security context of Winlogon.exe windows process (essentially a Winlogon notification package is a DLL which gets dynamically linked to Winlogon.exe) and in fact after some fixes everything worked flawlessly, even on different terminal services sessions. In this case StarterService.exe became merely a central TCP broker dispatching RPE request to the user session RPE server through global named pipes messages .

Having said this StarterService came into fully working existence in May 2005.

While developing this challenge I was called for a new position at Italian Revenue Agency in Milan after having won a public competition which I accepted due to higher salary and because I wasn't offered a permanent position directly at Siemens AD (I was told that between my employing company GEA and Siemens AD there were non-competition agreements which forbade the hiring of external consultants).

While phasing out I handed over what I did to my co-worker Sonia Marsano, who was in turn a close friend of Fabio Roccatagliata, another alumni of the computer science university in Genova who contacted me years later for an interview for a vacancy in Monaco, Montecarlo (he coincidentially attended the military service in the navy together with my former friend of family Roberto Bazzoni, he had also friends from Turin in Monaco).

Additional entry points for operating system starting from Vista

Starting from Windows Vista Microsoft provided an Api which, under certain privileges, allows a windows service to retrieve the current user token of a specified desktop session WTSQueryUserToken so implementing StarterService is much more easier now (and probably it has been updated with this new code because the original Winlogon notification package was removed from Vista, I still wonder if someone at Siemens asked formally to Microsoft for this because StarterService became a central component of Simatic at that time).

Moreover experimenting with the same simple method I used originally for developing StarterService (e.g. searching for the hToken inside c headers folder in order to retrieve all possible entry points) I found another entry point in the Group Policy callbacks, I started implementing a POC project called WinRPE but I haven't finished it for now (it is for now on a private GitHub repository on my account)

Curious note

I signed my first NDA when I was 19 with Plextor, a well-known Japanese company in the ‘90s which produced SCSI CD readers and burners. I was trying to create a software for burning CDs on Amiga OS (never released), which was lacking at that time and I was forced to use MacOS Toast on the Amiga's MAC emulator ShapeShifter (at that time Amiga and Mac shared the same CISC CPU Motorola 68xxx).

CD burners at beginning used proprietary SCSI commands to perform read/write of sectors, etc., then a standard was published, the so-called SCSI Multimedia Command Set 3 (MMC3), however every device could also define additional custom commands besides the one provided by the standard and I was forced to sign this NDA in order to receive the technical documentation of my Plextor 12X CD reader, then I was very young so I was little bit scared and I did not understand completely what signing a NDA meant.