友好连接

2008年11月24日星期一

黑客经验谈 MSSQL SA权限入侵的感悟

想必大家都知道MSSQL中SA权限是什么,可以说是至高无上。今天我就它的危害再谈点儿,我所讲的是配合NBSI上传功能得到WebShell。在讲之前先说几个条件,否则得到Shell是有难度的。
  1.存在SQL注入,并且数据库类型是MSSQL。




  2.连接数据库的权限必须是SA。


  3.后台必须有文件上传的程序。



  好了,我们找到一个网址hxxp://www.6x36x.com/fangchan/listpro.asp?id=53,用NBSI一会就一目了然了。

  很好,数据库类型是MSSQL,权限是SA,再看看第三个条件满足不满足。找到页面中的文章(新闻),看看里面的图片的地址是什么。好!一看就明白了hxxp://www.6x36x.com/admin/uploadpic/2xx5042823082994329.gif,你明白了吗?特别是2xx5042823082994329.gif 这下我们敢肯定后台有上传文件的功能了。下面做什么呢?晕,找出该网站所在的路径呀。这个嘛就得全靠NBSI的NB Commander(NB Tree_List)功能了(在这里我推荐大家用NB Commander,为什么呢?看完文章就知道了),不过找出网站所在的真实路径需要花一定的时间,那就看你有没有耐心了。我敢说只要有耐心,肯定能找出网站所在的真实路径。这里我找到了这个站点所在的路径D:\9x3x9,接着就是后台了,很快就得到Admin/login.asp,接下来就是账号和密码的猜解了。不过我这次猜解出现了问题。说什么也弄不出他的账号和密码,难道都是空的?我不相信,就试着登录了一下,结果失败了。于是从这开始,NB Commander功能就显得非常重要了(因为大家都知道,列目录NB Command和NB Tree_List都能实现),我找到文件conn.asp,用type D:\9x3x9\admin\logining.asp命令看了看源代码。


  够狠吧!读了读代码没有问题呀!就是用的admin表字段也一样,不多说了,谁能知道其中的原因?请告诉俺一下,也让俺这只菜鸟走出困惑。进不了后台怎么上传图片呢?这里我用NBSI的上传功能,我试过了,没有成功。因为我传上去后,看到代码每行都重复三次,也不知是为什么,就是用臭要饭的Getwebshell也是同样的结果。

  我想有了,看看它的Session是怎么验证的,又是一个type D:\9x3x9\admin\quanxian.asp。通过分析很快就明白了,它给Session(“wsl”)赋了一个值为1,哈哈!我写了一个非常简单的程序。用NBSI的上传功能传了上去,我想不管重复几次都是正确的(这里你又会想到什么呢?如果密码是MD5的,我们没有必要去爆破了,弄个session就ok了),传上去保存为1.asp,然后我访问hxxp://www.6x36x.com/admin/1.asp,接着访问hxxp://www.6x36x.com/admin/admin_index.asp,就这样进入了后台,本地测试。


  小提示:Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量! 当一个用户访问某页面时,每个Session变量的运行环境便自动生成,这些Session变量可在用户离开该页面后仍保留20分钟!(事实上,这些变量一直可保留至“timeout”。“timeout”的时间长短由Web服务器管理员设定。一些站点上的变量仅维持了3分钟,一些则为10分钟,还有一些则保留至默认值20分钟。)所以,如果在Session中置入了较大的对象(如ADO recordsets,connections, 等等),那就有麻烦了!随着站点访问量的增大,服务器将会因此而无法正常运行!

  因为创建Session变量有很大的随意性,可随时调用,不需要开发者做精确地处理。所以,过度使用session变量将会导致代码不可读而且不好维护。

  这样我找到上传图片的地方,把asp木马改成.gif传了上去,记住了上传后的名字,这里是uploadpic\2xx56171430123.gif,那么你会想到什么呢?哈哈我想起来了,把图片copy成.asp的,或者重命名成.asp的。

  好了,到这里我们的马就算是上去了,至于以后的事情就不提了。


  总结:SA的确给我们带来了很大危害,所以程序员在连接MSSQL数据库的时候千万不能用它,否则服务器成为肉鸡的可能性非常非常的大。还有,MSSQL 的扩展存储功能,用不到它就删除,留着就成了黑客的利器。
