内容目录:
-1.问题的范围 -2.SQL攻击的详细解释 -3.解决办法 -4.结论 -5.本文涉及的perl程序
------------------------------------------------------------------------
----[ 1. 问题的范围
许多应用程序都可以通过SQL来进行攻击。现在许多程序知道了避免使用strcpy(), 并且不把用户数据传递给system()调用,但是很多程序还不知道SQL查询可以被黑客 篡改来达到攻击的目的。
写一篇技术文章要比写个安全建议麻烦得多,但是技术文章能够全面地解释我是 如何利用wwwthreads程序的漏洞得到PacketStorm论坛管理员权限和将近800个用户密 码的。
----[ 2. SQL攻击的详细解释
某日,我正在PacketStorm的论坛上浏览,发现这个论坛使用的是wwwthreads。 我突然注意到了URL的参数(URL中’?’后面的部分)。作为一个web安全爱好者,我 对它感到极为好奇。使用试验的攻击方法,我把showpost.pl程序中的’Board=general’ 参数改为了’Board=rfp’。提交并发现传回来以下错误信息:
We cannot complete your request. The reason reported was: Can’t execute query: SELECT B_Main,B_Last_Post FROM rfp WHERE B_Number=1 . Reason: Table ’WWWThreads.rfp’ doesn’t exist
可以发现这儿还有一个参数’Number=1’,我们可以推断出查询请求是这样构造的:
SELECT B_Main,B_Last_Post FROM $Board WHERE B_Number=$Number
如果你读过我在phrack 54上发表过的文章的话(可以到 http://www.wiretrip.net/rfp/p/doc.asp?id=7&iface=2阅读),你就应该明白我要 做什么了。我们不仅可以修改$Board和$Number参数,而且还可以提交额外的SQL命令。 试想一下,如果我们提交的$Board参数是下面的样子:
’general; DROP TABLE general; SELECT * FROM general ’
那么在服务器端就会转化成:
SELECT B_Main,B_Last_Post FROM general; DROP TABLE general; SELECT * FROM general WHERE B_Number=$Number
’;’符号是SQL命令的结束符。通常我们可以使用’#’来使MySQL忽略此行上的其它 内容。但是,’FROM’和’WHERE’是在一个分开的行上,所以MySQL不会忽略它。考虑到 错误的SQL语句会使MySQL忽略运行后面的语句,所以我们至少要提交一个有效的命令。 在本例中,我们提交一个和原始命令相似的generic select命令,理论上的结果应该 是删除general论坛所在的表。
但是在实际上并没有成功,并不是因为理论是错误的,而是因为我们使用的数据 库用户没有DROP权限。并且根据wwwthreads编写的方法,它不完全允许你这么做。但 是一切并没有白费,我们可以修改其它的参数,看看哪里会出问题...而且我们可以到 www.wwwthreads.com去下载wwwthreads的源代码(免费版)。
可以发现,免费版和正式版(PacketStorm上运行的是正式版)的代码稍微有些不 同,包括它们的SELECT声明。所以我们得有点创造性。我们先找到和前面有关的SELECT 声明。
我喜欢使用less命令,所以我就’less showpost.pl’,并且寻找(用’/’)’SELECT’ 字符串。发现了:
# Grab the main post number for this thread $query = qq! SELECT Main,Last_Post FROM $Board WHERE Number=$Number !;
Wow,就是它!除了几个参数的名字(Main,Last_Post,Number)和前面的(B_Main, B_Last_Post,B_Number)不同。如果我们看看它的上面,我们会发现:
# Once and a while it people try to just put a number into the url, if (!$Number) { w3t::not_right("There was a problem looking up the Post...
这就是对$Number参数的限制。
基于这一点让我们来看看“为什么”我们要研究它。很显然我们有可能达到DROP表 这种DOS攻击,你还有可能修改其它人的发言,但那仍然不是我们要的。我们没准能建立 我们自己的论坛?所有的信息都储存在数据库里。但是有许多记录要去更新。成为一个 数据库操作员怎么样?或者更进一步,成为管理员怎么样?管理员可以增添、删除、修 改论坛、用户等。这是值得一试的,虽然你仍然将会被限制在论坛的领域里,那是一个 小的可怜的领域。
但是,这仍然有一件事情值得为它一试。如果你注册为一个用户,你会发现你必须要 输入一个密码。Hmmm...这个密码储存在某个地方,好象是数据库里。考虑到许多人的密 码用在很多地方,而且wwwthreads(在某些配置上的错误?)把发言者的IP地址发到论坛 上。如果我们能得到某个人的密码,就可能去攻破他的主机。
所以,让我们来看看密码是怎么存储的。进入到论坛的“编辑属性”页,有一个密码 域,通过HTML源码看,像是有一个可怕的加密密匙。妈的,这些密码是加密过的。这意味 着你需要一个密码破解软件和大量的时间去对密码进行解密。当然,这是假定你*能够*得 到密码...
首先我们要去获得论坛管理员权限。adduser.pl程序是我们开始的好地方,因为它可 以让我们看到一个用户的全部参数。看看下面的代码:
# -------------------------------------- # Check to see if this is the first user $query = qq! SELECT Username FROM Users !;
$sth = $dbh -> prepare ($query) or die "Query syntax error: $DBI::errstr. Query: $query"; $sth -> execute() or die "Can’t execute query: $query. Reason: $DBI::errstr"; my $Status = ""; my $Security = $config{’user_security’}; my $rows = $sth -> rows; $sth -> finish;
# ------------------------------------------------------- # If this is the first user, then status is Administrator # otherwise they are just get normal user status. if (!$rows){ $Status = "Administrator"; $Security = 100; } else { $Status = "User"; }
[1] [2] [3] [4] 下一页 |