URL编码与SQL注射 :: 『孤光剑隐』
来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=509479 存档链接: https://web.archive.org/web/20050113030759id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=509479
本站公告 BLOG停止更新 常见IP碎片攻击详解 从上传webshell到突破TCP-IP筛选到3389终端登陆 子网掩码及其应用 Windows命令行技巧 用PERL打造自己的缓冲区漏洞利用程序 Linux安全综述 DISCUZ2上传漏洞分析 上传漏洞变换利用 如何使tcp包和udp包穿透防火墙 TC函数命令详细表 dreamtheater Angel showlife tx7do jpxiong chensun netsky KKQQ Ziqi spy8888 Luzhu eVan SUNU Taynni wuhui CAT Neeao KusTa Hoky eviloctal lam Iceberg Jace Hardy Gusu・Lanye swap lilo xiaolu knIfe kaka Lo7e4L Super・Hei lichdr lamp FlyWeb evilhsu hackfree powers Sunlion EvilPhive xeric icyfoxlovelace GuoMing swords an85 ring zwx steve S4Ld0ne solaris myzky xpfox liso sevenline Golden・Section phoenix xrens BlackFox tuz hardy29a victorwoo xueyu・xiongying Blackfish skyshui zhouzhen cnbird <<<Win32Asm教程(基础篇) | 首页 | 子网掩码及其应用>>> URL编码与SQL注射 时间: 2004-11-22 说到url编码,你或许会想起N年前的url编码漏洞。可惜我是"生不逢时"啊,我接触网络时,那个漏洞早就绝迹咯。 言归正传,URL 编码是什么东东呢?看看我从网上抄的定义: 引用: url编码是一种浏览器用来打包表单输入的格式。浏览器从表单中获取所有的name和其中的值 ,将它们以name/value参数编码(移去那些不能传送的字符, 将数据排行等等)作为URL的一部分或者分离地发给服务器。不管哪种情况, 在服务器端的表单输入格式样子象这样: theName=Ichabod+Crane&gender=male&status=missing&headless=yes URL编码遵循下列规则: 每对name/value由&符分开;每对来自表单的name/value由=符分开。如果用户没有输入值给这个name,那么这个name还是出现,只是无值。任何特殊的字符(就是那些不是简单的七位ASCII,如汉字)将以百分符%用十六进制编码,当然也包括象 =, &, 和 % 这些特殊的字符。 呵呵,明白了吧,其实url编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上"%"。比如"",它的ascii码是92,92的十六进制是5c,所以""的url编码就是%5c。那么汉字的url编码呢?很简单,看例子:"胡"的ascii码是-17670,十六进制是BAFA,url编码是"%BA%FA"。呵呵,知道怎么转换的了吧。 URL编码平时我们是用不到的,因为IE会自动将你输入到地址栏的非数字字母转换为url编码。所以对于浏览器来说 http://blog.csdn.net/l%61ke2 与 http://blog.csdn.net/lake2 是等效的(注意,第一个url我用%61替换了a)。呵呵,或许你已经想起了,有人提出数据库名字里带上"#"以防止被下载,因为IE遇到#就会忽略后面的字母。破解方法很简单――用url编码%23替换掉#。我本来企图利用url编码来躲过注射检查的,不过失败了,因为服务器端会将url编码转换成字符的。 等等,好像跑题了啊,呵呵,不好意思:) 现在SQL注射非常流行,所以就有人写了一些防注射的脚本。当然啦,思路不一样,效果大不同。各位看官请看下面的××SQL通用防注入asp版部分代码。 Fy_Url=Request.ServerVariables("QUERY_STRING") Fy_a=split(Fy_Url,"&") redim Fy_Cs(ubound(Fy_a)) On Error Resume Next for Fy_x=0 to ubound(Fy_a) Fy_Cs(Fy_x) = left(Fy_a(Fy_x),instr(Fy_a(Fy_x),"=")-1) Next For Fy_x=0 to ubound(Fy_Cs) If Fy_Cs(Fy_x)<>"" Then If Instr(LCase(Request(Fy_Cs(Fy_x))),"and")<>0 then Response.Write "出现错误!" Response.End End If End If Next 它的思路就是先获得提交的数据,以"&"为分界获得并处理name/value组,然后判断value里是否含有定义的关键字(这里为求简便,我只留下了"and"),有之,则为注射。 乍一看去,value被检查了,似乎没有问题。呵呵,是的,value不会有问题,可是,name呢? 它的name/value组值来自于Request.ServerVariables("QUERY_STRING"),呵呵,不好意思,这里出问题了。Request.ServerVariables("QUERY_STRING")是得到客户端提交的字符串,这里并不会自动转换url编码,哈哈,如果我们把name进行url编码再提交的话,呵呵,那就可以绕过检查了。比如参数是ph4nt0m=lake2 and lis0,此时程序能够检测到;如果提交%50h4nt0m=lake2 and lis0(对p进行url编码),程序就会去判断%50h4nt0m的值,而%50h4nt0m会被转换为ph4nt0m,所以%50h4nt0m值为空,于是就绕过了检测。 等等,为什么既然name不解码可以绕过检查而value就不能绕过呢?因为value的值取自Request(Fy_Cs(Fy_x)),这个服务器就会解码的。 程序怎么改进呢?只要能够得到客户端提交的数据是解码后的就可以了,把得到name的语句改为For Each SubmitName In Request.QueryString就可以了。 呵呵,谢谢阁下耐着性子看完我的文章^_^ 孤光剑隐 发表于 2004-11-22 10:10 引用Trackback(0) | 编辑 评论 发表评论