由于看到前些日子retina里有个不需要预先知道帐号就可以获取一般任意 目标NT主机帐号的功能。几个月之前,我为了弄清原理,就做了一个工具。 这次整理硬盘,发现了这个小工具,这本身并不算什么,因为ISS scanner等 软件都包含了这类功能。但是我希望大家能够通过这个例子,了解一些NT的 API和安全性知识。
-- 完整的code(use Delphi)和一个编译好的zip文件在 ftp://202.96.215.252/incoming/sea/getuser.zip
这里贴一下程序的主要代码段: unit Unit1; { 这是一个演示如何去获取目标NT计算机上用户列表的程序, 由于Win32 API的限制,此程序只能在NT平台上正确运行。 由于是为了演示原理,所以没有使用多线程,也没有考虑太高 的健壮性,希望诸位海涵。欢迎和我联系
Vader Yang [email protected]} interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dia
logs, StdCtrls, ComCtrls, ExtCtrls; // 省略 若干行 {...}
{$R *.DFM} procedure TForm1.Button1Click(Sender: TObject);
var seaNetResource:NETRESOURCE; seaResult:DWORD; seaAccessBuffer:string[255]; seaAccessBufferLength:DWORD; sidbuffer:string[255]; lpAccessBuffer:PChar; seaSID:PSID; seaSIDlength:DWORD; seaReferencedDomainName:string[255]; seaReferencedDomainNameLength:DWORD; lpReferencedDomainName:PChar; seaSIDnameuse:SID_NAME_USE; tempPchar:Pchar; SidSubCount:PUCHAR; i,j:integer; StoreCount:byte; tempPDWORD:PDWORD; tempDWORD:DWORD; storeSIDsub: array [0..8] of Integer; seaSidIdentify:PSIDIdentifierAuthority; newSID:PSID; seaAccountBuffer:String[255]; pAccountName:LPTSTR; AccountLength:DWORD; BlResult:Boolean; const AccountType:array [0..8] of string=('','User','Group','Domain','al
ias', 'WelknowGroup','Deleted','Invalid','Unknown');
begin Button1.Enabled:=False; lpAccessBuffer:=@seaAccessBuffer; lpReferencedDomainName:=@seaReferencedDomainName; seaSID:=@sidbuffer; seaAccessBufferLength:=64; seaSIDLength:=255; seaReferencedDomainNameLength:=255; seaNetResource.dwScope:=RESOURCE_GLOBALNET; seaNetResource.dwType:=RESOURCETYPE_ANY; seaNetResource.lpLocalName:=PChar(''); seaNetResource.lpRemoteName:=PChar('\\'+EdtHostName.Text+'\IPC$');
seaNetResource.lpProvider:=PChar(''); seaResult:=WNetAddConnection2(seaNetResource,PChar(''),PChar(''),C
ONNECT_PROMPT); if seaResult=NO_ERROR then begin if LookupAccountName(PChar('\\'+EdtHostName.Text),Pchar(seedl
ine),seaSID,seaSIDlength, lpReferencedDomainName,seaReferencedDomainNamelength,seaS
IDnameuse) then begin cpDomain.Caption:=string(lpReferencedDomainName); seaSidIdentify:=GetSidIdentifierAuthority(seaSID); SidSubCount:=GetSidSubAuthorityCount(seaSID); StoreCount:=SidSubCount^;
for i:=0 to Integer(StoreCount)-1 do begin tempPDWORD:=GetSidSubAuthority(seaSID,i); storeSIDsub[i]:=tempPDWORD^; end;
//start to get username pAccountName:=@seaAccountBuffer ; seaReferencedDomainNameLength:=255; AccountLength:=255; storeSIDsub[StoreCount-1]:=500; if AllocateAndInitializeSid(seaSidIdentify^,SidSubCount^
,StoreSidSub[0], StoreSidSub[1],StoreSidSub[2],StoreSidSub[3],StoreSidSub
[4], StoreSidSub[5],StoreSidSub[6],StoreSidSub[7],newSID) the
n begin
if LookupAccountSid(PChar('\\'+EdtHostName.Text),ne
wsid, pAccountName,AccountLength,lpReferencedDomainName,
seaReferencedDomainNameLength,seaSIDnameuse) then begin lbAdmin.Caption:=String(pAccountName); ListBox1.Items.Add('\\'+lpReferencedDomainName+
'\'+pAccountName+' Built-in Admin'); end else exit; FreeSid(newSID); //tempDWORD:=GetLastError; j:=1; i:=1000; while j<=30 do begin seaReferencedDomainNamelength:=255; AccountLength:=255; StoreSidSub[StoreCount-1]:=i; AllocateAndInitializeSid(seaSidIdentify^,SidSu
bCount^,StoreSidSub[0], StoreSidSub[1],StoreSidSub[2],StoreSidSub
[3],StoreSidSub[4], StoreSidSub[5],StoreSidSub[6],StoreSidSub
[7],newSID); if LookupAccountSid(PChar('\\'+EdtHostName.Tex
t),newsid, pAccountName,AccountLength,lpReferencedDo
mainName, seaReferencedDomainNameLength,seaSIDnameu
se) then begin if seaSIDnameuse=sidTypeInvalid then j:=j+1 else if seaSIDnameuse<>sidTypeDeletedAccount t
hen begin j:=0; ListBox1.Items.Add('\\'+lpReferencedDomainN
ame+ '\'+pAccountName+' '+AccountType
[seaSIDnameuse]); StatusBar1.SimpleText:=pAccountName; end; end else j:=j+1; Application.ProcessMessages; i:=i+1; FreeSID(newsid); end; end;
end else ShowMessage('Cannot locate sid infomation!'); end else ShowMessage('Connection Error!'); WNetCancelConnection2(PChar('\\'+EdtHostName.Text+'\IPC$'),0,true)
; Button1.Enabled:=True; end;
{以后code 省略}
更多文章请访问:http://www.codesky.net 
|