The RedBox DVD Kiosk
by Mister Bojangles (cougar.slayer@gmail.com)
I never had a real job before 9/11, so I was caught off guard by how paranoid people in corporate America have become about security.
What has always irked me about this security is that you know its presence, but never are the details disclosed to you. Aside from the empty threat from HR that I am personally responsible for any outside software I install, they assume that the impotent security guards and worthless electronic badge system have put the fear of God into me. Hardly.
A while ago I received a text message reminding me that I am required to log out of my machine. They knew I had not logged out because my status in Windows Messenger was "Away" and not "Offline".
In fairness, my company is reasonably cool and has better things to do than babysit its employees. But I learned that they me Windows Messenger as a way of snooping. It's relatively benign this time, but what about in the future?
What else is being snooped that they aren't telling me?
In light of this occurrence I decided to develop something I could use to manipulate the people watching me, whoever they are. As usual, I'm not responsible for bad performance reviews, getting your ass fired, or any legal action as a result of this program.
The code is VB.NET, but could easily be ported to another language that supports COM objects and can build a Windows Forms app if you don't have Visual Studio or for some reason you can't install the .NET framework (which includes free command line compilers for VB, C#, Visual J#, and JavaScript).
First, let's look at the Windows Form (Figure 1) associated with this app.
Figure 1Only one value is accepted, which is a number that becomes a number of minutes. The "Go" button starts everything.
Notice the properties of this form (Figure 2). The maximize box is not enabled. This prevents a clumsy user from accidentally filling the screen with this window just as the boss walks by.
Figure 2By setting ShowInTaskbar to False, this program very easily becomes invisible. Minimize the program using the appropriate window control and the app will still run but disappear (nearly) completely.
Alternatively, the small window could easily be hidden by a larger one.
Now let's get into the code, starting from the top.
System.Math is necessary for random numbers. The first Private statement is a declaration of the ExitWindowsEx function from the USER32 library (a system library) which is what forces Windows to logoff (more on this later).
Next is the declaration of the Sleep subroutine from the KERNEL32 library, another system library. This is used to tell the program to wait for a specified number of milliseconds.
The Sleep subroutine is useful because it avoids the Timer control available in form design, which is only good for about a minute anyway.
Next is the instantiation of the Windows Messenger API. Before this will work, you must add a reference to Windows Messenger, which is easy in Visual Studio.
Go to the "Project" menu then "Add Reference". Next, click "Browse" and navigate to MSMSGS.EXE (should be C:\Program Files\Messenger) and the necessary reference is now included in your project!
This can be done for any DLL, TLB, OLB, OCX, or EXE file, so if you need to customize this for your own app try adding it as a reference to a Visual Studio project and use the Object Browser to see what methods are available!
Next, the Enum which handles the four different types of exiting Windows. Logoff does just a however other programs are allowed to interrupt the process. If you've ever seen the annoying "Program X is not responding... End Now or Cancel" box, this is a program interruption.
Shutdown and Restart... what do you think they do? The one we'll be using is ForceLogoff. This logs the user out regardless of what other programs need done. So make sure you saved everything.
Clicking "Go" sets everything in motion.
After the declarations, the first thing we need to do is get an instance of the Windows Messenger API, which is done with the New statement. Cursor position is initialized and IsNumeric is used for error checking. If the value is numeric, it returns true.
Next, the time at which to logoff (goTime) is set after passing the error checking.
The loop is the guts of the code.
Based on the seconds in the current time, the cursor moves around a range of 640x480, set as such for even the lowest resolution so an out of bounds will never occur. Note that a range can be specified from the .Next method of the random number variable.
Then the program will sleep for two seconds. The cursor movement is just in case they track user activity. The sleep is less trivial because it varies processor activity. This is useful for giving the appearance of a batch job running, just in case they would check processor activity.
Next, the status of Windows Messenger is manipulated based on the minute of the system time. This serves to give the appearance of normal modulation of status. True, this is formulaic, but there's much more that could be done here.
Random numbers provide a wealth of possibilities throughout the program, so get creative! I experimented with comparing two random numbers and changing the status when a match occurred. On a 1.5 GHz machine a range of one billion random numbers gave a suitable duration.
Experiment on your own machine, but be mindful that too small a range and the status will change a hundred times a second, too large a range and the status will never change.
Finally, if the goTime is equal to or greater than sysTime, Windows is forced to logoff.
No one is the wiser, and to the remote observer it appears as though you've been working hard!
Useful when you want the afternoon off or when you want the boss to think you're working hard for that big promotion!
Shoutz: Dogpatch, Daniel Cooper, f@t@$$, Mother Puelo, 200lx.
Option Explicit On Imports System.Math Public Class Form1 Inherits System.Windows.Forms.Form Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private WithEvents WinMsg As MessengerAPI.Messenger Private Enum WindowsExitFlags Logoff = 0 Shutdown = 1 Reboot = 2 ForceLogoff = 4 End Enum Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.Click Dim time As Integer Dim checkTime As Boolean Dim sysTime As Date = DateTime.Now Dim goTime As Date = DateTime.Now Dim position As Point Dim rand As New Random(CInt(Now.Ticks And Integer.Maxvalue)) Dim randPos As Integer WinMsg = New MessengerAPI.Messenger position = Cursor.Position() checkTime = IsNumeric(txtVal.Text) If (checkTime = True) Then If (txtVal.Text > 0) Then time = txtVal.Text goTime = Now.AddMinutes(time) Else MessageBox.Show("Value must be > 0. Try again.") txtVal.Clear() Exit Sub End If Else MessageBox.Show("Value must be numeric. Try again.") txtval.Clear() Exit Sub End If Do Until goTime = sysTime sysTime = DateTime.Now Select Case sysTime.Second Case 15, 59 randPos = rand.Next(0, 640) position.X = randPos Cursor.position = position Sleep(2000) Case 30, 45 randPos = rand.Next(0, 480) position.Y = randPos Cursor.Position = position Sleep(2000) End Select Select Case sysTime.Minute Case 8, 26, 39, 46 WinMsg.MyStatus = MessengerAPI.MISTATUS.MISTATUS_ONLINE Case 6, 23, 36, 44 WinMsg.MyStatus = MessengerAPI.MISTATUS.MISTATUS_AWAY End Select If goTime <= sysTime Then Exit WindowsEx(WindowsExitFlags.ForceLogoff, 0&) End If Loop End Sub #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub 'Form overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose (ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. Friend WithEvents btnGo As System.Windows.Forms.Button Friend WithEvents txtVal As System.Windows.Forms.TextBox <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(Form1)) Me.btnGo = New System.Windows.Forms.Button Me.txtVal = New System.Windows.Forms.TextBox Me.SuspendLayout() ' 'btnGo ' Me.btnGo.Location = New System.Drawing.Point(88, 5) Me.btnGo.Name = "btnGo" Me.btnGo.Size = New System.Drawing.Size(75, 24) Me.btnGo.TabIndex = 0 Me.btnGo.Text = "Go" ' 'txtVal ' Me.txtVal.Location = New System.Drawing.Point(8, 8) Me.txtVal.Name = "txtVal" Me.txtVal.Size = New System.Drawing.Size(70, 20) Me.txtVal.TabIndex = 1 Me.txtVal.Text = "" ' 'Form1 ' Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.ClientSize = New System.Drawing.Size(177, 37) Me.Controls.Add(Me.txtVal) Me.Controls.Add(Me.btnGo) Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) Me.Location = New System.Drawing.Point(150, 150) Me.MaximizeBox = False Me.Name = "Form1" Me.ShowInnTaskbar = False Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen Me.ResumeLayout(False) End Sub #End Region End ClassCode: punking-the-watchers.vb