返回列表 发帖

[讨论]用'or''=''or'就能登陆网

[讨论]用'or''=''or'就能登陆网
议题提交:小行
信息来源:邪恶八进制信息安全团队

现在很多的公司网站的后台漏洞是大的叫人害怕
只要写入'or' '=',

就可以顺利的登入它的后台管理
针对于此,大家都是如和处理的?

希望各位发出自己的检验,完善下这个帖子,

PS:为安全做点力量

我本着抛砖引玉思想欢迎大家来一起讨论此帖,谢谢!
此帖已经在远望论坛发帖子讨论,已经有人回复总结一文,在此一起发出,希望更多的人针对此发表自己的见解

针对ASP中SQL Injection的初级防护(总结版)
                      robur/文

记得大约是在2002年的时候,SQL Injection(SQL注入)开始有了最初的雏形。黑客们发现,在动态网页的某些地方(表单等……)插入一些可以在数据库查询中起作用的语句和符号,就可以让页面执行后,返回特殊的结果。于是,经过了2003的发展,到2004年,SQL Injection已经作为一种很成熟的入侵技术登上了安全界的舞台。也是2004年,有大批的网站程序被发现了SQL Injection漏洞,也有大批的网站栽倒在这种攻击手段之下。
下面,我就小行和逍遥一指令的帖子,作总结性的说明,仅供参考。
正如如小行所说的,在某些网站的登录界面,如果你知道了存在的用户名(例如:admin),你无须知道密码。只需在密码框中输入' or ''='即可。(注意,全是单引号!)这样在不知道密码的情况下,也可以用admin的身份登录。
但是,我想说的是,' or ''='在一些地方会出现问题。有些数据库不会认为“空”=“空”是成立的条件,这样就不行了。最好写成' or '1'='1
这样,SQL的查询语句,就变成了如下的样子。
select * from users where name='admin' and pass='123456' or '1'='1'
上面,蓝色的部分是用户在密码框中输入的数据。大家可以看见,由于用户的巧妙构造,使得SQL Server把这条查询语句解析为3个条件:
1、name='admin'
2、pass='123456'
3、'1'='1'
关键是中间的那个or,这样一来,SQL Server在解析的时候,只要条件2、3,符合一个就可以了。
因为1=1是衡成立的,所以这个查询的结果肯定是true。

既然已经知道了原理,那我们可以试着防范这种攻击。
我们的根本目标,就是把用户输入的单引号和or过滤掉,这样就能在基本上杜绝SQL Injection攻击。但是,需要强调的是,SQL语句中,起作用的还有and,分号,--(两个减号)等等。

解释一下:and用于连接两个条件。;(分号)用于分隔两个语句。(如果把两个语句写在一行,就需要它。)--(双减号只在MS SQL Server中起作用,含义是忽略后面的内容。这个通常在繁琐的MS SQL注入中使用。)

回归主题。asp中为我们提供的字符转义函数:Replace。看代码:

<%
Dim Usr,Pwd
Usr=Request.form("username") &#39;从表单获得数据

Pwd=Request.form("password") &#39;同上
if (Usr<>"") and (Pwd<>"") then &#39;判断数据为非空
Usr=Replace(Replace(Usr,"&#39;",""),"or","") &#39;嵌套了两个replace函数,过滤特殊字符
Pwd=Replace(Replace(Pwd,"&#39;",""),"or","")
end if
%>

Repalce语法规则:
Replace(变量名称,"要过滤的字符","要替换的字符")
说明,“要替换的字符”那里,如果留空,就是把要过滤的字符直接删除。
例子:
Replace(Pwd,"&#39;or","")
过滤Pwd变量中的or字符。
由于Replace函数,一次只能对一组字符进行转义,所以讲讲Replace的嵌套:
Replace(Replace(Pwd,"or",""),"&#39;","")
代码中红色的地方,被外面的replace函数看作一个变量,依此类推。
如果你还想过滤and,分号,--什么的,请看下面(完全过滤了在SQL注入中最关键的5个字符串。)
Replace(Replace(Replace(Replace(Replace(变量名称,"&#39;",""),"or",""),"and",""),"--",""),";","")

