开发者学堂课程【网络安全攻防 - Web渗透测试:SQL 注入攻击_4】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/630/detail/9907
SQL 注入攻击_4
内容介绍
一、SQL 注入流程
二、手动注入实战
一、SQL 注入流程
1、判断是否有 SQL 注入漏洞;
2、判断操作系统、数据库和 web 应用的类型;
3、获取数据库信息,包括管理员信息及拖库;
4、加密信息破解,sqlmap 可自动破解;
5、提升权限,获得 sql-shell、os-shell、登录应用后台;
注入方式分为手动和自动,落脚点都会在自动注入,任何工具都无法跟 sqlmap 对比。
二、手动注入实战
1、基于错误的注入
(1)错误注入的思路是通过构造特殊的 sq1语句,根据得到的错误信息,确认 sq1注入点;通过数据库报错信息,也可以探测到数据库的类型和其它有用信息。通过输入单引号,触发数据库异常,通过异常日志诊断数据库类型,例如这里是 MySQL 数据库。
(2)// Retrieve data
$id = $. GET['id'];
$getid = "SELECT first_ name, last_ nane FROM users WHERE user_ id = '$id'";
没有对输入做相应的安全过滤:直接将获取的值代入数据库语句。
(3)操作:点击 SQL injection,登陆。
SQL 注入的方式,一种是错误的注入,一种是基于布尔的注入,基于 UNION 注入,基于时间的盲注,比较常见的几种方式,错误的注入是比如输入1,输入2,输入3,代进去就是id等于1,等于2,等于3。
当前面 SQL 所使用的库为 dvwa
搜索框正常输入1
但是输一个单引号,单引号就是让它报语法错误,说明它能够接受单引号,它要是不能接受单引号,它就不会报语法错误了,如果输一个单引号,它直接过滤掉,就不会把单引号带到 SQL 语句里面,一会 SQL 中的构造语句就要通过单引号的方式来构造,如果单引号不识别或者不用,那就没办法进行构造,所以单引号是先试一下它有没有反应,如果用单引号一试进行报错,如果报的是语法错误,这就明确说明它把单引号给用上了,因为一个单引号肯定是语法错误,肯定不会有正确的结果,错误的注入,第一试探性的看看它有没有报错,或者是看它有没有返回一些 mySQL 的版本,这个是靶机,它显示的 mySQL 的版本,在生产当中可能它不会有显示,但是它可能会报错,只要报错就说明有注入的可能性,有注入点。如果报的是输入错误,那就说明它给过滤掉了,或者会说你现在正尝试对我们网站进行攻击,请停止此行为,那说明也被过滤了,还警告一下
(4)SQL 注入语句解析:
mysql> select first_ name,last_ name from dvwa. users ;
mysql> select first_ name,last name from dvwa. users where user id=' 1' ;
这个是原始语句,讲的时候会把它对应的翻译成这种语句,它操作的就是 dvwa. users 的这个表,输个1,正常是返回first_ name last_ name
+- -----------+----------·+
first_ name last_ name
+-----------·+---------··+
Admin admin
+- -----------+-----------+
1 row in set (0.00 sec )
mysql>
(5)刚才输入了一个单引号,页面就报错了。
You have an error in your SQL syntax;checkthemanualthatcorrespondstoyourMySQLserverversion for the right syntax to use near ·····at line 1
就相当于输了一个单引号,从这个角度来讲,它就报少了一个单引号,但是本身就少了一个,语法就会出错。
SQL 注入语句解析:
mysql> select first_ name,last_ name from dvwa»users where user_ id= "" "
所以错误的注入不是为了注入,是为了试探它,判断它这个位置是否是有注入点,有注入漏洞,所以别指望单引号能获得什么信息。
2、基于布尔的注入
(1)布尔逻辑注入的思路是闭合 SQL 语句、构造 or 和 and 逻辑语句、注释多余的代码。
所有输入的都转换成了 SQL 语句。
可以查到表中六条记录。
(2)原始语句:
mysql> select first_ name,last_ name from dvwa . usens where user_ id- ' '
这是原来的语句,首先输了一个‘or 1=1 --yangge,人家东西改变不了,整个是刚才输入的东西,第一个单引号是闭合前面的条件的,闭合 user_ id- ' ',select first_ name,last_ name from dvwa . usens where user_ id- ' ' or 1=1这个语句就很清晰了,后面不输都可以,第一个单引号是闭合前面的条件的,自己加了一个布尔的东西 or 1=1 ,后面--是注释后面的一切,写什么都不会有用,包括写的 yangge,单引号,分号全被注释,如果输入分号,是以下这个效果:
+------------+---·------·+
first_ name last_ name
+- ---·----···+--····--···+
Admin admin
Gordon Brown
Hack Me
Pablo Picasso
Bob Smith
user user
+-----------·+-----·-··--+
6 rows in set (0.00 sec )
这个分号在页面上它最后加上去的,不用管,这个sql语句在转化完之后会给加分号的,在执行的时候,模拟的效果跟它不是完全的一样,你只要构造语句即可。
(3)SQL 注入语句解析:’or 1-1 --‘
mysq1> select first_ name, last_ name-from dvwa . users where user_ id='' or 1=1 --‘ ‘
后面跟的是一个值,这个单引号或者写成其他字符串都是一个意思,这个只不过是写了两个单引号,让你认为它俩是一对,它俩最后都会被注释掉。
输入’or 1=1 -- yangge。
(4)说明:
① 第一个’用于闭合前面的条件,不能输一个条件让它报错,要让语句是保持正确的。
② or 1=1为真的条件。
③ --将注释后面的所有语句。
比如444' or2=2- YY,444带给前面的,闭合它,加一个条件,后面注释,最后的结果一样。但是这样做只能得到表中的所有记录,别的得不到,这种做法只能受制于原来 SQL 语句的表和字段,原来是查是三个字段就只能得到三个字段,查哪个表得到哪个表,但是能得到这个表里面的所有信息,如果不是所有信息,但只是也是相对的信息,紧接着是加上 UNION 联合查询。如果后面加 UNION 就意味着要加一条 sql 语句,因为要查别的库别的表,第一大问题就是要知道哪个库,哪个表,哪个字段,要是不知道,不借助 information 就是不知道。别的都不可信。
3、基于 UNION 注入
(1)UNION 要结合前面的 information,就是把前面人工写的那些对 information 的查询加到联合查询上面,但是还要顾及到前后的字段数要一致。
(2)UNION 语句用于联合前面的 SELECT 查询语句,合并查询更多信息; 一般通过错误和布尔注入确认注入点之后,便开始通过 union 语句来获取有效信息。但是 union 第一步要猜字段。
比如现在要联合查询,但是不知道有多少字段,加个单引号是闭合前面条件。
① //猜测数据列数
‘union select 1 -- 这个语句语法理论上不会出错,只不过字段如果数不匹配会报错。可能不会报这么直白,因为有些网站不会这么报。
’union select 1,2 -- * 出现的结果没什么意义,但是知道了有两个字段,以后组织语句的时候就两个字段,少了可以加,多了怎么办?现在前面是两个字段,后面最多能插两个字段,如果后面只有一个字段怎么办?补一个,如果后面五个字段呢?那就可以把多个字段合在一起,做字段的拼接,拼成两个即可,少了就凑,多了就合在一起。
’
union select 1,2,3 --
‘
union select 1,2,3,4 -- '
① SQL注入语句解析:
mysql> select first_ name,last_ name from dvwa.users where user_ id='' union select 1 --
‘
真正的语句执行就是这样。
mysql> select first_ name ,last_ name from dvwa. users where user_ _id='' union select1,2-- "'
② //获得当前数据库及用户信息
union select version(), database() --
‘
'union select user()
,
database() -- '
mysql>selectfirst_name,last_namefromdvwa.userswhereuser__id=''unionselectversion(),database() --
”
'
操作:输入 select first_ name,last_ name from dvwa.users where user_ id=''union select user( ), database()
select user( )表示当前用户,database()获得当前库,输在以下位置是一样的,获得库和当前用户。