sql注入

sql注入准备

环境

ubuntu+niginx+mysql+php sqli-labs
你也可以使用phpstudy打开nginx和mysql直接访问

##工具
burpsuit抓包
vscode编码

sql注入开始

//1 union select 1,2,3  第一件事 逃脱出单引号的控制 ------- 闭合单引号(加单引号)  
//但是单双引号要成对出现,python,java.....  
//2个办法   要么将多出来的单引号闭合  要么注释掉单引号
//mysql注释符   单行  --    #    多行-----  /** */     */
 
//需要知道联合查询的列数    要么试  要么查
//求当前表的列
//用order by 检测列数
//让第一个表为空,然后面连接的1,2,3显示,给个无效id就行   库名:security

//注入最终目的  注入管理员账号密码
//要知道管理员账号密码  首先要知道管理员表表名
//列名

一些指令函数

在这里插入图片描述

select substr(‘aaa’,1,1);从第一位开始截取截取一位

查看当前所处的数据库名
查看当前用户权限
查看当前登录数据的版本
length,截取函数
内置函数。。。。。

get传参

在这里插入图片描述

可以去mysql官网查看一些指令
链接: https://www.php.net/

连接数据库的
isset 检测变量是否已声明并且其值不为 null

一般get传参通过url
post传参一般是通过form表单

在这里插入图片描述
因为没有传参所以到这里
在这里插入图片描述

那就get传参数呗,
在这里插入图片描述

在这里插入图片描述

看代码,打开的result文件其实就是记录的日志文件的内容
后面就开始查询用where 条件id是谁就查谁
在这里插入图片描述

limit 0,1这里就是如果查询有多行就从第0行开始取1个,这里的意思就是最开始哪行

多用断点调试,查看具体的流程

sql

sql注入是合理合法的mysql执行语句,因为没有对用户的输入进行合理的过滤,导致意外的查询语句进到程序中,查询到本不应该查询的数据

字符型注入

有单双引号闭合需要闭合单双引号

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

那么这里是(用户输入)可控的,那是不是可以联表查询
本来id传的是1,那我现在传 select * from users where id=1 union select 1,2,3;

但是查出来没有反应,是因为数据库认为你的id是1 union select 1,2,3这么长,数据库的纠错机制就将union select 1,2,3给删了,还是查询的1,所以要逃脱单引号的控制,输入合理合法

在这里插入图片描述

在这里插入图片描述
改了之后查询还是报错?
因为在url进行地址栏传参的时候有编码规范,它会将#编码成%23,咋来的?

在这里插入图片描述
URLcode编码规范,先取assii再转成hex(16),再去掉前面的0x,加上%

在这里插入图片描述
成了!!!
把后面的 ’ 注释掉了,也将后面的单引号也注释掉了,正常回显了

好了!!!开始扩展思路了

在这里插入图片描述

但是你不知道select 后面对面数据库的表有几列

select * from goods order by gid desc;
//order by 用来排序,可以用户列数排序,desc表示倒序。默认正序asc


select * from goods order by gname desc;
//每一列都可以排序,基于ascii排序

在这里插入图片描述

但是不知道列名啊,诶嘿,mysql的列名可以用数字替换,用1可以代表第一列…

在这里插入图片描述

那么现在用order by 检测列数,但是不知道列数,反正代码里面有显示报错,比如20可以显示,30报错,那列数就在20 30 之间

在这里插入图片描述
在这里插入图片描述

注释 --空格  就是%20
--%20  也行
--+   也可以

让第一个表为空,然后面连接的1,2,3显示,给个无效id就行

在这里插入图片描述

select 1,2,可以展示那么 将这些换成mysql自带的函数可以不

在这里插入图片描述

在这里插入图片描述
那么当前的用户,权限,数据库名都ok了

库名:security

注入最终目的 注入管理员账号密码
要知道管理员账号密码 首先要知道管理员表表名
列名

在这里插入图片描述
mariadb默认三张表,mysql多了sys

mysql :mysql数据库的权限,用户对数据库的权限
performance_schema:性能,查表的快慢
information_schema:数据库表的信息

information_schema里面有tables 数据库里面所有的表名

colums:列名
schemata:所有数据库的库名

在这里插入图片描述

查到了库名,那看看information_schema里面的table

在这里插入图片描述

这个可疑,一个是数据表所处数据库的名称,一是数据表本身的表名

