MDT

Grabbing out-of-box drivers from a Windows 8 system

It seems like a common request:  I’ve got a brand new system, right out of the box from the OEM.  It has all the drivers on it that are needed.  So rather than find and download those same drivers from the OEM’s website, why can’t I just extract the drivers from OS that’s already on the system?

Well, you can – with some caveats described below.  I’ve never been a big fan of this approach due to those caveats, but it can work well in some scenarios.  It’s a little scary that people will download random utilities from random websites to do this though, especially when it’s so easy to do on Windows 8 and above using PowerShell.

So attached to this blog is a script for doing just that.  It’s really quite simple, as it leverages the “Get-WindowsDriver” PowerShell cmdlet to get the list of out-of-box drivers (which is what the cmdlet does by default).  The meat of it:

Get-WindowsDriver -online | % {
   $dir = Split-Path $_.OriginalFileName -Parent ;
   $subdir = Split-Path $dir -Leaf ;
   $driverDest = "$destination\$subdir";
   Write-Host "Copying $dir to $driverDest\$subdir" ;
   Copy-Item -Path $dir -Destination $driverDest -Recurse
}

(Don’t try to copy and paste this, unless you set the $destination variable manually.  The attached script is set up as a cmdlet and will prompt for that destination path, which should already exist.  The attached script also includes the required disclaimer that says this isn’t supported by Microsoft in any way.)

The logic is fairly simple:

  • For each out-of-box driver, get the original file name, which is the full path to the INF file in the driver repository folder, e.g. C:\Windows\System32\DriverStore\FileRepository\driverFolder\driver.inf. 
  • Chop the file name off of that to get the folder path, e.g. C:\Windows\System32\DriverStore\FileRepository\driverFolder. 
  • Chop the folder name from that path to use in the destination, e.g. driverFolder.
  • Copy from source to destination.

That’s it.  Give it a few minutes to run (the Get-WindowsDriver cmdlet will take a little while to execute as it sifts through all the drivers), then look at the destination folder you specified to see all the drivers.

Now for the caveats:

  • This assumes that all the files required for the driver and/or device are present in the driver folder.  While the core driver files should be there, any applets, control panels, shell extensions, etc. might not be.  So you might need to install the full OEM package to get complete functionality.  In some cases, the driver may not even work without this (e.g. Bluetooth, mobile broadband).
  • You might get more drivers than you really need.  For example, my laptop has over 100 out-of-box drivers.  Does it really need 100 drivers to work?  No, it only needs 6-7.  Some are older versions, some are for various USB devices that I’ve attached in the last year (printers, cameras, headsets, DisplayPort docks, etc.), some I have no idea where they came from.  So the cleaner the system is, the better.
  • You will probably get old versions.  The images that OEMs ship on new machines aren’t always kept up to date, so you might find that those original drivers have “issues” – some will get updated immediately from Windows Update, others will require updating from the OEM’s website anyway.  (I would definitely check for the latest video and network drivers regardless.)

Good luck.

Categories: MDT

Grabbing out-of-box drivers from a Windows 8 system

It seems like a common request:  I’ve got a brand new system, right out of the box from the OEM.  It has all the drivers on it that are needed.  So rather than find and download those same drivers from the OEM’s website, why can’t I just extract the drivers from OS that’s already on the system?

Well, you can – with some caveats described below.  I’ve never been a big fan of this approach due to those caveats, but it can work well in some scenarios.  It’s a little scary that people will download random utilities from random websites to do this though, especially when it’s so easy to do on Windows 8 and above using PowerShell.

So attached to this blog is a script for doing just that.  It’s really quite simple, as it leverages the “Get-WindowsDriver” PowerShell cmdlet to get the list of out-of-box drivers (which is what the cmdlet does by default).  The meat of it:

Get-WindowsDriver -online | % {
   $dir = Split-Path $_.OriginalFileName -Parent ;
   $subdir = Split-Path $dir -Leaf ;
   $driverDest = "$destination\$subdir";
   Write-Host "Copying $dir to $driverDest\$subdir" ;
   Copy-Item -Path $dir -Destination $driverDest -Recurse
}

(Don’t try to copy and paste this, unless you set the $destination variable manually.  The attached script is set up as a cmdlet and will prompt for that destination path, which should already exist.  The attached script also includes the required disclaimer that says this isn’t supported by Microsoft in any way.)

The logic is fairly simple:

  • For each out-of-box driver, get the original file name, which is the full path to the INF file in the driver repository folder, e.g. C:\Windows\System32\DriverStore\FileRepository\driverFolder\driver.inf. 
  • Chop the file name off of that to get the folder path, e.g. C:\Windows\System32\DriverStore\FileRepository\driverFolder. 
  • Chop the folder name from that path to use in the destination, e.g. driverFolder.
  • Copy from source to destination.

That’s it.  Give it a few minutes to run (the Get-WindowsDriver cmdlet will take a little while to execute as it sifts through all the drivers), then look at the destination folder you specified to see all the drivers.

Now for the caveats:

  • This assumes that all the files required for the driver and/or device are present in the driver folder.  While the core driver files should be there, any applets, control panels, shell extensions, etc. might not be.  So you might need to install the full OEM package to get complete functionality.  In some cases, the driver may not even work without this (e.g. Bluetooth, mobile broadband).
  • You might get more drivers than you really need.  For example, my laptop has over 100 out-of-box drivers.  Does it really need 100 drivers to work?  No, it only needs 6-7.  Some are older versions, some are for various USB devices that I’ve attached in the last year (printers, cameras, headsets, DisplayPort docks, etc.), some I have no idea where they came from.  So the cleaner the system is, the better.
  • You will probably get old versions.  The images that OEMs ship on new machines aren’t always kept up to date, so you might find that those original drivers have “issues” – some will get updated immediately from Windows Update, others will require updating from the OEM’s website anyway.  (I would definitely check for the latest video and network drivers regardless.)

Good luck.

Categories: MDT

Loading Scripts that Have VBScript Classes or that Don’t Have a UserExit Function as User Exit Scripts

The Deployment Guys - Fri, 09/13/2013 - 18:53

Most readers of this blog should be familiar with MDT User Exit scripts, as many of the posts provided them for many scenarios.  In case you are not, the MDT help file defines them this way:

“A user exit script is effectively a function library that can be called during the processing of the CustomSettings.ini file using the UserExit directive. A user exit script contains one or more functions that can be called during the process of the CustomSettings.ini file.”