转自:http://www.cnblogs.com/junzhongxu/

数据备份中可能出错的情况及解决办法

本文总结了数据库备份过程中所有可能出错的情况,大家可以参考以下。



  如果你做DBA时间不长,对数据库的备份有些担心,希望能找到一种让你放心的备份方案,那么本文绝对适合你。

  关于数据库的备份恢复原理,大家多少都比较熟悉了。但是,你目前做的数据库备份有多可靠?你可以安心睡觉了吗?如果答案是肯定的,那就不用多花时间看下文了,如果觉得还不够安心,总担心数据库哪一天坏了修不好,那么请接着看:



  1、我有RAID,还需要做数据库备份吗?需要。有了RAID,万一部份磁盘损坏, 可以修复数据库,有的情况下数据库甚至可以继续使用。但是,如果哪一天,你的同事不小心删除了一条重要的记录,怎么办?RAID是无能为力的。你需要合适 的备份策略,把那条被误删的数据恢复出来。所以有了RAID,仍需要做备份集群,磁盘镜像同理。

  2、如果你只做全备份,那么受限于全备份的大小和备份时间,不可能常做。而且只有 全备份,不能将数据库恢复至某个时间点。所以,我们需要全备份+日志备份。比如每天一个全备份,每隔1小时或若干分钟一个日志备份。说到差异备份,因为微 软的差异备份记录的是上一次全备份以来发生的变化,所以,如果数据库的改动很频繁的话,没过多久,差异备份就会和全备份的大小接近,因此这种情况下就不合 适了。因此,全备份+日志备份的方案适合绝大多数的用户。



  3、如果你仅在数据库本地做备份,万一磁盘损坏,或者整个服务器硬件损坏,备份也 就没了,就没法恢复数据库。因此,你需要把备份文件传送至另一个物理硬件上。大多数用户不用磁带机,因此不考虑。一般,我们需要另一台廉价的服务器或者 PC来存放数据库的备份,来防止硬件损坏造成的备份丢失。

  4、你可以在数据库服务器本地做完备份,然后使用某些方式将备份文件传送至备机。你是在备份完成后就马上穿送的吗?其实可以考虑将传送备份的脚本用T-SQL语句来写。

  5、备份文件传送至备机后,就可以高枕无忧了吗?不。作为DBA的你还需要检查备机上的备份文件是否能将数据库恢复至最新,如果采用日志备份,会不会因为丢失某一个日志备份文件而导致数据库不能恢复至最新?如何检查日志备份文件之间存在断档?



  6、为了将数据库尽可能的恢复到最新,你可能会每隔10分钟(甚至1分钟)执行一次日志备份,那么万一数据库坏了,在恢复的时候,手动恢复成百上千个日志文件,是不是不太现实?

  7、如果你所在公司有很多的数据库服务器(就像我所在的公司),而且磁盘空间有限,那么你不得不经常登录服务器来删除旧的备份文件,如果哪天忘了,或者五一十一长假,磁盘空间用完了,就麻烦了。


  8、数据库在备份的时候,并不会检查数据页面的完整性,如果数据页坏了,备份作业仍 会执行,而且不会报错,等到你发现数据页有错误的时候,你也很可能已经因为磁盘空间不足,而删除了早期的备份,而此时剩下的那些备份可能都是包含损坏的数 据页,如果损坏的数据页是某个表的表头的话,那这个表你就再也没办法恢复了。


  9、所以你需要定期执行DBCC检查,来尽早发现数据库页面的完整性。在未作完DBCC检查之前,你不能删除旧的备份,以防止新的备份存在问题。所以,删除备份文件的工作变的有些麻烦。



  10、你可能知道SQL Server提供了数据库维护计划。没错,使用它可以定期做备份,执行DBCC检查,但这一切仅限于本机操作。为了使数据库可靠,你还是需要自己把本地备份传送至备机。

  综上,你的备份做好了吗?检查了吗?删除旧的备份是不是花去你很多时间,特别是在网络条件不好的时候?如果数据库备份文件的传送在某一时刻停止了,你多久才能发现?公司值晚班的同事有权限检查数据库的备份情况吗?
转自:http://www.cnblogs.com/junzhongxu/

SQL Server各种日期计算方法之二