在这里插入图片描述
所有数据库名字

在这里插入图片描述
查到了所有数据库的所有表
但是我们要的是刚刚查到的数据表

在这里插入图片描述
那就查到了当前数据库下的所有表
users可疑

在这里插入图片描述
表名ok了,查列名
ok数据库名,表名,列名都查到了

上手,不and就把数据库下面的所有列名都查出来了
在这里插入图片描述
都有了直接查

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

数字型注入

在这里插入图片描述
在这里插入图片描述
直接显示数字都不需要闭合

在这里插入图片描述
在这里插入图片描述

直接查数据库和版本看看

在这里插入图片描述
看到了数据名是 security

那就查它
在这里插入图片描述
拉满

括号注入

在这里插入图片描述

在这里插入图片描述

看到了数据名那就查!!!

在这里插入图片描述

根据爆出的字段去查

在这里插入图片描述

双引号加括号

尝试注入,提示了双引号加括号
在这里插入图片描述

那就根据")去注入,记得后面加–+注释了

在这里插入图片描述

报错注入

?id=1’会报错,不加没显示,可以试试报错注入

在这里插入图片描述

用substr 最大截取32位,默认截取前32位

?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(username,0x3a,password)from users),1,32),0x7e),1) --+
?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(username,0x3a,password)from users),32,64),0x7e),1) --+


updatexml(xml_target, xpath_expr, new_xml)
xml_target:xml文档对象的名称,是一个string类型。
xpath_expr:使用xpath语法格式的路径。
new_xml:需要更新的内容。
第二个参数就是xml文件的路径,但是路径里不能用波浪线~ ,那就0x7e就是~的16进制表现的

SQL报错注入的应用:当使用updatexml(xml_target, xpath_expr, new_xml)函数时,若xpath_expr参数不符合xpath格式,就会报错。
而~符号(ascii编码值:0x7e)是不存在xpath格式中的, 所以一旦在xpath_expr参数中使用~符号,就会产生xpath syntax error (xpath语法错误),通过使用这个方法就可以达到报错注入的目的。

select group_concat(username,0x3a,password)from users;
select substr((select group_concat(username,0x3a,password)from users),32,64);

GROUP_CONCAT() 是聚合函数,将属于一组的相关行的数据项进行合并并以字符串的形式返回
0x3a就是  :   冒号,用来分隔其他字符串

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

一直截取,截完就好了

6:
在这里插入图片描述

这里闭合成了双引号而已
在这里插入图片描述

              
and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='security'),0x7e),1) --+


在这里插入图片描述

查完表就查表的字段

and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1) --+

在这里插入图片描述
在username paasword查就好了…

7

1:mysql用户权限必须为root,(现在很少给网站的权限为root,一般就是普通用户)

2:必须知道网站的物理路径(要导出webshell要导在网站里面,要访问到)

3:在my.ini里面有个参数必须为空 secure_file_priv
(my.cnf) 这要进到服务器才能改

三个参数
1:null 不让导出,默认配置就是null
2:写一个具体目录,只能往这个目录下导
3:啥都没有,啥目录都可以

在这里插入图片描述

在这里插入图片描述
有语法错误无所谓看文件生成没有

布尔盲注

错误不显示,页面展示不出报错和联合查询的效果,从侧面指标,页面回显正确与否
页面特征,加单引号为假,不加单引号为真

?id=1'and ascii(substr(database(),1,1))=115--+

substr截取当前数据库当前第一个字符s,转成ascii,不是115就是假,就能判断第一个字段是啥,

?id=1'and ascii(substr(database(),1,1))>115--+

取范围也ok

在这里插入图片描述
可以用sqlmap工具

可以使用二分法解决

在这里插入图片描述

出来了后面就按步骤走吧

时间盲注

这里的输入显示的解结果都是一样的 You are in…
状态没变,没法用布尔,那就用if 和sleep判断,真就沉睡,假就不沉睡
所有报错注入可能没戏了,所有可以试试时间注入

?id=1' and if(ascii(substr(database(),1,1)) > 100,sleep(3),0)--+
当注入的数据为真时,沉睡三秒


在这里插入图片描述
那就可以通过这样去查,转的久就是真,快就是假,用sqlmap或者脚本就行

post传参

联合查询

在这里插入图片描述


