
Stuxnet's Legacy Lives on in New Windows Bug - whiteyford
https://decipher.sc/stuxnets-legacy-lives-on-in-new-windows-bug
======
barbegal
It's worth reading the full technical analysis [https://windows-
internals.com/printdemon-cve-2020-1048/](https://windows-
internals.com/printdemon-cve-2020-1048/)

It's well written and easy to follow even for someone that doesn't know much
about Windows security.

And if you didn't read it the bug comes from the fact that the Powershell
command Add-PrinterPort can be used to add a printer port as a file that you
don't have access to. After restarting the spooler service you can then use
this port to write to that file.

~~~
quietbritishjim
This was very interesting, thanks for posting it! I will say that this is a
bit misleading though:

> the bug comes from the fact that the Powershell command Add-PrinterPort can
> be used ...

The bug is in the print spooler service and the Windows API to access to it.
It just happens that PowerShell offers an easy way to access the Windows API,
which makes it easy to illustrate the exploit.

------
ciarannolan
I thought Countdown to Zero Day: Stuxnet and the Launch of the World's First
Digital Weapon was a fantastic chronicle of Stuxnet.

For those not interested in the whole narrative, it's still interesting to
browse one or two chapters of interest.

[https://www.amazon.com/Countdown-Zero-Day-Stuxnet-
Digital/dp...](https://www.amazon.com/Countdown-Zero-Day-Stuxnet-
Digital/dp/0770436196)

~~~
accidentalrebel
I just checked and happy to find that it's on Audible.

Can anyone recommend similar audiobooks on tech that are not as well known?

~~~
khalladay
If you're looking for more computer security / hacking related books, I can
recommend "Sandworm" (by Andy Greenberg) and "The Cuckoo's Egg" (by Cliff
Stoll). Both appear to have audible versions.

------
Jonnax
Why's it so difficult to write a print spooler?

I'm not too familar with what it does exactly. But I presume it's a queue of
documents to send to a printer and some level of conversation of the data from
a print document format to what the printer driver understands.

This seems like quite a crazy bug. Also today, a lot of home printers are
network printers so it shouldn't even require higher privilages to send the
document to the printer, right?

Or is printing in Windows a huge can of worms like its use of UTF-16?

~~~
derefr
It is indeed _possible_ to design a system that only works as a client for
network printers as a pure-userland service; I believe this is what iOS has,
in the form of AirPrint.

But most OS printing services cover both network and local (USB, parallel,
even serial!) printing, and therefore the print daemon needs to essentially
"own" ACLs on some collection of USB-devices and even "own" direct bit-banging
access to a set of serial/parallel-ports, in the same sense that X11 gets to
own VRAM memory-regions, or an audio daemon gets to own bit-banging access to
a set of DAC controllers.

Coupled with this is the problem of supporting legacy software that expects
older consumer-microcomputer OS paradigms for device access. This isn't so
much of a problem on POSIX systems, where the oldest paradigm (having
/var/spool as a sticky dir, where roff(1) would just write files there) was
already multitenant-friendly; you just need a print daemon (CUPS) that can
watch /var/spool for changes, along with its non-legacy API. I believe you can
roff(1) even within Termux on Android, and it'll "just work", without special
kernel support other than the generic filesystem notification-event API.

But Windows specifically inherits a print-system design all the way from DOS,
and still supports software (e.g. Win9x software written for the Win32 API)
that was written to expect that legacy API. I don't know too much about the
Win32 print API specifically, but I'd guess that it was designed to be a
forward-compatible shim on top of the DOS printing "API"—which was really just
allowing the application to bang bits down the serial/parallel port through
memory-mapped IO.

That's what the "LPT1", "COM", etc. devices in Windows are: _emulations_ of
those same legacy memory-mapped IO channels that only make sense to access in
a single-tasking OS. But, as of NT/W2K, it's actually the OS on the other end
of that pipe, arbitrating data flows. So that's another thing that needs to
happen in kernel-land in Windows: the emulation of an unprotected MMIO memory
region within the process's address space, as a glorified syscall ABI, which
just (these days) routes messages to the userspace print daemon, but back in
Win9x probably _did_ do all its work in kernelspace.

~~~
ancarda
Why don't we have a version of Windows without as much legacy support? Like a
security hardened (or really just modern-only) version of Windows?

I suspect most people would be fine using that version of Windows, and it
would have less security problems.

~~~
derefr
Much of the "point" of Windows as a platform at this point (i.e. the reason
that developers stick with targeting Windows APIs, instead of re-developing
their software for portability using Java or Qt or Electron or whatever-else)
is backward-compatibility.

