背景:
某考试系统公布了考试成绩,很多朋友参加了这个考试,当时手上没有他们的考试号等信息,又比较好奇大家的成绩,一时兴起就想看看有没有方法在不知道考试号的情况下查询成绩。
目的:
获得大家的考试成绩。
条件:
网站采用php开发,数据库类型未知,表结构未知
工具及手段:
google、UE、Sqlyog、SQL注入、Eclipse
前期准备:
在网站提供的查询界面中,通过在各个输入框输入特殊字符单引号发现,输入框都做了js校验,不能使用特殊字符,想绕过js校验太简单了,url传参数或者自己构造一个html页面,我选择是使用html页面,将成绩查询页面另存为html,用ue编辑html,将无关的阶段全部删除,最重要的删除js校验部分,这样就构造了一个没有校验的html页面,然后用浏览器访问页面,输出单引号等特殊字符,试试看效果,不错果然是我们想要的结果,出现了sql的错误语句。
方法步骤:
通过观察返回的结果,我们可以知道网站采用的是mysql数据库,成绩存在与一个叫做fenshu的表中,我们可以针对页面上qname字段构造sql,对应到后台为username字段,后台执行的sql语句形如:select * from fenshu where time='2010年' and class=44 and username='12' and code='11' order by id,按照查询的话应该提供待查询人的姓名、考试号才能显示成绩,但我们可以对username进行注入同时可以将后面的语句注释掉(用--注释,/*不起作用),让其执行的sql为:
select * from fenshu where time='2010年' and class=44 and username='12'-- - and code='11' order by id(在页面qname输入框中只需要输入12'-- -就可以),这样界面中就可以显示我们要查询人12的成绩了,但只提供姓名的话如果有重名的成绩就不准确了,我们可以将所有重名人的成绩都拿出来,就是在sql中加入limit语句,qname输入框中内容变为12' limit 0,1-- -
12' limit 1,1-- -
12' limit 2,1-- -
等等,以此类推,直到页面提示错误表示这个名字没有那么人重名。如果我们只是想获取几个人的成绩的话,直接通过构造sql注入获取就可以得到成绩了,这个方法就足够了。
技能提升:
在拿到几个人的成绩后,我有了新的想法,想知道每个人的名次,在想是不是可以通过这个方法将系统中所有的成绩信息都爆出来,然后将全部信息在本地建立一个数据库,这样就可以方便的做排名统计了。
如果要爆全部数据,靠人工肯定是不行的了,需要借助程序去运行,还好本人有java开发基础,立马打开eclipse准备写代码,代码的主要步骤为:
1、构造sql
要爆全部数据就不能指定用户名了,需要将qname的值设为'or 1=1 limit i,1 -- -,其中i为变量,需要从0开始循环,至于循环到多少为止,这个就要靠猜测和尝试了,不过程序运行的很快,时间不是问题,我们可以每次爆1000个,直到爆完为止;
2、发送http请求及解析返回值
将构造的url请求通过程序发送到指定网站,并对返回值进行解析,返回的结果为html页面,我们需要在程序中对html页面进行逐行解读,识别我们的关键信息,通过字符分隔获得人名、考试号、成绩的等内容;
3、信息本地入库
在本地建立mysql数据库,按照需要建立表,将程序解析后的内容插入到本地数据库中。待全部数据都导入本地之后,就可以进行各种排名查询了。
技能再提升:
有些系统不会直接返回sql错误信息,我们就需要通过别的方式或者表结构了,在此给大家简单说说,构造如下sql:
='' union select table_name,table_schema,3,4,5 from information_schema.tables where table_schema=database() limit 6,1 --
通过变更limit后的数字,可以将目标网站数据库中的所有表名爆出来。
=''union select column_name,3,4,5,6 from information_schema.columns where table_name='fenshu' limit 1,1 --
通过变更limit后面的数字,可以将目标表的所有字段名爆出来。
解决办法:
加强url参数特殊字符过滤,增加数据库执行语句的预编译和过滤。
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入技术爱好者交流群373107565,我们一起学技术!