Less 24(二次注入)


前言

根据题目

Second Order injections
Real treat
Stored injections

我们晓得本次的知识点是二次注入。
那么再闯关之前,我们需要先了解一下二次注入。


1. 二次注入的原理

1.1 个人理解

二次注入(存储型注入),这种手法所利用的原理是:在网站处理用户提交的数据的时候,只是将某些敏感字符进行了转义。因而使得用户第一次提交的时候不会被当做代码执行。但是这些数据存入数据库的时候却没有转义,而网站程序默认数据库中的数据都是安全的,当网站程序第二次调用刚才存储的脏数据的时候,则不会转义使用而是直接使用,因此就会达到注入的效果。

注意两点:

  1. 网站会将数据原封不动的存入数据库中。
  2. 网站会直接调用数据库中的数据而不会对其进行检测等操作。(信任数据库中的数据)

1.2 Example

举一个例子:
某个网站,在处理注册登录的时候,对输入的用户名中的敏感字符执行转义操作,进行完对应的SQL查询后再将数据存入数据库中。比如输入了admin' #,网站则会将'#转义后进行SQL查询,但是最后存入数据库中的结果仍然是admin' #(并没有转义存储)。

这样一来,由于第一次存在转义的机制,我们无法通过第一次SQL的构造就实现注入,但是此时目标数据库中已经存在了SQL注入的语句,我们只要想办法让网站自己去调用这条数据,那么就会造成二次注入。

假设成功登录后,在修改密码时网站会自动从数据库中提取你的用户名,由于网站默认数据库中的数据都是安全的,因此当提取数据库中的用户名admin' #的时候,并不会进行转义操作,而是直接拼接到SQL语句中执行。假设执行如下语句:

UPDATE users SET PASSWORD='$pass' WHERE username='$username' and password='$curr_pass' 

这样,当我们修改密码的时候,网站则会直接提取数据库中的admin' #拼接到SQL中执行。

就会变成

UPDATE users SET PASSWORD='$pass' WHERE username='admin' #' and password='$curr_pass'

那么真正奏效的语句则是

UPDATE users SET PASSWORD='$pass' WHERE username='admin' 

此时我们的用户是admin' #但是却成功的修改了admin账户的密码。这样我们就可以登录admin账户。


2. 题目分析

本次题目的页面比较多,通过分析我们列举如下(这里将可能存在注入点的页面加粗):

  • 主页(登录页面): 可输入login_userlogin_password
  • 忘记密码界面:图片一张。
  • 用户注册界面:可输入username, password, re_password三个字段。
  • 登录界面:可修改密码。
  • 登录失败:图片一张。

通过上述分析,发现可能存在注入点的界面有三个

  1. 主页
  2. 注册页
  3. 登录成功页(修改密码)

2.1 主页

看一下主页中登录功能的相关代码

$username = mysql_real_escape_string($_POST["login_user"]);
$password = mysql_real_escape_string($_POST["login_password"]);
 
$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";

在这里可以看到在登陆的时候网站会接收用户输入的账号和密码,然后调用mysql_real_excape_string()处理。

mysql_real_excape_string()的作用就是转义字符串中的特殊字符:

  • \x00
  • \n
  • \r
  • \
  • "
  • \x1a

这样我们如果输入一个admin' #那么执行的时候则是select * from users where username ='admin\' #'。转义会将单引号当做内容进行查询而使得闭合作用失效。因此在这个页面我们无法注入。

2.2 注册页面

我们来看一下注册页面相关的代码

$username=  mysql_escape_string($_POST['username']) ;
$pass= mysql_escape_string($_POST['password']);
$re_pass= mysql_escape_string($_POST['re_password']);

$sql = "insert into users ( username, password) values(\"$username\", \"$pass\")";

这里将和数据库操作有关的放在上面。

在注册这里,首先是利用mysql_escape_string对用户输入的数据进行转义。

这里我们输入一个test' #那么后台获取到的$username就是test\' #,然后同样处理两次输入的密码并核对,最后通过insert将账号和对应的密码插入表中。

而最终的插入SQL的语句则变成了:

insert into users ( username, password) values("test\' #", "123456");

在SQL执行的过程中,单个转义符号是透明的(相当于告诉SQL我后面的单引号是一个插入的值而不是字符串的闭合标志),也就是说最终存储在
数据库中的数据是test' #。这就对应了第一点网站会将数据原封不动的存入数据库中。

综上所述,此页面是存在二次注入漏洞的。我们可以利用这个漏洞构造SQL注入语句然后存储于服务器数据库中。当服务器上的程序二次调用此数据的时候,就可能出现问题。

2.3 登录成功界面(修改密码)

看一下相关代码

$username= $_SESSION["username"];
$curr_pass= mysql_real_escape_string($_POST['current_password']);
$pass= mysql_real_escape_string($_POST['password']);
$re_pass= mysql_real_escape_string($_POST['re_password']);

$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

这里由于登录成功,因此程序直接从后台数据库中获取账户信息。那么获取到的数据就是刚才我们精心制作的“间谍”了。然后直接将这个username拼接到SQL中去执行。我们人工复现一下这个过程。

首先获取$username="test' #",然后执行SQL

$sql = "UPDATE users SET PASSWORD='$pass' where username='test' #' and password='$curr_pass' ";

这样一来,#后面的语句都被注释掉了。那么这条语句改的则是test账户的密码而不是test' #的密码。

这就对应了第二点:网站会直接调用数据库中的数据而不会对其进行检测等操作。

综上所述:我们利用注册界面先将被污染的数据存入数据库中,然后利用登录成功后的修改密码功能二次利用污染数据,造成最终的SQL注入。


3. 注入过程

如果你认真的看完了上面的思路整理。相信你一定可以自己实现后面的注入了。

首先看一下数据库中原本的用户信息:
在这里插入图片描述
这里注意一下admin账户的密码是admin'


然后,首先我们进入用户注册界面,构造一个可以注入的用户名:
用户名:admin' #
密码: 123456
注册后再看一下数据库
在这里插入图片描述
可以看到刚才注册的数据已经进去了,并且是原封不动的存入数据库了。

那么此时我们登进去看一下
在这里插入图片描述
可以看到我们的用户名是admin' #,然后我们将密码改成654321
在这里插入图片描述
再次观察数据表,就可以发现,最终是admin账户的密码改为654321而我们自己创建的admin' #的密码没有改变。原理上面已经说的很清楚了。

那么我们来登录一下admin账户试一下
在这里插入图片描述
成功了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值