这里post传参不涉及url编码,直接#就可以
密码随便写,因为#将后面的闭合掉了
username随便写,让前面的查不到,才会让后面的回显
在这里插入图片描述


在这里插入图片描述
注入页面的回显是两个字段name和password


那就老样子用
a' union select 1,group_concat(table_name) from information_schema.tables where table_schema = 'security' #

在这里插入图片描述

12

就是") 注入

a") union select 1,group_concat(table_name) from information_schema.tables where table_schema = 'security' #

在这里插入图片描述

出来了就直接去查

报错注入

13
报错不会在页面展示了就报错注入,联合查询展示不出来

asas') and updatexml(1,concat(0x7e,user(),0x7e),1) #


在这里插入图片描述

a') and updatexml(1,concat(0x7e,substr((select group_concat(username,0x7e,password)from users),1,32),0x7e),1) #

在这里插入图片描述

布尔盲注

只能通过图显示正确,那就考虑布尔盲注

在这里插入图片描述

request登录记得这个参数
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

admin' and ascii(substr(database(),1,1)) > 110 #

还是看报错显示

脚本暴力破解
在这里插入图片描述

16
和15一样只是闭合方式不一样
在这里插入图片描述
能显示,ok,用暴力破解或者sqlmap都行

17 过滤了username

在这里插入图片描述
说明在这里报错注入

update
在这里插入图片描述

还有种方法

看好了
分组功能 group by 和count或者 having配合

随机数种子是0或者中子数固定的话那么值就是固定的,向下取整都是0,*2就不是了

在这里插入图片描述

在这里插入图片描述


那么分组不就成了1和0两组,我天,那用count统计分别多少个0建立虚表,,试试

在这里插入图片描述

主键重复?
为啥,ok来看看,下面是我老师写的一段笔记

这个整合然后计数的过程中,中间发生了什么我们是必须要明白的。
首先mysql遇到该语句时会建立一个虚拟表。该虚拟表有两个字段,一个是分组的key,一个是计数值count0。也就对应于实验中的user nome fПcountO。
然后在查询数据的时候,首先查看该虚拟表中是否存在该分组,如果存在那么计数值加1,不存在则新建该分组
然后mysq!官方有给过提示,就是查询的时候如果使用rand()的话,该值会被计算多次,那这个"被计算多次"到底是什么意思,就是在使用group by的时候fioor(rand(0)2)会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次,我们来看下oor(rand(0)2)报错的过程就知道了,从上面的的数使用中可以看到在一次多记录的查询过程中介oor(rand(0)2)的值是定性的,为011011(这个顺序很重要),报错实际上就是/loor(rand(0)2)被计算多次导致的,
select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)as y;

那这样比如第一次插入没有,主键插入的是root@localhost,到下次有了的话那就会报错,爆出主键重复,但是查询三次,数据至少要三条,再用group by将数据整合

在这里插入图片描述
在这里插入图片描述

18
username 和passwd都被过滤了
在这里插入图片描述

一个浏览器版本一个客户端ip

看代码注入点,注册登录就行了

在这里插入图片描述

在这里插入图片描述
burpsuit抓包改就行

发现
看那个能注入
发现这里x-forwarded-for不行
那就user-agnt试试
在这里插入图片描述

诶嘿可以,两种方法要么闭合要注释,但是注释的话后面的参数需要跟不要丢,不然小心报错

闭合
在这里插入图片描述

注释

在这里插入图片描述

19
在这里插入图片描述
在这里插入图片描述
改这里就可以了

20
这里没有过滤
代码原理就是先设置cookie,将cookie取出来,再select查询,由于存的时候和取的时候都没过滤,那就出问题了
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

21
base64编码
在这里插入图片描述
多了编解码的过程
说明注入语句要编码,因为它要解码

在这里插入图片描述

在这里插入图片描述

22
跟21的区别就是闭合不一样
在这里插入图片描述
23
在这里插入图片描述

不让注释,那直接闭合
在这里插入图片描述

二次注入

数据库往外取的时候没有过滤
也就是存的时候没办法注入,但是取的时候可以注入
二次注入的特点就是可以修改任意用户的密码

看代码
在这里插入图片描述
那就只需要更新现在写的密码
在这里插入图片描述
后面闭合就好了

那就注册用户 admin’#,单引号一闭合,后面的被注释,admin密码就被修改了
admin’# 这样当然可以注册,但是’#就把后面注释掉了
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值