上个月的最后一天
  
  这是一个计算上个月最后一天的例子。它通过从一个月的最后一天这个例子上减去3毫秒来获得。有一点要记住,在Sql Server中时间是精确到3毫秒。这就是为什么我需要减去3毫秒来获得我要的日期和时间。
  
  SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0))
  
  计算出来的日期的时间部分包含了一个Sql Server可以记录的一天的最后时刻(“23:59:59:997”)的时间。
  
  去年的最后一天
  
  连接上面的例子,为了要得到去年的最后一天,你需要在今年的第一天上减去3毫秒。
  
  SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))
  
  本月的最后一天
  
  现在,为了获得本月的最后一天,我需要稍微修改一下获得上个月的最后一天的语句。修改需要给用DATEDIFF比较当前日期和“1900-01-01”返回的时间间隔上加1。通过加1个月,我计算出下个月的第一天,然后减去3毫秒,这样就计算出了这个月的最后一天。这是计算本月最后一天的SQL脚本。
  
  SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))
  
  本年的最后一天
  
  你现在应该掌握这个的做法,这是计算本年最后一天脚本
  
  SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))。
  
  本月的第一个星期一
  
  好了,现在是最后一个例子。这里我要计算这个月的第一个星期一。这是计算的脚本。
  
 select DATEADD(wk, DATEDIFF(wk,0,
  dateadd(dd,6-datepart(day,getdate()),getdate())
  ), 0)
  
  在这个例子里,我使用了“本周的星期一”的脚本,并作了一点点修改。修改的部分是把原来脚本中“getdate()”部分替换成计算本月的第6天,在计算中用本月的第6天来替换当前日期使得计算可以获得这个月的第一个星期一。
  
  总结
  
  我希望这些例子可以在你用DATEADD和DATEDIFF函数计算日期时给你一点启发。通过使用这个计算日期的时间间隔的数学方法,我发现为了显示两个日期之间间隔的有用历法是有价值的。注意,这只是计算出这些日期的一种方法。要牢记,还有很多方法可以得到相同的计算结果。假如你有其他的方法,那很不错,要是你没有,我希望这些例子可以给你一些启发,当你要用DATEADD和DATEDIFF函数计算你程序可能要用到的日期时。

  附录:其他日期处理方法
  
  1)去掉时分秒



  declare @ datetime
  set @ = getdate() --’2003-7-1 10:00:00’
  SELECT @,DATEADD(day, DATEDIFF(day,0,@), 0)
 
  2)显示星期几


select datename(weekday,getdate())

  3)如何取得某个月的天数

  declare @m int
  set @m=2 --月份
  select datediff(day,’2003-’+cast(@m as varchar)+’-15’ ,’2003-’+cast(@m+1 as varchar)+’-15’)
  另外,取得本月天数
  select datediff(day,cast(month(GetDate()) as varchar)+’-’+cast(month(GetDate()) as varchar)+’-15’ ,cast(month(GetDate()) as varchar)+’-’+cast(month(GetDate())+1 as varchar)+’-15’)
  或者使用计算本月的最后一天的脚本,然后用DAY函数区最后一天
  SELECT Day(dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0)))

  4)判断是否闰年:



  SELECT case day(dateadd(mm, 2, dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)))) when 28 then ’平年’ else ’闰年’ end
  或者
  select case datediff(day,datename(year,getdate())+’-02-01’,dateadd(mm,1,datename(year,getdate())+’-02-01’))
  when 28 then ’平年’ else ’闰年’ end
  
  5)一个季度多少天
 

  declare @m tinyint,@time smalldatetime
  select @m=month(getdate())
  select @m=case when @m between 1 and 3 then 1
  when @m between 4 and 6 then 4
  when @m between 7 and 9 then 7
  else 10 end
  select @time=datename(year,getdate())+’-’+convert(varchar(10),@m)+’-01’
  select datediff(day,@time,dateadd(mm,3,@time))
转自:http://www.cnblogs.com/junzhongxu/

防范SQL注入攻击的新办法

近段时间由于修改一个ASP程序(有SQL注入漏洞),在网上找了很多相关的一些防范办法,都不近人意,所以我将现在网上的一些方法综合改良了一下,写出这个ASP函数,供大家参考。



  以下是引用片段:


Function SafeRequest(ParaName)
Dim ParaValue
ParaValue=Request(ParaName)
if IsNumeric(ParaValue) = True then
SafeRequest=ParaValue
exit Function
elseIf Instr(LCase(ParaValue),"select ") > 0 or Instr(LCase(ParaValue),"insert ") > 0 or Instr(LCase(ParaValue),"delete from") > 0 or Instr(LCase(ParaValue),"count(") > 0 or Instr(LCase(ParaValue),"drop table") > 0 or Instr(LCase(ParaValue),"update ") > 0 or Instr(LCase(ParaValue),"truncate ") > 0 or Instr(LCase(ParaValue),"asc(") > 0 or Instr(LCase(ParaValue),"mid(") > 0 or Instr(LCase(ParaValue),"char(") > 0 or Instr(LCase(ParaValue),"xp_cmdshell") > 0 or Instr(LCase(ParaValue),"exec master") > 0 or Instr(LCase(ParaValue),"net localgroup administrators") > 0 or Instr(LCase(ParaValue)," and ") > 0 or Instr(LCase(ParaValue),"net user") > 0 or Instr(LCase(ParaValue)," or ") > 0 then
Response.Write "< script language='javascript' >"
Response.Write "alert('非法的请求!');" '发现SQL注入攻击提示信息



Response.Write "location.href='http://blog.knowsky.com/';" '发现SQL注入攻击转跳网址
Response.Write "< script >"
Response.end
else
SafeRequest=ParaValue
End If
End function

  使用SafeRequest函数替换你的Request
转自:http://www.cnblogs.com/junzhongxu/

SQL Server 用户自定义的数据库修复 new

本文讲解了用户如何自定义的数据库修复。

一、自动应用重做日志




1、 利用SET AUTORECOVERY命令自动应用重做日志,完成对数据文件的修复操作。

SQL>STARTUP MOUNT:启动实例并加载数据库。

SQL>SET AUTORECOVERY ON:启用重做日志自动应用功能。



SQL>RECOVER DATABASE:恢复指定表空间、数据文件或整个数据库。



SQL>ALTER DATABASE OPEN:完成恢复后打开数据库。



2、 利用RECOVERY AUTOMATIC命令自动应用重做日志,完成对数据文件的修复操作。

SQL>STARTUP MOUNT:启动实例并加载数据库。

SQL>RECOVER AUTOMATIC DATABASE。

SQL>ALTER DATABASE OPEN:完成恢复后打开数据库。



二、 不归档模式下的数据库介质恢复

1、 将数据库恢复到原来的位置上。



SQL>SHUTDOWN IMMEDIATE 如果数据库仍然处于打开状态,关闭数据库;将数据库文件恢复到原来的位置上,利用最近一次建立的一致性完全备份对整个数据库进行恢复,必须对所有的数据文件与控制文件进行修复。


SQL>RECOVER DATABASE UNTIL CANCEL
SQL>CANCEL
SQL>ALTER DATABASE OPEN RESETLOGS;
将当前重做日志顺序号设置为1。



2、 将数据库恢复到新的位置上。

SQL>SHUTDOWN IMMEDIATE:如果数据库仍然处于打开状态,关闭数据库;将数据库文件恢复到新的位置上,利用最近一次建立的一致性完全备份对整个数据库进行恢复,必须对所有的数据文件与控制文件进行修复;对初始化参数文件中的CONTROL_FILES参数进行编辑,使它执行保存在新位置中修复后的控制文件。


SQL>STARTUP MOUNT:如果修复后的数据库文件处于新的位置,必须利用ALTER DATABASE RENAME FILE语句对控制文件进行修改,使它指向新位置中修复后的数据文件。如:

SQL>ALTER DATABASE RENAME FILE
‘I: ora9ioradatasystem01.dbf’ TO ‘K: oracleoradatasystem01.dbf’;
SQL>RECOVER DATABASE UNTIL CANCEL
SQL>CANCEL
SQL>ALTER DATABASE OPEN RESETLOGS;
将当前重做日志顺序号设置为1。


三、 归档模式下的完全介质恢复

1、 关闭状态下的完全恢复。



SQL>SHUTDOWN ABORT(如果数据库处于打开状态,将它强行关闭):将数据文件恢复到原来的位置上,如果介质故障无法排除,需要将数据文件恢复到其它位置上;利用备份修复丢失或损坏的数据文件,也可利用ALTER DATABASE CREATE DATAFILE 语句重建一个空白的数据文件替换对视或损坏的数据文件。