上面只是防范从表单提交的数据,对于一些新闻系统,经常会出现诸如:
http://host/news/show.asp?id=1
之类的URL。
如果在那个1后面,加上一个单引号,一样会报错。我们往下看。
如果加上了单引号,SQL语句就变成了:
select * from news where id=&#39;1&#39;&#39;
因为最后一个引号没有闭合,所以系统一定会报错。
防范如下(其实和上面的原理是一样D……)看代码:

<%
Dim id
id=Request("id")
if Not IsNumeric(id) then &#39;------事先声明了变量,所以可以直接写进去。否则,就要写Request("id")
Response.write "Error!" &#39;------反馈错误信息
Response.end &#39;------中止执行下面的语句
end if
%>

因为,类似新闻ID之类的变量,是根本不需要有字母和符号存在的,所以用IsNumeric来判断是否为纯数字,确保万无一失。
如果一个变量,里面需要有字母和符号,那你就只好用Replace函数慢慢过滤了……:O)

最后,再说两种防止ASP页面暴出错误信息的方法。
众所周知,入侵者往往都是通过页面暴出的错误来得知一些额外的信息。比如你的系统,SQL Server的版本,是否存在某数据库,SQL语句是否执行成功等……
防止入侵者看到错误信息,就是让入侵者变成了睁眼瞎,找不到头绪。(骨灰级黑客除外~~~~)
方法1:打开你的IIS管理器(以IIS6.0为例),选择你的网站=》属性页面=》主目录选项卡=》点击配置按钮=》调试选项卡=》向客户端发送下列文本错误消息
这样,即使入侵者找到了注入点,注入后,得到也只是服务器返回的固定的错误消息。不能得到任何有价值的错误信息。

方法2:在你的ASP语句中(一般是在最开头的地方),加上一句
On Error Resume Next
(注意,这句必须加在<%  %>里面,不然IIS可不认。)
这就是著名的容错语句,当ASP语句执行时发生错误,就跳过错误,继续向下执行,而且不会返回错误信息。
当然,入侵者看不到错误信息,调试人员也看不到。所以,你一定在把一个ASP程序调试完毕后,再把这个语句加到ASP语句的顶端。否则,调试的时候,会烦死你的~~~~~~:O)

好了,不多说。就这些了,全是自己写的。大家随便看看,捧捧场哦~~~~~~

就这些,期待审核通过,大家都能好好的谈论下这个问题
帖子83 精华2 积分251 阅读权限100 性别男 在线时间6 小时 注册时间2005-4-8 最后登录2007-10-11 查看详细资料TOP 少女暴富的隐秘(图)

xhr
晶莹剔透§烈日灼然

<%
user=request.form("userID")
pass=request.form("password")
for i=l to len(userID)
cl=mid(userID,i,l)
if cl="&#39;"or us="="or" us="<"or us=">" then
response.redirect"提交非法字符,IP已经记录"
response.end
end if
next
%>自由 平等 共享

帖子51 精华0 积分126 阅读权限40 性别男 在线时间77 小时 注册时间2008-1-26 最后登录2008-6-22 查看详细资料TOP 您知道您年薪应是多少?

千寂孤城
Fypher

荣誉会员

TOP

<%
user=request.form("userID")
if instr(user,"&#39;")<>0 then
response.redirect "提交非法字符,IP已经记录"
response.end
end if
%>You're my FF~, forever~ ^_^
帖子188 精华2 积分933 阅读权限100 性别男 在线时间43 小时 注册时间2005-5-26 最后登录2008-7-22 查看个人网站
查看详细资料TOP 让女孩一夜变的更有女人味

