Evo, prvo veliki LOL jer pravljenje GINA-e nije nikakav problem, veoma je
jednostavno bilo da se nasa gina ponasa kao posrednik izmedji winlogona
i msgina.dll-a!
Evo ukratko par rijeci sta je bitno:
Nakon inicijalizacije korisnik jos uvijek nije logiran i stoga WinLogon poziva
WlxDispaySASNotice koji treba ispisat "Stisni CTRL-ALT-DEL"! Ok, nakon sto
se to ispise WinLogon ceka da korisnik to stisne ili pak da mu msgina posalje
WlxSASNotify poruku! Winlogon brise taj nas dialog na kojem je pisalo "stisni.."
i zatim salje WlxLoggedOutSAS!! Nakon sto nam winlogon pozove tu fju mi
trebamo napravit dialog sa par edita u kojima ce korisnik upisivat username,
password i domain! za vrijeme toga winlogon je u LOGGED_OUT stanju
(postoje jos 2 stanja, jedan je LOGGED_IN a drugi LOCKED) i zatim mi pozivamo
LsaLogonUser, evo kako izgleda:
Code:
NTSTATUS LsaLogonUser(
HANDLE LsaHandle,
PLSA_STRING OriginName,
SECURITY_LOGON_TYPE LogonType,
ULONG AuthenticationPackage, //vrsta paketa!!
PVOID AuthenticationInformation, //username, password, domain u obliku odabranog paketa!!, recimo KERB_INTERACTIVE_LOGON
ULONG AuthenticationInformationLength,
PTOKEN_GROUPS LocalGroups,
PTOKEN_SOURCE SourceContext,
PVOID* ProfileBuffer,
PULONG ProfileBufferLength,
PLUID LogonId,
PHANDLE Token,
PQUOTA_LIMITS Quotas,
PNTSTATUS SubStatus
);
Ok, ako je login uspjesan, tj. ako su podaci ispravni LsaLogonUser nam
vraca access token a u suprotnom vraca gresku! E sad, mi moramo vratit
WinLogonu taj access token (obican broj) i onda on poziva WlxActiveUserShell
i mi moramo sa CreateProcess/CreateProcessAsUser kreirat korisnicki shell
(obicno explorer.exe)! E sad tu je nesto jako vazno, naime osim sto mozemo
logirat sto je korisnik uspisao za username i password mi mozemo i prevarit
da su username i pwd ispravit jer prilikom vracanja access tokena winlogonu
on NE provjerava dal je tocan!!! I to je to, ja sam se zaebo jer kad sam bio
istrazivao o tome svi su srali da je nemoguce tesko napravit, ma joj.. idiotz,
a zapravo je veoma prosto da prostije ne moze bit!
I jos nesto, ne mozete pozivat fje tipa WinExec/ShellExecute prije nego se
user-shell ne inicijalizira, tako da cete logon dialog pravit sa CreateWindow
unutar DLL-a
Za vise info o GINI mozete nac u 2-dijelnom MSDN magazin tekstu:
http://msdn.microsoft.com/msdnmag/issues/05/05/SecurityBriefs/
Kao sto pise mora bit bulletproof=>otporan na metke/neprobojan
Code:
In short, if you replace GINA, be sure to put
your best programmers on the job, and then you
should carefully review their work.
Malo pretjeravaju s tim sranjima jer je jako prosto, ja sam sada za probu
ubacio jedan svoj digitron koji sam radio bez VCL-a pa sam ga odmah iskoristio
bzvz, cisto da se vidi kako se moze radit! Ovaj tjedan cu dovrsit sad sta sam
zapoceo a to je da kad se starta komp i kad WinLogon pozove WlxInitilaze
kreirat cu prozor i morat ce se na USB nakacit smart card reader sa karticom
na kojoj se nalazi fajl kex.txt a u njemu mora bit ispravan key da bi se komp
mogao startat
Jako zanimljivo i zabavno.. sve u svemu!
Evo kod ove moje probne gine za pocetak:
Code:
library Project1;
uses
SysUtils,
Classes, Windows, WinWlx, Messages;
type HANDLE=THandle;
LONG=LongInt;
LUID = record
LowPart: DWORD;
HighPart: LONG;
end;
PLuid = ^LUID;
PWSTR = PWideChar;
WLX_MPR_NOTIFY_INFO = record
pszUserName, pszDomain, pszPassword,
pszOldPassword:PWSTR;
end;
const REALGINA_PATH = 'MSGINA.DLL';
GINASTUB_VERSION = WLX_VERSION_1_3;
var
pfWlxNegotiate: TFNWlxNegotiate;
pfWlxInitialize: TFNWlxInitialize;
pfWlxDisplaySASNotice: TFNWlxDisplaySASNotice;
pfWlxLoggedOutSAS: TFNWlxLoggedOutSAS;
pfWlxActivateUserShell: TFNWlxActivateUserShell;
pfWlxLoggedOnSAS: TFNWlxLoggedOnSAS;
pfWlxDisplayLockedNotice: TFNWlxDisplayLockedNotice;
pfWlxWkstaLockedSAS: TFNWlxWkstaLockedSAS;
pfWlxIsLockOk: TFNWlxIsLockOk;
pfWlxIsLogoffOk: TFNWlxIsLogoffOk;
pfWlxLogoff: TFNWlxLogoff;
pfWlxShutdown: TFNWlxShutdown;
pfWlxStartApplication: TFNWlxStartApplication = nil;
pfWlxScreenSaverNotify: TFNWlxScreenSaverNotify = nil;
pfWlxNetworkProviderLoad: TFNWlxNetworkProviderLoad = nil;
pfWlxDisplayStatusMessage: TFNWlxDisplayStatusMessage = nil;
pfWlxGetStatusMessage: TFNWlxGetStatusMessage = nil;
pfWlxRemoveStatusMessage: TFNWlxRemoveStatusMessage = nil;
function MyInitialize (hDll: HMODULE; dwWlxVersion: DWORD): Boolean;
begin
Result := False;
pfWlxInitialize :=
GetProcAddress(hDll, 'WlxInitialize');
pfWlxDisplaySASNotice :=
GetProcAddress(hDll, 'WlxDisplaySASNotice');
pfWlxLoggedOutSAS :=
GetProcAddress(hDll, 'WlxLoggedOutSAS');
pfWlxActivateUserShell :=
GetProcAddress(hDll, 'WlxActivateUserShell');
pfWlxLoggedOnSAS :=
GetProcAddress(hDll, 'WlxLoggedOnSAS');
pfWlxDisplayLockedNotice :=
GetProcAddress(hDll, 'WlxDisplayLockedNotice');
pfWlxIsLockOk :=
GetProcAddress(hDll, 'WlxIsLockOk');
pfWlxWkstaLockedSAS :=
GetProcAddress(hDll, 'WlxWkstaLockedSAS');
pfWlxIsLogoffOk :=
GetProcAddress(hDll, 'WlxIsLogoffOk');
pfWlxLogoff :=
GetProcAddress(hDll, 'WlxLogoff');
pfWlxShutdown :=
GetProcAddress(hDll, 'WlxShutdown');
if Assigned(pfWlxInitialize) and
Assigned(pfWlxDisplaySASNotice) and
Assigned(pfWlxLoggedOutSAS) and
Assigned(pfWlxActivateUserShell) and
Assigned(pfWlxLoggedOnSAS) and
Assigned(pfWlxDisplayLockedNotice) and
Assigned(pfWlxIsLockOk) and
Assigned(pfWlxWkstaLockedSAS) and
Assigned(pfWlxIsLogoffOk) and
Assigned(pfWlxLogoff) and
Assigned(pfWlxShutdown) then
begin
Result := True;
if (dwWlxVersion >= WLX_VERSION_1_1) then
begin
pfWlxStartApplication := GetProcAddress(hDll, 'WlxStartApplication');
pfWlxScreenSaverNotify := GetProcAddress(hDll, 'WlxScreenSaverNotify');
Result := Assigned(pfWlxStartApplication) and
Assigned(pfWlxScreenSaverNotify);
end;
if Result and (dwWlxVersion >= WLX_VERSION_1_3) then
begin
pfWlxNetworkProviderLoad :=
GetProcAddress(hDll, 'WlxNetworkProviderLoad');
pfWlxDisplayStatusMessage :=
GetProcAddress(hDll, 'WlxDisplayStatusMessage');
pfWlxGetStatusMessage :=
GetProcAddress(hDll, 'WlxGetStatusMessage');
pfWlxRemoveStatusMessage :=
GetProcAddress(hDll, 'WlxRemoveStatusMessage');
Result := Assigned(pfWlxNetworkProviderLoad) and
Assigned(pfWlxDisplayStatusMessage) and
Assigned(pfWlxGetStatusMessage) and
Assigned(pfWlxRemoveStatusMessage);
end;
end;
end;
//Definicija mojih fja
//kreirisamo prozor :D
var MojProzor:TWNDCLASSEX;
Wnd:HWND;
Msg:TMsg;
text1:string; //text prvog edit-a
text2:string; //text drugog edit-a
rez:integer;
Stxt1:HWND;
Stxt2:HWND;
Edt1:HWND;
Edt2:HWND;
Btn1:HWND; // *
Btn2:HWND; // /
Btn3:HWND; // +
Btn4:HWND; // -
AboutBtn:HWND;
function WndProc(Wnd:HWND;
Msg:UINT;
wparam:WPARAM;
lparam:LPARAM):LRESULT; stdcall;
begin
case Msg of
WM_DESTROY:begin
PostQuitMessage(0);
Result:=0;
end;
WM_COMMAND:begin
if lparam = Btn1 then
begin
SetLength(text1,100);
GetWindowText(
Edt1,
Pchar(text1),
100);
SetLength(text2,100);
GetWindowText(
Edt2,
Pchar(text2),
100);
rez:=StrToInt(text1)*StrToInt(text2);
MessageBox(0,PChar(IntToStr(rez)),'Rezultat mnozenja:',0);
end;
if lparam = Btn2 then
begin
SetLength(text1,100);
GetWindowText(
Edt1,
Pchar(text1),
100);
SetLength(text2,100);
GetWindowText(
Edt2,
Pchar(text2),
100);
rez:=StrToInt(text1) div StrToInt(text2);
MessageBox(0,PChar(IntToStr(rez)),'Rezultat dijeljenja:',0);
end;
if lparam = Btn3 then
begin
SetLength(text1,100);
GetWindowText(
Edt1,
Pchar(text1),
100);
SetLength(text2,100);
GetWindowText(
Edt2,
Pchar(text2),
100);
rez:=StrToInt(text1)+StrToInt(text2);
MessageBox(0,PChar(IntToStr(rez)),'Rezultat zbrajanja:',0);
end;
if lparam = Btn4 then
begin
SetLength(text1,100);
GetWindowText(
Edt1,
Pchar(text1),
100);
SetLength(text2,100);
GetWindowText(
Edt2,
Pchar(text2),
100);
rez:=StrToInt(text1)-StrToInt(text2);
MessageBox(0,PChar(IntToStr(rez)),'Rezultat oduzimanja:',0);
end;
if lparam=AboutBtn then MessageBox(0,'Made by Passwd witohut VCL!! :)','About..',0);
end;
else Result:=DefWindowProc(Wnd,Msg,wparam,lparam);
end;
end;
//
procedure KreirajMe;
begin
MojProzor.cbSize:=SizeOf(MojProzor);
MojProzor.style:=CS_HREDRAW or CS_VREDRAW;
MojProzor.lpfnWndProc:=@WndProc;
MojProzor.cbClsExtra:=0;
MojProzor.hInstance:=HINSTANCE;
MojProzor.hIcon:=LoadIcon(0,IDI_APPLICATION);
MojProzor.hCursor:=LoadCursor(0,IDC_ARROW);
MojProzor.hbrBackground:=COLOR_BTNFACE +1;
MojProzor.lpszMenuName:=nil;
MojProzor.lpszClassName:='Prozor';
MojProzor.hIconSm:=0;
RegisterClassEx(MojProzor);
Wnd:=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, //dwExStyle
'Prozor', //lpClassName
'Digitron', //lpWindowName
WS_OVERLAPPEDWINDOW, //window style
100, //pozicija gornjeg lijevog kuta
100, //pozicija gornjeg desnog kuta
265, //sirina sirina
200, //visina prozora
0, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Wnd,SW_SHOW);
UpdateWindow(Wnd);
Stxt1:=CreateWindowEx(0,//dwExStyle
'STATIC', //lpClassName
'Prvi broj:', //lpWindowName
WS_CHILD, //window style
10, //lijevo-desno
10, //gore-dolje
70, //sirina sirina
15, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Stxt1,SW_SHOW);
UpdateWindow(Stxt1);
Stxt2:=CreateWindowEx(0,//dwExStyle
'STATIC', //lpClassName
'Drugi broj:', //lpWindowName
WS_CHILD, //window style
10, //lijevo-desno
35, //gore-dolje
70, //sirina sirina
15, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Stxt2,SW_SHOW);
UpdateWindow(Stxt2);
Edt1:=CreateWindowEx(0,//dwExStyle
'EDIT', //lpClassName
'0', //lpWindowName
WS_CHILD, //window style
90, //lijevo-desno
10, //gore-dolje
100, //sirina sirina
20, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Edt1,SW_SHOW);
UpdateWindow(Edt1);
Edt2:=CreateWindowEx(0,//dwExStyle
'EDIT', //lpClassName
'0', //lpWindowName
WS_CHILD, //window style
90, //lijevo-desno
35, //gore-dolje
100, //sirina sirina
20, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Edt2,SW_SHOW);
UpdateWindow(Edt2);
Btn1:=CreateWindowEx(0, //dwExStyle
'BUTTON', //lpClassName
'*', //lpWindowName
WS_CHILD, //window style
10, //lijevo desno
70, //gore-dolje
50, //sirina sirina
50, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Btn1,SW_SHOW);
UpdateWindow(Btn1);
Btn2:=CreateWindowEx(0, //dwExStyle
'BUTTON', //lpClassName
'/', //lpWindowName
WS_CHILD, //window style
70, //lijevo desno
70, //gore-dolje
50, //sirina sirina
50, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Btn2,SW_SHOW);
UpdateWindow(Btn2);
Btn3:=CreateWindowEx(0, //dwExStyle
'BUTTON', //lpClassName
'+', //lpWindowName
WS_CHILD, //window style
130, //lijevo desno
70, //gore-dolje
50, //sirina sirina
50, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Btn3,SW_SHOW);
UpdateWindow(Btn3);
Btn4:=CreateWindowEx(0, //dwExStyle
'BUTTON', //lpClassName
'-', //lpWindowName
WS_CHILD, //window style
190, //lijevo desno
70, //gore-dolje
50, //sirina sirina
50, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(Btn4,SW_SHOW);
UpdateWindow(Btn4);
AboutBtn:=CreateWindowEx(0, //dwExStyle
'BUTTON', //lpClassName
'About', //lpWindowName
WS_CHILD, //window style
80, //lijevo desno
125, //gore-dolje
80, //sirina sirina
30, //visina prozora
Wnd, //prozor u koji cemo postavit nas prozor (hWndParent)
0, //meni prozora
HInstance, //stalni parametar
nil); //parametar koji se proslijedjuje prozoru
ShowWindow(AboutBtn,SW_SHOW);
UpdateWindow(AboutBtn);
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
UnregisterClass('Prozor',HInstance);
end;
function WlxNegotiate(dwWinlogonVersion: DWORD; out pdwDllVersion: DWORD): BOOL; stdcall;
var hDll: HMODULE;
dwWlxVersion: DWORD;
begin
MessageBox(0,'Pokrecem ... blabla','da',0);
KreirajMe;
Result := False;
dwWlxVersion := GINASTUB_VERSION;
{ Load MSGINA.DLL. }
hDll := LoadLibrary(REALGINA_PATH);
if hDll <> 0 then
begin
{ Get pointers to WlxNegotiate function in the real MSGINA. }
pfWlxNegotiate := GetProcAddress(hDll, 'WlxNegotiate');
if Assigned(pfWlxNegotiate) then
begin
if (dwWinlogonVersion < dwWlxVersion) then
begin
dwWlxVersion := dwWinlogonVersion;
end;
if pfWlxNegotiate(dwWlxVersion, @dwWlxVersion) then
begin
if MyInitialize(hDll, dwWlxVersion) then
begin
pdwDllVersion := dwWlxVersion;
Result := True;
end;
end;
end;
end;
end;
function WlxInitialize(lpWinsta: LPWSTR; hWlx: HANDLE; pvReserved: pointer; pWinlogonFunctions: pointer; out WlxContext: pointer): BOOL; stdcall;
begin
MessageBox(0,'Jupi;)','Pozdrav',0);
KreirajMe;
Result:=pfWlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,WlxContext);
end;
procedure WlxDisplaySASNotice(pWlxContext: pointer); stdcall;
begin
pfWlxDisplaySASNotice(pWlxContext);
end;
function WlxLoggedOutSAS(pWlxContext: Pointer; dwSasType: DWORD;
pAuthenticationId: PLargeInteger; pLogonSid: PSID; pdwOptions: PDWORD;
phToken: PHandle; pMprNotifyInfo: PWlxMprNotifyInfo; out pProfile: Pointer
): Integer; stdcall;
begin
Result:=pfWlxLoggedOutSAS(pWlxContext,dwSasType,pAuthenticationId,pLogonSid,pdwOptions,phToken,pMprNotifyInfo,pProfile);
end;
function WlxActivateUserShell(pWlxContext: pointer; pszDesktopName: PWideChar; pszMprLogonScript: PWideChar; pEnvironment: pointer): BOOL; stdcall;
begin
Result:=pfWlxActivateUserShell(pWlxContext,pszDesktopName,pszMprLogonScript,pEnvironment);
end;
function WlxLoggedOnSAS(pWlxContext: pointer; dwSasType: DWORD; pReserved: pointer): integer; stdcall;
begin
Result:=pfWlxLoggedOnSAS(pWlxContext,dwSasType,pReserved);
end;
procedure WlxDisplayLockedNotice(pWlxContext: pointer); stdcall;
begin
pfWlxDisplayLockedNotice(pWlxContext);
end;
function WlxWkstaLockedSAS(pWlxContext: pointer; dwSasType: DWORD): integer; stdcall;
begin
Result:=pfWlxWkstaLockedSAS(pWlxContext,dwSasType);
end;
function WlxIsLockOk(pWlxContext: pointer): BOOL; stdcall;
begin
Result:=pfWlxIsLockOk(pWlxContext);
end;
function WlxIsLogoffOk(pWlxContext: pointer): BOOL; stdcall;
begin
Result:=pfWlxIsLogoffOk(pWlxContext);
end;
procedure WlxLogoff(pWlxContext: pointer); stdcall;
begin
pfWlxLogoff(pWlxContext);
end;
procedure WlxShutdown(pWlxContext: pointer; ShutdownType: DWORD); stdcall;
begin
pfWlxShutdown(pWlxContext,ShutdownType);
end;
function WlxScreenSaverNotify(pWlxContext: pointer; var pSecure: BOOL): BOOL; stdcall;
begin
Result:=pfWlxScreenSaverNotify(pWlxContext,pSecure);
end;
function WlxStartApplication(pWlxContext: pointer; pszDesktopName: PWideChar; pEnvironment: pointer; pszCmdLine: PWideChar): BOOL; stdcall;
begin
Result:=pfWlxStartApplication(pWlxContext,pszDesktopName,pEnvironment,pszCmdLine);
end;
function WlxNetworkProviderLoad(pWlxContext: Pointer;
pNprNotifyInfo: PWlxMprNotifyInfo): BOOL; stdcall;
begin
Result := pfWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
end;
function WlxDisplayStatusMessage(pWlxContext: pointer; hDesktop: HDESK; dwOptions: DWORD; pTitle: PWideChar; pMessage: PWideChar): BOOL; stdcall;
begin
Result:=pfWlxDisplayStatusMessage(pWlxContext,hDesktop,dwOptions,pTitle,pMessage);
end;
function WlxGetStatusMessage(pWlxContext: pointer; var pdwOptions: DWORD; pMessage: PWideChar; dwBufferSize: DWORD): BOOL; stdcall;
begin
Result:=pfWlxGetStatusMessage(pWlxContext,pdwOptions,pMessage,dwBufferSize);
end;
function WlxRemoveStatusMessage(pWlxContext: pointer): BOOL;stdcall;
begin
Result:=pfWlxRemoveStatusMessage(pWlxContext);
end;
exports
WlxNegotiate,
WlxInitialize,
WlxDisplaySASNotice,
WlxLoggedOutSAS,
WlxActivateUserShell,
WlxLoggedOnSAS,
WlxDisplayLockedNotice,
WlxWkstaLockedSAS,
WlxIsLockOk,
WlxIsLogoffOk,
WlxLogoff,
WlxShutdown,
WlxScreenSaverNotify,
WlxStartApplication,
WlxNetworkProviderLoad,
WlxDisplayStatusMessage,
WlxGetStatusMessage,
WlxRemoveStatusMessage;
begin
end.
Jos jednom.. jako prosto i zabavno!!
poz do iduce gine (sa SC readerom)
[Ovu poruku je menjao de_c0der dana 28.01.2007. u 14:12 GMT+1]