People say that a lot, but it has a very specific meaning when talking about a
platform SDK: "backward compatibility" here specifically means that if you
wrote version N of your software for version N of Windows, then when you're
writing version N+1 of your software targeting version N+1 of Windows, you
don't need to re-write any of the old code. You can just start taking
advantage of the new Windows API features in the new code you write, while
leaving your old code that calls legacy Windows APIs alone.

Almost all large Windows applications are written this way: a gradual
sedimentary accretion of calls to whatever Windows APIs were modern at the
time of writing. Even first-party software like Office still makes calls to
kernel-shimmed 16-bit APIs, right alongside calls to the modern UWP APIs.

But nevertheless:

> Why don't we have a version of Windows without as much legacy support? Like
> a security hardened (or really just modern-only) version of Windows?

We did get this; it was called Windows RT, which could only run software
(re)developed specifically for the WinRT platform SDK.

WinRT applications are automatically sandboxed; are able to be developed in
many languages, including Rust and Javascript; and, while being native code
(when you use a compiled language), are also architecture-agnostic—meaning
mostly that you can easily build one deliverable for the Windows Store that
contains binaries for x86, ARM, and any other arch Windows Store supports, and
then by downloading your app people will transparently be downloading
whichever sub-package their device needs.

But, well, few developers bothered, because most major pieces of software
would need to be _majorly_ rewritten to support WinRT. It was mostly used for
greenfield projects by existing companies; or as a target for new Windows
porting efforts (e.g. of iOS/Android software.)

Originally the incentive for using WinRT was supposed to be that only WinRT
apps could be sold through the Windows Store; but since so few third-parties
bit this bullet, Microsoft backed off and allowed all their biggest bigcorp
partners—exactly the people they were really trying to convince—to just submit
non-WinRT apps to the store. As of that moment, WinRT-the-SDK was dead in the
water; basically no large project has been rewritten for it since then.

~~~
asveikau
> Even first-party software like Office still makes calls to kernel-shimmed
> 16-bit APIs, right alongside calls to the modern UWP APIs.

This is a bit of a misleading statement, because Win16 and Win95 had a
different kernel interface than exists today: namely kernel.dll, then
kernel32.dll -- those all used to be very simple traps into kernel mode. Then
NT-based Windows made those and others into user-mode wrappers for the "real"
syscall interface living in ntdll.dll. To prevent people from writing software
that wouldn't run on 9x, and to provide flexibility to change ntdll at will,
they resisted making ntdll a public, documented API for a very long time.

So basically, all Win32 apps today are written against a shim for a legacy
kernel interface, any time they open a file, etc.

Regarding your description of WinRT.... You are missing that WinRT was not
very capable and missing a lot of functionality. There is a bit of a problem
with 21st century Microsoft in this regard. They cannot re-create their prior
1990s successes. They don't know how to write app platforms anymore, without
deprecating them a short number of years later because oops, they turned out
to be inadequate.. So the only way to have a decent Windows app is to write
against the stuff that's been working for ~25 years and they haven't managed
to break yet.

That is the reason you won't see, say, a browser rendering engine not depend
on Win32. It's not because they don't have the time or ability to rewrite.
(Google Chrome's Windows engineers, I don't know if you noticed this from
reading their source tree or looking at their blog posts, but they are _damn
good_.) It's because WinRT is missing stuff and it can't be done.

See also: Microsoft's various quests to provide a next-gen app framework.
WinForms, WPF, Silverlight... They can't get anything to stick like Win32 did,
and many later attempts end up with worse quality and shorter lifetimes than
the earlier ones.

~~~
WorldMaker
WinRT is more capable and has more functionality. The added permissions
sandbox and tougher (battery-life focused) app cycles blinded a lot of
developers. The biggest problem with the WinRT stack has never been
capabilities: it's been migration paths from legacy Win32 brownfields. (Had
Microsoft delivered more of WinRT earlier to older versions of Windows such as
XP and 7 as stepping stones, and/or had Microsoft delivered more of the XAML
Islands-style interop between Win32 HWND world and WinRT CoreWindow world
there probably would have been a lot faster adoption and lot less hand
wringing from developers.)

Under the hood, WinRT isn't even that different from Win32 "best practices":
ignoring the sandbox and app lifecycle it's a subtly better version of COM in
its own apartment.

> That is the reason you won't see, say, a browser rendering engine not depend
> on Win32.

What are you even talking about? IE11's Trident rendering engine fork that
became Spartan/EdgeHTML was (and sort of still is in that it will be supported
for a while left) entirely WinRT native from Windows 8.1 up until New
Edge/Edgmium.

