|
记住,我们所要做的关键是要使我们提交的东西看起来像是数据,而最终SQL引擎 即数据库会把它解释成命令。注意一下,查询语句中域是按这种形式列出来的: field=&#118alue, field=&#118alue, field=&#118alue, 等等(当然,它们被分隔在不同的行)。 如果我插入一些伪造的值,(处于举例的缘故)我会有:
Name=’rfp’, Signature=’rfp’, Homepage=’www.wiretrip.net/rfp/’
我所要做的就是把这些值放在同一行上,去掉空格,并把它们放进字符串值里, 这是合法的SQL语句。
现在让我们把所有一切和在一起。注意’Sort’变量,它是数字类型的,我们这样 提交:
Bio=’puppy’, Sort=5, Display=’threaded’
这仍然是合法的SQL语句。因为$Sort=$FORM{’sort_order’},这意味着要达到上 面的Sort值,我们应该提交一个sort_order=5的参数。现在我们就利用Sort来达到我 们的攻击目的。我们要做的是包含一个逗号和其它的语句。假定要改变Status域的话, 我们就应该提交一个值为"5, Status=’Administrator’,"的sort_order参数,当它经 过程序处理流程后,最终会变成这个样子:
Bio=’puppy’, Sort=5, Status=’Administrator’, Display=’threaded’ ^^^^^^^^^^^^^^^^^^^^^^^^^^ 我们提交的数据
这仍然是合法的SQL语句。而且这个语句会令数据库把Status域升级为’Administrator’! 别忘了我们前面看过的adduser.pl程序,第一个用户的安全级别是100。我们也要100的 安全级别,所以我们就把sort_order参数设置成"5, Status=’Administrator’, Security=100," 那么我们就会得到:
Bio=’puppy’, Sort=5, Status=’Administrator’, Security=100, ...
这就更新了所有我们想要的值。数据库不知道我们的诡计,就会更新这两个域, 并把这个用户升级为论坛管理员。
于是我们就把这种攻击技术用到了PacketStorm论坛上...结果对changeprofile.pl 请求得到了一个404错误。恩,看来前面看的那个版本没有这个问题。我又去看了看 ’Edit Profile’菜单,我看它有’Basic Profile’、’Display Preferences’、和 ’Email Notifications/Subscriptions’这几个demo版所没有的东西。如果它们能改变 脚本的话,它们也同样能够改变SQL查询语句(实际上它们必须能够)。于是我们现在 进入“黑盒子”状态(进行猜测性尝试,看看结果会怎样)。因为我们仍然对sort_order 参数进行尝试,你可以看到它包含在’Display Preferences’脚本里(editdisplay.pl)。 这个脚本处理sort_order, display, view, PostPer, Post_Format, Preview, TextCols, TextRows, FontSize, FontFace, PictureView, 和 PicturePost这几个参数(通过查看 HTML源码得到)。它是参数的一个子集。使用上面的代码片段,我们可以猜到SQL查询 是什么样子的。所以马上开火!
首先我把一些非法的值放进sort_order参数(用字符串而不是数字)。这当然将 返回错误,我们就可以检查错误信息。在第一个例子里的’Board’表前加了’B_’前缀, ’User’表前加了’U_’前缀。所以可以推断出我们应该使用’U_Status’和’U_Security’ 作为域的名字。太棒了!
为了提交一个合法的命令,我们需要提交前面列出来的所有那些值。应该指出我 们需要一个合法的用户帐号来改变它的权限。所以我们要有用户名和密码(加密过的), 从editdisplay.pl中可以发现,它们的参数应该是Username和Oldpass。于是基于上面 说过的全部,我们应该提交一个这样的URL:
changedisplay.pl? Cat=& Username=rfp &Oldpass=(加密过的密码) &sort_order=5,U_Status%3d’Administrator’,U_Security%3d100 &display=threaded &view=collapsed &PostsPer=10 &Post_Format=top &Preview=on &TextCols=60 &TextRows=5 &FontSize=0 &FontFace= &PictureView=on &PicturePost=off
其中最重要的一个参数是:
&sort_order=5,U_Status%3d’Administrator’,U_Security%3d100
这就是我们所要改变的数据库部分(%3d等于’=’字符)。如果把上面的URL合成 一个字符串,你会得到:
changedisplay.pl?Cat=&Username=rfp&Oldpass=(加密过的密码) &sort_order=5,U_Status%3d’Administrator’,U_Security%3d100&display=threaded &view=collapsed&PostsPer=10&Post_Format=top&Preview=on&TextCols=60 &TextRows=5&FontSize=0&FontFace=&PictureView=on&PicturePost=off
这就是所有全部的东西了,于是我把它提交到PacketStorm论坛,并且得到: Your display preferences have been modified.
再注意一下顶部上的菜单,我已经看到了’Admin’菜单。我点击了这个菜单,看到 一行令我心中温暖的信息:
As an Administrator the following options are available to you.
太棒了!管理员权限!看看我的选项,我可以编辑用户、留言板和论坛,指派操 作员和管理员权限,禁止用户/主机,终止/关闭/打开线程,等等。
现在进行我们的第二个目标...密码!我进入到’Show/Edit Users’菜单,并被要求 选择我赶兴趣的用户名的第一个字母。于是我选择了‘R’,所以以R开头的用户全都 被列了出来,我选择了’rfp’。然后出现了我的加密过的密码。不幸的是,要得到全部 的用户名和密码是件极为麻烦的事,于是我就写了个perl脚本来自动做。所有得到的 密码都保存为可以直接用john the ripper来解密的形式。
----[ 3. 解决办法
那么怎么避免出现这种问题呢?你可以看到,出现这种问题的原因在于对传给SQL 查询的数据没有做限制。虽然wwwthreads对大部分数据使用了quote()处理,但是它没有 对数字类型的数据进行处理。解决的办法就是确保传递过来的数字类型值是真正的数字 类型。你可以用如下函数来处理:
sub onlynumbers { ($data=shift)=~tr/0-9//cd; return $data;}
就像把字符串传递给DBI->quote()函数来处理一样,也把所有的数字类型值传递给 onlynumbers()处理。在上面的例子中,就用以下语句:
my $Sort = onlynumbers($FORM{’sort_order’});
另一个需要验证的地方是表名。在本文开头的例子中,可以看到那个’Board=general’ 参数。这个表名并没有用quote()来处理,因此我们也需要对所有的表名用一个函数来 进行处理。假设我们允许表名含有数字、字符等,可以用下面语句处理:
sub scrubtable { ($data=shift)=~tr/a-zA-Z0-9.//cd; return $data;}
最后要说的是,*所有*(强调是“所有”)用户传来的数据都必须经过quote()、 ()、 onlynumbers() 或者 scrubtable()等来进行处理...绝对不能有例外。如果直接 把用户数据传递给SQL查询语句就会造成攻击者修改你的数据库。
新版本的wwwthreads可以在www.wwwthreads.com,它已经修复了这个漏洞,就和 我前边所建议的一样。
----[ 4. 结论
下面包含了两个perl程序。wwwthreads.pl用来对有漏洞的wwwthreads发起攻击 查询。你只需要知道要攻击的IP、用户名和密码。w3tpass.pl用来下载所有的wwwthreads 的用户密码,并把它们转化成可以用john the ripper来解密的格式。
感谢PacketStorm提供了这个漏洞的试验场所!
上一页 [1] [2] [3] [4] 下一页 |