史翔
晶莹剔透§烈日灼然

TOP

response.redirect"提交非法字符,IP已经记录"不对吧应该是:
response.write"提交非法字符,IP已经记录"12345667891

帖子52 精华0 积分541 阅读权限50 性别男 在线时间93 小时 注册时间2005-3-22 最后登录2008-4-13 查看个人网站
查看详细资料TOP

wasp520
晶莹剔透§烈日灼然

TOP

最简单的是用instr函数
这个东西好呀!instr函数
pwd = request.form("pwd")
name = request.form("name")
if instr(name,"&#39;")<>0  or instr(pwd,"&#39;")<>0 then
Response.Redirect "Loginsb.asp?msg=用户名/密码错误,请重新输入!"
response.end
end if

还有就是replace
adminname=trim(replace(request("adminname"),"&#39;",""))
adminpwd=trim(replace(request("adminpwd"),"&#39;",""))
当然可以过滤更多的了,着就看自己的了
帖子2 精华0 积分3 阅读权限40 在线时间32 小时 注册时间2005-5-31 最后登录2007-7-26 查看详细资料TOP 少女暴富的隐秘(图)

haicao
技术核心组

TOP

如果是asp+access结构的话.
过不过滤无所谓.
asp+access密码验证可以这样写
...
.....
sql="select * from ad where user=&#39;"&user&"&#39;"
rs.open sql,conn,1,1
if password=rs("password") then
成功登陆!
end if在我纯真年少時,有一個女生,她願意爲我失去生命,她意志堅定地說:你再纏著我,我就去死! 在我負笈外地時,有一個女生,她願意等我到下輩子,她溫柔婉約地說:你想成爲我男友?等下輩子!! 在我窮困潦倒時,有一個女生,她願意與我共赴黃泉,她眨著紅眼說:你再不還錢,我和你同歸于盡!
帖子428 精华24 积分5194 阅读权限200 性别男 在线时间164 小时 注册时间2004-10-5 最后登录2008-7-13 查看详细资料TOP 良辰择日,预测咨询,公司改名,权威易经

haicao
技术核心组

TOP

要有效的防注入我想还是用通用防注入那样的方法最简单,直接获取传递过来的每个参数,进行检查,把关键的字符进行检查......非法就reponse.end下.在我纯真年少時,有一個女生,她願意爲我失去生命,她意志堅定地說:你再纏著我,我就去死! 在我負笈外地時,有一個女生,她願意等我到下輩子,她溫柔婉約地說:你想成爲我男友?等下輩子!! 在我窮困潦倒時,有一個女生,她願意與我共赴黃泉,她眨著紅眼說:你再不還錢,我和你同歸于盡!
帖子428 精华24 积分5194 阅读权限200 性别男 在线时间164 小时 注册时间2004-10-5 最后登录2008-7-13 查看详细资料TOP 让女孩一夜变的更有女人味

逍遥天下
晶莹剔透§烈日灼然

TOP

没想到小行居然也跑到这里来了,还把我们的讨论贴给发上来了
我觉得还是直接过滤 ’ 比较实际

Username=Replace(Request.form("username") ,"&#39;","")
Password=Replace(Request.form("password") ,"&#39;","")

直接在密码验证页面中这样写就可以了~!本来要取逍遥一指令的

帖子23 精华0 积分178 阅读权限40 性别男 来自成都 在线时间7 小时 注册时间2005-6-17 最后登录2008-1-30 查看详细资料TOP

职业欠钱
荣誉会员

TOP