Even Chromium is adopting _some_ of the WinRT libraries for rendering on
Windows. For instance, by default for many versions of Chromium it uses
DirectWrite (when running on Windows 10) for font rendering, and DirectWrite
is the font rendering system from WinRT/UWP.

> See also: Microsoft's various quests to provide a next-gen app framework.
> WinForms, WPF, Silverlight... They can't get anything to stick like Win32
> did, and many later attempts end up with worse quality and shorter lifetimes
> than the earlier ones.

This also makes less sense than you think it does. WinForms is a simple .NET
wrapper around Win32. It's practically the same thing.

The way Microsoft sees it, and WPF and Silverlight (which at one point was
known as WPF/E for Everywhere) were the Alpha/Beta stages of what became
WinRT/UWP. Microsoft remembered (it was originally a design goal of WPF that
got cut for time/effort in the Longhorn struggle) they needed to move back to
COM or a COM-like space from focusing on the .NET VM space only, because they
do have a lot of brownfield C/C++ and other language applications such as
Office. (Here again, pretty much the history of both the reasons behind WinRT
and its successes/failures are all about the brownfields of development.)

~~~
asveikau
> tougher (battery-life focused) app cycles

This is ... not the whole story. The best way to be kind to the battery is to
stay off the CPU when you have no useful work to do. If you are saving and
restoring state at every loss and gain of focus because you might be killed by
an overzealous app platform in between, you are burning more resources for
nothing.

> What are you even talking about? IE11's Trident rendering engine fork that
> became Spartan/EdgeHTML was

So you cite what is pretty commonly regarded as a "loser" browser engine -- so
much so even Microsoft abandoned it.

> and DirectWrite is the font rendering system from WinRT/UWP.

I thought it was neither WinRT nor GDI. AFAIK a COM API in the style of
DirectX.

> WinForms is a simple .NET wrapper around Win32. It's practically the same
> thing.

Yes, I know, and this is why it's often more popular than WPF and its
descendants. As I said, _many later attempts end up with worse quality and
shorter lifetimes than the earlier ones._

~~~
WorldMaker
> The best way to be kind to the battery is to stay off the CPU when you have
> no useful work to do. If you are saving and restoring state at every loss
> and gain of focus because you might be killed by an overzealous app platform
> in between, you are burning more resources for nothing.

The original WinRT lifecycle never save/restored at every loss/gain of focus.
It did exactly what you suggested and zeroed CPU usage at loss of focus. Best
practices encouraged "save as you go", which most applications have moved to
naturally as disk and network I/O got "cheaper". (Look at the history of auto-
save across the decades in Office, for instance.) It forced applications to
save additional restore state only at intervals _after_ usage stopped (X
minutes after loss of focus with no return to focus; -Y in the "alt+tab stack"
MRU list of recently accessed apps), and it tried its best to merge restore
state and deep linking as concepts (the only thing that "should have been
needed" when forced to save/restore while doing "save-as-you-go" was deep link
state). Post-web, deep linking is a critical tool and should be a default, if
you are "burning more resources" to deep link you are probably doing something
wrong, and that _is_ what the platform tried to build on. At least in terms of
the strictest best practices around the Windows 8 app lifecycle model, it
seemed quite clear that it was very battery focused first and foremost (and
yes, very tough). Windows 8 even had (and Windows 10 relaxed) very strict
quotas on how much CPU, storage access, and other parts of what you could do
to save/restore state towards the goal of enforcing the best practices that
save/restore should be mostly deep links and other content saves done
elsewhere in the application (presumably "save-as-you-go").

> So you cite what is pretty commonly regarded as a "loser" browser engine --
> so much so even Microsoft abandoned it.

Just because it "lost" doesn't mean that it _didn 't exist_ like you strongly
asserted, nor does it even mean that it was technically inferior. "Worse is
better" is a Unix mantra for a number of reasons, but seems to apply here
quite appropriately. Microsoft didn't abandon EdgeHTML because it was
technically bad, they abandoned it because it was some version of marketingly
bad and/or politically bad and no one was using it.

> I thought it was neither WinRT nor GDI. AFAIK a COM API in the style of
> DirectX.

This gets back to the "WinRT is just a subtly better COM" discussion and the
ever so intentionally blurry space between DirectX COM and WinRT and the
semantic games of who owns what. I think it's silly that more of DirectX COM
doesn't have better native WinRT bindings because it's mostly just a
difference of metadata at this point, but besides that DirectWrite is direct
dependency in the WinRT stack, doesn't exist in non-WinRT versions of Windows,
and is often considered to be a (low level) WinRT library more than a DirectX
library.

