יום שישי, 18 במאי 2012

Target Eye Source Code Revealed

Introduction 

Auto Update mechanism doesn't have to be based on the actual version number (kept in the Version String), but can also base on the Last Modified Date Stamp of the newer version compared to the old one. Target Eye Monitoring System, developed starting of 2000, had such mechanism.

Background

Target Eye Monitoring System, which I have developed 12 years ago, was one of the first surveillance and monitoring tools for capturing activity of remote computers. The following description is taken from the original Business Plan of this venture:

Target Eye Monitogin System 
Target Eye is a start-up company whose mission is to develop integrated software solutions for real-time monitoring of remote PCs, which are based on the company’s patent pending technologies (60/204,084 and 60/203,832). Our major product, Target Eye Monitoring System, is a software product that can continuously track, record, playback, analyze and report any activity performed on one or multiple remote PCs, in a way which is undetectable by their users. The software relies on a stream of rapidly captured, compressed full-screen images and continuous keystroke capturing to provide a comprehensive and accurate account of user activities, including local activities which do not generate any network traffic. In this way, the software can track and record activities, which are undetectable by systems relying on network traffic analysis. A smart agent module running on the monitored PCs uses a rule base to send alerts to the monitoring location(s) or perform pre-defined local operations. Monitoring can be performed from multiple locations. Major markets are law-enforcement.
Target Eye Monitoring System was developed with an auto update mechanism. This mechanism allows smooth and silent (un-attendant) execution of the new version instead of the current one.

An historical image: The first version of Target Eye (Apr 2000)  

A more recent version (Target Eye 2007) 

This article focuses only in one aspect of this product, which is the Auto Update mechanism.  

Creating and Marking Incremental Versions

In order to be able to determine a newer version over the current one, there must be a mechanism to mark the various versions, to increment the version number, and to examine the version of a given executable.
The most common way of doing so is using the "Version String" resource, and to use a prebuild automated tool to promote this string each time the application is built.
I used another method which is based on the list modification date of the executable file. This method has its pros and cons, but can be useful for most cases, since it will allow your end users to get any version of your application that was built after the one that is currently installed.
Before I explain, it is important to mention 2 global variables which are used to build at start:
strRegularLocation   
The location and full path of the application when it runs normally (i.e. c:\program files\your app name\your app.exe),
and…
strTemporaryLocation
Another full path to be used for the temporary version downloaded when there is an update.
The reason for doing so it because since the application downloads it's new version, the new version can't be downloaded to its current location, and can't replace itself because while a file is used (or an application is running) the file is locked and can't be moved, deleted or renamed.
char strRegularLocation[256];
char strTemporaryLocation[256];
Filling strRegularLocation and strTemporaryLocation with real values
strRegularLocation is taken simply from __argv[0], provided that we are sure that we aren't running already from the temporary location. We ensure that by using a parameter named "INSTALL" which will be explained later. 
strTemporaryLocaiton is built using a common folder and a temporary name combined. We use GetSpecialFolder() to find the path name of this folder in any computer running the application.

Getting the date stamp of current version 

