SqlServer 2000和2005存储过程破解
发布时间:2020-12-12 15:43:43 所属栏目:MsSql教程 来源:网络整理
导读:亲自测试了一下,发现2k的确实可以破解. sk5的可能需要搞到master表. 原文如下 =========================================================================== SQL Server加密存储过程用到“WITH ENCRYPTION”参数的时候,就可以将它加密,这种加密方式是不
亲自测试了一下,发现2k的确实可以破解. sk5的可能需要搞到master表. 原文如下 =========================================================================== SQL Server加密存储过程用到“WITH ENCRYPTION”参数的时候,就可以将它加密,这种加密方式是不可逆的,再也不能打开了,呜呜~那么我们改怎么样才能看到原来的代码而不破坏这个存储过程呢?icech在网上找到了两个十分十分大牛的人!一个是j9988,早在2004年就写了一个可以破解加密的存储过程,支持SQL Server 2000非常的好;另一个是王成辉翻译老外写的一个,竟然可以支持SQL Server 2005版本! 如何加密SQL Server存储过程? 命令如: CREATE Procedure 存储过程名(...) WITH ENCRYPTION AS ... SQLServer2005里使用with encryption选项创建的存储过程仍然和sqlserver2000里一样,都是使用XOR进行了的加密。和2000不一样的是,在2005的系统表syscomments里已经查不到加密过的密文了。要查密文必须使用DAC(专用管理员连接)连接到数据库后,在系统表 sys.sysobjvalues查询,该表的列imageval存储了相应的密文。具体可以使用下面的查询: SELECT imageval FROM sys.sysobjvalues WHERE objid = object_id(@procedure) AND valclass = 1 AND subobjid = 1 针对SQL Server 2000的解密存储过程 create? PROCEDURE sp_decrypt(@objectname varchar(50)) AS begin set nocount on --CSDN:j9988 copyright:2004.07.15 --V3.2 --破解字节不受限制,适用于SQLSERVER2000存储过程,函数,视图,触发器 --修正上一版"视图触发器"不能正确解密错误 --发现有错,请E_MAIL:CSDNj9988@tom.com begin tran declare @objectname1 varchar(100),@orgvarbin varbinary(8000) declare @sql1 nvarchar(4000),@sql2 varchar(8000),@sql3 nvarchar(4000),@sql4 nvarchar(4000) DECLARE? @OrigSpText1 nvarchar(4000),? @OrigSpText2 nvarchar(4000),@OrigSpText3 nvarchar(4000),@resultsp nvarchar(4000) declare? @i int,@status int,@type varchar(10),@parentid int declare @colid int,@n int,@q int,@j int,@k int,@encrypted int,@number int select @type=xtype,@parentid=parent_obj from sysobjects where id=object_id(@objectname) create table? #temp(number int,colid int,ctext varbinary(8000),encrypted int,status int) insert #temp SELECT number,colid,ctext,encrypted,status FROM syscomments? WHERE id = object_id(@objectname) select @number=max(number) from #temp set @k=0 while @k<=@number begin if exists(select 1 from syscomments where id=object_id(@objectname) and number=@k) begin if @type='P' set @sql1=(case when @number>1 then 'ALTER PROCEDURE '+ @objectname +';'+rtrim(@k)+' WITH ENCRYPTION AS ' ????????????????????????? else 'ALTER PROCEDURE '+ @objectname+' WITH ENCRYPTION AS ' ????????????????????????? end) if @type='TR' begin declare @parent_obj varchar(255),@tr_parent_xtype varchar(10) select @parent_obj=parent_obj from sysobjects where id=object_id(@objectname) select @tr_parent_xtype=xtype from sysobjects where id=@parent_obj if @tr_parent_xtype='V' begin set @sql1='ALTER TRIGGER '+@objectname+' ON '+OBJECT_NAME(@parentid)+' WITH ENCRYPTION INSTERD OF INSERT AS PRINT 1 ' end else begin set @sql1='ALTER TRIGGER '+@objectname+' ON '+OBJECT_NAME(@parentid)+' WITH ENCRYPTION FOR INSERT AS PRINT 1 ' end end if @type='FN' or @type='TF' or @type='IF' set @sql1=(case @type when 'TF' then 'ALTER FUNCTION '+ @objectname+'(@a char(1)) returns @b table(a varchar(10)) with encryption as begin insert @b select @a return end ' when 'FN' then 'ALTER FUNCTION '+ @objectname+'(@a char(1)) returns char(1) with encryption as begin return @a end' when 'IF' then 'ALTER FUNCTION '+ @objectname+'(@a char(1)) returns table with encryption as return select @a as a' end) if @type='V' set @sql1='ALTER VIEW '+@objectname+' WITH ENCRYPTION AS SELECT 1 as f' set @q=len(@sql1) set @sql1=@sql1+REPLICATE('-',4000-@q) select @sql2=REPLICATE('-',8000) set @sql3='exec(@sql1' select @colid=max(colid) from #temp where number=@k set @n=1 while @n<=CEILING(1.0*(@colid-1)/2) and len(@sql3)<=3996 begin set @sql3=@sql3+'+@' set @n=@n+1 end set @sql3=@sql3+')' exec sp_executesql @sql3,N'@sql1 nvarchar(4000),@ varchar(8000)',@sql1=@sql1,@=@sql2 end set @k=@k+1 end set @k=0 while @k<=@number begin if exists(select 1 from syscomments where id=object_id(@objectname) and number=@k) begin select @colid=max(colid) from #temp where number=@k set @n=1 while @n<=@colid begin select @OrigSpText1=ctext,@encrypted=encrypted,@status=status FROM #temp? WHERE colid=@n and number=@k SET @OrigSpText3=(SELECT ctext FROM syscomments WHERE id=object_id(@objectname) and colid=@n and number=@k) if @n=1 begin if @type='P' SET @OrigSpText2=(case when @number>1 then 'CREATE PROCEDURE '+ @objectname +';'+rtrim(@k)+' WITH ENCRYPTION AS ' ?????????????????????? else 'CREATE PROCEDURE '+ @objectname +' WITH ENCRYPTION AS ' ?????????????????????? end) if @type='FN' or @type='TF' or @type='IF' SET @OrigSpText2=(case @type when 'TF' then 'CREATE FUNCTION '+ @objectname+'(@a char(1)) returns @b table(a varchar(10)) with encryption as begin insert @b select @a return end ' when 'FN' then 'CREATE FUNCTION '+ @objectname+'(@a char(1)) returns char(1) with encryption as begin return @a end' when 'IF' then 'CREATE FUNCTION '+ @objectname+'(@a char(1)) returns table with encryption as return select @a as a' end) if @type='TR' begin if @tr_parent_xtype='V' begin set @OrigSpText2='CREATE TRIGGER '+@objectname+' ON '+OBJECT_NAME(@parentid)+' WITH ENCRYPTION INSTEAD OF INSERT AS PRINT 1 ' end else begin set @OrigSpText2='CREATE TRIGGER '+@objectname+' ON '+OBJECT_NAME(@parentid)+' WITH ENCRYPTION FOR INSERT AS PRINT 1 ' end end if @type='V' set @OrigSpText2='CREATE VIEW '+@objectname+' WITH ENCRYPTION AS SELECT 1 as f' set @q=4000-len(@OrigSpText2) set @OrigSpText2=@OrigSpText2+REPLICATE('-',@q) end else begin SET @OrigSpText2=REPLICATE('-',4000) end SET @i=1 SET @resultsp = replicate(N'A',(datalength(@OrigSpText1) / 2)) WHILE @i<=datalength(@OrigSpText1)/2 BEGIN SET @resultsp = stuff(@resultsp,@i,1,NCHAR(UNICODE(substring(@OrigSpText1,1)) ^ ??????????????????????????????? (UNICODE(substring(@OrigSpText2,1)) ^ ??????????????????????????????? UNICODE(substring(@OrigSpText3,1))))) ?SET @i=@i+1 END set @orgvarbin=cast(@OrigSpText1 as varbinary(8000)) set @resultsp=(case when @encrypted=1 ??????????????????? then @resultsp ??????????????????? else convert(nvarchar(4000),case when @status&2=2 then uncompress(@orgvarbin) else @orgvarbin end) ?????????????? end) print @resultsp set @n=@n+1 end end set @k=@k+1 end drop table #temp rollback tran end 针对SQL Server 2005的解密存储过程 create PROCEDURE [dbo].[sp__windbi$decrypt] (@procedure sysname = NULL,@revfl int = 1) AS /* 王成辉翻译整理,转贴请注明出自微软BI开拓者www.windbi.com 目前这个存储过程只能解密存储过程,至于解密函数、触发器、视图的存储过程本网站会进一步关注,调用形式为: exec dbo.sp__windbi$decrypt @procedure,0 如果第二个参数使用1的话,会给出该存储过程的一些提示。 --版本2.0 */ SET NOCOUNT ON IF @revfl = 1 BEGIN PRINT '警告:该存储过程会删除并重建原始的存储过程。' PRINT ' 在运行该存储过程之前确保你的数据库有一个备份。' PRINT ' 该存储过程通常应该运行在产品环境的一个备份的非产品环境下。' PRINT ' 为了运行这个存储过程,将参数@refl的值更改为0。' RETURN 0 END DECLARE @intProcSpace bigint,@t bigint,@maxColID smallint,@intEncrypted tinyint,@procNameLength int select @maxColID = max(subobjid),@intEncrypted = imageval FROM sys.sysobjvalues WHERE objid = object_id(@procedure) GROUP BY imageval --select @maxColID as 'Rows in sys.sysobjvalues' select @procNameLength = datalength(@procedure) + 29 DECLARE @real_01 nvarchar(max) DECLARE @fake_01 nvarchar(max) DECLARE @fake_encrypt_01 nvarchar(max) DECLARE @real_decrypt_01 nvarchar(max),@real_decrypt_01a nvarchar(max) declare @objtype varchar(2),@ParentName nvarchar(max) select @real_decrypt_01a = '' --提取对象的类型如是存储过程还是函数,如果是触发器,还要得到其父对象的名称 select @objtype=type,@parentname=object_name(parent_object_id) from sys.objects where [object_id]=object_id(@procedure) -- 从sys.sysobjvalues里提出加密的imageval记录 SET @real_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid = object_id(@procedure) and valclass = 1 order by subobjid) --创建一个临时表 create table #output ( [ident] [int] IDENTITY (1,1) NOT NULL,[real_decrypt] NVARCHAR(MAX) ) --开始一个事务,稍后回滚 BEGIN TRAN --更改原始的存储过程,用短横线替换 if @objtype='P' ? SET @fake_01='ALTER PROCEDURE '+ @procedure +' WITH ENCRYPTION AS ? '+REPLICATE('-',40003 - @procNameLength) else if @objtype='FN' ? SET @fake_01='ALTER FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1 ? /*'+REPLICATE('*',datalength(@real_01) /2 - @procNameLength)+'*/ END' else if @objtype='V' ? SET @fake_01='ALTER view '+ @procedure +' WITH ENCRYPTION AS select 1 as col ? /*'+REPLICATE('*',datalength(@real_01) /2 - @procNameLength)+'*/' else if @objtype='TR' ? SET @fake_01='ALTER trigger '+ @procedure +' ON '+@parentname+' WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10) ? /*'+REPLICATE('*',datalength(@real_01) /2 - @procNameLength)+'*/' EXECUTE (@fake_01) --从sys.sysobjvalues里提出加密的假的 SET @fake_encrypt_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid = object_id(@procedure) and valclass = 1 order by subobjid ) if @objtype='P' ? SET @fake_01='Create PROCEDURE '+ @procedure +' WITH ENCRYPTION AS ? '+REPLICATE('-',40003 - @procNameLength) else if @objtype='FN' ? SET @fake_01='CREATE FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1 ? /*'+REPLICATE('*',datalength(@real_01) /2 - @procNameLength)+'*/ END' else if @objtype='V' ? SET @fake_01='Create view '+ @procedure +' WITH ENCRYPTION AS select 1 as col ? /*'+REPLICATE('*',datalength(@real_01) /2 - @procNameLength)+'*/' else if @objtype='TR' ? SET @fake_01='Create trigger '+ @procedure +' ON '+@parentname+' WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',datalength(@real_01) /2 - @procNameLength)+'*/' --开始计数 SET @intProcSpace=1 --使用字符填充临时变量 SET @real_decrypt_01 = replicate(N'A',(datalength(@real_01) /2 )) --循环设置每一个变量,创建真正的变量 --每次一个字节 SET @intProcSpace=1 --如有必要,遍历每个@real_xx变量并解密 WHILE @intProcSpace<=(datalength(@real_01)/2) BEGIN --真的和假的和加密的假的进行异或处理 SET @real_decrypt_01 = stuff(@real_decrypt_01,@intProcSpace,NCHAR(UNICODE(substring(@real_01,1)) ^ (UNICODE(substring(@fake_01,1)) ^ UNICODE(substring(@fake_encrypt_01,1))))) SET @intProcSpace=@intProcSpace+1 END --通过sp_helptext逻辑向表#output里插入变量 insert #output (real_decrypt) select @real_decrypt_01 -- select real_decrypt AS '#output chek' from #output --测试 -- ------------------------------------- --开始从sp_helptext提取 -- ------------------------------------- declare @dbname sysname,@BlankSpaceAdded int,@BasePos int,@CurrentPos int,@TextLength int,@LineId int,@AddOnLen int,@LFCR int --回车换行的长度,@DefinedLength int,@SyscomText nvarchar(4000),@Line nvarchar(255) Select @DefinedLength = 255 SELECT @BlankSpaceAdded = 0 --跟踪行结束的空格。注意Len函数忽略了多余的空格 CREATE TABLE #CommentText (LineId int,Text nvarchar(255) collate database_default) --使用#output代替sys.sysobjvalues DECLARE ms_crs_syscom CURSOR LOCAL FOR SELECT real_decrypt from #output ORDER BY ident FOR READ ONLY --获取文本 SELECT @LFCR = 2 SELECT @LineId = 1 OPEN ms_crs_syscom FETCH NEXT FROM ms_crs_syscom into @SyscomText WHILE @@fetch_status >= 0 BEGIN SELECT @BasePos = 1 SELECT @CurrentPos = 1 SELECT @TextLength = LEN(@SyscomText) WHILE @CurrentPos != 0 BEGIN --通过回车查找行的结束 SELECT @CurrentPos = CHARINDEX(char(13)+char(10),@SyscomText,@BasePos) --如果找到回车 IF @CurrentPos != 0 BEGIN --如果@Lines的长度的新值比设置的大就插入@Lines目前的内容并继续 While (isnull(LEN(@Line),0) + @BlankSpaceAdded + @CurrentPos-@BasePos + @LFCR) > @DefinedLength BEGIN SELECT @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) + @BlankSpaceAdded) INSERT #CommentText VALUES ( @LineId,isnull(@Line,N'') + isnull(SUBSTRING(@SyscomText,@BasePos,@AddOnLen),N'')) SELECT @Line = NULL,@LineId = @LineId + 1,@BasePos = @BasePos + @AddOnLen,@BlankSpaceAdded = 0 END SELECT @Line = isnull(@Line,@CurrentPos-@BasePos + @LFCR),N'') SELECT @BasePos = @CurrentPos+2 INSERT #CommentText VALUES( @LineId,@Line ) SELECT @LineId = @LineId + 1 SELECT @Line = NULL END ELSE --如果回车没找到 BEGIN IF @BasePos <= @TextLength BEGIN --如果@Lines长度的新值大于定义的长度 While (isnull(LEN(@Line),0) + @BlankSpaceAdded + @TextLength-@BasePos+1 ) > @DefinedLength BEGIN SELECT @AddOnLen = @DefinedLength - (isnull(LEN(@Line),@TextLength-@BasePos+1 ),N'') if LEN(@Line) < @DefinedLength and charindex(' ',@TextLength+1 ) > 0 BEGIN SELECT @Line = @Line + ' ',@BlankSpaceAdded = 1 END END END END FETCH NEXT FROM ms_crs_syscom into @SyscomText END IF @Line is NOT NULL INSERT #CommentText VALUES( @LineId,@Line ) select Text from #CommentText order by LineId CLOSE ms_crs_syscom DEALLOCATE ms_crs_syscom DROP TABLE #CommentText -- ------------------------------------- --结束从sp_helptext提取 -- ------------------------------------- --删除用短横线创建的存储过程并重建原始的存储过程 ROLLBACK TRAN DROP TABLE #output 英文原文: http://www.derkeiler.com/Newsgroups/microsoft.public.sqlserver.security/2006-08/msg00286.html SQL 2005 still obfuscates object encryption in a similar manner to SQL 2000. It is simply an XOR of the encrypted bytes against a known sample to dump out the real unencrypted bytes. The trick is getting to the the encrypted bytes. In SQL 2005,instead of querying the SYSCOMMENTS view to get the binary bytes to decrypt,you need to run the following query from the dedicated admin connection (DAC) to get the bytes to decrypt: SELECT imageval FROM sys.sysobjvalues WHERE id = object_id(@procedure) AND valclass = 1 AND subobjid = 1 where @procedure is the name of the object that you want to decrypt. The table sys.sysobjvalues is one of those new system tables that is normally hidden. It is actually easier in SQL 2005 because you don't have to string together 4000 character blocks from SYSCOMMENTS records like you had to do in SQL 2000. Code to do the XOR on SQL 2000 is well documented on the web. I'm including my work below. This is code that I quickly rolled together from my old SQL 2000 decrypt code. It isn't perfect yet but should get you down the line. It only does procedures. It actually wraps the ALTER PROCEDURE in a rolled-back transaction so it shouldn't be too problematic. Then again my local copy of SQL Server 2005 only starts with the -f flag this morning ;-). Have fun. Chuck CREATE PROCEDURE dbo.sp__procedure$decrypt (@procedure sysname = NULL,@revfl int = 1) AS SET NOCOUNT ON IF @revfl = 1 BEGIN PRINT 'CAUTION: THIS PROCEDURE DELETES AND REBUILDS THE ORIGINAL STORED PROCEDURE.' PRINT ' MAKE A BACKUP OF YOUR DATABASE BEFORE RUNNING THIS PROCEDURE.' PRINT ' IDEALLY,THIS PROCEDURE SHOULD BE RUN ON A NON-PRODUCTION COPY OF THE PROCEDURE.' PRINT ' To run the procedure,change the @revfl parameter to 0' RETURN 0 END DECLARE @intProcSpace bigint,@procNameLength int select @maxColID = max(colid),@intEncrypted = encrypted FROM sys.sysobjvalues WHERE id = object_id(@procedure) GROUP BY encrypted --select @maxColID as 'Rows in sys.sysobjvalues' select @procNameLength = datalength(@procedure) + 29 DECLARE @real_01 nvarchar(max) DECLARE @fake_01 nvarchar(max) DECLARE @fake_encrypt_01 nvarchar(max) DECLARE @real_decrypt_01 nvarchar(max),@real_decrypt_01a nvarchar(max) select @real_decrypt_01a = '' -- extract the encrypted imageval rows from sys.sysobjvalues SET @real_01=(SELECT imageval FROM sys.sysobjvalues WHERE id = object_id(@procedure) and valclass = 1 and subobjid = 1 ) -- create this table for later use create table #output ( [ident] [int] IDENTITY (1,[real_decrypt] NVARCHAR(MAX) ) -- We'll begin the transaction and roll it back later BEGIN TRAN -- alter the original procedure,replacing with dashes SET @fake_01='ALTER PROCEDURE '+ @procedure +' WITH ENCRYPTION AS '+REPLICATE('-',40003 - @procNameLength) EXECUTE (@fake_01) -- extract the encrypted fake imageval rows from sys.sysobjvalues SET @fake_encrypt_01=(SELECT imageval FROM sys.sysobjvalues WHERE id = object_id(@procedure) and valclass = 1 and subobjid = 1) SET @fake_01='CREATE PROCEDURE '+ @procedure +' WITH ENCRYPTION AS '+REPLICATE('-',40003 - @procNameLength) --start counter SET @intProcSpace=1 --fill temporary variable with with a filler character SET @real_decrypt_01 = replicate(N'A',(datalength(@real_01) /2 )) --loop through each of the variables sets of variables,building the real variable --one byte at a time. SET @intProcSpace=1 -- Go through each @real_xx variable and decrypt it,as necessary WHILE @intProcSpace<=(datalength(@real_01)/2) BEGIN --xor real & fake & fake encrypted SET @real_decrypt_01 = stuff(@real_decrypt_01,1))))) SET @intProcSpace=@intProcSpace+1 END -- Load the variables into #output for handling by sp_helptext logic insert #output (real_decrypt) select @real_decrypt_01 -- select real_decrypt AS '#output chek' from #output -- Testing -- ------------------------------------- -- Beginning of extract from sp_helptext -- ------------------------------------- declare @dbname sysname,@LFCR int --lengths of line feed carriage return,@Line nvarchar(255) Select @DefinedLength = 255 SELECT @BlankSpaceAdded = 0 --Keeps track of blank spaces at end of lines. Note Len function ignores trailing blank spaces CREATE TABLE #CommentText (LineId int,Text nvarchar(255) collate database_default) -- use #output instead of sys.sysobjvalues DECLARE ms_crs_syscom CURSOR LOCAL FOR SELECT real_decrypt from #output ORDER BY ident FOR READ ONLY -- Else get the text. SELECT @LFCR = 2 SELECT @LineId = 1 OPEN ms_crs_syscom FETCH NEXT FROM ms_crs_syscom into @SyscomText WHILE @@fetch_status >= 0 BEGIN SELECT @BasePos = 1 SELECT @CurrentPos = 1 SELECT @TextLength = LEN(@SyscomText) WHILE @CurrentPos != 0 BEGIN --Looking for end of line followed by carriage return SELECT @CurrentPos = CHARINDEX(char(13)+char(10),@BasePos) --If carriage return found IF @CurrentPos != 0 BEGIN --If new value for @Lines length will be > then the --set length then insert current contents of @line --and proceed. While (isnull(LEN(@Line),@Line ) SELECT @LineId = @LineId + 1 SELECT @Line = NULL END ELSE --else carriage return not found BEGIN IF @BasePos <= @TextLength BEGIN --If new value for @Lines length will be > then the --defined length -- While (isnull(LEN(@Line),@BlankSpaceAdded = 1 END END END END FETCH NEXT FROM ms_crs_syscom into @SyscomText END IF @Line is NOT NULL INSERT #CommentText VALUES( @LineId,@Line ) select Text from #CommentText order by LineId CLOSE ms_crs_syscom DEALLOCATE ms_crs_syscom DROP TABLE #CommentText -- ------------------------------------- -- End of extract from sp_helptext -- ------------------------------------- -- Drop the procedure that was setup with dashes and rebuild it with the good stuff -- Version 1.1 mod; makes rebuilding hte proc unnecessary ROLLBACK TRAN DROP TABLE #output GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- sql – 多次调用select语句中的标量函数多次运行该函数,以及
- sql – 在Access中连接记录和GROUP BY
- sql-server – 将SQL Server Express数据库复制到另一台计算
- SQLServer数据库自动备份说明书
- 分发服务器 系统抛出18483错误,未能连接服务器,因为'
- sql – 为什么在INSERT语句的列列表中忽略以点分隔的前缀?
- 在Symfony2中保存与数据库的多对多关系
- 连sqlserver出错Error 20017,Error 20002
- sql – 附加没有LDF文件的MDF文件
- SQL Server Bulk Insert 只需要部分字段时的方法