Again, I think that only further serves my point that ignoring the app
lifecycle and sandboxing, WinRT is a blurrier thing than the rigid box people
think it is with more backward/forward compatibility with the Win32 world than
both was apparent at first (especially in the Windows 8 era) and had there
earlier been a more graceful path to opt in to the harder pills to swallow
like the sandboxing and the app lifecycle then we'd probably have a lot fewer
conversation today about whether or not WinRT was "capable" or was "missing
features" from Win32.

(Yes, that also means that WinRT isn't also the extreme "clean" break from
Windows Win32 legacy that people always assume it is. The walls are a lot
blurrier today with more WinRT libraries than before providing direct Win32
COM access and XAML Islands, but removing app sandboxing the walls would have
been a lot blurrier even in Windows 8's yesterday too.)

>> WinForms is a simple .NET wrapper around Win32. It's practically the same
thing.

> Yes, I know, and this is why it's often more popular than WPF and its
> descendants. As I said, many later attempts end up with worse quality and
> shorter lifetimes than the earlier ones.

I feel like my point escaped you on this one. WinForms was never sold as a
replacement for Win32, it was always just Win32. If it was marketed as a
replacement for anything it was a replacement for previous Win32 RAD tools
like VB6.

Silverlight was never marketed as a replacement for Win32. It was marketed as
a replacement for Flash and Java applets (and HTML in some cases).

Two of your three examples were never meant to be Win32 replacements, so their
"worse quality" (ymmv) and "shorter lifetimes" are irrelevant with respect to
WinRT.

(Sure, you can bring up Windows Phone 7 where Silverlight was used as an
application API stop gap in the brief period where WinRT wasn't finished but
was the writing on the wall, but Silverlight was sold as a stop gap at the
time and the expectation and admission was always that a "Silverlight-like"
system would replace it in the next version, as it did, migration headaches
aside for developing for a stop gap on the road to the next application
framework.)

Also, "shorter lifetimes" is an interesting statement given that both WinForms
and WPF are still supported in Windows, expected to be supported nearly
perpetually, were just ported to .NET Core for many benefits and gains, and
have a much increased access to WinRT libraries and XAML Islands. The future
is bright for brownfield developers of WinForms and WPF. Sure, the general
recommendation is still not to use either tech for greenfield work, but most
companies go for "security and support" when discussing lifetimes and those
horizons are still fine, there's nothing stopping greenfield work from
happening in WinForms/WPF beyond "general recommendation".

Now, WPF was sold as a DirectX-based replacement for WinForms certainly. It's
possible to see that as an implicit argument that it was meant to be a
replacement for all of Win32, but of course WPF never entirely escaped the
Win32 legacy as had been it's original predecessor's vision. I still often
assert that WinRT is the fulfilling of a lot of the original WPF vision, and
in that way that they are more alike than different, WinRT is a "final"
version of WPF and the evolutionary tree of WPF, Silverlight (WPF/E), and
WinRT a lot less choppy and/or internally discordant than a lot of people want
to think. That comes down to aesthetic judgments like "worse quality"; I don't
think that statement applies to the evolutionary tree like you think it does.
WPF, Silverlight, and WinRT all have different niches/fitnesses in the
evolutionary tree. But I also don't see Silverlight nor WinRT as "descendants"
of WPF but that all three are descendants of the proto-WinRT (sometimes code-
named Avalon), which was more WinRT like than not and it took a lot of
evolutionary pressure to "finish".

~~~
asveikau
> Post-web, deep linking is a critical tool and should be a default, if you
> are "burning more resources" to deep link you are probably doing something
> wrong, and that is what the platform tried to build on.

This whole statement results from shoehorning the web inappropriately into an
app model and only makes sense if you have done that mental gymnastics in
precisely the same way. Nobody else did so nobody built WinRT apps.

The model works best for toy apps. This fits with other aspects to conclude
they shipped something which was appropriate for demos written by interns but
not battle tested like decades of win32 was.

> Windows 8 even had (and Windows 10 relaxed) very strict quotas on how much
> CPU, storage access, and other parts of what you could do to save/restore
> state towards the goal of enforcing the best practices that save/restore
> should be mostly deep links and other content saves done elsewhere in the
> application (presumably "save-as-you-go").

Yes, I remember some discussion of this in Redmond. It seemed very misguided.
We are not talking about a real-time OS here where you can feel good about
hard deadlines. And it's quite difficult to intelligently enforce those limits
without knowing what useful work the application might do legitimately for the
user. It is an arrogance and a denial of realities of things like the halting
problem. And, it's been a while since I looked into it, but it seemed at one
point like Apple and Google did a better job letting you react to being killed
through similar mechanisms.

~~~
WorldMaker
> This whole statement results from shoehorning the web inappropriately into
> an app model and only makes sense if you have done that mental gymnastics in
> precisely the same way.

Where have you been? The web has been the application platform of choice for a
number of users and developers for nearly a decade now. Sure, HN is full of
complaints about every Electron app under the sun, but the web "won". Most
user expectations on how apps function come from the web these days. Mobile
app platforms are full of deep linking and other web (and post-web) concepts.

> The model works best for toy apps. This fits with other aspects to conclude
> they shipped something which was appropriate for demos written by interns
> but not battle tested like decades of win32 was.

This is blaming the egg for the chicken. WinRT hasn't been battle tested for
decades because it hasn't yet _had_ decades. It's arrogant in its
impossibility.

I have used some _great_ WinRT apps that weren't "toys", "demos", nor "written
by interns". At this point you just seem to be name calling for no benefit. I
get it, you haven't liked what you have seen for WinRT. You haven't given many
technical reasons, and this name calling continues to not serve your argument.

> at one point like Apple [...] did a better job letting you react to being
> killed through similar mechanisms.

Apple has basically the exact same quotas early WinRT tried to place on apps,
Apple just has a lot more clout when it tells developers "Our Way or the
highway".

Which again, continues to prove my point that if Microsoft hadn't tried to
"force" developers to do the right thing, and instead offer more carrots and
fewer sticks people would have a better idea of what WinRT actually is rather
than just name calling at it because it forced them to learn new things and
then was "mean" by requiring sandboxes and app lifecycles that actually tried
to be user friendly, you know just like Apple was already doing with iOS years
before WinRT released.

------
s_dev
I'm still in awe of stuxnet:

[https://www.quora.com/What-is-the-most-sophisticated-
piece-o...](https://www.quora.com/What-is-the-most-sophisticated-piece-of-
software-ever-written-1?share=1)

Almost certainly an NSA product.

~~~
ciarannolan
It was a multinational effort (US, Israel, Germany), mostly lead by the NSA.

~~~
detuur
This must be the first time I've ever seen Germany implicated in this. I
consider it 100 times more likely that the UK was involved than Germany.

~~~
dsl
I personally believe the German government was aware, but did not directly
participate in a meaningful way. However a German corporation played a huge
role.

Siemens engineers deployed a PCS 7 lab environment at the Idaho National
Laboratory, where research in to exploits was conducted. Coincidently one of
the methods Stuxnet used to stay hidden was demonstrated at the KEMA Control
Systems Conference in Idaho Falls.

Separately, Siemens engineers built a replica of the Iranian system at Shimon
Peres Negev Nuclear Research Center in Israel using P-1 centrifuges the US
obtained from Libya's nuclear program.

------
jstrieb
For a recent take on the geopolitical effects of Stuxnet and many other cyber
attacks, I can recommend _The Hacker and the State: Cyber Attacks and the New
Normal of Geopolitics_ by Dr. Ben Buchanan.

I found it to be a fascinating account of international cyber attacks with a
clear, well-argued thesis.

[https://www.amazon.com/Hacker-State-Attacks-Normal-
Geopoliti...](https://www.amazon.com/Hacker-State-Attacks-Normal-
Geopolitics/dp/0674987551)

------
jakozaur
Stuxnet is a masterpiece in terms of achieving goals while attacking hard to
hit, network isolated facilities.

[https://en.wikipedia.org/wiki/Stuxnet](https://en.wikipedia.org/wiki/Stuxnet)

It would be very interesting to see the next Stuxnet class viruses, sponsored
by major companies/countries. I'm fairly sure there are some already running
in the wild.

------
cyptus
See also on
[https://news.ycombinator.com/item?id=23178247](https://news.ycombinator.com/item?id=23178247)

------
caf
I'm pretty sure I recall the "Generic / Text-Only" printer driver from Windows
3.0 days.

------
mrlonglong
Isn't Alex Ionescu also the chap working on ReactOS, a clone of Windows?

------
lostmsu
TL;DR; there was a local privilege escalation bug in Print Spooler (fixed
yesterday). The article calls it "Stuxnet's Legacy" because Stuxnet hit the
same component. But Stuxnet bug was a remote code execution (10 years ago).

~~~
draugadrotten
TL;DR; There are undisclosed unpatched CVEs pending for Windows Print Spooler
services.

From the article: "The [researchers] also said that they had found and
disclosed some other bugs in the same are that have not yet been patched “so
there’s definitely still some dragons hiding.”"

