上两节的实验都是我们对数据库有极大的权限去执行的,是一个理想化的状态。但是实际上,即使存在sql注入的漏洞,在用户操作层面的权限肯定不会是root权限。就是information_schema这个库我们无法查询,甚至union、order by等语句也无法使用;即我们无法直接查询到库、表、列等等信息。这个时候我们就需要花费多一点时间和资源去对数据库进行猜解了。
!!!一个存在sql漏洞的页面,在进行猜解的时候,我们要通过页面返回的信息进行归纳和总结来判断我们的猜解是否是正确的。(就是字典一个个尝试,正确和错误返回的结果是不同的,不是直接告诉你是正确的或者错误的;)
猜解原理
服务器给我们准备的语句是:
select * from 表 where uid=’ '; 那么我们前面说的擦入and 1=1 和 1=2就是区别正确和错误的;
那么我们插入 and 列 is null 。意味着and前面如果没有,那么后面的‘列’是空的也是什么都没有,但是正确,返回的信息肯定和‘列’不存在不一致;如图:
综上,我们至少可以判断user这个列是存在的,对于这个‘列’我们可以利用字典进行自动化的去尝试。(字典可以直接上网下载或者收集、也可以kali直接搜索column.txt这个文件)
burp猜解
这里就基本完成对列的一个猜解,我们在实际中还应该尝试更多的列文件字典去猜解,还需要细心去发现响应的特征信息,不一定就是图示的length特征。
猜表名
select * from 表 where uid=’ ’ 结合我们前面已经猜解到的列名,我们可以这样想:
相对路径和完整路径,此select语句已经指定了固定的表了,我们可以尝试完整路径进行判断。在以知的列名前面加上表的名称;所以构造: and 表.user is null (已经查到的列user),其操作和前面一模一样:
猜解到了表users;我们猜解的数据是users.user。同理,还想要往上猜解库名,可以构造db.users.user这样的数据提交;
猜解该库下其他表名
我们构造这样的语句:
' and (select count(*) from users)>0--+
计算users下的所有行(数据),判断是否大于0?实际上存在表基本上就一定有数据,所以只要存在表那么这个语句就是正确的;
方法和前面一样,在intruder下替换’表‘参数;这里直接给出结果:
猜字段内容:
有多种种方式对字段内容进行猜解,这里举例两个:
1、完全匹配:字符不小心完全符合:
select * from users where uid=' ' or user='admin '
有且仅当user(我们前面已经确认了users下存在这个表)有一个数据为admin为真,输出符合条件内容;
都为假页面无返回信息,因为什么也不查询;
2、模糊字符匹配
select * from users where uid=' ' or user like '%a% '
猜完user然后猜其对应密码:
' or user='admin' and password='5f4dcc3b5aa765d61d8327deb882cf99
密码可以使用md5密码字典如上面去不断尝试
写数据库
试想一种情况,我们前面的操作已经把账号和密码都爆出来了,但是由于密码太过复杂无法破解为明文,这又怎么办呢?这个时候不妨尝试一种可能,往数据库重新添加一下账号和密码或者修改密码 (经过加密),因为可能存在管理不严格的情况,忽略了该账号的对数据库的权限问题。
'; update users set password='修改内容' where user='admin
或!
'; INSERT INTO users (' user_id',' first_name',' last_name',' user','password','avatar') VALUES
(‘35',‘CHOU',‘JAY',‘ZJL','5f4dcc3b5aa765d61d8327deb882cf99','OK');--+
我们构造如上同时执行两条命令,所以前面会用分号隔开。
这个要说明一下,在dvwa中这条语句执行是失败的,因为不能同时运行两条查询语句,这并不是真的不能而是代码编写者编写出了问题;甚至在有些数据库客户端也是如此,但是在数据库直接交互的命令行下是可以执行的。实际上这条语句没有任何问题,凡事也不一定能成功总要多试试。
还比如:
'; DROP TABLE users; --+ 删除表
总之,sql注入没有上面通用方法。想有很好的了解,就需要非常全面的了解各种数据库;