我有一个正在尝试“破解”的网络应用程序。有一个登录页面需要输入用户名和密码。假设我有一个表 Auser
,它在 MySQL 中存储用户名信息。
当我输入凭据后点击“登录”时,它会执行以下代码行:
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
现在,我知道不使用 preparedStatement
会使 SQL 查询容易受到 SQL 注入(inject)的攻击,我想执行这样的特技。我创建了一个名为 test
的虚拟表,以便能够通过注入(inject)命令删除该表。
我尝试了各种方法,例如我的用户名输入(root 是用户名):
root` DROP TABLE test;
但它不起作用。有没有办法让我的注入(inject)成功?
更新:
只是额外信息,我的用户名列是 VARCHAR(255)
,我获取用户名的方法如下:
public Auser get(String username, boolean moreInfo) {
try {
Auser u = null;
String sql = "select object(o) from Auser as o where ausername='" + username + "'";
List resList = em.createQuery(sql).getResultList();
if (resList == null) { // null check for sql query / library error
msg = CoreUtil.wrapMsg(CoreUtil.FUNC_ERROR,
this.getClass().getName(), "get[" + username + "]", "query error AUSER.");
} else if (resList.isEmpty()) {
msg = "User " + username + " not found.";
} else {
u = (Auser) resList.get(0);
}
return u;
} catch (Exception e) {
msg = CoreUtil.wrapMsg(CoreUtil.FUNC_ERROR,
this.getClass().getName(), "get[" + username + "]", e.getMessage());
return null;
}
}
似乎每个解决方案,我尝试不断抛出IllegalArgumetnException
并且表仍然存在。我只是想利用我的程序的漏洞,它可以是任何类型的注入(inject),无论是删除表,返回所有用户信息等
最佳答案
EntityManager 内置了一些(非常)基本的保护,不会在同一 SQL 语句中运行多个命令。
这将保护你免受罗伯特的伤害”);下降表学生; --
,但它无法防止攻击者尝试扩展/更改正在运行的一个查询。
例如,在您的代码中,攻击者可以通过输入用户名 ' OR 1 = 1 --
来获取其他用户的详细信息;这将使 SQL 字符串被执行
select object(o) from Auser as o where ausername='' OR 1 = 1 --'
这将选择表中的每个用户(请注意,输入末尾的 --
将注释掉注入(inject)代码后的所有内容),并且您的方法将返回表中的第一个用户结果列表 这可能会向攻击者提供他们不应访问的其他用户的详细信息。如果第一个帐户是管理员帐户,那么他们也可能拥有不应拥有的访问权限。
攻击者还可以通过这种方式了解表的结构 - 他们可以尝试诸如 ' 和 IS_ADMIN = IS_ADMIN --
或 ' OR ID = 0 --
之类的字符串>。如果他们尝试了足够多的这些(并且这样的攻击可以很容易地自动化),那么当查询不抛出错误时,他们将找到有效的列名。然后,他们可能会进行更有针对性的注入(inject)攻击,以获得对管理员帐户的访问权限。
他们还可能从失败尝试返回的错误消息中了解一些信息,例如数据库平台,这可以使攻击变得更容易。
关于java-如何执行 SQL 注入(inject)以进行测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55571337/