这个 SQLi 语句是如何工作的?

信息安全 sql注入 mysql
2021-09-11 14:11:01

嘿,我正在尝试hacker101 CTF,我对这些东西还是很陌生

我试图理解的标志的 CTF 答案是https://github.com/testerting/hacker101-ctf/tree/master/micro-cms_v2/flag0

'当您在用户名字段中输入 单个时,您得到的错误的重要部分if cur.execute('SELECT password FROM admins WHERE username=\'%s\'' % request.form['username'].replace('%', '%%')) == 0:

该标志的解决方案是将其输入到用户名字段中

' UNION SELECT '123' AS password#

这是我不明白的说法。我用谷歌搜索了“SQL AS 关键字”,我得到了一些类似的东西,“as 关键字是列或表的别名”但是'123'是一个字符串,对吗?然后我很沮丧,然后转到我不理解该语句的另一件事,即密码末尾的#。然后我也用谷歌搜索了“sql磅符号”,我得到它正在引用一个临时表,这又是一个,我真的不明白..

谢谢!

2个回答

输入时执行的SQL语句' UNION SELECT '123' AS password#为:

SELECT password FROM admins WHERE username='' UNION SELECT '123' AS password#'

井号在那里,因此'原始格式字符串的结尾(现在在查询末尾尾随)不会触发语法错误。这是 SQL 语言的 MySQL 扩展,不能在许多其他 SQL 服务器上工作,例如在 PostgreSQL 上。那里--需要标准。

UNION关键字组合了来自两个或多个SELECT语句的结果集(通过将它们与关键字链接UNION第一个结果 fromSELECT password FROM admins WHERE username=''是空的,除非有一行的NULL用户名是空的(但不是 )。第二个是来自 的结果集SELECT '123' AS password,它是一个单行表,其中有一列称为passwordAS password不是绝对必要的,因为 MySQL 在执行联合时使用第一条语句中的列名。

在 SQL 中,选择类似常量'123'或类似常量表达式LENGTH('123')会将它们的值复制到结果集的行上。如果查询中没有任何内容产生多于一行,则结果包含一行。

在 MySQL 中,#表示注释的开始。这意味着该行的其余部分不会被解析为 SQL。这是 SQL 注入中的一种常用技术,用于强制忽略注入的 SQL 之后的尾随 SQL。

在这种情况下,通过' UNION SELECT '123' AS password#输入用户名字段,它会执行以下命令:

SELECT password FROM admins WHERE username='' UNION SELECT '123' AS password

这将返回一行以“123”作为密码列(无论提供的用户名如何),允许您使用任何用户名和密码“123”登录。