User exit scripts are a great way to extend the Gather process. However, how ZTIGather.wsf actually process user exit scripts has implications for which scripts you can use as user exit scripts.

When ZTIGather.wsf finds a UserExit entry in a CustomSettings.ini section, it actually processes the user exit script twice, once at the beginning of the section processing and once at the end.  When it does this it first loads the contents of the user exit script file into a string variable, executes the loaded code in the global namespace of a script using the VBScript ExecuteGlobal statement, and then calls the UserExit function that is included in the script.

The UserExit function I usually include is similar to this and requires the function signature (set of parameters) shown below:

Function UserExit(sType, sWhen, sDetail, bSkip)
    oLogging.CreateEntry "USEREXIT:TestUserExit.vbs started: " & sType & " " & sWhen & " " & sDetail, LogTypeInfo
    UserExit = Success
End Function

The sType input parameter is always called with a value of "SECTION".  The sWhen input parameter is called with "BEFORE" at the beginning of section processing and "AFTER" at the end of section processing.  The sDetail input parameter is the CustomSettings.ini section name.  The bSkip parameter is a return parameter.  If bSkip is set to True in the UserExit function when it is called at the beginning of section processing, the rest of that section in CustomSettings.ini is skipped.

This behavior allows you to run different code at the beginning or end of section processing or skip section processing based on code run at the beginning of section processing like the trivial samples shown below.

Function UserExit(sType, sWhen, sDetail, bSkip)
    oLogging.CreateEntry "USEREXIT:TestUserExit.vbs started: " & sType & " " & sWhen & " " & sDetail, LogTypeInfo
    If sWhen = "BEFORE" Then oEnvironment.Item("WhenProperty") = "Before"
    If sWhen = "AFTER" Then oEnvironment.Item("WhenProperty") = "After"
    UserExit = Success
End Function

Function UserExit(sType, sWhen, sDetail, bSkip)
    oLogging.CreateEntry "USEREXIT:TestUserExit.vbs started: " & sType & " " & sWhen & " " & sDetail, LogTypeInfo
    If TestCondition = False Then bSkip = True
    UserExit = Success
End Function

While this functionality is interesting, I have never had any occasion where I needed to use it.  I only know one person who has put logic in a UserExit function, fellow Deployment Guy Dave Hornbaker.  So why did I bother explaining it to you?  Well, as I said earlier it has implications for which scripts you can use as user exit scripts.

The first is that any script you want to use as a user exit script must have a UserExit function.  Fellow Deployment Guy Dave Hornbaker once needed to use ZTIDiskUtility.vbs functions in one of his user exit scripts.  Now he could have either added a UserExit function to ZTIDiskUtility.vbs so it could be used as a user exit script directly as well or added a script tag to ZTIGather.wsf that referenced ZTIDiskUtility.vbs.  However, we generally recommend against modifying the scripts that ship with MDT unless it is absolutely necessary.  If you do, then you have to remember to redo those changes when applying an update to MDT.

The second is that the when a user exit script contains VBScript Classes, the second ExecuteGlobal of the contents at the end of section processing fails with a “name redefined” error.  This causes ZTIGather.wsf execution to fail.

To overcome both of these limitations, I created a user exit script (MDTExitInclude.vbs) with a function called Include that only loads the contents of a VBScript file into a string variable, executes the loaded code using the VBScript ExecuteGlobal statement, and only does this once.  So while this does not allow the little-used section processing control behavior I described above, this function essentially allows you to use any VBScript as a user exit script.

After adding MDTExitInclude.vbs to Scripts folder in the LTI Deployment Share or ConfigMgr MDT Toolkit package, modify CustomSetting.ini similar to the example below to load MDTExitInclude.vbs as a user exit script and then load another script using the Include function.  This sample loads a script named TestUserExit.vbs and make functions inside it available for use.

[Settings]
Priority=IncludeScript, Default
Properties=IncludeResult

[IncludeScript]
UserExit=IncludeExit.vbs
IncludeResult=#Include("TestUserExit.vbs")#

One other advantage of loading user exit scripts in this fashion is that it simplifies loading multiple scripts.  For example, I recently needed to load five user exit scripts for one deployment.  Normally this would require creating five sections in CustomSettings.ini since you can only have one UserExit directive per section.  Using MDTExitInclude.vbs you can load as many scripts as you want in a single section like this:

[Settings]
Priority=IncludeExitScripts, Default
Properties=ExitScripts(*)

[IncludeExitScripts]
UserExit=MDTExitInclude.vbs
ExitScripts001=#Include("MDTLibHelperClasses.vbs")#
ExitScripts002=#Include("ModelAliasExit.vbs")#
ExitScripts003=#Include("MDTConfigMgrFunctions.vbs")#
ExitScripts004=#Include("MDTExitGetCollectionAdvertsDeploys.vbs")#
ExitScripts005=#Include("MDTExitGetResourceAdvertsDeploys.vbs")#

This sample uses one “throw away” list item, ExitScripts, to execute the Include function for each script.  This avoids “Settings section bloat” by not requiring multiple entries in the Priority or Properties line for just loading multiple scripts.

 

 

Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use.

This post was contributed by Michael Murgolo, a Senior Consultant with Microsoft Services - U.S. East Region.

Categories: MDT

Loading Scripts that Have VBScript Classes or that Don’t Have a UserExit Function as User Exit Scripts

The Deployment Guys - Fri, 09/13/2013 - 18:53

Most readers of this blog should be familiar with MDT User Exit scripts, as many of the posts provided them for many scenarios.  In case you are not, the MDT help file defines them this way:

“A user exit script is effectively a function library that can be called during the processing of the CustomSettings.ini file using the UserExit directive. A user exit script contains one or more functions that can be called during the process of the CustomSettings.ini file.”

User exit scripts are a great way to extend the Gather process. However, how ZTIGather.wsf actually process user exit scripts has implications for which scripts you can use as user exit scripts.

When ZTIGather.wsf finds a UserExit entry in a CustomSettings.ini section, it actually processes the user exit script twice, once at the beginning of the section processing and once at the end.  When it does this it first loads the contents of the user exit script file into a string variable, executes the loaded code in the global namespace of a script using the VBScript ExecuteGlobal statement, and then calls the UserExit function that is included in the script.

The UserExit function I usually include is similar to this and requires the function signature (set of parameters) shown below:

Function UserExit(sType, sWhen, sDetail, bSkip)
    oLogging.CreateEntry "USEREXIT:TestUserExit.vbs started: " & sType & " " & sWhen & " " & sDetail, LogTypeInfo
    UserExit = Success
End Function

The sType input parameter is always called with a value of "SECTION".  The sWhen input parameter is called with "BEFORE" at the beginning of section processing and "AFTER" at the end of section processing.  The sDetail input parameter is the CustomSettings.ini section name.  The bSkip parameter is a return parameter.  If bSkip is set to True in the UserExit function when it is called at the beginning of section processing, the rest of that section in CustomSettings.ini is skipped.

This behavior allows you to run different code at the beginning or end of section processing or skip section processing based on code run at the beginning of section processing like the trivial samples shown below.

Function UserExit(sType, sWhen, sDetail, bSkip)
    oLogging.CreateEntry "USEREXIT:TestUserExit.vbs started: " & sType & " " & sWhen & " " & sDetail, LogTypeInfo
    If sWhen = "BEFORE" Then oEnvironment.Item("WhenProperty") = "Before"
    If sWhen = "AFTER" Then oEnvironment.Item("WhenProperty") = "After"
    UserExit = Success
End Function

Function UserExit(sType, sWhen, sDetail, bSkip)
    oLogging.CreateEntry "USEREXIT:TestUserExit.vbs started: " & sType & " " & sWhen & " " & sDetail, LogTypeInfo
    If TestCondition = False Then bSkip = True
    UserExit = Success
End Function

While this functionality is interesting, I have never had any occasion where I needed to use it.  I only know one person who has put logic in a UserExit function, fellow Deployment Guy Dave Hornbaker.  So why did I bother explaining it to you?  Well, as I said earlier it has implications for which scripts you can use as user exit scripts.

The first is that any script you want to use as a user exit script must have a UserExit function.  Fellow Deployment Guy Dave Hornbaker once needed to use ZTIDiskUtility.vbs functions in one of his user exit scripts.  Now he could have either added a UserExit function to ZTIDiskUtility.vbs so it could be used as a user exit script directly as well or added a script tag to ZTIGather.wsf that referenced ZTIDiskUtility.vbs.  However, we generally recommend against modifying the scripts that ship with MDT unless it is absolutely necessary.  If you do, then you have to remember to redo those changes when applying an update to MDT.

The second is that the when a user exit script contains VBScript Classes, the second ExecuteGlobal of the contents at the end of section processing fails with a “name redefined” error.  This causes ZTIGather.wsf execution to fail.

To overcome both of these limitations, I created a user exit script (MDTExitInclude.vbs) with a function called Include that only loads the contents of a VBScript file into a string variable, executes the loaded code using the VBScript ExecuteGlobal statement, and only does this once.  So while this does not allow the little-used section processing control behavior I described above, this function essentially allows you to use any VBScript as a user exit script.

After adding MDTExitInclude.vbs to Scripts folder in the LTI Deployment Share or ConfigMgr MDT Toolkit package, modify CustomSetting.ini similar to the example below to load MDTExitInclude.vbs as a user exit script and then load another script using the Include function.  This sample loads a script named TestUserExit.vbs and make functions inside it available for use.

[Settings]
Priority=IncludeScript, Default
Properties=IncludeResult

[IncludeScript]
UserExit=IncludeExit.vbs
IncludeResult=#Include("TestUserExit.vbs")#

One other advantage of loading user exit scripts in this fashion is that it simplifies loading multiple scripts.  For example, I recently needed to load five user exit scripts for one deployment.  Normally this would require creating five sections in CustomSettings.ini since you can only have one UserExit directive per section.  Using MDTExitInclude.vbs you can load as many scripts as you want in a single section like this:

[Settings]
Priority=IncludeExitScripts, Default
Properties=ExitScripts(*)

[IncludeExitScripts]
UserExit=MDTExitInclude.vbs
ExitScripts001=#Include("MDTLibHelperClasses.vbs")#
ExitScripts002=#Include("ModelAliasExit.vbs")#
ExitScripts003=#Include("MDTConfigMgrFunctions.vbs")#
ExitScripts004=#Include("MDTExitGetCollectionAdvertsDeploys.vbs")#
ExitScripts005=#Include("MDTExitGetResourceAdvertsDeploys.vbs")#

This sample uses one “throw away” list item, ExitScripts, to execute the Include function for each script.  This avoids “Settings section bloat” by not requiring multiple entries in the Priority or Properties line for just loading multiple scripts.

 

 

Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use.

This post was contributed by Michael Murgolo, a Senior Consultant with Microsoft Services - U.S. East Region.

Categories: MDT

OSD Pre-stage and UEFI Systems

Steve Rachui's Manageability blog - Fri, 09/13/2013 - 11:57
The concept of pre-staging an operating system for deployment with OSD is well understood and effective. There is plenty of documentation detailing configuring pre-staging for legacy BIOS based systems. But what about pre-staging with UEFI based systems...(read more)
Categories: MDT

Looking at Replica Delta in Hyper-V with PowerShell

Virtual PC Guy's WebLog - Thu, 09/12/2013 - 01:11

If you have used Hyper-V Replica, you will know about the replica status column.  This is the part of the user interface where we tell you what the state of replica is: normal, warning or critical.  A simple interpretation of these states is:

  • Normal: everything is fine, nothing to worry about.
  • Warning: there have been some problems, but we think we can fix them for you.
  • Critical: things have gone past the point where we can fix them, you need to intervene.

On issue that I have encountered with my home configuration is that there is that there can be a wide variance in the “warning” state.  To help me to better understand what is going on with a virtual machine that is in the “warning” state I like to see how far behind the replica virtual machine is from the primary virtual machine.

You can do this quite easily through the user interface by bringing up the Hyper-V Replica health report for a single virtual machine.  But there is no easy way to do this for multiple virtual machines at once, that is unless you use PowerShell!

Here is a little one-liner that I put together that will show you the current replication delta for all your virtual machines:

get-vm | Get-VMReplication | select name, replicationmode, replicationhealth,  @{Expression={"{0:N0}" -f ((get-date)-($_.lastreplicationtime)).TotalMinutes};Label="Delta (min)"}

Which looks like this when run:

Note – this screenshot comes from after I needed to change a disk in one of my systems, and then resync the virtual machines.  At this point in time all virtual machines have resynced except for my file server.