SQL>STARTUP MOUNT:如果修复后的数据文件不在原来的位置上,需要使用ALTER DATABASE RENAME FILE …TO …语句在控制文件中更新它们的信息。

SQL>SELECT name,status FROM V$DATAFILE;
查询数据文件的名称和状态。
SQL>ALTER DATABASE DATAFILE … ONLINE;
将脱机数据文件改未联机。
SQL>RECOVER DATABASE
或 SQL>RECOVER TABLESPACE users
或 SQL>RECOVER DATAFILE ‘I: ora9ioradatausers0.dbf;
SQL>ALTER DATABASE OPEN;


2、 打开状态下的完全介质恢复。



SQL>SELECT d.file# f#,d.name,d.status,
h.status from v$datafile d,v$datafile_header h
WHERE d.file#=h.file#;
查询哪些数据文件被自动设置为脱机状态;
SQL>ALTER TABLESPACE users OFFLINE TEMPORARY;

将包含损坏数据文件的表空间设置为脱机状态;将数据文件恢复到原来的位置上,如果介质故障无法排除,需要将数据文件恢复到其它位置上;利用备份修复丢失或损坏的数据文件;如果修复后的数据文件不在原来的位置上,需要使用ALTER DATABASE RENAME FILE …TO …语句在控制文件中更新它们的信息。

SQL>RECOVER TABLESPACE users AUTOMATIC
对包含损坏数据文件的脱机表空间进行恢复;
SQL>ALTER TABLESPACE users ONLINE;

四、 归档模式下的不完全介质恢复


1、 不完全恢复的操作准则:


在恢复前后都对数据库进行完全备份。

完成不完全介质恢复后,检查数据库是否已经恢复到了目标时刻下的状态。



完成不完全介质恢复后,将归档重做日志文件移动到其它位置保存。



2、 基于时间的不完全恢复:

对数据库进行一次完全备份,包括控制文件和所有的联机重做日志文件。


SQL>SHUTDOWN ABORT:确定不完全介质恢复的目标时间,即你需要将数据库恢复到哪个时刻下的状态,然后确定需要使用哪些备份来对数据进行修复,数据库修复所使用的控制文件备份应当能够正确反映出目标时刻下数据库的物理结构,所使用的数据文件备份应当是在目标时刻之前创建的,而且必须修复所有的数据文件,如果没有在目标时刻之前建立的数据文件备份,需要重新创建空白的数据文件。

如果在数据库中包含在目标时刻之后建立的数据文件,不要对这个数据文件进行修复,因为在完成不完全恢复后的数据库中根本不应当存在这个数据文件;将数据文件恢复到原来的位置上,如果介质故障无法排除,则恢复到其它位置上;利用选定的备份文件修复所有的控制文件和数据文件。

SQL>STARTUP MOUNT 启动实例并加载数据库;如果修复后的数据文件不在它们原来的位置上,需使用ALTER DATABASE RENAME FILE … TO …语句在控制文件中更新它们的信息。

SQL>SELECT name,status FROM V$DATAFILE;
确定所有数据文件都处于联机
SQL>ALTER DATABASE DATAFILE … ONLINE;
将数据文件恢复为联机;
SQL>RECOVER DATABASE UNTIL TIME ‘2004-02-01:12:30:30’
如果控制文件是利用备份修复的,
必须在RECOVER名利中指定USING BACKUP CONTROLFILE子句;
SQL>ALTER DATABASE OPEN RESETLOGS;


立即对数据库进行一次完全备份。

3、 基于撤销的不完全恢复。

SQL>RECOVER DATABASE UNTIL CANCEL:其它步骤同基于时间的不完全恢复。



4、 基于SCN的不完全恢复。

在进行基于SCN的不完全恢复时,oracle会在应用了所有具有小于等于指定SCN的事务的重做记录之后终止恢复过程。


RESETLOGS选项在如下三种情况下,必须使用RESETLOGS选项打开数据库:



1、 在执行任何类型的不完全介质恢复之后;

2、 在使用备份修复控制文件后(在RECOVER命令中使用USING BACKUP CONTROLFILE子句);


在没有联机重做日志文件备份的情况下对不归档数据库进行完全恢复之后。
转自:http://www.cnblogs.com/junzhongxu/