如何使 SQL INSERT 注入在 SQLite 上工作

How to make the SQL Injection on INSERT work on SQLite

我不知道如何使这个 SQL 注入在 SQLite 中工作。我在 Python 中使用一个连接到数据库并插入字符串的函数。

我的“database.db”有两个 table:“反馈”和“用户”。
反馈 table 有 1 列:消息。
用户 table 有 2 列:用户名和密码。

def send_feedback(feedback):
    conn = sqlite3.connect("database.db")
    curs = conn.cursor()
    curs.execute("INSERT INTO feedback VALUES ('%s')" % (feedback))
    print(curs.fetchall())
    conn.close()

我知道执行函数允许我对数据库进行单个查询,所以我不能使用“;”到 进行多个查询。

我试过的是让字符串看起来像这样:

a') SELECT password FROM users --
feedback = "INSERT INTO feedback VALUES ('a') SELECT password FROM users --')"

但这给了我以下错误:

sqlite3.OperationalError: near "SELECT": syntax error

所以我尝试使用 UNION 命令:

a') UNION SELECT password FROM users --  
feedback = "INSERT INTO feedback VALUES ('a') UNION SELECT password FROM users --')"

这个有效,但是 fetchall 函数 returns 是一个空列表。

大多数 SQL 注入对犯罪者没有任何用处,只是一个语法错误。

例如,将字符串“我不满意”传递给此反馈函数,额外的 ' 字符将导致引号不平衡,这将导致一个错误,导致 INSERT 失败。

sqlite3.OperationalError: near "m": syntax error

这在技术上是 SQL 注入。 插入到查询中的内容影响了 SQL 语句的语法。就这样。它不一定会导致成功的“碟中谍”类型的渗透。

除了导致错误之外,我想不出一种方法来利用您展示的 INSERT 语句使其做一些聪明的事情。

您不能将 INSERT 更改为生成结果集的 SELECT。即使您尝试在第二个 SQL 查询之后注入一个分号,您也只会得到 sqlite3.Warning: You can only execute one statement at a time

您在上面的第一次尝试导致语法错误,因为您将 VALUES 子句和 SELECT 作为要插入的数据源。您可以在 SQL 语法中使用其中之一,但不能同时使用两者。参见 https://www.sqlite.org/lang_insert.html

您可能已经知道如何使代码安全,因此不安全的内容甚至不会导致语法错误。但我会把它包括给其他读者:

curs.execute("INSERT INTO feedback VALUES (?)", (feedback,))

你可以做到,例如得到table名字

a' || (SELECT tbl_name FROM sqlite_master  WHERE type='table' and tbl_name NOT like 'sqlite_%'))-- -