Cheers,
Ben

Categories: MDT

Slides and scripts from the System Center 2012 Configuration Manager R2 Advanced Infrastructure session #WCL307

Coretech Blog » Kent Agerlund - Wed, 09/11/2013 - 16:24
As promised in the session here are the scripts and links that I was using. Video and slides available on Channel 9: http://channel9.msdn.com/Events/TechEd/NewZealand/2013/WCL307 Blog: Management Point replica http://blog.coretech.dk/kea/working-with-database-replicas-on-your-management-point/ http://myitforum.com/myitforumwp/2012/08/06/next-sccm-guru-webcast-features-brian-mason/   SQL Scripts: Index and Statistics Maintenance: http://ola.hallengren.com/sql-server-index-and-statistics-maintenance.html Pre-creating the SQL database: Download   My generel SQL recommendations: http://blog.coretech.dk/kea/system-center-2012-configuration-manager-sql-recommendations/   Planning for Cloud based Distribution Points [...]
Categories: MDT

MSRT September 2013 - Win32/Simda

Microsoft Deployment Toolkit Team Blog - Tue, 09/10/2013 - 13:00

 

This month’s Microsoft Malicious Software Removal Tool (MSRT) release includes one new malware family – the high-volume banking trojan Win32/Simda.
 
Simda is a multi-component malware family that includes trojan, backdoor, password-stealing, downloader and file-infector variants. It is very rare for a single malware family to possess all of these characteristics; Alureon and Sirefef are among the few families also in this category.

Simda was first seen in mid-2009 with samples detected as Backdoor:Win32/Simda.A. This variant allows a remote user to connect to an infected machine and perform various malicious actions, such as stealing user credentials and taking screen grabs.

At the same time, the backdoor component drops a malicious DLL that is injected into Windows processes to gather user information. The DLL is detected as PWS:Win32/Simda.A.

The backdoor variant can exploit the following vulnerabilities to gain elevated privileges to perform more restrictive behaviors, such as Windows process injection (such as into Winlogon.exe, Explorer.exe):

It may also gain admin privileges by trying to brute-force the administrator password with a dictionary attack. Once it gets access, it gathers user information such as user names and passwords, logs keystrokes, and takes screen grabs.

The backdoor connects to its command and control server to report infection and download a configuration file. Once connected, a remote attacker can collect the stolen information and run other commands.

Like other top threats, we’ve also seen Simda use exploit kits and social engineering as attack vectors. For instance, it can disguise itself as a Flash update or be delivered as a PDF or Java exploit.

Simda targets e-banking systems

Simda has recently evolved from a typical password stealer to a banker trojan targeting mostly Russian and European banks.

Our telemetry in Figure 1 shows Russia topped the chart of infected countries from January to August 2013.

It is followed by the United States, Brazil, Turkey, and Canada.

 

Figure 1: Simda threat report (January-August 2013)

Win32/Simda hooks several APIs from Windows DLLs and third-party libraries for various purposes, including keylogging and gathering a user’s sensitive information related to a number of e-banking systems, including:

  • AGAVA

  • ALPHA

  • BS-CLIENT

  • BSS/BSSS

  • CC

  • COLV

  • CRAIF

  • FAKTURA

  • IBANK

  • INIST

  • INTER-PRO

  • ISB

  • KBP

  • RAIFF

  • RFK

  • RSTYLE

  • SBER

  • VEFK

  • VTB24

A complete hooked API list is available in the Win32/Simda family description.

Traffic manipulation

As well as blocking access to some security websites, Win32/Simda is also known to inject its own malicious JavaScript into a webpage by replacing the reference to “google-analytics” with its own code.

It can also modify the search engine of a user’s browser to its own liking, for example to “findgala.com”.

Figure 2: Simda code replacing a browser’s search engine.

Win32/Simda is a classic example of a complex malware threat. It has several components with specific behavior that, when working together, pose a significant threat to the security community and especially to individual computer users.

This malware family has been able to find ways to exist and operate for a long time. From a typical backdoor and password stealing malware to a complex botnet and banking trojan, it’s clear that Simda’s authors have shown they are attempting to adapt to changing security measures.

We’ve targeted it in the September release of MSRT to ensure our users are protected from this banking trojan.

Our Win32/Simda family description has more technical details about this threat.  

SHA-1s:

9d4a73ede108c6df628fa93c75a275671ab2ac6a 
970008499c9915bf2c693eb614b9f5ea501436e9
d92275455c9acbe5d3b58c06a45c1206c9cf97c3

Rex Plantado

MMPC

Categories: MDT

MSRT September 2013 - Win32/Simda

The USMT team blog - Tue, 09/10/2013 - 13:00

 

This month’s Microsoft Malicious Software Removal Tool (MSRT) release includes one new malware family – the high-volume banking trojan Win32/Simda.
 
Simda is a multi-component malware family that includes trojan, backdoor, password-stealing, downloader and file-infector variants. It is very rare for a single malware family to possess all of these characteristics; Alureon and Sirefef are among the few families also in this category.

Simda was first seen in mid-2009 with samples detected as Backdoor:Win32/Simda.A. This variant allows a remote user to connect to an infected machine and perform various malicious actions, such as stealing user credentials and taking screen grabs.

At the same time, the backdoor component drops a malicious DLL that is injected into Windows processes to gather user information. The DLL is detected as PWS:Win32/Simda.A.

The backdoor variant can exploit the following vulnerabilities to gain elevated privileges to perform more restrictive behaviors, such as Windows process injection (such as into Winlogon.exe, Explorer.exe):

It may also gain admin privileges by trying to brute-force the administrator password with a dictionary attack. Once it gets access, it gathers user information such as user names and passwords, logs keystrokes, and takes screen grabs.

The backdoor connects to its command and control server to report infection and download a configuration file. Once connected, a remote attacker can collect the stolen information and run other commands.

Like other top threats, we’ve also seen Simda use exploit kits and social engineering as attack vectors. For instance, it can disguise itself as a Flash update or be delivered as a PDF or Java exploit.

Simda targets e-banking systems

Simda has recently evolved from a typical password stealer to a banker trojan targeting mostly Russian and European banks.

Our telemetry in Figure 1 shows Russia topped the chart of infected countries from January to August 2013.

It is followed by the United States, Brazil, Turkey, and Canada.

 

