这是一个有效的 SQL 注入。服务器端查询字符串是什么样的?

信息安全 sql注入 注射 sql服务器 微软
2021-08-21 14:23:28

这个问题是关于一个更大的学校作业中的一个小细节。我已经为这个小问题苦苦挣扎太久了。

ABCTF 安排了今年早些时候举行的夺旗比赛。这场比赛中的一个问题是 SQL 注入。这是任务描述的 URL ,这是要注入的登录表单的 URL 。这个问题有一个已发布的解决方案,它看起来像这样:

用户名:-1' union select 1,1,1,1 #

密码:1

我需要弄清楚后端查询字符串可能是什么样子。最简单、最天真的假设是

String query = "SELECT FROM user WHERE username = '" + inputA + "' AND password = '" + inputB + "';";
execute(query);

但这会产生

String query = "SELECT FROM users WHERE username = '-1' union select 1,1,1,1 #' AND password = '1';";
execute(query);

最明显的问题是报价不平衡。此外,我不明白 SELECT 语句会产生什么输出。据我了解,“#”字符用于表示 MS SQL Server 中的临时表,例如“#temporary_table”。我也玩过其他简单的陈述,但没有任何意义。

有没有人知道后端查询的样子任何建议表示赞赏。

2个回答

在 MySQL 中,#符号可以用作注释标记。 评论中的引号不必平衡。

并非所有 SQL 实例都在 Microsoft 数据库上运行。

该链接指出该解决方案涉及通过联合添加一个全新的假行,其中每个值都是 1。作为用户名的 -1 试图确保查询不返回任何有效数据,因为服务器端语言通常只比较第一个排。下面的代码就是一个例子。

password = execute("SELECT password FROM users WHERE username = '{$username}'");
if( password != $password ) fail();
pass();

这导致

password = execute("SELECT password FROM users WHERE username = '-1' union select 1,1,1,1 #'");
// no username called -1 means that the only row returned is the artificial row, so password = 1
if( password != 1 ) fail();
pass();

请记住,此代码有数百万种工作方式,从仅 SQL 到 Web 应用程序中的漏洞。但是,我发现这种方法最现实。