Sqli-Labs 是一个印度人的开源项目平台。里面包含了基本的各种注入类型,同时又有get和post类型,以及一些基本的绕过学习。
项目地址:https://github.com/Audi-1/sqli-labs
Lesson-1 #Get - Error based - Single quotes - String (基于错误的GET单引号字符型注入)
运行测试环境:http://localhost/sqli-labs-master/Less-1/
输入ID参数1:http://localhost/sqli-labs-master/Less-1/?id=1,返回正常,继续测试陆续输入2,3,4,5,6....,均返回正常,而且随着参数ID值的改变,页面返回的name和Password的值也会出现不同
根据上面情况,推测出数据库操作指令:
【SELECT name,Password FROM TABLE WHERE ID=INPUT_ID】
试着来让其报错,报错的方法通常有 单引号 and1=1 and 1=2 双引号 反斜杠 注释 等等
我输入单引号进行测试:
【http://localhost/sqli-labs-master/Less-1/?id=1%27】
网站报出错误信息:
【You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1】
根据报错信息可以推测出更加详细的SQL语句:
由错误提示【' ' 1' ' LIMIT 0,1 '】推测的SQL语句存在单引号
【SELECT name,Password FROM TABLE WHERE ID='$ID'】
发现报了SQL语句的语法错误,应该存在SQL注入,由于没有过滤单引号,我们可以通过闭合单引号来构造payload:
利用order by测试数据库中的列数:
【http://localhost/sqli-labs-master/Less-1/?id=1' order by 3 #】
发现当3的时候不报错,4的时候报错,知道数据库表中有三个字段
直接使用UNION语句联合查询,但是发现只出现一行?!
【http://localhost/sqli-labs-master/Less-1/?id=1' union select 1,2,3 #】
So,查看网站源代码:
源码中mysql_fetch_array()被调用了一次,mysql_fetch_array()函数从结果集合中取出一行数据输出,导致不管怎么查询只能查询第一行数据。
mysql_fetch_array(data,array_type)
data:可选。规定要使用的数据指针。该数据指针是 mysql_query() 函数产生的结果。
array_type:可选。规定返回哪种结果。可能的值:
MYSQL_ASSOC - 关联数组
MYSQL_NUM - 数字数组
MYSQL_BOTH - 默认。同时产生关联和数字数组
如果我传入的ID值为非负数(负数或者0),浮点数字符或者字符串呢?
看到只有第二列和第三列的结果显示在网页上。
那我们就根据第二列或者第三列来查询数据库的信息:
user():返回当前数据库连接使用的用户
database():返回当前数据库连接使用的数据库
version():返回当前数据库的版本
【http://localhost/sqli-labs-master/Less-1/?id=0'union select 1,version(),3#】
也可以使用数据库的连接函数来查询多条信息,常用concat和concat_ws函数
char码值对应列表(附)
Char("32") 空格 SPACE Char("33") ! Char("34")
"Char("35") # Char("36") $ Char("37") %
Char("38") & Char("39") ’ Char("40") (
Char("41") ) Char("42") * Char("43") +
Char("44") , Char("45") - Char("46") .
Char("47") / Char("58") : Char("59");
Char("60") < Char("61") = Char("62")>
Char("63") ? Char("64") @
CONCAT()函数用于将多个字符串连接成一个字符串
CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。
如果所有参数均为非二进制字符串,则结果为非二进制字符串。
如果自变量中含有任一二进制字符串,则结果为一个二进制字符串。
一个数字参数被转化为与之相等的二进制字符串格式;若要避免这种情况,可使用显式类型 cast。
查询users表中的列名:
写一个获取用户名和密码的脚本(基于POCsuite):
验证测试(爆出用户名密码):
最后用注入神器SQLMAP来验证一下,结果如下:
SQL Injection:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。