Figure 1: Simda threat report (January-August 2013)

Win32/Simda hooks several APIs from Windows DLLs and third-party libraries for various purposes, including keylogging and gathering a user’s sensitive information related to a number of e-banking systems, including:

  • AGAVA

  • ALPHA

  • BS-CLIENT

  • BSS/BSSS

  • CC

  • COLV

  • CRAIF

  • FAKTURA

  • IBANK

  • INIST

  • INTER-PRO

  • ISB

  • KBP

  • RAIFF

  • RFK

  • RSTYLE

  • SBER

  • VEFK

  • VTB24

A complete hooked API list is available in the Win32/Simda family description.

Traffic manipulation

As well as blocking access to some security websites, Win32/Simda is also known to inject its own malicious JavaScript into a webpage by replacing the reference to “google-analytics” with its own code.

It can also modify the search engine of a user’s browser to its own liking, for example to “findgala.com”.

Figure 2: Simda code replacing a browser’s search engine.

Win32/Simda is a classic example of a complex malware threat. It has several components with specific behavior that, when working together, pose a significant threat to the security community and especially to individual computer users.

This malware family has been able to find ways to exist and operate for a long time. From a typical backdoor and password stealing malware to a complex botnet and banking trojan, it’s clear that Simda’s authors have shown they are attempting to adapt to changing security measures.

We’ve targeted it in the September release of MSRT to ensure our users are protected from this banking trojan.

Our Win32/Simda family description has more technical details about this threat.  

SHA-1s:

9d4a73ede108c6df628fa93c75a275671ab2ac6a 
970008499c9915bf2c693eb614b9f5ea501436e9
d92275455c9acbe5d3b58c06a45c1206c9cf97c3

Rex Plantado

MMPC

Categories: MDT

MSRT September 2013 - Win32/Simda

 

This month’s Microsoft Malicious Software Removal Tool (MSRT) release includes one new malware family – the high-volume banking trojan Win32/Simda.
 
Simda is a multi-component malware family that includes trojan, backdoor, password-stealing, downloader and file-infector variants. It is very rare for a single malware family to possess all of these characteristics; Alureon and Sirefef are among the few families also in this category.

Simda was first seen in mid-2009 with samples detected as Backdoor:Win32/Simda.A. This variant allows a remote user to connect to an infected machine and perform various malicious actions, such as stealing user credentials and taking screen grabs.

At the same time, the backdoor component drops a malicious DLL that is injected into Windows processes to gather user information. The DLL is detected as PWS:Win32/Simda.A.

The backdoor variant can exploit the following vulnerabilities to gain elevated privileges to perform more restrictive behaviors, such as Windows process injection (such as into Winlogon.exe, Explorer.exe):

It may also gain admin privileges by trying to brute-force the administrator password with a dictionary attack. Once it gets access, it gathers user information such as user names and passwords, logs keystrokes, and takes screen grabs.

The backdoor connects to its command and control server to report infection and download a configuration file. Once connected, a remote attacker can collect the stolen information and run other commands.

Like other top threats, we’ve also seen Simda use exploit kits and social engineering as attack vectors. For instance, it can disguise itself as a Flash update or be delivered as a PDF or Java exploit.

Simda targets e-banking systems

Simda has recently evolved from a typical password stealer to a banker trojan targeting mostly Russian and European banks.

Our telemetry in Figure 1 shows Russia topped the chart of infected countries from January to August 2013.

It is followed by the United States, Brazil, Turkey, and Canada.

 

Figure 1: Simda threat report (January-August 2013)

Win32/Simda hooks several APIs from Windows DLLs and third-party libraries for various purposes, including keylogging and gathering a user’s sensitive information related to a number of e-banking systems, including:

  • AGAVA

  • ALPHA

  • BS-CLIENT

  • BSS/BSSS

  • CC

  • COLV

  • CRAIF

  • FAKTURA

  • IBANK

  • INIST

  • INTER-PRO

  • ISB

  • KBP

  • RAIFF

  • RFK

  • RSTYLE

  • SBER

  • VEFK

  • VTB24

A complete hooked API list is available in the Win32/Simda family description.

Traffic manipulation

As well as blocking access to some security websites, Win32/Simda is also known to inject its own malicious JavaScript into a webpage by replacing the reference to “google-analytics” with its own code.

It can also modify the search engine of a user’s browser to its own liking, for example to “findgala.com”.

Figure 2: Simda code replacing a browser’s search engine.

Win32/Simda is a classic example of a complex malware threat. It has several components with specific behavior that, when working together, pose a significant threat to the security community and especially to individual computer users.

This malware family has been able to find ways to exist and operate for a long time. From a typical backdoor and password stealing malware to a complex botnet and banking trojan, it’s clear that Simda’s authors have shown they are attempting to adapt to changing security measures.

We’ve targeted it in the September release of MSRT to ensure our users are protected from this banking trojan.

Our Win32/Simda family description has more technical details about this threat.  

SHA-1s:

9d4a73ede108c6df628fa93c75a275671ab2ac6a 
970008499c9915bf2c693eb614b9f5ea501436e9
d92275455c9acbe5d3b58c06a45c1206c9cf97c3

Rex Plantado

MMPC

Categories: MDT

MSRT September 2013 - Win32/Simda

The Deployment Guys - Tue, 09/10/2013 - 13:00

 

This month’s Microsoft Malicious Software Removal Tool (MSRT) release includes one new malware family – the high-volume banking trojan Win32/Simda.
 
Simda is a multi-component malware family that includes trojan, backdoor, password-stealing, downloader and file-infector variants. It is very rare for a single malware family to possess all of these characteristics; Alureon and Sirefef are among the few families also in this category.

Simda was first seen in mid-2009 with samples detected as Backdoor:Win32/Simda.A. This variant allows a remote user to connect to an infected machine and perform various malicious actions, such as stealing user credentials and taking screen grabs.

At the same time, the backdoor component drops a malicious DLL that is injected into Windows processes to gather user information. The DLL is detected as PWS:Win32/Simda.A.

The backdoor variant can exploit the following vulnerabilities to gain elevated privileges to perform more restrictive behaviors, such as Windows process injection (such as into Winlogon.exe, Explorer.exe):

It may also gain admin privileges by trying to brute-force the administrator password with a dictionary attack. Once it gets access, it gathers user information such as user names and passwords, logs keystrokes, and takes screen grabs.