引用:
下面是引用haicao于06-12-2005 13:19发表的:
如果是asp+access结构的话.
过不过滤无所谓.
asp+access密码验证可以这样写
...
.....
.......
sql="select * from ad where user=&#39;"&user&"&#39;"
rs.open sql,conn,1,1
if password=rs("password") then
成功登陆!
end if
user字段俺这么输:
admin&#39; or password=&#39;123456
如果运气好,有个密码正好是123456的
在密码字段再输个 123456
不就进去了么?
对于字符输入,还是过滤的比较好,至少单引号必须过滤
这样一来,被单引号引起来的东西,无论如何躲不过去了
比如&#39;&user&&#39;
把单引号转换为& #39;
只要user字段输任何东西,都会当作字符串处理,而单引号一出现又被替换掉
那么该字段的注射就不可能了(愚见,请大家批评)
所以事实上很多的注射都是发生在数字型参数里,因为程序员总是记得对于数字型的参数,在SQL里是不需要用单引号引起来的,那么,即使进行了过滤,如果不充分,还是可以进行注射的.
比如在BBSXP上次的blog.asp中,有个id字段进行了过滤,但是,我们完全可以绕过去.
复制内容到剪贴板
代码:
if id<>"" then
sql="select * from [calendar] where id="&id&" order by id Desc"
虽然这个id变量过滤掉了&#39;
不过对于AC的我们构造一个union查询
12 union select 1,2,username,userpass,5,6,7 from [user] where membercode=5
就可以查询区长的用户名和密码了,当然,修改条件查询任何人的密码也没问题的
对于MSSQL,union会出错,那么我们这么做:
12  and exists(select * from clubconfig where substring(adminpassword,1,1) between 0x30 and 0x46)
这样就跳过了单引号的限制,还有比较大小时用到的>和<符号
用二分法很容易得到所有数据,毕竟这种公开代码的程序的表的结构都很清楚
总结:
要防止用&#39; or &#39;&#39;=&#39;登陆后台,应该说是要防止SQL 注射
防止SQL注射,个人认为最简单的注意方法有两个,1,检查所有输入,凡字符型,过滤掉单引号,并且用单引号引起来.
比如
user=replace(request(user),"&#39;")
select * from admin where user=&#39;"&user&"&#39;
如果是数字型,直接用
id=int (request(id))
select * from blog where id="&id&"
个人认为这样基本上就差不多了,有错误的地方欢迎大家指正个人论坛: http://www.xdxf.net
帖子60 精华2 积分3417 阅读权限100 性别男 在线时间134 小时 注册时间2005-5-3 最后登录2008-5-28 查看详细资料TOP

evilow
晶莹剔透§烈日灼然

TOP

呵呵 对于‘等特殊字符的提交 我以为应该是得自VB的数据类型的模糊(有时数据可以为字符串,也可以是整型。。。。)  ASP可以说是vb的一个子集(某种程度上) 所以就继承了那个数据类型模糊的漏洞  楼上对数据类型的严格限制 我想的确是个很不错的方式   不过我想也可以将返回的信息页面转换成静态的html页面  不是那种传统的asp的页面表达方式  比如这个页面http://www.tbhacker.com/www/Soft/hkdh/200506/20050625054422.html  呵呵 乱说的  不对的地方请指教偶在卿不在,卿在偶不在;问世间缘为何物,只叫你我难相逢^^^^^

帖子21 精华0 积分21 阅读权限40 性别男 来自安徽[现在广州读书] 在线时间0 小时 注册时间2005-6-8 最后登录2006-4-2 查看个人网站
查看详细资料TOP

玄猫
荣誉会员

TOP

复制内容到剪贴板
代码:
objRs.open "Select * From [t4dmin] where cP4ssword=&#39;" & MD5(strPass)& "&#39;",conn,1,1
     If objRs.eof and objRs.bof Then
          fError()
     Else
          bolIs = False
          For i = 1 to objRs.RecordCount
              If objRs("c4dmin")=strName then
                   bolIs = True
                   Exit For
              End If
          Next
     
          If bolIs = False Then
              fError()
          Else
              session("IsAdmin")=True
              response.Redirect("admin.asp")
          End If
     End If
