通过 Python 在 SQL 查询中使用通配符和特殊字符

时间:2021-01-05 18:10:04

标签: python mysql

对 Python 还是有点陌生​​,请耐心等待。我正在编写一个 Python 脚本来对多个 MySQL 数据库进行审计,以专门使用 value 列中的目录提取变量信息。通过 MySQL 进行的简单查询是 SHOW VARIABLES WHERE VALUE LIKE '/%';,这是我正在尝试转换并在此脚本中工作的内容。第一个问题似乎是声明 % 通配符,因为 Python 认为它是一个字符串,但最重要的是声明 /,因为我正在寻找带有目录的任何变量。

这是有问题的脚本部分,后面是错误:

def dbQuery(server,username,password):
    conn = MySQLdb.connect(host=server, user=username, passwd=password, db="")
    cursor = conn.cursor(MySQLdb.cursors.DictCursor)
    cursor.execute("SHOW VARIABLES WHERE VALUE LIKE $s", ('%%/%',))
    result = cursor.fetchall()
    #Cleanup
    cursor.close()
    conn.close()
Traceback (most recent call last):
  File "./check-mysql-var.py", line 118, in <module>
    main()
  File "./check-mysql-var.py", line 109, in main
    ret = checkVar(options.server,uname,mysqlPass)
  File "./check-mysql-var.py", line 47, in checkVar
    result = dbQuery(server,username,password)
  File "./check-mysql-var.py", line 39, in dbQuery
    cursor.execute("SHOW VARIABLES WHERE VALUE LIKE $s", ('%%/%',))
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 187, in execute
    query = query % tuple([db.literal(item) for item in args])
TypeError: not all arguments converted during string formatting

关于声明通配符和字符有什么问题的想法?

编辑 1:

使用来自@Noah 的原始字符串信息,我对 '/%' 的变量进行了调整,但它似乎没有改变任何错误。我用 Skulpt 测试了一个简单的变量打印,它的格式正确,但我还没有到那里。我知道这会使我的脚本容易受到攻击,但我在短期内将查询拆分为一个单独的变量进行测试,但没有看到任何变化:

    v = "\t'/%'\n"
    query = """SHOW VARIABLES WHERE VALUE LIKE $s"""
    cursor.execute(query, (v))

编辑 2:

在它上面睡了一会后,我想我离它更近了,但仍然错过了一些东西。我稍微改变了变量并得到了结果,但不是我所期望的。所以我假设我很接近但仍然在某个地方遗漏了一部分。变化如下:

    v = "'/%\'"
    cursor.execute("SHOW VARIABLES WHERE VALUE LIKE %s", (v, ))

我知道使用 Bash 脚本,您可以使用 bash -x 运行它们以进行调试并查看其中每个命令的输出。你能用 Python 做类似的事情吗,如果可以,怎么做?这可能会帮助我了解脚本在代替 %s 的位置。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,它不起作用的原因是因为 %s 是方法 cursor.execute() 格式化变量发送的数据的一种方式。它根据 MySQL 决定发送的数据应该是 string、int 或任何其他类型。因此,如果您有一个变量 var='hello world' 并想将其发送到 cursor.execute(),您需要编写

var = 'hello world'
cursor.execute("SHOW VARIABLES WHERE VALUE LIKE %s;", (var))
result = cursor.fetchall()
#Cleanup
cursor.close()
conn.close()

这会检查输入是否应该是字符串,

希望我回答了你的问题。

答案 1 :(得分:0)

我能够解决我的问题。事实证明,整个脚本中发生的一些事情导致了我的问题:

  • 第一,由于我试图最初声明通配符变量的方式,它继续干扰。我从另一个来源得到建议,使用 % 的 ASCII 标识符转换。它需要声明更多的变量,但我确实让它工作了:
def dbQuery(server,username,password):
    conn = MySQLdb.connect(host=server, user=username, passwd=password, db="")
    cursor = conn.cursor(MySQLdb.cursors.DictCursor)
    v = chr(37)
    v2 = '/'
    v3 = v2 + v
    cursor.execute("SHOW VARIABLES WHERE VALUE LIKE %s", (v3, ))
    result = cursor.fetchall()
    #Cleanup
    cursor.close()
    conn.close()
    return result
  • 2nd,我在定义的末尾遗漏了一个 return result(见上文),所以结果没有通过脚本的其余部分继续执行,从而触发了我后来设置的一些失败条件