The backdoor connects to its command and control server to report infection and download a configuration file. Once connected, a remote attacker can collect the stolen information and run other commands.

Like other top threats, we’ve also seen Simda use exploit kits and social engineering as attack vectors. For instance, it can disguise itself as a Flash update or be delivered as a PDF or Java exploit.

Simda targets e-banking systems

Simda has recently evolved from a typical password stealer to a banker trojan targeting mostly Russian and European banks.

Our telemetry in Figure 1 shows Russia topped the chart of infected countries from January to August 2013.

It is followed by the United States, Brazil, Turkey, and Canada.

 

Figure 1: Simda threat report (January-August 2013)

Win32/Simda hooks several APIs from Windows DLLs and third-party libraries for various purposes, including keylogging and gathering a user’s sensitive information related to a number of e-banking systems, including:

  • AGAVA

  • ALPHA

  • BS-CLIENT

  • BSS/BSSS

  • CC

  • COLV

  • CRAIF

  • FAKTURA

  • IBANK

  • INIST

  • INTER-PRO

  • ISB

  • KBP

  • RAIFF

  • RFK

  • RSTYLE

  • SBER

  • VEFK

  • VTB24

A complete hooked API list is available in the Win32/Simda family description.

Traffic manipulation

As well as blocking access to some security websites, Win32/Simda is also known to inject its own malicious JavaScript into a webpage by replacing the reference to “google-analytics” with its own code.

It can also modify the search engine of a user’s browser to its own liking, for example to “findgala.com”.

Figure 2: Simda code replacing a browser’s search engine.

Win32/Simda is a classic example of a complex malware threat. It has several components with specific behavior that, when working together, pose a significant threat to the security community and especially to individual computer users.

This malware family has been able to find ways to exist and operate for a long time. From a typical backdoor and password stealing malware to a complex botnet and banking trojan, it’s clear that Simda’s authors have shown they are attempting to adapt to changing security measures.

We’ve targeted it in the September release of MSRT to ensure our users are protected from this banking trojan.

Our Win32/Simda family description has more technical details about this threat.  

SHA-1s:

9d4a73ede108c6df628fa93c75a275671ab2ac6a 
970008499c9915bf2c693eb614b9f5ea501436e9
d92275455c9acbe5d3b58c06a45c1206c9cf97c3

Rex Plantado

MMPC

Categories: MDT

Changing TFS 2010 $(sourcedir)

NINet.org - Tue, 09/03/2013 - 06:45
Seemingly this was set by can be by editing the TfsBuildServer.exe.config on the build agent machine and changing the value of the following Key: <add key=”SourcesSubdirectory” value=”Sources” /> On a 2010 build agent this isn’t possible however if you look at the build definition -> Process Tab there is a parameter called “Sources Subdirectory” set [...]
Categories: MDT

The Ultimate Event, Sweden, October–Do not Miss this!

The Deployment Bunny - Mon, 09/02/2013 - 05:31

(In Swedish)

Kollegor, vänner, det är nu det händer. I oktober månad åker Jag(Mikael Nystrom), Johan Arwidmark och Mark Minasi ut på en turné, vi kommer att besöka Malmö, Göteborg, Stockholm, Umeå och sist men inte minst Oslo. Denna gång ger vi oss ut med ett demo mania kring Windows Server 2012 R2, Windows 8.1 och System Center 2012 R2. Vi har sedan I våras vridit, vänt, lekt, testat och nu vill vi att DU ska förstå vad som är fantastiskt och vad som kanske inte var helt genomtänkt. Vi kommer att lägg ner tid på både klienten men också server och datacenter hantering, det blir lagom med deployment och lagom med management. Att sedan Mark Minasi följer med är inte bara roligt för vår egen skull, Mark är helt klart en av dom bästa föreläsare som finns, underhållande och kompetent. Det finns en risk att eventet blir fullbokat, särskilt när den här affischen sitter uppe I Stockholms tunnelbana!


Categories: MDT

Keeping VM Configurations in Sync with Hyper-V Replica

Virtual PC Guy's WebLog - Thu, 08/29/2013 - 01:41

Yesterday I posted about my new home setup, which makes heavy use of Hyper-V Replica.

When you first setup Hyper-V Replica for a virtual machine – we copy the virtual machine configuration and storage from the primary server to the replica server. From that point on we replicate any new data that is written to the virtual machine storage – but we do not replicate any new changes to the virtual machine configuration.

Why?

Well – there are two reasons for this:

  1. We have many deployments where the Hyper-V administrator on the primary and replica servers are different people (e.g. a small business replicating to a local service provider). In this case the administrator on the replica server is not going to want the administrator on the primary server to be able to make arbitrary configuration changes.
  2. There are a number of configuration changes where you want things to be different. E.g. you may want the virtual machine on the replica server to be connected to a different network or to have a different amount of memory, etc…

While this all makes sense, it has tripped me up a number of times. The scenario I have experienced is this:

  1. Enable Hyper-V Replica on a virtual machine
    … months pass …
  2. Make a configuration change to the virtual machine, forgetting that it is configured for replica
    … months pass…
  3. Perform a planned failover of the virtual machine for some reason, and wonder why all the settings are wrong!

After having this happen to me a couple of times – I have taken to using PowerShell to perform quick sanity checks on my virtual machine configurations. This is actually quite easy to do – as PowerShell allows you to target multiple physical computers with one command.

Some checks that I have done include:

Checking memory configurations:

This command will get all the details of the memory configuration from two servers:

get-vm -computername Hyper-V-1, Hyper-V-2 | select name, DynamicMemoryEnabled, MemoryStartup, MemoryMinimum, MemoryMaximum | Sort-Object name | ft

Which looks like this when it is run:

Checking startup delay:

This command shows you all the startup information:

get-vm -computername Hyper-V-1, Hyper-V-2 | select name,automaticstartaction, automaticstartdelay | Sort-Object automaticstartdelay, name

Checking MAC address configuration:

I use DHCP with MAC address reservations in my house, so it is critical that virtual machines not change their MAC address. This command shows you what MAC addresses are being used, and whether dynamic mac address generation is enabled or not:

get-vm -computername Hyper-V-1, Hyper-V-2 | Get-VMNetworkAdapter | select VMName, macaddress, DynamicMacAddressEnabled | sort-object VMName, macaddress

Cheers,
Ben

Categories: MDT