To do so, TEGetVersion(), the first building block, is used and returns a CString containing the last modification date of a given file. 
//
TEGetVersion returns the last modification date / time of a given file
CString TEGetVersion (CString FileName)  {  
Time1; if( CFile::Ge
CFileStatus status1; CTime tStatus( FileName, status1) ) {
return (Time1.Format("%d%m%M%S")
Time1 = status1.m_mtime;  ); }  // Failed  return ((CString)""); }
//
When my application starts, I store the date / time stamp of it somewhere.
TE_Options.Version=TEGetVersion((CString)__argv[0]);
// here we keep the date/time stamp of the current version
Now we need to get the date / time stamp of the file online, preferably, without having to download it first, so we only download when we need to update to a newer version.
HINTERNET FileHandle=NULL; 
ND_DATA ftpFileData;  //find
WIN32_F Ithe file on the ftp server 
ndle, FTP_NEWVERSION, &ftpFileData, INTERNET_FLAG_RELOAD, 0 ); if( NULL
FileHandle= FtpFindFirstFile( m_ftpH a!= FileHandle ) { // get the write time of the ftp file
FileTimeToSystemTime( &ftpFileData.ftL
SYSTEMTIME ftpFileWriteTime, stUTC1; FILETIME ftp; astWriteTime, &stUTC1 ); SystemTimeToTzSpecificLocalTime( NULL, &stUTC1, &ftpFileWriteTime );
}
We need to define how old should be the current version in order to update it. Again, this approach can be very useful in some cases and less useful in other. For example, if your application involves a database, you might be interested to ensure that the database is always most recent and never older than 3 days.
#define UPDATEEVERY 60*24*7 // 7 days
#define APP_EXE_NAME "TargetEyeTest.exe"
#define FTP_NEWVERSION "NewVersion.exe"
\"
#define APP_REGULAR_FOLDER "\\TargetEye \
The next step is to compare the date / time stamp of each file.
CFileStatus
statusOld;
ld; if( CFile:
CTime Time
O:GetStatus( FileHandle, statusOld ) )
{ CTime ct,OldTime;
d.m_mtime; hFindFile.GetLastWr
OldTime=statusO liteTime(ct); LONG Diff;
Y %H:%M %Z"); oldver=OldTime.FormatGmt
ver=ct.FormatGmt("%d %m %("%d %m %Y %H:%M %Z");
-OldTime)).GetTotalMinutes(); hFindFile.Close();
Diff = ((CTimeSpan)(c tif (Diff>UPDATEEVERY || resultSpecific) {
// download the newer version }

Downloading the new version

Downloading the newer version is performed using TE_DownladLoad() which is listed here. We make several attempts in case there is a temporary block or communication problem.
#define FTPRETRIES 5 // number of retries
BOOL TE_DownloadLoad(char *FtpFileName,char *LocalFileName)
{ int DoTry=FTPRETRIES;  int result; 
t = MyConnection
TryAgain:;  try  { resu l.m_FtpConn->GetFile(FtpFileName, LocalFileName, FALSE); }
4];  pEx->GetErrorMessage(sz
catch (CInternetException* pEx) { TCHAR sz[10 2,1024); WriteToLog("Error %s\n", sz);
6 - TE_Load",MB_OK); pEx->Delete();  } if (!resul
if(TE_DEBUG) MessageBox(NULL,sz,"Error t) { if(DoTry-- >0) goto TryAgain; return(FALSE); } else {
return (TRUE); }
}
Now we are ready to switch between the currently running version (the old one) with the newer one. 

Executing the newer version 

BOOL ExecuteNewVersion(char *ExeName,char *Param)
{ STARTUPINFO sinfo;
pinfo; ZeroMemory(&sinfo, s
PROCESS_INFORMATION izeof(sinfo)); sinfo.cb = sizeof(sinfo);
info.dwFlags=STARTF_USESHOWWINDOW ;
sinfo.lpDesktop= "WinSta0\\Default"; ssinfo.wShowWindow=SW_SHOW;
(char*)(LPCTSTR)((CString)(ExeName)+(CString)" "+(CString)(Param)
if(!CreateProcess(NULL ,), NULL, NULL,FALSE,NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, NULL, NULL, &sinfo, &pinfo))
);
{ char s[256]; sprintf(s,"Can't execute program: %s params %s",ExeName,Para m // ERROR LOG TELog.LogError("Execute New Version",s,0); return FALSE; }
else { return TRUE; }
So if we put all the code together we get:
CFileStatus statusOld;
CTime TimeOld;
atus( FileHandle, statusOld ) ) { CTime c
if(CFile::GetS tt,OldTime; OldTime=statusOld.m_mtime;
NG Diff; ver=ct.FormatGmt("%d %
hFindFile.GetLastWriteTime(ct); L Om %Y %H:%M %Z"); oldver=OldTime.FormatGmt("%d %m %Y %H:%M %Z");
e.Close(); if (Diff>UPDATEEVERY || resultSp
Diff = ((CTimeSpan)(ct-OldTime)).GetTotalMinutes(); hFindFi lecific) { // downloading the newer version
MPPLACE)) { // We have successfully downloade
if(TE_DownLoad((resultGeneric)?NEWEXESTR:NEWEXE,T Ed the newer version if(ExecuteNewVersion(TEMPPLACE,"INSTALL")) {
rent version can now quit }
// We have successfully executed the // newer version. Cu r else // Failed to execute new version } else {
TELog.LogError("New Ftp version found","Can't download",0); } }
}

The TE_Init() function 

TE_Init() is used to determine the parameters used when application was executed (Unlike the full version of Target Eye Monitoring System, which is much more complex, in our example, there is one optional parameter – "INSTALL").
if(__argc>1) 
{
if(strcmp(__argv[1],"INSTALL")==0)
{
// TE_FirstTime(); -> here you can place code you wish to
//be executed only during the first run  } } else
xists at the tem
// No parameters { // Delete a temporary version if eporary location
}

Replacing old with new 

In order to quit in a normal fashion, without missing anything we wish to do before quitting, the main even loop contains a check for the value of NeedToQuit, which would normally be FALSE.
BOOL NeedToQuit=FALSE; 
When NeedToQuit becomes TRUE, the application will perform any routine required before quitting (for example, saving unsaved work). For example:
if(NeedToQuit)
{
if(TE_DEBUG)
MessageBox(NULL,"Terminating Targe Eye",
"Target Eye Monitoring System",NULL);
return FALSE;
Further, the application expects to be executed either with the "INSTALL" parameter as part of the command line, or without it. The following scheme illustrates the flow of an installation of a newer version to a temporary location (the Desktop folder, in our example), up to the moment the temporary file used for it is deleted. This requires several stages:
The Target Eye Cycle
Stage
Ran with Parameter
Ran from location
Description
None
Regular
The current (old) version is running before the newer version is available
2
The newer version checks if there is a temporary copy of itself at the temporary location, but there isn't any
3
A newer version is found
4
Newer version is downloaded to a temporary location
5
Newer version runs from the temporary location with the "INSTALL" parameter.
6
Current version quits
7
INSTALL
Temporary
The newer application ran from the temporary location copies itself to the regular location, replacing the old version which quitted (5)
8
The newer version runs the copy located in the regular location and quits.
9
None
Regular
The newer version checks if there is a temporary copy of itself at the temporary location, and deletes it.

Choosing an FTP server for this demo

In order to use the source code that attached to this article, there are predefined settings of a public Secured FTP server available to the public by Chilkat Software, Inc.
The details of this server are:
Secure FTP Server Details
Type FileZilla
Address ftp.secureftp-test.com
Login Test
Password Test
There is a file there named hamlet.xml which can be used for testing a remote file date stamp.

Internationalization

To comply with scenarios in which there are users worldwide, and yet we wish to release a version to be available at the same moment to all of them regardless of their local time, we use
FormatGmt 
GMT is an absolute time reference and doesn't change regardless of the season or the location. FormatGmt is used like that:
CTime t( 1999, 3, 19, 22, 15, 0 );
// 10:15 PM March 19, 1999
%B %d, %Y" ); ATLASSERT( s == "Friday, M
CString s = t.Format( "%A,
arch 19, 1999" );

Limiting to a single instance

The mechanism described in this article can only work if we limit our application to run only once at any given moment. To do so, several methods can be used, such as CreateMutex().
Target Eye Monitoring System uses a different and a bit "brutal" approach, which will be explain in details over another article. Basically, Target Eye Monitoring System searches for other instances currently running in memory, and when found, does one of the two following options:
  1. If the instance found is newer, the current running instance quits.
  2. If the instance found is older, the current running instance kills it.
To explain, let's consider the following scenario. An end user had his current copy of software updated to a newer one. A day after, this end user runs the original CD of the software. The version that resides on the original CD, will search for new updates at the FTP server, which is unnecessary. Further, if the application runs constantly (like a monitoring application should), then probably when the CD version is ran, there is also another newer version already running. To address such scenario and other scenarios, we should take the necessary measures to ensure that an application will always be up to date.

Published at www.codeproject.com 

חבילת הסמסים שלי

התחרות בענף הסלולר, אשר תפסה תאוצה בשבוע האחרון לאחר כניסת שתי שחקניות חדשות לשוק: גולן טלקום והוט מובייל, מהווה אמתלה טובה להביא סקירה קצרה של הטכנולוגיה שמאחורי הסלולר, ובמקרה זה, משלוח הודעות SMS.

נניח שאתם רוצים להציע מוצר או שירות אשר כולל במסגרתו גם משלוח הודעות SMS. ההודעות עשויות להיות מקומיות (בארץ בלבד), או בינלאומיות (מכל מדינה לכל מדינה).

חברה בריטית ותיקה בשם CardBoardFish, מציעה תשתית טכנולוגית כזו, המקיפה את רוב מדינות העולם, ותעריף משלוח SMS בישראל (לצורך הדוגמה) יעלה כמחצית האגורה.

החברה מספקת תשתית אשר מנתבת את ההודעות על פני רוב חברות הסלולר בעולם כולו.

הדרך לצרוך שירות כזה הוא באמצעות התממשקות. זה יכול להיות אתר אינטרנט שמציע שירות הכולל משלוח SMS, או תוכנה (Desktop Applition), כאשר הדרכים להתממשק למערכת הנן:

  1. המרת מייל לסמס. שיטת Mail2SMS.
  2. פנייה לשרת HTTP באמצעות פקודת GET.
הטכנולוגיות הנתמכות על ידי החברה הן:
SMPP 3.3 ו-3.4
CIMD2
OIS

שפות התכנות הנתמכות כוללות: Soap, XML, Java, Visual Basic, PHP ו-Pearl. 
שפת ++C אינה נתמכת ישירות. פניתי לחברה וקיבלתי תשובה שאין להם תמיכה או דוגמאות קוד לשפה זו, שכנראה הולכת ונעלמת מן העולם. למרות זאת, כתבתי בעצמי תוכנה קטנה שעושה שימוש בשפה זו ובMFC אשר שולחת SMS לכל יעד בארץ ובעולם, ואף נידבתי את קוד התוכנה (עכשיו יש להם תמיכה ב++C ... ).

התוכנה נראית כך:
והקסם מאחוריה הוא בהתממשקות שנעשית באופן הבא:
כל משתמש (כולל משתמש Trial כמו במקרה שלי), מקבל שם משתמש וסיסמה אשר הופכים לחלק מקוד התוכנה. 
התוכנה שלי עושה שימוש בClass קוד פתוח בשם WinHTTPClient אשר חיבר תוכניתן סיני בשם Sheng Chi.
כתבתי רוטינה בשם SendSMS אשר משמשת ה"מנוע" של התוכנה.
כפי שתראו יש צורך לקבוע פרמטר בשם DC עם ערך "4" ולקדד את ההודעה כHexadecimal, זאת על מנת שתתמוך בתווים בעברית (ובשפות נוספות), ולצורך כך כתבתי פונקציה נוספת בשם ConvertHex:

שם השולח יכול להיות מספר טלפון, או שם (באותיות לטיניות בלבד, וללא רווחים).
כתובת הנמען כוללת קידומת מדינה, ומספר טלפון (ללא ה"0" בהתחלה).

והעלות, כאמור, חינם לתקופת נסיון ולאחר מכן 0.006 יורו (כ-2 אגורות) להודעה.

יום שני, 19 במרץ 2012

אפשר גם וגם

לפני מספר חודשים נחשפה פעילות ה"האקר הסעודי" והיקפה, אשר התבטאה בין השאר בגנבת פרטי אזרחים ישראלים לרבות מספרי כרטיסי אשראי שלהם ומספרי תעודות זהות, וכן פרטי חשבונות מייל ואינטרנט שונים שהם מחזיקים (שם משתמש וסיסמה). פעילות ההאקר הסעודי וחבורתו לא נפסקה וניתן לקרוא עליה ולהתעדכן בבלוג הבא.

אחד הכשלים שנחשפים מהפרשה נוגע לעובדה שפרטי מידע רגישים כגון מספרי כרטיסי אשראי ותעודות זהות, נשמרים על ידי אתרים רבים, ויש בכך פירצה הקוראת לגנב.

ביום ראשון האחרון הודיע משרד המשפטים כי הוא בכוונתו לאסור על אתרי אינטרנט לאסוף מספרי זהות של משתמשים ללא הצדקה ממשית. משמעות הדבר היא שאתרים יעברו להשתמש במספר לקוח שהם ייצרו לכל לקוח ולקוח. מספר הלקוח ישמש כמזהה חד ערכי לכל אחד מלקוחות האתר באופן שיאפשר להבדיל בין לקוחות הנושאים, לדוגמה, את אותו שם, וכך משה כהן מתל אביב הנושא מספר לקוח X יזוהה כלקוח שונה ממשה כהן מתל אביב הנושא מספר לקוח Y.

יש לתת את הדעת לכך שאופרטיבית אין דרך טובה יותר ממספר תעודת הזהות לזהות משתמש או לקוח. מספר הזהות מלווה כל אזרח בכל מקום ובכל חנות או אתר, בעוד שלפי השינוי המוצע, כל אדם יצטרך להחזיק במספר רב של "מספרי לקוח", לכל אתר ואתר. לעומת זאת אם היו כל אתרי ה e-commerse מתאגדים ומנפיקים מספר לקוח אחיד, אזי הבעיה של מספרי הזהות הייתה צצה מחדש שכן האקרים היו מתלבשים על מספר הלקוח הגלובאלי בהיותו מספר בעל ערך ומשמעות כמעט זהה לזו של מספר הזהות...

הפתרון המוצע

ניתן לפתור את הבעיה בדרך הבאה. באמצעות מנגנון של checksum, שבאמצעותו בצד של משתמש הקצה, מספר הזהות ימשיך להיות אמצעי הזיהוי באתרים, אולם בצד של האתר, ויותר חשוב, בדטה בייס שלו, יישמר נתון אחר שהוא תולדה של פונקציית הchecksum.

המייחד תהליכים אלה, בהם הופך נתון אחד לנתון אחר באמצעות פונקציות ההמרה האלה הוא שמדובר בתהליך חד כיווני. לא ניתן באמצעים סבירים ונגישים להמיר בחזרה את הנתון שיתקבל ממספר הזהות וישמר בדטה בייס, חזרה למספר הזהות, ומכאן שמספר הזהות יוגן, לא יוחזק בשום מקום, ועם זאת, ישמש במזהה חד ערכי.

בשבועות האחרונים פרסם האקר המוכר בשם עומאר ("ההאקר הסעודי") פרטים אישיים של גולשים ישראלים, שנגנבו בפריצות לאתרי אינטרנט מקומיים. אלו כללו שמות, כתובות מייל, מספרי כרטיסי אשראי ובפרט מספרי תעודות זהות. כמו כן נערכו בתקופה האחרונה דיונים בוועדת המדע והטכנולוגיה של הכנסת, לאור תלונות שהתקבלו על איסוף גורף של מספרי תעודות זהות מצד עסקים שונים.



כיצד יתבצע זיהוי של לקוח חוזר

כאשר לקוח יקליד את מספר הזהות שלו, מספר הזהות יומר לchecksum שלו. המערכת תחפש נתון זה בדטה בייס ובמידה ונתון זה נמצא, יזוהה הלקוח כלקוח חוזר וניתן יהיה לשלוף את נתוניו שנשמרו (ואשר כמובן לא יכללו מספר זהות).

האם הCheckSum לא יהפוך למזהה הייחודי החדש?

לא. משום שניתן להפיק מזהים אלה בדרכים רבות ותוך שקלול פרמטרים רבים. כל עוד משתמשים באלגוריתם ופרמרטים זהים בכל פעם שמקלידים מספר זהות באתר מסוים, השיטה תעבוד. פרמטרים ייחודיים יכולים להיות שם האתר, כתובתו, וכל פרט נוסף שניתן לבקש מהלקוח כאמצעי אבטחת מידע. לדוגמה: 4 ספרות אחרונות של כרטיס האשראי. כך גם שליפת checksum מדטה בייס אחד לא תועיל במאום מול דטה בייס אחר.

ומה קורה למספר תעודת הזהות בכל התהליך

מספר תעודת הזהות משמש ככרטיס הכניסה, אולם משול הדבר לאדם שמציג תעודת זהות בכניסה לבניין, ולאחר שהוא מזוהה, תעודת הזהות מוחזרת לו ופרטיה אינם נשמרים. כך גם בתהליך זה. מספר הזהות נדרש לצורך האימות / רישום אולם הוא נזרק ולא נשמר.

יום שבת, 10 במרץ 2012

האם תכתובות הסמס שלך מוגנות?

הודעות טקסט (סמס) הפכו להיות חלק מחיינו ותופסים מקום הולך וגדל בדרך ההתקשרות בין אנשים. עם זאת, בשונה מהודעות מייל, כמה מכם שומרים הודעות סמס שנשלחו או התקבלו? מסיבה לא ברורה התרגלנו שהודעות הסמס נמחקות לאחר פרק זמן ואובדות לנצח בסל המיחזור של המרחב הקיברנטי.
מי שמשתמש בITunes ומחזיק במכשיר IPhone אולי יופתע לגלות עד כמה קל לשלוף את תוכן הודעות הסמס מהמחשב שלו.
אחרי חיבור המכשיר למחשב, מתבצע סינכרון, ולמרות שאין כל חיווי לכך בתוכנת ITunes שלכאורה מסנכרנת רק קבצי מדיה, הרי שמאותו רגע המידע הרגיש שמור כבר בתיקיה הבאה:
c:\users\שם המשתמש שלך\appdata\roaming\apple computer\Mobilesync\backup\תיקיה זמנית
עכשיו נסביר מה זה מה:
"שם המשתמש שלך", השם דרכו עשית לוג אין לWindows.
תיקיה זמנית, תיקיה בעלת שם אקראי שנוצרת על ידי ITunes. לכל מכשיר אייפון תיווצר תיקיה נפרדת.
אם תפתחו תיקיה זו תראו קבצים מוזרים למראה...
Image
אולם הקובץ בו נשמרות כל תכתובות הסמס, הנו קובץ ייחודי בעל שם אחיד לכולם.
שם הקובץ: 3d0d7e5fb2ce288813306e4d4636395e047a3d28 .
כן. פשוט וקליט...
נפתח את הקובץ ונראה משהו כזה:
Image
אולם בעזרת ידע או כלים מתאימים ניתן לשלוף כל הודעה, כולל הודעות שנשלחו או התקבלו, מאז שהמכשיר היה בשימוש.
רק לדוגמה, ניתן לטעון קובץ זה לאתר הבא, ולהמיר אותו לפורמט קריא כמו PDF או אקסל.
גם המרה לפורמט HTML אפשרית בקלות. לדוגמה:
<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body>
<table border='0'><tr style='font-weight: bold'><td>Date</td><td>Number</td><td>Sent</td><td>Text</td></tr>
<tr><td>'2011-09-12 03:03:00'</td><td>'07777'</td><td></td><td>'בהתאם להחלטת משרד התקשורת, חסימת זיהוי מספר הפלאפון (קבועה או חד פעמית) אינה חלה בעת התקשרות לשירותי חירום ציבוריים'</td></tr>
<tr><td>'2011-09-12
אשר יוצג כך:
כמה פשוט...
ואין מדובר בתצוגת ההודעות כפי שהיא מופיעה בטלפון הנייד שלכם (רק ההודעות האחרונות) אלא כל ההודעות מיומו הראשון של המכשיר.
והרי לכם סיבה נוספת להגן על המחשב שלכם.