objRs.close那些好像永远都不会停的雪。那一季永远不结束的冬天。
帖子38 精华2 积分95 阅读权限100 性别男 来自BugCenterTeam 在线时间33 小时 注册时间2005-3-3 最后登录2008-1-18 查看个人网站
查看详细资料TOP

haicao
技术核心组

TOP

我觉得职业欠钱说得有点搞笑了吧?
user字段俺这么输:
admin&#39; or password=&#39;123456

...
你为什么不直接用户名输入admin
密码框输入123456呢?
再说了
sql="select * from ad where user=&#39;"&user&"&#39;"
rs.open sql,conn,1,1
if password=rs("password") then
有没看到还有一个判断密码字段和用户输入的是否一致的检查,可不是简单的
if not(rs.eof and rs.bof)的判断呀,晕!在我纯真年少時,有一個女生,她願意爲我失去生命,她意志堅定地說:你再纏著我,我就去死! 在我負笈外地時,有一個女生,她願意等我到下輩子,她溫柔婉約地說:你想成爲我男友?等下輩子!! 在我窮困潦倒時,有一個女生,她願意與我共赴黃泉,她眨著紅眼說:你再不還錢,我和你同歸于盡!
帖子428 精华24 积分5194 阅读权限200 性别男 在线时间164 小时 注册时间2004-10-5 最后登录2008-7-13 查看详细资料TOP

kevin1986
荣誉会员

TOP

防范的方法很多嘛
1.破坏构造的字符串
  (1) MD5加密:不管怎么样,字符串都将转换成MD5值,不存在与SQL语句冲突的问题.当然,如果是MSSQL的话,用户名要放在句后,以防一些人用;--注释掉MD5的Hash(一般有MD5存在的,ACCESS饶不过应该,MSSQL可以看先后次序)
  (2) 过滤特殊字符,比如replace(username,"&#39;","") | replace(username,"--","")之类的..(网上N多系统这么过滤)
2.将数据与字符串比对
   先查看是否eof,如果不是,那么将数据库中取出一个未知的值与输入的值比对.如果相同,则可以说明正确...也是杜绝的办法(看过一个叫ET-Comic的代码使用这种方法)
3.先取出再验证
   一个比较低效率的办法...来一个循环,然后读出数据比对...输入的字符串本身不参与查询...(很早的时候看一个文章系统用过..)me=\"kEvin1986\" & chr(0) & \"at solitude\" msgbox len(me) \' You can see somthing. msgbox me \' But just part of it. \'i think i will hide part of myself
帖子325 精华12 积分3936 阅读权限100 性别男 在线时间308 小时 注册时间2005-2-5 最后登录2007-9-3 查看个人网站
查看详细资料TOP

crack
晶莹剔透§烈日灼然

TOP

在程序中增加过滤输入单引号的过滤函数,如果输入单引号的密码时出现“不能输入带有’的字符”这样的对话框。


if (document.login.Uname.value.indexOf9"&#39;")>-1
{
  validity=false;alert("不能输入带有’的字符");
  document.login.Uname.focus();
return validity;
}我的ID是:3721

帖子111 精华0 积分339 阅读权限40 性别男 来自山东博兴实中 在线时间294 小时 注册时间2005-4-17 最后登录2006-2-24 查看详细资料TOP

kevin1986
荣誉会员

TOP

楼上的方法只是在做表面...其实是可以修改提交参数的me=\"kEvin1986\" & chr(0) & \"at solitude\" msgbox len(me) \' You can see somthing. msgbox me \' But just part of it. \'i think i will hide part of myself
帖子325 精华12 积分3936 阅读权限100 性别男 在线时间308 小时 注册时间2005-2-5 最后登录2007-9-3 查看个人网站
查看详细资料TOP

crack
晶莹剔透§烈日灼然

TOP

呵呵,对,好像是删掉那段过滤的函数,再改一下提交到的网站,可以饶过,在本地登陆我的ID是:3721