Automate importing and creating driver packages in SCCM 2012 R2

Coretech Blog » Kent Agerlund - Wed, 08/28/2013 - 05:46
  I take that you are familiar with drivers and manually creating driver categories and driver packages in Configuration Manager. Here I will show you how you can optimize the process by running a very need little PowerShell script called ImportDrivers.ps1 (main developer is Claus Codam). There are a few prerequisites that needs to be [...]
Categories: MDT

Hyper-V in my House - 2013

Virtual PC Guy's WebLog - Wed, 08/28/2013 - 00:56

A while ago I talked about how I was using Hyper-V in my house.  These days I have a quite different configuration in place.  I updated my household deployment immediately after Windows Server 2012 was released.

I had a couple of goals with my new architecture:

  1. I wanted to minimize downtime due to hardware servicing.

    My Hyper-V server handles DHPC, DNS, Internet Connectivity, hosts the kids movies, etc…  All this means that if I need to turn it off for any reason – I have to do it after everyone else has gone to bed.  Not fun.

  2. I wanted to minimize the frequency with which I needed to service hardware.

    The leading cause for me needing to work on hardware has been hard drive failure.  So logically, more hard drives means more weekends working on servers.  Fewer hard drives means fewer weekends working on servers.

  3. I need high levels of data protection.

    My server has all the family photos on it – data loss is not an option!

  4. I need lots of storage.

    At this point in time I have about 5TB of data on my family file server.  So realistically I need 7-8 TB of storage for my file server and all other virtual machines.

  5. I want to keep the cost down.

    Hey, no one likes to waste money!

With all of this in mind – here is what I ended up deploying:


 
I setup two Hyper-V servers.  Each server has a single quad-core processor (I do not use a lot of CPU), 16 GB of ram and 3 1 gigabit network adapters.  Each server also has 6 hard disks.  The first two disks are configured in RAID1 using the onboard Intel RAID.  The next four disks are configured as a 6TB parity space to give me the most capacity possible (note – in practice these four disks are a mix of 2TB and 3TB disks).

I then run half of my virtual machines on each server, and use Hyper-V Replica to replicate them to the other server.

This configuration gives me a high level of data protection (both from a single disk failure and an entire server failure).  It also means that if I have to replace a physical disk / fix a hardware problem with one of the servers – I just move all the virtual machines to the working server, and get to take my time fixing the broken server.

I have been running this configuration for almost a year now – and for the most part it has worked just fine.  I have had three separate occasions where I needed to work on a server, and my family did not notice it (for the most part – other than the general cursing and complaining that I was making while working).  That said, there have been some lessons learned for me:

  1. Low storage IOPs can really hurt sometimes.

    When I built this system I knew that the storage throughput of the 6TB data disk would not be great, but I accepted this as a reasonable trade off in the space / price / performance matrix.  For 90% of the time it has also not been an issue – but there have been a couple of times when I have been surprised by how long operations took.

  2. I need more memory.

    My previous setup was a single server with 8GB of memory.  So two servers with 16GB should be huge – right?  This was my thinking when I built the system – but I was wrong.  First, I need to make sure that I do not oversubscribe my memory so that I can run all my virtual machines off of one server when I need too.  Thankfully dynamic memory makes this easy to do, and ensures that when my virtual machines are spread across both servers I get to use all the memory.  Second though, as soon as I had the memory available I started firing up new virtual machines simply because I could – and it was not long until I was at my limit again.

Anyway – now that I have gotten this all written down, I am planning to blog about some of the experience I have had with this setup over the last year, and the lessons learned in the process.

Cheers,
Ben 

Categories: MDT

Thanks!

Xtreme Deployment - Sun, 08/25/2013 - 23:44

UPDATE:

Time passes, and most of the members of the Xtreme Deployment Consulting Team have moved on.

We can be reached at the following:

Tim Mintner – http://www.linkedin.com/pub/tim-mintner/2/740/6a1

Keith Garner – http://www.linkedin.com/pub/keith-garner/24/719/474

Dave Field – http://www.linkedin.com/in/davefield

Polly Reese – http://www.linkedin.com/pub/polly-reese/1/441/a84

Micah Rowland - http://www.linkedin.com/in/micahjrowland

Thanks to our clients and friends.


Categories: MDT

Bulk Registering Virtual Machines with PowerShell

Virtual PC Guy's WebLog - Wed, 08/21/2013 - 13:56

I recently rebuilt a Hyper-V server – where all of my virtual machines were shutdown first and stored on a secondary disk.  Once I had finished installing the operating system and had Hyper-V up and running – I wondered what the most efficient way to get the virtual machines all reconnected would be.  I ended up using PowerShell to do a bulk import; however this did involve a bit of experimentation to get right.

The first thing I had to deal with was the fact that our “import-VM” command requires that you provide a .XML file to import.  An initial listing of all XML files in my virtual machines folder revealed a problem – there were XML files for virtual machines and for snapshots – and I needed to be able to differentiate between the two.

I ended up relying on the fact that the virtual machine XML file is always in a folder called “Virtual Machines” while the snapshot XML file is in a folder called “Snapshots”.  So this piece of PowerShell got me the right files:

Get-ChildItem e:\vms -Recurse -Filter "Virtual Machines" | %{Get-ChildItem $_.FullName -Filter *.xml} | select fullname

As shown here:

The next concern that I had was that I did not know if I had all the files I needed / had named virtual switches correctly / etc…

If I were importing these virtual machines one at a time it would be easy to fix them up – but that would be annoying for a bulk import.  What I decided to do was to check if any virtual machines would fail to import – and then move them to another location for individual treatment later on.  To do this I used this piece of PowerShell:

Get-ChildItem e:\vms -Recurse -Filter "Virtual Machines" | %{write-host "VM Name: "$_.Fullname; Get-ChildItem $_.FullName -Filter *.xml} | %{Compare-VM $_.FullName -Register} | %{$_.Incompatibilities.message; write-host}

Shown here:

What this PowerShell does is use the Compare-VM commandlet to let me know if any of the virtual machines would have compatibility issues with my new Hyper-V server.  After running this I either moved problematic VMs to a separate folder (the screenshot above is actually taken after I did this) so I could manually register them one at time later on.

Finally – I ran my command to import all of the known good virtual machines:

Get-ChildItem e:\vms -Recurse -Filter "Virtual Machines" | %{Get-ChildItem $_.FullName -Filter *.xml} | %{import-vm $_.FullName -Register}

