我正在一些培训网页上学习sqlinjection(所以我不知道后端是什么)。我正在尝试下一次注射,以获得de-db型。
(1) http://url/?departamento=1 union select user()
这样,如果数据库是mysql,我应该会得到一些结果。但是,我没有看到任何结果。如果我将注入更改为这个新语句,数据将正确返回,因此db是mysql(即使我可以通过这个新注入看到db名称):
(2) http://url/?departamento=1 union select 1,user()
然而,如果我再次改变注射到其中一个结果改变。
(3) http://url/?departamento=1 union select 1,2,user() (I don't see any data)
(4) http://url/?departamento=1 union select user(),2 (Here I don't see the DB name)
我不明白为什么要添加(在第二个select语句中)更多的列来查看数据。为什么会这样?
谢谢!
最佳答案
假设后端是Java,则代码正在执行类似的操作:
// 1 union select 1,user()
String query = "select a, b, c from someTable where departamento = "
+ request.getParameter("departamento"); // the injection is here
try (Statement stmt = con.createStatement()) {
try (Result rs = stmt.executeQuery()) {
while (rs.next()) {
int a = rs.getInt(1); // column "a"
String b = rs.getString(2); // column "b"
Date c = rs.getDate(3); // column "c"
System.out.println("a: " + a + ", b: " + b + ", " c: " + c);
}
}
}
要使注入工作,您需要生成有效的sql语句。
联合必须具有与源查询相同的列数
列类型必须匹配;第一个子查询中的列类型必须与第二个子查询中的列类型相同(某些数据库可能因此而失败)。
您的条件(“1”)必须与筛选器的右侧匹配(
departemento
)可能是特定于Java(和本例)的,要使循环工作,您需要能够将列强制转换为其目标类型。如果列1是一个数字,那么如果联合生成的字符串不能转换为数字,则很可能永远无法显示其内容。