解释如何在Rails中利用order子句

时间:2015-02-20 13:41:54

标签: sql ruby-on-rails sql-injection

我很难理解this website on Rails SQL Injections中此部分的工作原理。

  

在ORDER BY子句中利用SQL注入很棘手,但CASE语句可用于测试其他字段,将sort列切换为true或false。虽然它可能需要很多查询,但攻击者可以确定该字段的值。

有人可以解释一下吗?他们说"将排序列切换为true或false"是一个难以理解的,因为我不知道如何使攻击者能够揭示另一个领域的价值。

2 个答案:

答案 0 :(得分:4)

如果你试图确定你知道的字段的值在表中,但是没有在select中返回,你可以按顺序迭代它,直到得到值:

 ORDER BY CASE WHEN variableIdLikeToDiscover < 'N' then 1 else 0 end

然后看它是否大于或小于'N'。如果它小于,接下来你可以尝试:

 ORDER BY CASE WHEN variableIdLikeToDiscover < 'F' then 1 else 0 end

依此类推,直到你(最终)确定了价值。

答案 1 :(得分:1)

该示例显示:order参数将放置在语句的末尾,因此如果您添加一个在结尾处始终为true的比较,它将更新所有行。

例如,如果您制作了非恶意订单,它将类似于:

params[:order] = "name"
User.update_all("admin = 1", "name LIKE 'B%'" , { :order => params[:order] })

生成的SQL将是:

UPDATE "users" SET admin = 1 WHERE "users"."id" IN (SELECT "users"."id" FROM "users" WHERE (name LIKE 'B%') ORDER BY name))

因此,更新将对名为LIKE&#39; B%&#39;的用户进行。

但是,当param设置为:

params[:order] = "name) OR 1=1;"

生成的SQL将是:

UPDATE "users" SET admin = 1 WHERE "users"."id" IN (SELECT "users"."id" FROM "users" WHERE (name LIKE 'B%') ORDER BY name) OR 1=1;)

基本上,OR比较将添加到原始WHERE,比较将是:更新名称为LIKE&#39; B%&#39;或1 = 1。这将导致所有用户更新为admin = 1(在给定的示例中)。

然后,攻击者可以使用具有管理员权限的任何用户登录。

希望它有所帮助...