The result of this was that in under a minute I had all of my virtual machines back and functioning on my new Hyper-V server.  Neat!

Cheers,
Ben

Categories: MDT

Nice to Know–Deploying Applications using System Center Virtual Machine Manager 2012 (SP1/R2) in UI or in PowerShell

The Deployment Bunny - Wed, 08/21/2013 - 06:28

Yes, I know, there other methods to deploy applications, but sometimes it make sense to use SCVMM to deploy applications to the host machines that you manage. If we look on this from a new and more modern way, SCVMM will be the System Center member that does the deployment of the “only” needed physical machines, that is the Hyper-V hosts and the fileservers used to store the VHDx files over the the SMB network, maybe there is no Configuration Manager Server in this datacenter for any reason.

The App = HP Service Pack

In this case we are going to deploy the HP Service Pack to our hosts since we need that to be able to monitor correctly using OpsMgr (When using an Agent) amongst many things. The Application can be “pushed” from a central location but in this case we are going to run the application locally on each and every server and reboot it if needed. The Command to make a silent express install is HPSUM.exe /express_install and you download the Service Pack for the Proliant servers from HP.com (https://h20392.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=HPICE#Download). After downloading the ISO, mount and extract and share the folder so it is accessible to all your hosts.

The GUI Method

Rater easy actually, we can use the “Run Script Command” that is available on every server in the SCVMM Console and then fill out all the parameters

Fill out the parameters like this:

-Executable program: \\vmm01\CD\hp\swpackages\hpsum.exe

-Parameters: /express_install

-Timeout: 1800

-Advanced:

–Standard Output: Do not match

–Standard error: Do not match

–Exit Code: Do not Match

–Action when matched: Warn and Continue

–Job restart action: Ignore Script

–Always restart after the script has finished running: Checked

–Restart the computer or virtual machines if the specified exit code is returned: Unchecked

Summary using the UI:

This will work, but not they way I wanted it to, the problem is that I cannot define my own values in the dialg boxes, as an example the application HPSUM.exe will return exit code 1,2 or 3 when it needs a reboot and that cannot be “picked” in the dropdown list, however, using PowerShell well be easier, better and faster since you can define all the applications in an XML file wit all the different settings. so lets drop the UI and switch over to what works and make sense, PowerShell

The PowerShell Method

In this case we will use the same engine, but fire it of using PowerShell instead, it gives us more flexibility and more control

Step Number One – Create the Apps.XML

Here we create an XML file that contain all the settings for all the different application we would like to deploy and here it how it looks:

as you can see it contains the application, arguments, reboot settings and all the return codes this application could return when it “feels” that it needs a reboot

Step Number Two – Create the Deploy-Apps.ps1 script

The script uses the Parameter function to read in data from the command line and then it reads the XML file, we also need to make sure that some of the data from the XML file is parsed correctly as strings or as Boolean. Then we use all that data set some static settings and last we use the Invoke-SCScriptCommand to execute the command on the host, the script looks like this:

Step Number Three – Execute!

Execute the script like this:

And wait for the job in the log and after a while it will inform you that the job did finish with warnings, the reason for the warning is that is actually a real warning from the application that is picked up up by the output

The hpsum.exe detects the version of windows as 6.2 (and that is correct), but even if HP claims that is supported, the HPSUM.exe does not have the same opinion . Hopefully HP will fix this later.

So in the Job log it will show up like this:

Summary using PowerShell:

This gives a more stable solution which can be extended and automated and that I like…

You can download the scripts from here:


Categories: MDT

Better Together - The New Windows Server 2012 R2 Innovations – Download Now

Microsoft Deployment Toolkit Team Blog - Tue, 08/20/2013 - 12:00

There are quite a few products that make up the Microsoft Cloud OS vision. Windows Server 2012 R2 is in preview right now and ready for your evaluation.  We also have a strong management platform that make up the System Center family of products. They are designed to have tight integration with the core being Windows Server.

If you are looking for information on Windows Server 2012 R2, we have been rolling out detailed information though Brad Anderson’s What’s New in 2012 R2 blog series.  That will continue but we thought you would like a short consolidated list for consideration.  Here are some of the new innovations in Windows Server 2012 R2.

Storage transformation – Delivers breakthrough performance at a fraction of the cost

  • The storage tiering feature of Storage Spaces in Windows Server 2012 R2 automatically tiers data across hard disks and solid state drives based on usage to dramatically increase storage performance and cost efficiency.

Software defined networking – Provides new levels of agility and flexibility

  • Network virtualization in Windows Server 2012 R2, along with the management capabilities in System Center 2012 R2 provides the flexibility to place any virtual machine on any node regardless of IP address with isolation. 
  • New in-box gateway in Windows Server 2012 R2 extends virtual networks to provide full connectivity to physical networks as well as access to virtual networks over the internet.

Virtualization and live migration – Provides an integrated and high-performance virtualization platform

  • Cross-version live migration enables virtual machines running on Windows Server 2012 to be migrated to Windows Server 2012 R2 hosts with no downtime.
  • Live migration compression provides dramatic time savings (approximately 50% or greater) by using spare CPU cycles to compress live migration traffic with no special hardware.
  • Live migration with RDMA enables offloading of the process to the NICs (if they support RDMA) for even faster live migrations.

Access & Information Protection – Empowering your users to be productive while maintaining control and security of corporate information with Windows Server 2012 R2

  • Enable users to work on the device of their choice (through BYOD programs or on personal devices) by providing a simple registration process to make the devices known to IT and be taken into account as part of your conditional access policies
  • Deliver policy-based access control to corporate applications and data with consistent experiences across devices
  • Protect corporate information and mitigate risk by managing a single identity for each user across both on-premises and cloud-based applications and enabling multi-factor authentication for additional user validation

Java application monitoring – Enables deep application insight into Java applications.

  • Provides performance and exception events as well as level alerting within Operations Manager for Java applications.
  • Supports Tomcat, Java JDK, and other Java web services frameworks.
  • Line-of-code level traceability with performance and exception metrics for .NET and Java application monitoring for more actionable, tool-driven dev-ops collaboration

This is by no means a comprehensive lists of new features and benefits, but we just wanted to give you some information on the key focus areas.  For those of you interested in downloading some of the products and trying them, here are some resources to help you:

Categories: MDT

Pages