Nontrivial
task for Security administrator can be reading data from client, or
troubleshooting scenario, when a company policies dictates to use
Endpoint in Stealth mode. Switching to UI mode from previous example
has been prohibited as well.
From
first point parsing files such as XML config, sqlite format dbs is
good idea but this case has couple disadvantages (for instance –
yeah, we able to get Primary and Secondary servers, but who is an
active at this moment, etc...)
So,
looks like we need our personal application to gather all necessary
data.
Let's start our investigation from observing processes in memory. WinSpy++ is a nice tool for that. Drag Finder Aim and drop on Endpoint client window (for investigation purposes we are using UI mode – temporary).
Let's start our investigation from observing processes in memory. WinSpy++ is a nice tool for that. Drag Finder Aim and drop on Endpoint client window (for investigation purposes we are using UI mode – temporary).
Have
a look at Windows tab, interesting. Almost all data is available just
from static labels.
Knowing
proper handlers we can pull up necessary info to our app. OK, how
about buttons? Very simple too, knowing a button handler we can send
proper event, for example mouse button click. Main window handler can
be detected from memory window caption 'Websense Endpoint' scanning.
My
final result you can check from pictures posted bellow:
Unfortunately
I don't have any C licenses, so I was using Lazarus Free Pascal.
For
button click emulation I was using two types of events somehow,
different buttons were reacting differently. As a parameter I'm
sending necessary button handler and type of clicking.
Procedure SendButtonClick(TypeClick:Boolean; myhandle:Thandle);
Begin
ShowWindow(WebsenseHandle,10);
ShowWindow(WebsenseHandle,SW_HIDE);
If Typeclick=True then
begin
SendMessage(myhandle, WM_LBUTTONDOWN,0,0);
SendMessage(myhandle, WM_LBUTTONUP,0,0);
End
else
PostMessage(myhandle, BM_CLICK, 0, 0);
End;
Our
memory hound function, with 'Websense Endpoint' input string and main
window handler return as a result.
function FindWindowExtd(partialTitle: string): HWND;
var
hWndTemp: hWnd;
iLenText: Integer;
cTitletemp: array [0..254] of Char;
sTitleTemp: string;
begin
hWndTemp := FindWindow(nil, nil);
while hWndTemp <> 0 do begin
iLenText := GetWindowText(hWndTemp, cTitletemp, 255);
sTitleTemp := cTitletemp;
sTitleTemp := UpperCase(copy( sTitleTemp, 1, iLenText));
partialTitle := UpperCase(partialTitle);
if pos( partialTitle, sTitleTemp ) <> 0 then
Break;
hWndTemp := GetWindow(hWndTemp, GW_HWNDNEXT);
end;
result := hWndTemp;
end;
Next
procedure is building tree list view of all child objects from main
endpoint window.
procedure Sys_Websense_Tree(Node: TTreeNode; AHandle: HWND);
const
MAX = 128;
var
szClassName, szCaption: array[0..MAX - 1] of Char;
Result : String;
szFileName : array[0..255] of Char;
PID, TID: Cardinal;
szLayoutName: array[0..MAX - 1] of Char;
begin
while AHandle <> 0 do
begin
GetClassName(AHandle, szClassName, MAX);
GetWindowText(AHandle, szCaption, MAX);
FillChar(szFileName, 256, #0);
TID := GetWindowThreadProcessId(AHandle, PID);
AttachThreadInput(GetCurrentThreadId, TID, True);
VerLanguageName(GetKeyboardLayout(TID) and $FFFF, szLayoutName, MAX);
AttachThreadInput(GetCurrentThreadId, TID, False);
Result := Format('%s [%s] Caption = %s, Handle = %d',
[String(szClassName), String(szFileName), String(szCaption), AHandle]);
If (Ahandle = WebsenseHandle) or (GetParent (Ahandle)=WebsenseHandle) then begin
MainSenseStatusForm.LL:=MainSenseStatusForm.LL+1;
With Vault[MainSenseStatusForm.LL-1] do begin
ObjectType:=String(szClassName);
FileObject:=String(szFileName);
Caption:=String(szCaption);
Handle:= Ahandle;
ePid:=PID;
Layout:=String(szLayoutName);
end;
result:=inttostr(MainSenseStatusForm.LL-1)+'. '+result;
Sys_Websense_Tree(LogForm.TreeView1.Items.Add(Node,Result),
GetWindow(AHandle, GW_CHILD));
end;
AHandle := GetNextWindow(AHandle, GW_HWNDNEXT);
end;
end;
Then
all working set moving to array of elements, Vault.
CardOfObject = record
ObjectType: String;
FileObject: String;
Caption:String;
Handle: Thandle;
ePID: Cardinal;
Layout: String
end;
Vault: array of CardOfObject;
And
key procedure for application, presenting info.
procedure TMainSenseStatusForm.RefreshButtonClick(Sender: TObject);
var
StartHandle: Thandle;
begin
PreInit(LL);
StartHandle := GetDeskTopWindow;
WebsenseHandle := FindWindowExtd('Websense Endpoint');
Sys_Websense_Tree(nil, WebsenseHandle);
if vault[9].Caption<>'' then UserNameLabeledEdit.text:=Vault[9].Caption;
if vault[12].Caption<>''then DataSecurityLabeledEdit.text:=Vault[12].Caption;
if vault[14].Caption<>''then UpdatedLabeledEdit.text:=Vault[14].Caption;
if vault[18].Caption<>''then ProfileLabeledEdit.text:=Vault[18].Caption;
if Vault[55].Caption='Disconnected' then
begin
ConnectionStatusLabel.Caption:='Disconnected';
ConnectionStatusLabel.color:=clRed;
end;
if Vault[55].Caption='Connected' then
begin
ConnectionStatusLabel.Caption:='Connected';
ConnectionStatusLabel.color:=clGreen;
end;
if Vault[20].Caption='Enabled' then
begin
EndpointStatusLabel.Caption:='Enabled';
EndpointStatusLabel.Color:=clGreen;
end;
if Vault[20].Caption='Disabled' then
begin
EndpointStatusLabel.Caption:='Disabled';
EndpointStatusLabel.Color:=clRed;
end;
end;
As
an example to check Policy, Fingerprint, Profile versions, I'm using
next procedure.
procedure TMainSenseStatusForm.VersionsButtonClick(Sender: TObject);
begin
SendButtonClick(True, Vault[14].Handle);
end;
PS:
Final question for today. How many times did you click red cross button
trying closing picture window? :)
And if you want to try this app just let me know.
No comments:
Post a Comment