SQL注入一次完整的利用information_schema注入过程 参考文献: 《sql注入攻击与防御》 使用平台:pikachu漏洞练习平台 在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。 一个严重的SQL注入漏洞,可能会直接导致一家公司破产! SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。 本文将从web程序的基本原理、理解SQL注入、找到SQL注入、开始SQL注入、利用information-schema注入进行一次完整的入侵过程,这几个小结来进行详细的介绍。 0x00 理解web应用的工作原理 在日常生活中,我们会用到很多web应用,来服务于我们的日常生活,随着人们生活质量的提高,web应用的形式也越来越多,但是大部分的web应用有一点是相同的,就是他们都是他们都具有交互性并且多半是数据库驱动的,在互联网中,用数据库驱动的web应用非常多,他们通常含有一个后台数据库以及很多页面,这些页面包含了利用某种编程语言来写成的服务器端脚本,这些脚本能够用于web页面与用户进行交互时来从数据库中提取特定的数据。一般的web应用通常分三层,分别是表示层、逻辑层、储存层。下面我们介绍一下这三层以及交互方式。 表示层是一个web应用的最高层,词如其意,它的主要功能是将该web应用的具体功能以及信息呈现给用户,还可以与其他层进行交互,逻辑层(中间层)是用来处理细节以达到控制应用的目的,存储层包括数据库服务器,用来进行的信息的检索和存贮。通常的交互方式就是表示层向中间层发出请求,中间层通过查询、检索存储层,获取信息来响应该请求。这就是一次完成的交互过程。三层架构有一个基本原则:表示层不能直接于数据层通信。在三层架构中,所有通信必须都通过中间层。 1x00理解SQL注入 前面讲了那么多,那究竟什莫是SQL注入呢? 其实所谓的SQL注入就是构造SQL语句并且将他们插入到输入参数中的攻击,然后将这些参数传递给后台的SQL服务器加以解析并执行。这里我用一个最基本的数字型注入演示SQL注入。 例子: 对于一个基本的查询页面时这样的
我们输入一个1试一试 结果是hello,_用户名_ __email_ 这里可以看出查询了两个字段 SQL语句构造应该是:select 字段1,字段2 from 表 where id =1 那我们如何获得表的其他数据呢?(爆表) 这里就可以构造payload了1 or 1=1 (在SQL中or是如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。1=1是永久返回为真,就是where 后面输入的值永远为真,也就可以将表中所有内容给遍历出来了) 因为是post方法,我们使用hackbar进行post提交
这样一次完整的SQL注入就完成了 2x00找到SQL注入 由于我们很难访问到应用的源代码,不知道设计者如何设计的,因此我们需要找到SQL注入,需要借助推理进行测试。借助推理进行测试的基本原理原理就是:向服务器发送请求,然后检测查看其中的异常。 2x01通过SQL错误来找到SQL注入 在靶场中我们可以通过看源码知道这个web应用的构造,但是在生活中,我们绝大多数碰到的是不开源的web应用,我们对于内部构造是完全不清楚的,这样我们如何进行SQL注入呢?我们往往采用一种让SQL报错的方式来猜测内部构造,以达到找到注入点的目的,这次我们使用字符型注入来为大家演示什莫是基于报错的SQL注入的查找方式。 例子:
对于字符型的注入,对于这类需要符号修饰的我们构造payload原则是:闭合测试、构造合法SQL、欺骗后台,基于以上三个原则,我们的payload就是这样的:xxx (符号闭合) or 1=1(注释)。 但是,首先还是一个输入框,首先我们不知道输入的是字符还是数字,我们就可以用报错机制来判断出来,正常SQL中字符和数字的区别是数字不用’’或者””来修饰,而字符需要修饰,我们就需要判断两次,第一:这个输入框是数字型的还是字符型的。第二:如果是字符型的话它是“”还是‘‘修饰的
这个错误的意思是列名不存在,从这个错误我们就知道了,SQL服务器认为这个值不是一个数字,那末就是一个列,然后SQL就去寻找这个列,然后当然找不到了,然后就返回报错了,这里我们就可以判断出应该输入一个什莫样的类型 然后知道什莫类型之后我们判断是“”还是‘’
查询后是这个画面
失败了,这个表示这个双引号并没有进入到数据库服务器里面,也就是存储层,我们再试一个单引号
欸,报错了,但是这是一个好消息说明已经进入到了SQL服务器中,说明存在注入点,下面可以开始注入了,payload构造试这样:xxx (符号闭合) or 1=1(注释)现在知道该用什莫符号进行闭合了,然后解释一下我们为什莫要注释,每当我们传递一个值到SQL构造语句中的时候,如果传递的一个值是需要符号修饰的,那末SQL语句会自带一个符号去进行闭合,例如:传值为a,到SQL语句中就会使这样:select xxx,xxx from xxx where id=’a’。那两个单引号就是SQL构造语句中用来进行参数闭合的,简单的说就是,只要你输入一个需要符号修饰的词语,后台就会自动给它加一个修饰符号,这也就是我们为什莫要把前面进行符号闭合,但是后面就会多了一个‘ 符号,我们直接注释掉就好了。 同样的方法,利用order by 可以猜测有几个字段,道理相同,这里就不赘述了。 3x00利用information_schema进行一次注入进行一次完整的入侵过程 3x01 了解什莫是information_schema information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。 也就是说information_schma可以查到你的所有的搭建的数据库名、表名和列的数据类型,在一切条件未知的情况下,存在注入点的话我们可以直接尝试对information_schema进行访问,从而获得更多的信息。 例如SCHEMATA:提供了当前MySQL实例中所有数据库的信息 TABLES:所有数据库表的信息 CONLUMNS:提供了列信息 3x02 union联合注入 既然要从一个信息数据库开始注入,也就是另外一个数据库,我们就不能在当前的数据库下进行查询,但是当前数据库查询下还存在一个注入点,所以说如何才能同时查询两次呢?这个时候我们就可以用到union联合注入了。 首先我们了解一下什莫是union union的作用是将两个或多个select语句查询语句结果合并起来 1.UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔 2. UNION中的每个查询的列数(字段数)必须相同 3. UNION会从查询结果集中自动去除了重复行 例子:主查询: select username,password form member where name=“zero“ (union查询)union select id,password form member where id=1 例子构造 payload:xx' union select database(),user()# Database():这个是查询数据库名称 user():这个是使用者权限
3x03 information_schema注入 还是使用字符型注入,在前面的报错推测中我们知到了两个字段和注入点是单引号,开始注入 1.首先获取基本信息:当前数据库名称 Payload: xxx’union select database(),user()#
2.现在我们知道了当前的数据库的名字叫pikachu 现在通过information_schema数据库来获取叫pikachu这个数据库中有多少个表,表的名称是什莫 Payload:xxx’union select table_schema,table_name from information_schema.tables where table_schema=”pikachu”#
现在我们已经爆表找到users 3.有了目标表的名称了,现在我们要找到列 Payload: xxx’union select table_name,column_name from information_schema.columns where table_name=’users’#
现在我们知道有一个数据库叫pikachu,pikachu中有一个表名叫users,表中有两个列一个是 username 一个是 password 现在信息已经足够了,现在直接爆出列的数据 Payload:xxx’union select username,password from users#
随便找个MD5解密就可以得到密码了 这样一次完整的入侵流程就这样完成了。 4x00 总结 我们在本文中介绍了SQL Injection的基本原理,通过介绍什么是SQL Injection,怎样进行SQL Injection。作为一名Web应用开发人员,一定不要盲目相信用户的输入,而要对用户输入的数据进行严格的校验处理,否则的话,SQL Injection将会不期而至。 总结注入流程 1.寻找注入点:一般都是1‘或者(1and1=1 1and1=2) 2.查看注入点类型:数字型一般不用,都是,因为没有引号所以直接被执行,但是字符型不同,字符型首先是有引号的,引号里面的不会被执行,只是查询,所以要将前面的引号闭合,构造执行语句,最后再注释掉后面的引号。 搜索型注入跟字符型注入同理,闭合——构造——注释/闭合 3.注入点提交方式: get:url提交 post&cookie:使用抓包工具进行提交 4.使用order by查询字段数 5.使用union查询来获得数据库信息 用户名user() 数据库版本 version() 服务器操作系统 @@version_compile_os 6利用information schema进行完整的注入 附件: |