帖子111 精华0 积分339 阅读权限40 性别男 来自山东博兴实中 在线时间294 小时 注册时间2005-4-17 最后登录2006-2-24 查看详细资料TOP

职业欠钱
荣誉会员

TOP

引用:
下面是引用haicao于06-30-2005 13:19发表的:
我觉得职业欠钱说得有点搞笑了吧?
user字段俺这么输:
admin&#39; or password=&#39;123456

...
.......
表中字内容如下:
[user]        [password]
admin        !@$$%Q@$
test           123456
asdfas        klajsdigaklj;

SQL语句执行的结果是什么?(当我们在user字段输  admin&#39; or password=&#39;123456)
select * from [admin] where [user]=&#39;admin&#39; or password=&#39;123456&#39;

if password=rs("password") then
现在这里可以认证成功了吧?
如果你直接输
admin
123456
SQL语句是
select * from [admin] where [user]=&#39;admin&#39;
这时候得到的东西才不可能使if password=rs("password") then逻辑成立呢个人论坛: http://www.xdxf.net
帖子60 精华2 积分3417 阅读权限100 性别男 在线时间134 小时 注册时间2005-5-3 最后登录2008-5-28 查看详细资料TOP

haicao
技术核心组

TOP

你上面的写法我试过。
执行结果得到的数据应该是:
admin !@$$%Q@$
test   123456
主要是因为admin记录在test对应记录之前
所以 程序逻辑能不能通过还是得看点运气了。。。。。在我纯真年少時,有一個女生,她願意爲我失去生命,她意志堅定地說:你再纏著我,我就去死! 在我負笈外地時,有一個女生,她願意等我到下輩子,她溫柔婉約地說:你想成爲我男友?等下輩子!! 在我窮困潦倒時,有一個女生,她願意與我共赴黃泉,她眨著紅眼說:你再不還錢,我和你同歸于盡!
帖子428 精华24 积分5194 阅读权限200 性别男 在线时间164 小时 注册时间2004-10-5 最后登录2008-7-13 查看详细资料TOP

影に尸鬼封尽
晶莹剔透§烈日灼然

TOP

如果你还想过滤and,分号,--什么的,请看下面(完全过滤了在SQL注入中最关键的5个字符串。)
Replace(Replace(Replace(Replace(Replace(变量名称,"&#39;",""),"or",""),"and",""),"--",""),";","")

我要是提交o;ra;nd-;-  过滤后看看or and -- 还不是存在
帖子12 精华0 积分11 阅读权限40 在线时间35 小时 注册时间2005-3-20 最后登录2005-12-5 查看详细资料TOP

haicao
技术核心组

TOP

引用:
下面是引用影に尸鬼封尽于2005-08-10 10:46发表的:
如果你还想过滤and,分号,--什么的,请看下面(完全过滤了在SQL注入中最关键的5个字符串。)
Replace(Replace(Replace(Replace(Replace(变量名称,"&#39;",""),"or",""),"and",""),"--",""),";","")

我要是提交o;ra;nd-;-  过滤后看看or and -- 还不是存在
这主意不错。哈哈。。。。。。。。。。。。。。
看来过滤某些字符未必有意义,还是发现危险字符随时结束掉比较安全。。。在我纯真年少時,有一個女生,她願意爲我失去生命,她意志堅定地說:你再纏著我,我就去死! 在我負笈外地時,有一個女生,她願意等我到下輩子,她溫柔婉約地說:你想成爲我男友?等下輩子!! 在我窮困潦倒時,有一個女生,她願意與我共赴黃泉,她眨著紅眼說:你再不還錢,我和你同歸于盡!
帖子428 精华24 积分5194 阅读权限200 性别男 在线时间164 小时 注册时间2004-10-5 最后登录2008-7-13 查看详细资料TOP

k2k
晶莹剔透§烈日灼然

TOP

返回列表